rmc-tabs
Version:
React Mobile Tabs Component(web & react-native)
233 lines (221 loc) • 10.7 kB
JavaScript
import _extends from 'babel-runtime/helpers/extends';
import _createClass from 'babel-runtime/helpers/createClass';
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
import _inherits from 'babel-runtime/helpers/inherits';
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
var __rest = this && this.__rest || function (s, e) {
var t = {};
for (var p in s) {
if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
}if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0) t[p[i]] = s[p[i]];
}return t;
};
import React from 'react';
import Gesture from 'rc-gesture';
import { setPxStyle, getTransformPropValue, getPxStyle } from './util';
export var StateType = function StateType() {
_classCallCheck(this, StateType);
this.transform = '';
this.isMoving = false;
this.showPrev = false;
this.showNext = false;
};
export var DefaultTabBar = function (_React$PureComponent) {
_inherits(DefaultTabBar, _React$PureComponent);
function DefaultTabBar(props) {
_classCallCheck(this, DefaultTabBar);
var _this = _possibleConstructorReturn(this, (DefaultTabBar.__proto__ || Object.getPrototypeOf(DefaultTabBar)).call(this, props));
_this.onPan = function () {
var lastOffset = 0;
var finalOffset = 0;
var getLastOffset = function getLastOffset() {
var isVertical = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this.isTabBarVertical();
var offset = +('' + lastOffset).replace('%', '');
if (('' + lastOffset).indexOf('%') >= 0) {
offset /= 100;
offset *= isVertical ? _this.layout.clientHeight : _this.layout.clientWidth;
}
return offset;
};
return {
onPanStart: function onPanStart() {
_this.setState({ isMoving: true });
},
onPanMove: function onPanMove(status) {
if (!status.moveStatus || !_this.layout) return;
var isVertical = _this.isTabBarVertical();
var offset = getLastOffset() + (isVertical ? status.moveStatus.y : status.moveStatus.x);
var canScrollOffset = isVertical ? -_this.layout.scrollHeight + _this.layout.clientHeight : -_this.layout.scrollWidth + _this.layout.clientWidth;
offset = Math.min(offset, 0);
offset = Math.max(offset, canScrollOffset);
setPxStyle(_this.layout, offset, 'px', isVertical);
finalOffset = offset;
_this.setState({
showPrev: -offset > 0,
showNext: offset > canScrollOffset
});
},
onPanEnd: function onPanEnd() {
var isVertical = _this.isTabBarVertical();
lastOffset = finalOffset;
_this.setState({
isMoving: false,
transform: getPxStyle(finalOffset, 'px', isVertical)
});
},
setCurrentOffset: function setCurrentOffset(offset) {
return lastOffset = offset;
}
};
}();
_this.getTransformByIndex = function (props) {
var activeTab = props.activeTab,
tabs = props.tabs,
_props$page = props.page,
page = _props$page === undefined ? 0 : _props$page;
var isVertical = _this.isTabBarVertical();
var size = _this.getTabSize(page, tabs.length);
var center = page / 2;
var pos = Math.min(activeTab, tabs.length - center - .5);
var skipSize = Math.min(-(pos - center + .5) * size, 0);
_this.onPan.setCurrentOffset(skipSize + '%');
return {
transform: getPxStyle(skipSize, '%', isVertical),
showPrev: activeTab > center - .5 && tabs.length > page,
showNext: activeTab < tabs.length - center - .5 && tabs.length > page
};
};
_this.onPress = function (index) {
var _this$props = _this.props,
goToTab = _this$props.goToTab,
onTabClick = _this$props.onTabClick,
tabs = _this$props.tabs;
onTabClick && onTabClick(tabs[index], index);
goToTab && goToTab(index);
};
_this.isTabBarVertical = function () {
var position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this.props.tabBarPosition;
return position === 'left' || position === 'right';
};
_this.renderTab = function (t, i, size, isTabBarVertical) {
var _this$props2 = _this.props,
prefixCls = _this$props2.prefixCls,
renderTab = _this$props2.renderTab,
activeTab = _this$props2.activeTab,
tabBarTextStyle = _this$props2.tabBarTextStyle,
tabBarActiveTextColor = _this$props2.tabBarActiveTextColor,
tabBarInactiveTextColor = _this$props2.tabBarInactiveTextColor,
instanceId = _this$props2.instanceId;
var textStyle = _extends({}, tabBarTextStyle);
var cls = prefixCls + '-tab';
var ariaSelected = false;
if (activeTab === i) {
cls += ' ' + cls + '-active';
ariaSelected = true;
if (tabBarActiveTextColor) {
textStyle.color = tabBarActiveTextColor;
}
} else if (tabBarInactiveTextColor) {
textStyle.color = tabBarInactiveTextColor;
}
return React.createElement(
'div',
{ key: 't_' + i, style: _extends({}, textStyle, isTabBarVertical ? { height: size + '%' } : { width: size + '%' }), id: 'm-tabs-' + instanceId + '-' + i, role: 'tab', 'aria-selected': ariaSelected, className: cls, onClick: function onClick() {
return _this.onPress(i);
} },
renderTab ? renderTab(t) : t.title
);
};
_this.setContentLayout = function (div) {
_this.layout = div;
};
_this.getTabSize = function (page, tabLength) {
return 100 / Math.min(page, tabLength);
};
_this.state = _extends({}, new StateType(), _this.getTransformByIndex(props));
return _this;
}
_createClass(DefaultTabBar, [{
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
if (this.props.activeTab !== nextProps.activeTab || this.props.tabs !== nextProps.tabs || this.props.tabs.length !== nextProps.tabs.length) {
this.setState(_extends({}, this.getTransformByIndex(nextProps)));
}
}
}, {
key: 'render',
value: function render() {
var _this2 = this;
var _props = this.props,
prefixCls = _props.prefixCls,
animated = _props.animated,
_props$tabs = _props.tabs,
tabs = _props$tabs === undefined ? [] : _props$tabs,
_props$page2 = _props.page,
page = _props$page2 === undefined ? 0 : _props$page2,
_props$activeTab = _props.activeTab,
activeTab = _props$activeTab === undefined ? 0 : _props$activeTab,
tabBarBackgroundColor = _props.tabBarBackgroundColor,
tabBarUnderlineStyle = _props.tabBarUnderlineStyle,
tabBarPosition = _props.tabBarPosition,
renderUnderline = _props.renderUnderline;
var _state = this.state,
isMoving = _state.isMoving,
transform = _state.transform,
showNext = _state.showNext,
showPrev = _state.showPrev;
var isTabBarVertical = this.isTabBarVertical();
var needScroll = tabs.length > page;
var size = this.getTabSize(page, tabs.length);
var Tabs = tabs.map(function (t, i) {
return _this2.renderTab(t, i, size, isTabBarVertical);
});
var cls = prefixCls;
if (animated && !isMoving) {
cls += ' ' + prefixCls + '-animated';
}
var style = {
backgroundColor: tabBarBackgroundColor || ''
};
var transformStyle = needScroll ? _extends({}, getTransformPropValue(transform)) : {};
var _a = this.onPan,
setCurrentOffset = _a.setCurrentOffset,
onPan = __rest(_a, ["setCurrentOffset"]);
var underlineProps = {
style: _extends({}, isTabBarVertical ? { height: size + '%' } : { width: size + '%' }, isTabBarVertical ? { top: size * activeTab + '%' } : { left: size * activeTab + '%' }, tabBarUnderlineStyle),
className: prefixCls + '-underline'
};
return React.createElement(
'div',
{ className: cls + ' ' + prefixCls + '-' + tabBarPosition, style: style },
showPrev && React.createElement('div', { className: prefixCls + '-prevpage' }),
React.createElement(
Gesture,
_extends({}, onPan, { direction: isTabBarVertical ? 'vertical' : 'horizontal' }),
React.createElement(
'div',
{ role: 'tablist', className: prefixCls + '-content', style: transformStyle, ref: this.setContentLayout },
Tabs,
renderUnderline ? renderUnderline(underlineProps) : React.createElement('div', underlineProps)
)
),
showNext && React.createElement('div', { className: prefixCls + '-nextpage' })
);
}
}]);
return DefaultTabBar;
}(React.PureComponent);
DefaultTabBar.defaultProps = {
prefixCls: 'rmc-tabs-tab-bar',
animated: true,
tabs: [],
goToTab: function goToTab() {},
activeTab: 0,
page: 5,
tabBarUnderlineStyle: {},
tabBarBackgroundColor: '#fff',
tabBarActiveTextColor: '',
tabBarInactiveTextColor: '',
tabBarTextStyle: {}
};