UNPKG

12.4 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.DefaultTabBar = undefined;
7
8var _extends2 = require('babel-runtime/helpers/extends');
9
10var _extends3 = _interopRequireDefault(_extends2);
11
12var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
13
14var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
15
16var _createClass2 = require('babel-runtime/helpers/createClass');
17
18var _createClass3 = _interopRequireDefault(_createClass2);
19
20var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
21
22var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
23
24var _inherits2 = require('babel-runtime/helpers/inherits');
25
26var _inherits3 = _interopRequireDefault(_inherits2);
27
28var _react = require('react');
29
30var _react2 = _interopRequireDefault(_react);
31
32var _reactNative = require('react-native');
33
34var _Styles = require('./Styles.native');
35
36var _Styles2 = _interopRequireDefault(_Styles);
37
38function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
39
40var WINDOW_WIDTH = _reactNative.Dimensions.get('window').width;
41
42var 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
246DefaultTabBar.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