UNPKG

rmc-tabs

Version:

React Mobile Tabs Component(web & react-native)

320 lines (276 loc) 14 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.Tabs = exports.StateType = undefined; var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _get2 = require('babel-runtime/helpers/get'); var _get3 = _interopRequireDefault(_get2); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _rcGesture = require('rc-gesture'); var _rcGesture2 = _interopRequireDefault(_rcGesture); var _TabPane = require('./TabPane'); var _DefaultTabBar = require('./DefaultTabBar'); var _util = require('./util'); var _Tabs = require('./Tabs.base'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var getPanDirection = function getPanDirection(direction) { switch (direction) { case 2: case 4: return 'horizontal'; case 8: case 16: return 'vertical'; default: return 'none'; } }; var StateType = exports.StateType = function (_BaseStateType) { (0, _inherits3['default'])(StateType, _BaseStateType); function StateType() { (0, _classCallCheck3['default'])(this, StateType); var _this = (0, _possibleConstructorReturn3['default'])(this, (StateType.__proto__ || Object.getPrototypeOf(StateType)).apply(this, arguments)); _this.contentPos = ''; _this.isMoving = false; return _this; } return StateType; }(_Tabs.StateType); var Tabs = exports.Tabs = function (_Component) { (0, _inherits3['default'])(Tabs, _Component); function Tabs(props) { (0, _classCallCheck3['default'])(this, Tabs); var _this2 = (0, _possibleConstructorReturn3['default'])(this, (Tabs.__proto__ || Object.getPrototypeOf(Tabs)).call(this, props)); _this2.onPan = function () { var lastOffset = 0; var finalOffset = 0; var panDirection = void 0; var getLastOffset = function getLastOffset() { var isVertical = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this2.isTabVertical(); var offset = +('' + lastOffset).replace('%', ''); if (('' + lastOffset).indexOf('%') >= 0) { offset /= 100; offset *= isVertical ? _this2.layout.clientHeight : _this2.layout.clientWidth; } return offset; }; return { onPanStart: function onPanStart(status) { if (!_this2.props.swipeable || !_this2.props.animated) return; panDirection = getPanDirection(status.direction); _this2.setState({ isMoving: true }); }, onPanMove: function onPanMove(status) { var _this2$props = _this2.props, swipeable = _this2$props.swipeable, animated = _this2$props.animated, useLeftInsteadTransform = _this2$props.useLeftInsteadTransform; if (!status.moveStatus || !_this2.layout || !swipeable || !animated) return; var isVertical = _this2.isTabVertical(); var offset = getLastOffset(); if (isVertical) { offset += panDirection === 'horizontal' ? 0 : status.moveStatus.y; } else { offset += panDirection === 'vertical' ? 0 : status.moveStatus.x; } var canScrollOffset = isVertical ? -_this2.layout.scrollHeight + _this2.layout.clientHeight : -_this2.layout.scrollWidth + _this2.layout.clientWidth; offset = Math.min(offset, 0); offset = Math.max(offset, canScrollOffset); (0, _util.setPxStyle)(_this2.layout, offset, 'px', isVertical, useLeftInsteadTransform); finalOffset = offset; }, onPanEnd: function onPanEnd() { if (!_this2.props.swipeable || !_this2.props.animated) return; lastOffset = finalOffset; var isVertical = _this2.isTabVertical(); var offsetIndex = _this2.getOffsetIndex(finalOffset, isVertical ? _this2.layout.clientHeight : _this2.layout.clientWidth); _this2.setState({ isMoving: false }); if (offsetIndex === _this2.state.currentTab) { if (_this2.props.usePaged) { (0, _util.setTransform)(_this2.layout.style, _this2.getContentPosByIndex(offsetIndex, _this2.isTabVertical(), _this2.props.useLeftInsteadTransform)); } } else { _this2.goToTab(offsetIndex); } }, setCurrentOffset: function setCurrentOffset(offset) { return lastOffset = offset; } }; }(); _this2.onSwipe = function (status) { var _this2$props2 = _this2.props, tabBarPosition = _this2$props2.tabBarPosition, swipeable = _this2$props2.swipeable, usePaged = _this2$props2.usePaged; if (!swipeable || !usePaged || _this2.isTabVertical()) return; // DIRECTION_NONE 1 // DIRECTION_LEFT 2 // DIRECTION_RIGHT 4 // DIRECTION_UP 8 // DIRECTION_DOWN 16 // DIRECTION_HORIZONTAL 6 // DIRECTION_VERTICAL 24 // DIRECTION_ALL 30 switch (tabBarPosition) { case 'top': case 'bottom': switch (status.direction) { case 2: if (!_this2.isTabVertical()) { _this2.goToTab(_this2.prevCurrentTab + 1); } case 8: if (_this2.isTabVertical()) { _this2.goToTab(_this2.prevCurrentTab + 1); } break; case 4: if (!_this2.isTabVertical()) { _this2.goToTab(_this2.prevCurrentTab - 1); } case 16: if (_this2.isTabVertical()) { _this2.goToTab(_this2.prevCurrentTab - 1); } break; } break; } }; _this2.setContentLayout = function (div) { _this2.layout = div; }; _this2.state = (0, _extends3['default'])({}, _this2.state, new StateType(), { contentPos: _this2.getContentPosByIndex(_this2.getTabIndex(props), _this2.isTabVertical(props.tabDirection), props.useLeftInsteadTransform) }); return _this2; } (0, _createClass3['default'])(Tabs, [{ key: 'goToTab', value: function goToTab(index) { var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var usePaged = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.props.usePaged; var props = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : this.props; var tabDirection = props.tabDirection, useLeftInsteadTransform = props.useLeftInsteadTransform; var newState = {}; if (usePaged) { newState = { contentPos: this.getContentPosByIndex(index, this.isTabVertical(tabDirection), useLeftInsteadTransform) }; } return (0, _get3['default'])(Tabs.prototype.__proto__ || Object.getPrototypeOf(Tabs.prototype), 'goToTab', this).call(this, index, force, newState, props); } }, { key: 'tabClickGoToTab', value: function tabClickGoToTab(index) { this.goToTab(index, false, true); } }, { key: 'getContentPosByIndex', value: function getContentPosByIndex(index, isVertical) { var useLeft = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var value = -index * 100 + '%'; this.onPan.setCurrentOffset(value); if (useLeft) { return '' + value; } else { var translate = isVertical ? '0px, ' + value : value + ', 0px'; // fix: content overlay TabBar on iOS 10. ( 0px -> 1px ) return 'translate3d(' + translate + ', 1px)'; } } }, { key: 'renderContent', value: function renderContent() { var _this3 = this; var getSubElements = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getSubElements(); var _props = this.props, prefixCls = _props.prefixCls, tabs = _props.tabs, animated = _props.animated, destroyInactiveTab = _props.destroyInactiveTab, useLeftInsteadTransform = _props.useLeftInsteadTransform; var _state = this.state, currentTab = _state.currentTab, isMoving = _state.isMoving, contentPos = _state.contentPos; var isTabVertical = this.isTabVertical(); var contentCls = prefixCls + '-content-wrap'; if (animated && !isMoving) { contentCls += ' ' + contentCls + '-animated'; } var contentStyle = animated ? useLeftInsteadTransform ? (0, _extends3['default'])({ position: 'relative' }, this.isTabVertical() ? { top: contentPos } : { left: contentPos }) : (0, _util.getTransformPropValue)(contentPos) : (0, _extends3['default'])({ position: 'relative' }, this.isTabVertical() ? { top: -currentTab * 100 + '%' } : { left: -currentTab * 100 + '%' }); var _getTabBarBaseProps = this.getTabBarBaseProps(), instanceId = _getTabBarBaseProps.instanceId; return _react2['default'].createElement( 'div', { className: contentCls, style: contentStyle, ref: this.setContentLayout }, tabs.map(function (tab, index) { var cls = prefixCls + '-pane-wrap'; if (_this3.state.currentTab === index) { cls += ' ' + cls + '-active'; } else { cls += ' ' + cls + '-inactive'; } var key = tab.key || 'tab_' + index; // update tab cache if (_this3.shouldRenderTab(index)) { _this3.tabCache[index] = _this3.getSubElement(tab, index, getSubElements); } else if (destroyInactiveTab) { _this3.tabCache[index] = undefined; } return _react2['default'].createElement( _TabPane.TabPane, { key: key, className: cls, active: currentTab === index, role: 'tabpanel', 'aria-hidden': currentTab !== index, 'aria-labelledby': 'm-tabs-' + instanceId + '-' + index, fixX: isTabVertical, fixY: !isTabVertical }, _this3.tabCache[index] ); }) ); } }, { key: 'render', value: function render() { var _props2 = this.props, prefixCls = _props2.prefixCls, tabBarPosition = _props2.tabBarPosition, tabDirection = _props2.tabDirection, useOnPan = _props2.useOnPan, noRenderContent = _props2.noRenderContent; var isTabVertical = this.isTabVertical(tabDirection); var tabBarProps = (0, _extends3['default'])({}, this.getTabBarBaseProps()); var onPan = !isTabVertical && useOnPan ? this.onPan : {}; var content = [_react2['default'].createElement( 'div', { key: 'tabBar', className: prefixCls + '-tab-bar-wrap' }, this.renderTabBar(tabBarProps, _DefaultTabBar.DefaultTabBar) ), !noRenderContent && _react2['default'].createElement( _rcGesture2['default'], (0, _extends3['default'])({ key: '$content', onSwipe: this.onSwipe }, onPan), this.renderContent() )]; return _react2['default'].createElement( 'div', { className: prefixCls + ' ' + prefixCls + '-' + tabDirection + ' ' + prefixCls + '-' + tabBarPosition }, tabBarPosition === 'top' || tabBarPosition === 'left' ? content : content.reverse() ); } }]); return Tabs; }(_Tabs.Tabs); Tabs.DefaultTabBar = _DefaultTabBar.DefaultTabBar; Tabs.defaultProps = (0, _extends3['default'])({}, _Tabs.Tabs.defaultProps, { prefixCls: 'rmc-tabs', useOnPan: true });