UNPKG

12.9 kBJavaScriptView Raw
1import _extends from 'babel-runtime/helpers/extends';
2import _createClass from 'babel-runtime/helpers/createClass';
3import _get from 'babel-runtime/helpers/get';
4import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
5import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
6import _inherits from 'babel-runtime/helpers/inherits';
7import React from 'react';
8import Gesture from 'rc-gesture';
9import { TabPane } from './TabPane';
10import { DefaultTabBar } from './DefaultTabBar';
11import { getTransformPropValue, setTransform, setPxStyle } from './util';
12import { Tabs as Component, StateType as BaseStateType } from './Tabs.base';
13var getPanDirection = function getPanDirection(direction) {
14 switch (direction) {
15 case 2:
16 case 4:
17 return 'horizontal';
18 case 8:
19 case 16:
20 return 'vertical';
21 default:
22 return 'none';
23 }
24};
25export var StateType = function (_BaseStateType) {
26 _inherits(StateType, _BaseStateType);
27
28 function StateType() {
29 _classCallCheck(this, StateType);
30
31 var _this = _possibleConstructorReturn(this, (StateType.__proto__ || Object.getPrototypeOf(StateType)).apply(this, arguments));
32
33 _this.contentPos = '';
34 _this.isMoving = false;
35 return _this;
36 }
37
38 return StateType;
39}(BaseStateType);
40export var Tabs = function (_Component) {
41 _inherits(Tabs, _Component);
42
43 function Tabs(props) {
44 _classCallCheck(this, Tabs);
45
46 var _this2 = _possibleConstructorReturn(this, (Tabs.__proto__ || Object.getPrototypeOf(Tabs)).call(this, props));
47
48 _this2.onPan = function () {
49 var lastOffset = 0;
50 var finalOffset = 0;
51 var panDirection = void 0;
52 var getLastOffset = function getLastOffset() {
53 var isVertical = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this2.isTabVertical();
54
55 var offset = +('' + lastOffset).replace('%', '');
56 if (('' + lastOffset).indexOf('%') >= 0) {
57 offset /= 100;
58 offset *= isVertical ? _this2.layout.clientHeight : _this2.layout.clientWidth;
59 }
60 return offset;
61 };
62 return {
63 onPanStart: function onPanStart(status) {
64 if (!_this2.props.swipeable || !_this2.props.animated) return;
65 panDirection = getPanDirection(status.direction);
66 _this2.setState({
67 isMoving: true
68 });
69 },
70 onPanMove: function onPanMove(status) {
71 var _this2$props = _this2.props,
72 swipeable = _this2$props.swipeable,
73 animated = _this2$props.animated,
74 useLeftInsteadTransform = _this2$props.useLeftInsteadTransform;
75
76 if (!status.moveStatus || !_this2.layout || !swipeable || !animated) return;
77 var isVertical = _this2.isTabVertical();
78 var offset = getLastOffset();
79 if (isVertical) {
80 offset += panDirection === 'horizontal' ? 0 : status.moveStatus.y;
81 } else {
82 offset += panDirection === 'vertical' ? 0 : status.moveStatus.x;
83 }
84 var canScrollOffset = isVertical ? -_this2.layout.scrollHeight + _this2.layout.clientHeight : -_this2.layout.scrollWidth + _this2.layout.clientWidth;
85 offset = Math.min(offset, 0);
86 offset = Math.max(offset, canScrollOffset);
87 setPxStyle(_this2.layout, offset, 'px', isVertical, useLeftInsteadTransform);
88 finalOffset = offset;
89 },
90 onPanEnd: function onPanEnd() {
91 if (!_this2.props.swipeable || !_this2.props.animated) return;
92 lastOffset = finalOffset;
93 var isVertical = _this2.isTabVertical();
94 var offsetIndex = _this2.getOffsetIndex(finalOffset, isVertical ? _this2.layout.clientHeight : _this2.layout.clientWidth);
95 _this2.setState({
96 isMoving: false
97 });
98 if (offsetIndex === _this2.state.currentTab) {
99 if (_this2.props.usePaged) {
100 setTransform(_this2.layout.style, _this2.getContentPosByIndex(offsetIndex, _this2.isTabVertical(), _this2.props.useLeftInsteadTransform));
101 }
102 } else {
103 _this2.goToTab(offsetIndex);
104 }
105 },
106 setCurrentOffset: function setCurrentOffset(offset) {
107 return lastOffset = offset;
108 }
109 };
110 }();
111 _this2.onSwipe = function (status) {
112 var _this2$props2 = _this2.props,
113 tabBarPosition = _this2$props2.tabBarPosition,
114 swipeable = _this2$props2.swipeable,
115 usePaged = _this2$props2.usePaged;
116
117 if (!swipeable || !usePaged || _this2.isTabVertical()) return;
118 // DIRECTION_NONE 1
119 // DIRECTION_LEFT 2
120 // DIRECTION_RIGHT 4
121 // DIRECTION_UP 8
122 // DIRECTION_DOWN 16
123 // DIRECTION_HORIZONTAL 6
124 // DIRECTION_VERTICAL 24
125 // DIRECTION_ALL 30
126 switch (tabBarPosition) {
127 case 'top':
128 case 'bottom':
129 switch (status.direction) {
130 case 2:
131 if (!_this2.isTabVertical()) {
132 _this2.goToTab(_this2.prevCurrentTab + 1);
133 }
134 case 8:
135 if (_this2.isTabVertical()) {
136 _this2.goToTab(_this2.prevCurrentTab + 1);
137 }
138 break;
139 case 4:
140 if (!_this2.isTabVertical()) {
141 _this2.goToTab(_this2.prevCurrentTab - 1);
142 }
143 case 16:
144 if (_this2.isTabVertical()) {
145 _this2.goToTab(_this2.prevCurrentTab - 1);
146 }
147 break;
148 }
149 break;
150 }
151 };
152 _this2.setContentLayout = function (div) {
153 _this2.layout = div;
154 };
155 _this2.state = _extends({}, _this2.state, new StateType(), { contentPos: _this2.getContentPosByIndex(_this2.getTabIndex(props), _this2.isTabVertical(props.tabDirection), props.useLeftInsteadTransform) });
156 return _this2;
157 }
158
159 _createClass(Tabs, [{
160 key: 'goToTab',
161 value: function goToTab(index) {
162 var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
163 var usePaged = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.props.usePaged;
164 var props = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : this.props;
165 var tabDirection = props.tabDirection,
166 useLeftInsteadTransform = props.useLeftInsteadTransform;
167
168 var newState = {};
169 if (usePaged) {
170 newState = {
171 contentPos: this.getContentPosByIndex(index, this.isTabVertical(tabDirection), useLeftInsteadTransform)
172 };
173 }
174 return _get(Tabs.prototype.__proto__ || Object.getPrototypeOf(Tabs.prototype), 'goToTab', this).call(this, index, force, newState, props);
175 }
176 }, {
177 key: 'tabClickGoToTab',
178 value: function tabClickGoToTab(index) {
179 this.goToTab(index, false, true);
180 }
181 }, {
182 key: 'getContentPosByIndex',
183 value: function getContentPosByIndex(index, isVertical) {
184 var useLeft = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
185
186 var value = -index * 100 + '%';
187 this.onPan.setCurrentOffset(value);
188 if (useLeft) {
189 return '' + value;
190 } else {
191 var translate = isVertical ? '0px, ' + value : value + ', 0px';
192 // fix: content overlay TabBar on iOS 10. ( 0px -> 1px )
193 return 'translate3d(' + translate + ', 1px)';
194 }
195 }
196 }, {
197 key: 'renderContent',
198 value: function renderContent() {
199 var _this3 = this;
200
201 var getSubElements = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getSubElements();
202 var _props = this.props,
203 prefixCls = _props.prefixCls,
204 tabs = _props.tabs,
205 animated = _props.animated,
206 destroyInactiveTab = _props.destroyInactiveTab,
207 useLeftInsteadTransform = _props.useLeftInsteadTransform;
208 var _state = this.state,
209 currentTab = _state.currentTab,
210 isMoving = _state.isMoving,
211 contentPos = _state.contentPos;
212
213 var isTabVertical = this.isTabVertical();
214 var contentCls = prefixCls + '-content-wrap';
215 if (animated && !isMoving) {
216 contentCls += ' ' + contentCls + '-animated';
217 }
218 var contentStyle = animated ? useLeftInsteadTransform ? _extends({ position: 'relative' }, this.isTabVertical() ? { top: contentPos } : { left: contentPos }) : getTransformPropValue(contentPos) : _extends({ position: 'relative' }, this.isTabVertical() ? { top: -currentTab * 100 + '%' } : { left: -currentTab * 100 + '%' });
219
220 var _getTabBarBaseProps = this.getTabBarBaseProps(),
221 instanceId = _getTabBarBaseProps.instanceId;
222
223 return React.createElement(
224 'div',
225 { className: contentCls, style: contentStyle, ref: this.setContentLayout },
226 tabs.map(function (tab, index) {
227 var cls = prefixCls + '-pane-wrap';
228 if (_this3.state.currentTab === index) {
229 cls += ' ' + cls + '-active';
230 } else {
231 cls += ' ' + cls + '-inactive';
232 }
233 var key = tab.key || 'tab_' + index;
234 // update tab cache
235 if (_this3.shouldRenderTab(index)) {
236 _this3.tabCache[index] = _this3.getSubElement(tab, index, getSubElements);
237 } else if (destroyInactiveTab) {
238 _this3.tabCache[index] = undefined;
239 }
240 return React.createElement(
241 TabPane,
242 { key: key, className: cls, active: currentTab === index, role: 'tabpanel', 'aria-hidden': currentTab !== index, 'aria-labelledby': 'm-tabs-' + instanceId + '-' + index, fixX: isTabVertical, fixY: !isTabVertical },
243 _this3.tabCache[index]
244 );
245 })
246 );
247 }
248 }, {
249 key: 'render',
250 value: function render() {
251 var _props2 = this.props,
252 prefixCls = _props2.prefixCls,
253 tabBarPosition = _props2.tabBarPosition,
254 tabDirection = _props2.tabDirection,
255 useOnPan = _props2.useOnPan,
256 noRenderContent = _props2.noRenderContent;
257
258 var isTabVertical = this.isTabVertical(tabDirection);
259 var tabBarProps = _extends({}, this.getTabBarBaseProps());
260 var onPan = !isTabVertical && useOnPan ? this.onPan : {};
261 var content = [React.createElement(
262 'div',
263 { key: 'tabBar', className: prefixCls + '-tab-bar-wrap' },
264 this.renderTabBar(tabBarProps, DefaultTabBar)
265 ), !noRenderContent && React.createElement(
266 Gesture,
267 _extends({ key: '$content', onSwipe: this.onSwipe }, onPan),
268 this.renderContent()
269 )];
270 return React.createElement(
271 'div',
272 { className: prefixCls + ' ' + prefixCls + '-' + tabDirection + ' ' + prefixCls + '-' + tabBarPosition },
273 tabBarPosition === 'top' || tabBarPosition === 'left' ? content : content.reverse()
274 );
275 }
276 }]);
277
278 return Tabs;
279}(Component);
280Tabs.DefaultTabBar = DefaultTabBar;
281Tabs.defaultProps = _extends({}, Component.defaultProps, { prefixCls: 'rmc-tabs', useOnPan: true });
\No newline at end of file