1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.DefaultTabBar = undefined;
|
7 |
|
8 | var _extends2 = require('babel-runtime/helpers/extends');
|
9 |
|
10 | var _extends3 = _interopRequireDefault(_extends2);
|
11 |
|
12 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
|
13 |
|
14 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
|
15 |
|
16 | var _createClass2 = require('babel-runtime/helpers/createClass');
|
17 |
|
18 | var _createClass3 = _interopRequireDefault(_createClass2);
|
19 |
|
20 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
|
21 |
|
22 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
|
23 |
|
24 | var _inherits2 = require('babel-runtime/helpers/inherits');
|
25 |
|
26 | var _inherits3 = _interopRequireDefault(_inherits2);
|
27 |
|
28 | var _react = require('react');
|
29 |
|
30 | var _react2 = _interopRequireDefault(_react);
|
31 |
|
32 | var _reactNative = require('react-native');
|
33 |
|
34 | var _Styles = require('./Styles.native');
|
35 |
|
36 | var _Styles2 = _interopRequireDefault(_Styles);
|
37 |
|
38 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
39 |
|
40 | var WINDOW_WIDTH = _reactNative.Dimensions.get('window').width;
|
41 |
|
42 | var DefaultTabBar = exports.DefaultTabBar = function (_React$PureComponent) {
|
43 | (0, _inherits3['default'])(DefaultTabBar, _React$PureComponent);
|
44 |
|
45 | function DefaultTabBar(props) {
|
46 | (0, _classCallCheck3['default'])(this, DefaultTabBar);
|
47 |
|
48 | var _this = (0, _possibleConstructorReturn3['default'])(this, (DefaultTabBar.__proto__ || Object.getPrototypeOf(DefaultTabBar)).call(this, props));
|
49 |
|
50 | _this._tabsMeasurements = [];
|
51 | _this.updateView = function (offset) {
|
52 | var position = Math.floor(offset.value);
|
53 | var pageOffset = offset.value % 1;
|
54 | var tabCount = _this.props.tabs.length;
|
55 | var lastTabPosition = tabCount - 1;
|
56 | if (tabCount === 0 || offset.value < 0 || offset.value > lastTabPosition) {
|
57 | return;
|
58 | }
|
59 | if (_this.necessarilyMeasurementsCompleted(position, position === lastTabPosition)) {
|
60 | _this.updateTabPanel(position, pageOffset);
|
61 | _this.updateTabUnderline(position, pageOffset, tabCount);
|
62 | }
|
63 | };
|
64 | _this.onPress = function (index) {
|
65 | var _this$props = _this.props,
|
66 | goToTab = _this$props.goToTab,
|
67 | onTabClick = _this$props.onTabClick,
|
68 | tabs = _this$props.tabs;
|
69 |
|
70 | onTabClick && onTabClick(tabs[index], index);
|
71 | goToTab && goToTab(index);
|
72 | };
|
73 | _this.measureTab = function (page, event) {
|
74 | var _event$nativeEvent$la = event.nativeEvent.layout,
|
75 | x = _event$nativeEvent$la.x,
|
76 | width = _event$nativeEvent$la.width,
|
77 | height = _event$nativeEvent$la.height;
|
78 |
|
79 | _this._tabsMeasurements[page] = { left: x, right: x + width, width: width, height: height };
|
80 | _this.updateView({ value: _this.props.scrollValue._value });
|
81 | };
|
82 | _this.onTabContainerLayout = function (e) {
|
83 | _this._tabContainerMeasurements = e.nativeEvent.layout;
|
84 | var width = _this._tabContainerMeasurements.width;
|
85 | if (width < WINDOW_WIDTH) {
|
86 | width = WINDOW_WIDTH;
|
87 | }
|
88 | _this.setState({ _tabContainerWidth: width });
|
89 | if (!_this.props.dynamicTabUnderlineWidth) {
|
90 | _this.state._widthTabUnderline.setValue(width / _this.props.tabs.length);
|
91 | }
|
92 | _this.updateView({ value: _this.props.scrollValue._value });
|
93 | };
|
94 | _this.onContainerLayout = function (e) {
|
95 | _this._containerMeasurements = e.nativeEvent.layout;
|
96 | _this.setState({ _containerWidth: _this._containerMeasurements.width });
|
97 | _this.updateView({ value: _this.props.scrollValue._value });
|
98 | };
|
99 | _this.state = {
|
100 | _leftTabUnderline: new _reactNative.Animated.Value(0),
|
101 | _widthTabUnderline: new _reactNative.Animated.Value(0),
|
102 | _containerWidth: WINDOW_WIDTH,
|
103 | _tabContainerWidth: WINDOW_WIDTH
|
104 | };
|
105 | return _this;
|
106 | }
|
107 |
|
108 | (0, _createClass3['default'])(DefaultTabBar, [{
|
109 | key: 'componentDidMount',
|
110 | value: function componentDidMount() {
|
111 | this.props.scrollValue.addListener(this.updateView);
|
112 | }
|
113 | }, {
|
114 | key: 'necessarilyMeasurementsCompleted',
|
115 | value: function necessarilyMeasurementsCompleted(position, isLastTab) {
|
116 | return this._tabsMeasurements[position] && (isLastTab || this._tabsMeasurements[position + 1]) && this._tabContainerMeasurements && this._containerMeasurements;
|
117 | }
|
118 | }, {
|
119 | key: 'updateTabPanel',
|
120 | value: function updateTabPanel(position, pageOffset) {
|
121 | var containerWidth = this._containerMeasurements.width;
|
122 | var tabWidth = this._tabsMeasurements[position].width;
|
123 | var nextTabMeasurements = this._tabsMeasurements[position + 1];
|
124 | var nextTabWidth = nextTabMeasurements && nextTabMeasurements.width || 0;
|
125 | var tabOffset = this._tabsMeasurements[position].left;
|
126 | var absolutePageOffset = pageOffset * tabWidth;
|
127 | var newScrollX = tabOffset + absolutePageOffset;
|
128 | newScrollX -= (containerWidth - (1 - pageOffset) * tabWidth - pageOffset * nextTabWidth) / 2;
|
129 | newScrollX = newScrollX >= 0 ? newScrollX : 0;
|
130 | if (_reactNative.Platform.OS === 'android') {
|
131 | this._scrollView.scrollTo({ x: newScrollX, y: 0, animated: false });
|
132 | } else {
|
133 | var rightBoundScroll = this._tabContainerMeasurements.width - this._containerMeasurements.width;
|
134 | newScrollX = newScrollX > rightBoundScroll ? rightBoundScroll : newScrollX;
|
135 | this._scrollView.scrollTo({ x: newScrollX, y: 0, animated: false });
|
136 | }
|
137 | }
|
138 | }, {
|
139 | key: 'updateTabUnderline',
|
140 | value: function updateTabUnderline(position, pageOffset, tabCount) {
|
141 | var dynamicTabUnderlineWidth = this.props.dynamicTabUnderlineWidth;
|
142 |
|
143 | if (0 <= position && position <= tabCount - 1) {
|
144 | if (dynamicTabUnderlineWidth) {
|
145 | var nowLeft = this._tabsMeasurements[position].left;
|
146 | var nowRight = this._tabsMeasurements[position].right;
|
147 | var nextTabLeft = this._tabsMeasurements[position + 1].left;
|
148 | var nextTabRight = this._tabsMeasurements[position + 1].right;
|
149 | var newLineLeft = pageOffset * nextTabLeft + (1 - pageOffset) * nowLeft;
|
150 | var newLineRight = pageOffset * nextTabRight + (1 - pageOffset) * nowRight;
|
151 | this.state._leftTabUnderline.setValue(newLineLeft);
|
152 | this.state._widthTabUnderline.setValue(newLineRight - newLineLeft);
|
153 | } else {
|
154 | var _nowLeft = position * this.state._tabContainerWidth / tabCount;
|
155 | var _nextTabLeft = (position + 1) * this.state._tabContainerWidth / tabCount;
|
156 | var _newLineLeft = pageOffset * _nextTabLeft + (1 - pageOffset) * _nowLeft;
|
157 | this.state._leftTabUnderline.setValue(_newLineLeft);
|
158 | }
|
159 | }
|
160 | }
|
161 | }, {
|
162 | key: 'renderTab',
|
163 | value: function renderTab(tab, index, width, onLayoutHandler) {
|
164 | var _this2 = this;
|
165 |
|
166 | var _props = this.props,
|
167 | activeTextColor = _props.tabBarActiveTextColor,
|
168 | inactiveTextColor = _props.tabBarInactiveTextColor,
|
169 | textStyle = _props.tabBarTextStyle,
|
170 | activeTab = _props.activeTab,
|
171 | renderTab = _props.renderTab,
|
172 | _props$styles = _props.styles,
|
173 | styles = _props$styles === undefined ? _Styles2['default'] : _props$styles;
|
174 |
|
175 | var isTabActive = activeTab === index;
|
176 | var textColor = isTabActive ? activeTextColor || styles.TabBar.activeTextColor : inactiveTextColor || styles.TabBar.inactiveTextColor;
|
177 | return _react2['default'].createElement(
|
178 | _reactNative.TouchableOpacity,
|
179 | { activeOpacity: 1, key: tab.title + '_' + index, accessible: true, accessibilityTraits: 'button', onPress: function onPress() {
|
180 | return _this2.onPress(index);
|
181 | }, onLayout: onLayoutHandler },
|
182 | _react2['default'].createElement(
|
183 | _reactNative.View,
|
184 | { style: (0, _extends3['default'])({}, styles.TabBar.tab, this.props.tabStyle, { width: width }) },
|
185 | renderTab ? renderTab(tab) : _react2['default'].createElement(
|
186 | _reactNative.Text,
|
187 | { style: (0, _extends3['default'])({ color: textColor }, styles.TabBar.textStyle, textStyle) },
|
188 | tab.title
|
189 | )
|
190 | )
|
191 | );
|
192 | }
|
193 | }, {
|
194 | key: 'render',
|
195 | value: function render() {
|
196 | var _this3 = this;
|
197 |
|
198 | var _props2 = this.props,
|
199 | tabs = _props2.tabs,
|
200 | _props2$page = _props2.page,
|
201 | page = _props2$page === undefined ? 1 : _props2$page,
|
202 | tabBarUnderlineStyle = _props2.tabBarUnderlineStyle,
|
203 | tabBarBackgroundColor = _props2.tabBarBackgroundColor,
|
204 | _props2$styles = _props2.styles,
|
205 | styles = _props2$styles === undefined ? _Styles2['default'] : _props2$styles,
|
206 | tabsContainerStyle = _props2.tabsContainerStyle,
|
207 | renderUnderline = _props2.renderUnderline,
|
208 | keyboardShouldPersistTaps = _props2.keyboardShouldPersistTaps;
|
209 |
|
210 | var tabUnderlineStyle = (0, _extends3['default'])({ position: 'absolute', bottom: 0 }, styles.TabBar.underline, tabBarUnderlineStyle);
|
211 | var dynamicTabUnderline = {
|
212 | left: this.state._leftTabUnderline,
|
213 | width: this.state._widthTabUnderline
|
214 | };
|
215 | var tabWidth = this.state._containerWidth / Math.min(page, tabs.length);
|
216 | var underlineProps = {
|
217 | style: (0, _extends3['default'])({}, tabUnderlineStyle, dynamicTabUnderline)
|
218 | };
|
219 | return _react2['default'].createElement(
|
220 | _reactNative.View,
|
221 | { style: (0, _extends3['default'])({}, styles.TabBar.container, { backgroundColor: tabBarBackgroundColor }), onLayout: this.onContainerLayout },
|
222 | _react2['default'].createElement(
|
223 | _reactNative.ScrollView,
|
224 | { ref: function ref(scrollView) {
|
225 | _this3._scrollView = scrollView;
|
226 | }, horizontal: true, showsHorizontalScrollIndicator: false, showsVerticalScrollIndicator: false, directionalLockEnabled: true, bounces: false, scrollsToTop: false, scrollEnabled: tabs.length > page, keyboardShouldPersistTaps: keyboardShouldPersistTaps },
|
227 | _react2['default'].createElement(
|
228 | _reactNative.View,
|
229 | { style: (0, _extends3['default'])({}, styles.TabBar.tabs, tabsContainerStyle, { backgroundColor: tabBarBackgroundColor }), onLayout: this.onTabContainerLayout },
|
230 | tabs.map(function (name, index) {
|
231 | var tab = { title: name };
|
232 | if (tabs.length - 1 >= index) {
|
233 | tab = tabs[index];
|
234 | }
|
235 | return _this3.renderTab(tab, index, tabWidth, _this3.measureTab.bind(_this3, index));
|
236 | }),
|
237 | renderUnderline ? renderUnderline(underlineProps) : _react2['default'].createElement(_reactNative.Animated.View, underlineProps)
|
238 | )
|
239 | )
|
240 | );
|
241 | }
|
242 | }]);
|
243 | return DefaultTabBar;
|
244 | }(_react2['default'].PureComponent);
|
245 |
|
246 | DefaultTabBar.defaultProps = {
|
247 | animated: true,
|
248 | tabs: [],
|
249 | goToTab: function goToTab() {},
|
250 | activeTab: 0,
|
251 | page: 5,
|
252 | tabBarUnderlineStyle: {},
|
253 | tabBarBackgroundColor: '#fff',
|
254 | tabBarActiveTextColor: '',
|
255 | tabBarInactiveTextColor: '',
|
256 | tabBarTextStyle: {},
|
257 | dynamicTabUnderlineWidth: false,
|
258 | styles: _Styles2['default']
|
259 | }; |
\ | No newline at end of file |