UNPKG

4.01 kBJavaScriptView Raw
1/**
2* This source code is quoted from rc-tabs.
3* homepage: https://github.com/react-component/tabs
4*/
5import React from 'react';
6import PropTypes from 'prop-types';
7import classnames from 'classnames';
8import { setTransform, isTransformSupported, getLeft, getStyle, getTop, getActiveIndex } from './utils';
9
10function componentDidUpdate(component, init) {
11 const { styles, panels, activeKey, direction } = component.props;
12 const rootNode = component.props.getRef('root');
13 const wrapNode = component.props.getRef('nav') || rootNode;
14 const inkBarNode = component.props.getRef('inkBar');
15 const activeTab = component.props.getRef('activeTab');
16 const inkBarNodeStyle = inkBarNode.style;
17 const tabBarPosition = component.props.tabBarPosition;
18 const activeIndex = getActiveIndex(panels, activeKey);
19 if (init) {
20 // prevent mount animation
21 inkBarNodeStyle.display = 'none';
22 }
23 if (activeTab) {
24 const tabNode = activeTab;
25 const transformSupported = isTransformSupported(inkBarNodeStyle);
26
27 // Reset current style
28 setTransform(inkBarNodeStyle, '');
29 inkBarNodeStyle.width = '';
30 inkBarNodeStyle.height = '';
31 inkBarNodeStyle.left = '';
32 inkBarNodeStyle.top = '';
33 inkBarNodeStyle.bottom = '';
34 inkBarNodeStyle.right = '';
35
36 if (tabBarPosition === 'top' || tabBarPosition === 'bottom') {
37 let left = getLeft(tabNode, wrapNode);
38 let width = tabNode.offsetWidth;
39
40 // If tabNode'width width equal to wrapNode'width when tabBarPosition is top or bottom
41 // It means no css working, then ink bar should not have width until css is loaded
42 // Fix https://github.com/ant-design/ant-design/issues/7564
43 if (width === rootNode.offsetWidth) {
44 width = 0;
45 } else if (styles.inkBar && styles.inkBar.width !== undefined) {
46 width = parseFloat(styles.inkBar.width, 10);
47 if (width) {
48 left += (tabNode.offsetWidth - width) / 2;
49 }
50 }
51 if (direction === 'rtl') {
52 left = getStyle(tabNode, 'margin-left') - left;
53 }
54 // use 3d gpu to optimize render
55 if (transformSupported) {
56 setTransform(inkBarNodeStyle, `translate3d(${left}px,0,0)`);
57 } else {
58 inkBarNodeStyle.left = `${left}px`;
59 }
60 inkBarNodeStyle.width = `${width}px`;
61 } else {
62 let top = getTop(tabNode, wrapNode, true);
63 let height = tabNode.offsetHeight;
64 if (styles.inkBar && styles.inkBar.height !== undefined) {
65 height = parseFloat(styles.inkBar.height, 10);
66 if (height) {
67 top += (tabNode.offsetHeight - height) / 2;
68 }
69 }
70 if (transformSupported) {
71 setTransform(inkBarNodeStyle, `translate3d(0,${top}px,0)`);
72 inkBarNodeStyle.top = '0';
73 } else {
74 inkBarNodeStyle.top = `${top}px`;
75 }
76 inkBarNodeStyle.height = `${height}px`;
77 }
78 }
79 inkBarNodeStyle.display = activeIndex !== -1 ? 'block' : 'none';
80}
81
82export default class InkTabBarNode extends React.Component {
83 componentDidMount() {
84 this.timeout = setTimeout(() => {
85 componentDidUpdate(this, true);
86 }, 0);
87 }
88
89 componentDidUpdate() {
90 componentDidUpdate(this);
91 }
92
93 componentWillUnmount() {
94 clearTimeout(this.timeout);
95 }
96
97 render() {
98 const { clsPrefix, styles, inkBarAnimated } = this.props;
99 const className = `${clsPrefix}-ink-bar`;
100 const classes = classnames({
101 [className]: true,
102 [
103 inkBarAnimated ?
104 `${className}-animated` :
105 `${className}-no-animated`
106 ]: true,
107 });
108 return (
109 <div
110 style={styles.inkBar}
111 className={classes}
112 key="inkBar"
113 ref={this.props.saveRef('inkBar')}
114 />
115 );
116 }
117}
118
119InkTabBarNode.propTypes = {
120 clsPrefix: PropTypes.string,
121 styles: PropTypes.object,
122 inkBarAnimated: PropTypes.bool,
123 saveRef: PropTypes.func,
124 direction: PropTypes.string,
125};
126
127InkTabBarNode.defaultProps = {
128 clsPrefix: '',
129 inkBarAnimated: true,
130 styles: {},
131 saveRef: () => { },
132};