rmc-tabs
Version:
React Mobile Tabs Component(web & react-native)
320 lines (276 loc) • 14 kB
JavaScript
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 });
;