UNPKG

13.3 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
8
9var _react = require('react');
10
11var _react2 = _interopRequireDefault(_react);
12
13var _propTypes = require('prop-types');
14
15var _propTypes2 = _interopRequireDefault(_propTypes);
16
17var _classnames3 = require('classnames');
18
19var _classnames4 = _interopRequireDefault(_classnames3);
20
21var _reactHammerjs = require('react-hammerjs');
22
23var _reactHammerjs2 = _interopRequireDefault(_reactHammerjs);
24
25var _reactDom = require('react-dom');
26
27var _reactDom2 = _interopRequireDefault(_reactDom);
28
29var _utils = require('./utils');
30
31function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
32
33function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }
34
35function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
36
37function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
38
39function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
40
41function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : _defaults(subClass, superClass); } /**
42 * This source code is quoted from rc-tabs.
43 * homepage: https://github.com/react-component/tabs
44 */
45
46
47var SwipeableTabBarNode = function (_React$Component) {
48 _inherits(SwipeableTabBarNode, _React$Component);
49
50 function SwipeableTabBarNode(props) {
51 _classCallCheck(this, SwipeableTabBarNode);
52
53 var _this = _possibleConstructorReturn(this, _React$Component.call(this, props));
54
55 _initialiseProps.call(_this);
56
57 var _this$checkPagination = _this.checkPaginationByKey(_this.props.activeKey),
58 hasPrevPage = _this$checkPagination.hasPrevPage,
59 hasNextPage = _this$checkPagination.hasNextPage;
60
61 _this.state = {
62 hasPrevPage: hasPrevPage,
63 hasNextPage: hasNextPage
64 };
65 return _this;
66 }
67
68 SwipeableTabBarNode.prototype.componentDidMount = function componentDidMount() {
69 var swipe = this.props.getRef('swipe');
70 var nav = this.props.getRef('nav');
71 var activeKey = this.props.activeKey;
72
73 this.swipeNode = _reactDom2["default"].findDOMNode(swipe); // dom which scroll (9999px)
74 this.realNode = _reactDom2["default"].findDOMNode(nav); // dom which visiable in screen (viewport)
75 this.setCache();
76 this.setSwipePositionByKey(activeKey);
77 };
78
79 SwipeableTabBarNode.prototype.componentDidUpdate = function componentDidUpdate(prevProps) {
80 this.setCache();
81 if (this.props.activeKey && this.props.activeKey !== prevProps.activeKey || this.props.panels.length !== prevProps.panels.length || this.props.pageSize !== prevProps.pageSize) {
82 this.setSwipePositionByKey(this.props.activeKey);
83 }
84 };
85
86 SwipeableTabBarNode.prototype.setCache = function setCache() {
87 var _props = this.props,
88 tabBarPosition = _props.tabBarPosition,
89 pageSize = _props.pageSize,
90 panels = _props.panels;
91
92 var _isVertical = (0, _utils.isVertical)(tabBarPosition);
93 var _viewSize = (0, _utils.getStyle)(this.realNode, _isVertical ? 'height' : 'width');
94 var _tabWidth = _viewSize / pageSize;
95 this.cache = _extends({}, this.cache, {
96 vertical: _isVertical,
97 totalAvaliableDelta: _tabWidth * panels.length - _viewSize,
98 tabWidth: _tabWidth
99 });
100 };
101
102 /**
103 * used for props.activeKey setting, not for swipe callback
104 */
105
106
107 SwipeableTabBarNode.prototype.getDeltaByKey = function getDeltaByKey(activeKey) {
108 var pageSize = this.props.pageSize;
109
110 var index = this.getIndexByKey(activeKey);
111 var centerTabCount = Math.floor(pageSize / 2);
112 var tabWidth = this.cache.tabWidth;
113
114 var delta = (index - centerTabCount) * tabWidth;
115 // in rtl direction tabs are ordered from right to left, so delta should be positive in order to
116 // push swiped element to righ side (start of view)
117 if (!this.isRtl()) {
118 delta *= -1;
119 }
120 return delta;
121 };
122
123 SwipeableTabBarNode.prototype.getIndexByKey = function getIndexByKey(activeKey) {
124 var panels = this.props.panels;
125
126 var length = panels.length;
127 for (var i = 0; i < length; i++) {
128 if (panels[i].key === activeKey) {
129 return i;
130 }
131 }
132 return -1;
133 };
134
135 SwipeableTabBarNode.prototype.setSwipePositionByKey = function setSwipePositionByKey(activeKey) {
136 var _checkPaginationByKey = this.checkPaginationByKey(activeKey),
137 hasPrevPage = _checkPaginationByKey.hasPrevPage,
138 hasNextPage = _checkPaginationByKey.hasNextPage;
139
140 var totalAvaliableDelta = this.cache.totalAvaliableDelta;
141
142 this.setState({
143 hasPrevPage: hasPrevPage,
144 hasNextPage: hasNextPage
145 });
146 var delta = void 0;
147 if (!hasPrevPage) {
148 // the first page
149 delta = 0;
150 } else if (!hasNextPage) {
151 // the last page
152 delta = this.isRtl() ? totalAvaliableDelta : -totalAvaliableDelta;
153 } else if (hasNextPage) {
154 // the middle page
155 delta = this.getDeltaByKey(activeKey);
156 }
157 this.cache.totalDelta = delta;
158 this.setSwipePosition();
159 };
160
161 SwipeableTabBarNode.prototype.setSwipePosition = function setSwipePosition() {
162 var _cache = this.cache,
163 totalDelta = _cache.totalDelta,
164 vertical = _cache.vertical;
165
166 (0, _utils.setPxStyle)(this.swipeNode, totalDelta, vertical);
167 };
168
169 SwipeableTabBarNode.prototype.checkPaginationByKey = function checkPaginationByKey(activeKey) {
170 var _props2 = this.props,
171 panels = _props2.panels,
172 pageSize = _props2.pageSize;
173
174 var index = this.getIndexByKey(activeKey);
175 var centerTabCount = Math.floor(pageSize / 2);
176 // the basic rule is to make activeTab be shown in the center of TabBar viewport
177 return {
178 hasPrevPage: index - centerTabCount > 0,
179 hasNextPage: index + centerTabCount < panels.length
180 };
181 };
182
183 SwipeableTabBarNode.prototype.checkPaginationByDelta = function checkPaginationByDelta(delta) {
184 var totalAvaliableDelta = this.cache.totalAvaliableDelta;
185
186 return {
187 hasPrevPage: delta < 0,
188 hasNextPage: -delta < totalAvaliableDelta
189 };
190 };
191
192 SwipeableTabBarNode.prototype.isRtl = function isRtl() {
193 return this.props.direction === 'rtl';
194 };
195
196 SwipeableTabBarNode.prototype.render = function render() {
197 var _classnames2;
198
199 var _props3 = this.props,
200 clsPrefix = _props3.clsPrefix,
201 hammerOptions = _props3.hammerOptions,
202 tabBarPosition = _props3.tabBarPosition;
203 var _state = this.state,
204 hasPrevPage = _state.hasPrevPage,
205 hasNextPage = _state.hasNextPage;
206
207 var navClassName = clsPrefix + '-nav';
208 var navClasses = (0, _classnames4["default"])(_defineProperty({}, navClassName, true));
209 var events = {
210 onPan: this.onPan
211 };
212 return _react2["default"].createElement(
213 'div',
214 {
215 className: (0, _classnames4["default"])((_classnames2 = {}, _defineProperty(_classnames2, clsPrefix + '-nav-container', 1), _defineProperty(_classnames2, clsPrefix + '-nav-swipe-container', 1), _defineProperty(_classnames2, clsPrefix + '-prevpage', hasPrevPage), _defineProperty(_classnames2, clsPrefix + '-nextpage', hasNextPage), _classnames2)),
216 key: 'container',
217 ref: this.props.saveRef('container')
218 },
219 _react2["default"].createElement(
220 'div',
221 { className: clsPrefix + '-nav-wrap', ref: this.props.saveRef('navWrap') },
222 _react2["default"].createElement(
223 _reactHammerjs2["default"],
224 _extends({}, events, {
225 direction: (0, _utils.isVertical)(tabBarPosition) ? 'DIRECTION_ALL' : 'DIRECTION_HORIZONTAL',
226 options: hammerOptions
227 }),
228 _react2["default"].createElement(
229 'div',
230 { className: clsPrefix + '-nav-swipe', ref: this.props.saveRef('swipe') },
231 _react2["default"].createElement(
232 'div',
233 { className: navClasses, ref: this.props.saveRef('nav') },
234 this.props.children
235 )
236 )
237 )
238 )
239 );
240 };
241
242 return SwipeableTabBarNode;
243}(_react2["default"].Component);
244
245var _initialiseProps = function _initialiseProps() {
246 var _this2 = this;
247
248 this.onPan = function (e) {
249 var _cache2 = _this2.cache,
250 vertical = _cache2.vertical,
251 totalAvaliableDelta = _cache2.totalAvaliableDelta,
252 totalDelta = _cache2.totalDelta;
253 var speed = _this2.props.speed;
254 // calculate touch distance
255
256 var nowDelta = vertical ? e.deltaY : e.deltaX;
257 nowDelta *= speed / 10;
258
259 // calculate distance dom need transform
260 var _nextDelta = nowDelta + totalDelta;
261
262 if (_this2.isRtl()) {
263 // calculate distance from right when direction is right-to-left
264 if (_nextDelta <= 0) {
265 _nextDelta = 0;
266 } else if (_nextDelta >= totalAvaliableDelta) {
267 _nextDelta = totalAvaliableDelta;
268 }
269 }
270 // calculate distance from left when direction is left-to-right
271 else if (_nextDelta >= 0) {
272 _nextDelta = 0;
273 } else if (_nextDelta <= -totalAvaliableDelta) {
274 _nextDelta = -totalAvaliableDelta;
275 }
276
277 _this2.cache.totalDelta = _nextDelta;
278 _this2.setSwipePosition();
279
280 // calculate pagination display
281
282 var _checkPaginationByDel = _this2.checkPaginationByDelta(_this2.cache.totalDelta),
283 hasPrevPage = _checkPaginationByDel.hasPrevPage,
284 hasNextPage = _checkPaginationByDel.hasNextPage;
285
286 if (hasPrevPage !== _this2.state.hasPrevPage || hasNextPage !== _this2.state.hasNextPage) {
287 _this2.setState({
288 hasPrevPage: hasPrevPage,
289 hasNextPage: hasNextPage
290 });
291 }
292 };
293};
294
295exports["default"] = SwipeableTabBarNode;
296
297
298SwipeableTabBarNode.propTypes = {
299 activeKey: _propTypes2["default"].string,
300 panels: _propTypes2["default"].node,
301 pageSize: _propTypes2["default"].number,
302 tabBarPosition: _propTypes2["default"].oneOf(['left', 'right', 'top', 'bottom']),
303 clsPrefix: _propTypes2["default"].string,
304 children: _propTypes2["default"].node,
305 hammerOptions: _propTypes2["default"].object,
306 speed: _propTypes2["default"].number,
307 saveRef: _propTypes2["default"].func,
308 getRef: _propTypes2["default"].func,
309 direction: _propTypes2["default"].string
310};
311
312SwipeableTabBarNode.defaultProps = {
313 panels: null,
314 tabBarPosition: 'top',
315 clsPrefix: '',
316 children: null,
317 hammerOptions: {},
318 pageSize: 5, // per page show how many tabs
319 speed: 7, // swipe speed, 1 to 10, more bigger more faster
320 saveRef: function saveRef() {},
321 getRef: function getRef() {}
322};
323module.exports = exports['default'];
\No newline at end of file