react-native-tab-view 3.2.1 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/PagerViewAdapter.js +2 -1
- package/lib/commonjs/PagerViewAdapter.js.map +1 -1
- package/lib/commonjs/PanResponderAdapter.js +2 -1
- package/lib/commonjs/PanResponderAdapter.js.map +1 -1
- package/lib/commonjs/SceneMap.js +9 -12
- package/lib/commonjs/SceneMap.js.map +1 -1
- package/lib/commonjs/SceneView.js +54 -101
- package/lib/commonjs/SceneView.js.map +1 -1
- package/lib/commonjs/TabBar.js +327 -327
- package/lib/commonjs/TabBar.js.map +1 -1
- package/lib/commonjs/TabBarIndicator.js +81 -99
- package/lib/commonjs/TabBarIndicator.js.map +1 -1
- package/lib/commonjs/TabBarItem.js +184 -161
- package/lib/commonjs/TabBarItem.js.map +1 -1
- package/lib/module/PagerViewAdapter.js +2 -1
- package/lib/module/PagerViewAdapter.js.map +1 -1
- package/lib/module/PanResponderAdapter.js +2 -1
- package/lib/module/PanResponderAdapter.js.map +1 -1
- package/lib/module/SceneMap.js +9 -14
- package/lib/module/SceneMap.js.map +1 -1
- package/lib/module/SceneView.js +53 -98
- package/lib/module/SceneView.js.map +1 -1
- package/lib/module/TabBar.js +323 -323
- package/lib/module/TabBar.js.map +1 -1
- package/lib/module/TabBarIndicator.js +74 -92
- package/lib/module/TabBarIndicator.js.map +1 -1
- package/lib/module/TabBarItem.js +178 -154
- package/lib/module/TabBarItem.js.map +1 -1
- package/lib/typescript/SceneMap.d.ts +5 -3
- package/lib/typescript/SceneView.d.ts +1 -18
- package/lib/typescript/TabBar.d.ts +7 -38
- package/lib/typescript/TabBarIndicator.d.ts +2 -10
- package/lib/typescript/TabBarItem.d.ts +3 -5
- package/package.json +4 -1
- package/src/PagerViewAdapter.tsx +6 -1
- package/src/PanResponderAdapter.tsx +6 -3
- package/src/SceneMap.tsx +11 -7
- package/src/SceneView.tsx +70 -106
- package/src/TabBar.tsx +451 -391
- package/src/TabBarIndicator.tsx +108 -114
- package/src/TabBarItem.tsx +214 -185
package/lib/module/TabBar.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
2
|
-
|
|
3
1
|
import * as React from 'react';
|
|
4
2
|
import { Animated, StyleSheet, View, I18nManager, Platform } from 'react-native';
|
|
5
3
|
import TabBarItem from './TabBarItem';
|
|
6
4
|
import TabBarIndicator from './TabBarIndicator';
|
|
5
|
+
import useAnimatedValue from './useAnimatedValue';
|
|
7
6
|
|
|
8
7
|
const Separator = _ref => {
|
|
9
8
|
let {
|
|
@@ -16,359 +15,360 @@ const Separator = _ref => {
|
|
|
16
15
|
});
|
|
17
16
|
};
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
_defineProperty(this, "state", {
|
|
24
|
-
layout: {
|
|
25
|
-
width: 0,
|
|
26
|
-
height: 0
|
|
27
|
-
},
|
|
28
|
-
tabWidths: {}
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
_defineProperty(this, "measuredTabWidths", {});
|
|
18
|
+
const getFlattenedTabWidth = style => {
|
|
19
|
+
const tabStyle = StyleSheet.flatten(style);
|
|
20
|
+
return tabStyle === null || tabStyle === void 0 ? void 0 : tabStyle.width;
|
|
21
|
+
};
|
|
32
22
|
|
|
33
|
-
|
|
23
|
+
const getComputedTabWidth = (index, layout, routes, scrollEnabled, tabWidths, flattenedWidth) => {
|
|
24
|
+
if (flattenedWidth === 'auto') {
|
|
25
|
+
return tabWidths[routes[index].key] || 0;
|
|
26
|
+
}
|
|
34
27
|
|
|
35
|
-
|
|
28
|
+
switch (typeof flattenedWidth) {
|
|
29
|
+
case 'number':
|
|
30
|
+
return flattenedWidth;
|
|
36
31
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
});
|
|
32
|
+
case 'string':
|
|
33
|
+
if (flattenedWidth.endsWith('%')) {
|
|
34
|
+
const width = parseFloat(flattenedWidth);
|
|
41
35
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
if (Number.isFinite(width)) {
|
|
37
|
+
return layout.width * (width / 100);
|
|
38
|
+
}
|
|
45
39
|
}
|
|
46
40
|
|
|
47
|
-
|
|
48
|
-
case 'number':
|
|
49
|
-
return flattenedWidth;
|
|
50
|
-
|
|
51
|
-
case 'string':
|
|
52
|
-
if (flattenedWidth.endsWith('%')) {
|
|
53
|
-
const width = parseFloat(flattenedWidth);
|
|
54
|
-
|
|
55
|
-
if (Number.isFinite(width)) {
|
|
56
|
-
return layout.width * (width / 100);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
}
|
|
41
|
+
}
|
|
61
42
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
43
|
+
if (scrollEnabled) {
|
|
44
|
+
return layout.width / 5 * 2;
|
|
45
|
+
}
|
|
65
46
|
|
|
66
|
-
|
|
67
|
-
|
|
47
|
+
return layout.width / routes.length;
|
|
48
|
+
};
|
|
68
49
|
|
|
69
|
-
|
|
50
|
+
const getMaxScrollDistance = (tabBarWidth, layoutWidth) => tabBarWidth - layoutWidth;
|
|
70
51
|
|
|
71
|
-
|
|
72
|
-
const {
|
|
73
|
-
layout,
|
|
74
|
-
tabWidths
|
|
75
|
-
} = state;
|
|
76
|
-
const {
|
|
77
|
-
scrollEnabled,
|
|
78
|
-
tabStyle
|
|
79
|
-
} = props;
|
|
80
|
-
const {
|
|
81
|
-
routes
|
|
82
|
-
} = props.navigationState;
|
|
83
|
-
return routes.reduce((acc, _, i) => acc + (i > 0 ? props.gap ?? 0 : 0) + this.getComputedTabWidth(i, layout, routes, scrollEnabled, tabWidths, this.getFlattenedTabWidth(tabStyle)), 0);
|
|
84
|
-
});
|
|
52
|
+
const getTranslateX = (scrollAmount, maxScrollDistance) => Animated.multiply(Platform.OS === 'android' && I18nManager.isRTL ? Animated.add(maxScrollDistance, Animated.multiply(scrollAmount, -1)) : scrollAmount, I18nManager.isRTL ? 1 : -1);
|
|
85
53
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
54
|
+
const getTabBarWidth = _ref2 => {
|
|
55
|
+
let {
|
|
56
|
+
navigationState,
|
|
57
|
+
layout,
|
|
58
|
+
gap,
|
|
59
|
+
scrollEnabled,
|
|
60
|
+
flattenedTabWidth,
|
|
61
|
+
tabWidths
|
|
62
|
+
} = _ref2;
|
|
63
|
+
const {
|
|
64
|
+
routes
|
|
65
|
+
} = navigationState;
|
|
66
|
+
return routes.reduce((acc, _, i) => acc + (i > 0 ? gap ?? 0 : 0) + getComputedTabWidth(i, layout, routes, scrollEnabled, tabWidths, flattenedTabWidth), 0);
|
|
67
|
+
};
|
|
93
68
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
69
|
+
const normalizeScrollValue = _ref3 => {
|
|
70
|
+
let {
|
|
71
|
+
layout,
|
|
72
|
+
navigationState,
|
|
73
|
+
gap,
|
|
74
|
+
scrollEnabled,
|
|
75
|
+
tabWidths,
|
|
76
|
+
value,
|
|
77
|
+
flattenedTabWidth
|
|
78
|
+
} = _ref3;
|
|
79
|
+
const tabBarWidth = getTabBarWidth({
|
|
80
|
+
layout,
|
|
81
|
+
navigationState,
|
|
82
|
+
tabWidths,
|
|
83
|
+
gap,
|
|
84
|
+
scrollEnabled,
|
|
85
|
+
flattenedTabWidth
|
|
86
|
+
});
|
|
87
|
+
const maxDistance = getMaxScrollDistance(tabBarWidth, layout.width);
|
|
88
|
+
const scrollValue = Math.max(Math.min(value, maxDistance), 0);
|
|
99
89
|
|
|
100
|
-
|
|
101
|
-
|
|
90
|
+
if (Platform.OS === 'android' && I18nManager.isRTL) {
|
|
91
|
+
// On Android, scroll value is not applied in reverse in RTL
|
|
92
|
+
// so we need to manually adjust it to apply correct value
|
|
93
|
+
return maxDistance - scrollValue;
|
|
94
|
+
}
|
|
102
95
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
layout,
|
|
106
|
-
tabWidths
|
|
107
|
-
} = state;
|
|
108
|
-
const {
|
|
109
|
-
scrollEnabled,
|
|
110
|
-
tabStyle
|
|
111
|
-
} = props;
|
|
112
|
-
const {
|
|
113
|
-
routes
|
|
114
|
-
} = props.navigationState;
|
|
115
|
-
const centerDistance = Array.from({
|
|
116
|
-
length: index + 1
|
|
117
|
-
}).reduce((total, _, i) => {
|
|
118
|
-
const tabWidth = this.getComputedTabWidth(i, layout, routes, scrollEnabled, tabWidths, this.getFlattenedTabWidth(tabStyle)); // To get the current index centered we adjust scroll amount by width of indexes
|
|
119
|
-
// 0 through (i - 1) and add half the width of current index i
|
|
96
|
+
return scrollValue;
|
|
97
|
+
};
|
|
120
98
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
99
|
+
const getScrollAmount = _ref4 => {
|
|
100
|
+
let {
|
|
101
|
+
layout,
|
|
102
|
+
navigationState,
|
|
103
|
+
gap,
|
|
104
|
+
scrollEnabled,
|
|
105
|
+
flattenedTabWidth,
|
|
106
|
+
tabWidths
|
|
107
|
+
} = _ref4;
|
|
108
|
+
const centerDistance = Array.from({
|
|
109
|
+
length: navigationState.index + 1
|
|
110
|
+
}).reduce((total, _, i) => {
|
|
111
|
+
const tabWidth = getComputedTabWidth(i, layout, navigationState.routes, scrollEnabled, tabWidths, flattenedTabWidth); // To get the current index centered we adjust scroll amount by width of indexes
|
|
112
|
+
// 0 through (i - 1) and add half the width of current index i
|
|
113
|
+
|
|
114
|
+
return total + (navigationState.index === i ? (tabWidth + (gap ?? 0)) / 2 : tabWidth + (gap ?? 0));
|
|
115
|
+
}, 0);
|
|
116
|
+
const scrollAmount = centerDistance - layout.width / 2;
|
|
117
|
+
return normalizeScrollValue({
|
|
118
|
+
layout,
|
|
119
|
+
navigationState,
|
|
120
|
+
tabWidths,
|
|
121
|
+
value: scrollAmount,
|
|
122
|
+
gap,
|
|
123
|
+
scrollEnabled,
|
|
124
|
+
flattenedTabWidth
|
|
125
|
+
});
|
|
126
|
+
};
|
|
126
127
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
const getLabelTextDefault = _ref5 => {
|
|
129
|
+
let {
|
|
130
|
+
route
|
|
131
|
+
} = _ref5;
|
|
132
|
+
return route.title;
|
|
133
|
+
};
|
|
130
134
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
const getAccessibleDefault = _ref6 => {
|
|
136
|
+
let {
|
|
137
|
+
route
|
|
138
|
+
} = _ref6;
|
|
139
|
+
return typeof route.accessible !== 'undefined' ? route.accessible : true;
|
|
140
|
+
};
|
|
137
141
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
142
|
+
const getAccessibilityLabelDefault = _ref7 => {
|
|
143
|
+
let {
|
|
144
|
+
route
|
|
145
|
+
} = _ref7;
|
|
146
|
+
return typeof route.accessibilityLabel === 'string' ? route.accessibilityLabel : typeof route.title === 'string' ? route.title : undefined;
|
|
147
|
+
};
|
|
143
148
|
|
|
144
|
-
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
149
|
+
const renderIndicatorDefault = props => /*#__PURE__*/React.createElement(TabBarIndicator, props);
|
|
147
150
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
});
|
|
151
|
+
const getTestIdDefault = _ref8 => {
|
|
152
|
+
let {
|
|
153
|
+
route
|
|
154
|
+
} = _ref8;
|
|
155
|
+
return route.testID;
|
|
156
|
+
};
|
|
155
157
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
+
export default function TabBar(_ref9) {
|
|
159
|
+
let {
|
|
160
|
+
getLabelText = getLabelTextDefault,
|
|
161
|
+
getAccessible = getAccessibleDefault,
|
|
162
|
+
getAccessibilityLabel = getAccessibilityLabelDefault,
|
|
163
|
+
getTestID = getTestIdDefault,
|
|
164
|
+
renderIndicator = renderIndicatorDefault,
|
|
165
|
+
gap = 0,
|
|
166
|
+
scrollEnabled,
|
|
167
|
+
jumpTo,
|
|
168
|
+
navigationState,
|
|
169
|
+
position,
|
|
170
|
+
activeColor,
|
|
171
|
+
bounces,
|
|
172
|
+
contentContainerStyle,
|
|
173
|
+
inactiveColor,
|
|
174
|
+
indicatorContainerStyle,
|
|
175
|
+
indicatorStyle,
|
|
176
|
+
labelStyle,
|
|
177
|
+
onTabLongPress,
|
|
178
|
+
onTabPress,
|
|
179
|
+
pressColor,
|
|
180
|
+
pressOpacity,
|
|
181
|
+
renderBadge,
|
|
182
|
+
renderIcon,
|
|
183
|
+
renderLabel,
|
|
184
|
+
renderTabBarItem,
|
|
185
|
+
style,
|
|
186
|
+
tabStyle
|
|
187
|
+
} = _ref9;
|
|
188
|
+
const [layout, setLayout] = React.useState({
|
|
189
|
+
width: 0,
|
|
190
|
+
height: 0
|
|
191
|
+
});
|
|
192
|
+
const [tabWidths, setTabWidths] = React.useState({});
|
|
193
|
+
const flatListRef = React.useRef(null);
|
|
194
|
+
const isFirst = React.useRef(true);
|
|
195
|
+
const scrollAmount = useAnimatedValue(0);
|
|
196
|
+
const measuredTabWidths = React.useRef({});
|
|
197
|
+
const {
|
|
198
|
+
routes
|
|
199
|
+
} = navigationState;
|
|
200
|
+
const flattenedTabWidth = getFlattenedTabWidth(tabStyle);
|
|
201
|
+
const isWidthDynamic = flattenedTabWidth === 'auto';
|
|
202
|
+
const scrollOffset = getScrollAmount({
|
|
203
|
+
layout,
|
|
204
|
+
navigationState,
|
|
205
|
+
tabWidths,
|
|
206
|
+
gap,
|
|
207
|
+
scrollEnabled,
|
|
208
|
+
flattenedTabWidth
|
|
209
|
+
});
|
|
210
|
+
const hasMeasuredTabWidths = Boolean(layout.width) && routes.every(r => typeof tabWidths[r.key] === 'number');
|
|
211
|
+
React.useEffect(() => {
|
|
212
|
+
if (isFirst.current) {
|
|
213
|
+
isFirst.current = false;
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
158
216
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
const {
|
|
164
|
-
layout,
|
|
165
|
-
tabWidths
|
|
166
|
-
} = this.state;
|
|
217
|
+
if (isWidthDynamic && !hasMeasuredTabWidths) {
|
|
218
|
+
// When tab width is dynamic, only adjust the scroll once we have all tab widths and layout
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
167
221
|
|
|
168
|
-
if (
|
|
169
|
-
|
|
170
|
-
// When tab width is dynamic, only adjust the scroll once we have all tab widths and layout
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
222
|
+
if (scrollEnabled) {
|
|
223
|
+
var _flatListRef$current;
|
|
173
224
|
|
|
174
|
-
|
|
225
|
+
(_flatListRef$current = flatListRef.current) === null || _flatListRef$current === void 0 ? void 0 : _flatListRef$current.scrollToOffset({
|
|
226
|
+
offset: scrollOffset,
|
|
227
|
+
animated: true
|
|
228
|
+
});
|
|
175
229
|
}
|
|
176
|
-
}
|
|
177
|
-
// when all onLayout's are fired, this would be set in state
|
|
178
|
-
|
|
230
|
+
}, [hasMeasuredTabWidths, isWidthDynamic, scrollEnabled, scrollOffset]);
|
|
179
231
|
|
|
180
|
-
|
|
232
|
+
const handleLayout = e => {
|
|
181
233
|
const {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
style: indicatorStyle,
|
|
243
|
-
getTabWidth: i => this.getComputedTabWidth(i, layout, routes, scrollEnabled, tabWidths, this.getFlattenedTabWidth(tabStyle)),
|
|
244
|
-
gap
|
|
245
|
-
})), /*#__PURE__*/React.createElement(View, {
|
|
246
|
-
style: styles.scroll
|
|
247
|
-
}, /*#__PURE__*/React.createElement(Animated.FlatList, {
|
|
248
|
-
data: routes,
|
|
249
|
-
keyExtractor: item => item.key,
|
|
250
|
-
horizontal: true,
|
|
251
|
-
accessibilityRole: "tablist",
|
|
252
|
-
keyboardShouldPersistTaps: "handled",
|
|
253
|
-
scrollEnabled: scrollEnabled,
|
|
254
|
-
bounces: bounces,
|
|
255
|
-
alwaysBounceHorizontal: false,
|
|
256
|
-
scrollsToTop: false,
|
|
257
|
-
showsHorizontalScrollIndicator: false,
|
|
258
|
-
showsVerticalScrollIndicator: false,
|
|
259
|
-
automaticallyAdjustContentInsets: false,
|
|
260
|
-
overScrollMode: "never",
|
|
261
|
-
contentContainerStyle: [styles.tabContent, scrollEnabled ? {
|
|
262
|
-
width: tabBarWidth > separatorsWidth ? tabBarWidth : tabBarWidthPercent
|
|
263
|
-
} : styles.container, contentContainerStyle],
|
|
264
|
-
scrollEventThrottle: 16,
|
|
265
|
-
renderItem: _ref2 => {
|
|
266
|
-
let {
|
|
267
|
-
item: route,
|
|
268
|
-
index
|
|
269
|
-
} = _ref2;
|
|
270
|
-
const props = {
|
|
271
|
-
key: route.key,
|
|
272
|
-
position: position,
|
|
273
|
-
route: route,
|
|
274
|
-
navigationState: navigationState,
|
|
275
|
-
getAccessibilityLabel: getAccessibilityLabel,
|
|
276
|
-
getAccessible: getAccessible,
|
|
277
|
-
getLabelText: getLabelText,
|
|
278
|
-
getTestID: getTestID,
|
|
279
|
-
renderBadge: renderBadge,
|
|
280
|
-
renderIcon: renderIcon,
|
|
281
|
-
renderLabel: renderLabel,
|
|
282
|
-
activeColor: activeColor,
|
|
283
|
-
inactiveColor: inactiveColor,
|
|
284
|
-
pressColor: pressColor,
|
|
285
|
-
pressOpacity: pressOpacity,
|
|
286
|
-
onLayout: isWidthDynamic ? e => {
|
|
287
|
-
this.measuredTabWidths[route.key] = e.nativeEvent.layout.width; // When we have measured widths for all of the tabs, we should updates the state
|
|
288
|
-
// We avoid doing separate setState for each layout since it triggers multiple renders and slows down app
|
|
289
|
-
|
|
290
|
-
if (routes.every(r => typeof this.measuredTabWidths[r.key] === 'number')) {
|
|
291
|
-
this.setState({
|
|
292
|
-
tabWidths: { ...this.measuredTabWidths
|
|
293
|
-
}
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
} : undefined,
|
|
297
|
-
onPress: () => {
|
|
298
|
-
const event = {
|
|
299
|
-
route,
|
|
300
|
-
defaultPrevented: false,
|
|
301
|
-
preventDefault: () => {
|
|
302
|
-
event.defaultPrevented = true;
|
|
303
|
-
}
|
|
304
|
-
};
|
|
305
|
-
onTabPress === null || onTabPress === void 0 ? void 0 : onTabPress(event);
|
|
234
|
+
height,
|
|
235
|
+
width
|
|
236
|
+
} = e.nativeEvent.layout;
|
|
237
|
+
setLayout(layout => layout.width === width && layout.height === height ? layout : {
|
|
238
|
+
width,
|
|
239
|
+
height
|
|
240
|
+
});
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
const tabBarWidth = getTabBarWidth({
|
|
244
|
+
layout,
|
|
245
|
+
navigationState,
|
|
246
|
+
tabWidths,
|
|
247
|
+
gap,
|
|
248
|
+
scrollEnabled,
|
|
249
|
+
flattenedTabWidth
|
|
250
|
+
});
|
|
251
|
+
const separatorsWidth = Math.max(0, routes.length - 1) * gap;
|
|
252
|
+
const separatorPercent = separatorsWidth / tabBarWidth * 100;
|
|
253
|
+
const tabBarWidthPercent = `${routes.length * 40}%`;
|
|
254
|
+
const translateX = React.useMemo(() => getTranslateX(scrollAmount, getMaxScrollDistance(tabBarWidth, layout.width)), [layout.width, scrollAmount, tabBarWidth]);
|
|
255
|
+
const renderItem = React.useCallback(_ref10 => {
|
|
256
|
+
let {
|
|
257
|
+
item: route,
|
|
258
|
+
index
|
|
259
|
+
} = _ref10;
|
|
260
|
+
const props = {
|
|
261
|
+
key: route.key,
|
|
262
|
+
position: position,
|
|
263
|
+
route: route,
|
|
264
|
+
navigationState: navigationState,
|
|
265
|
+
getAccessibilityLabel: getAccessibilityLabel,
|
|
266
|
+
getAccessible: getAccessible,
|
|
267
|
+
getLabelText: getLabelText,
|
|
268
|
+
getTestID: getTestID,
|
|
269
|
+
renderBadge: renderBadge,
|
|
270
|
+
renderIcon: renderIcon,
|
|
271
|
+
renderLabel: renderLabel,
|
|
272
|
+
activeColor: activeColor,
|
|
273
|
+
inactiveColor: inactiveColor,
|
|
274
|
+
pressColor: pressColor,
|
|
275
|
+
pressOpacity: pressOpacity,
|
|
276
|
+
onLayout: isWidthDynamic ? e => {
|
|
277
|
+
measuredTabWidths.current[route.key] = e.nativeEvent.layout.width; // When we have measured widths for all of the tabs, we should updates the state
|
|
278
|
+
// We avoid doing separate setState for each layout since it triggers multiple renders and slows down app
|
|
279
|
+
|
|
280
|
+
if (routes.every(r => typeof measuredTabWidths.current[r.key] === 'number')) {
|
|
281
|
+
setTabWidths({ ...measuredTabWidths.current
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
} : undefined,
|
|
285
|
+
onPress: () => {
|
|
286
|
+
const event = {
|
|
287
|
+
route,
|
|
288
|
+
defaultPrevented: false,
|
|
289
|
+
preventDefault: () => {
|
|
290
|
+
event.defaultPrevented = true;
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
onTabPress === null || onTabPress === void 0 ? void 0 : onTabPress(event);
|
|
306
294
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
295
|
+
if (event.defaultPrevented) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
310
298
|
|
|
311
|
-
|
|
312
|
-
},
|
|
313
|
-
onLongPress: () => onTabLongPress === null || onTabLongPress === void 0 ? void 0 : onTabLongPress({
|
|
314
|
-
route
|
|
315
|
-
}),
|
|
316
|
-
labelStyle: labelStyle,
|
|
317
|
-
style: [tabStyle, // Calculate the deafult width for tab for FlatList to work.
|
|
318
|
-
this.getFlattenedTabWidth(tabStyle) === undefined && {
|
|
319
|
-
width: this.getComputedTabWidth(index, layout, routes, scrollEnabled, tabWidths, this.getFlattenedTabWidth(tabStyle))
|
|
320
|
-
}]
|
|
321
|
-
};
|
|
322
|
-
return /*#__PURE__*/React.createElement(React.Fragment, {
|
|
323
|
-
key: route.key
|
|
324
|
-
}, gap > 0 && index > 0 ? /*#__PURE__*/React.createElement(Separator, {
|
|
325
|
-
width: gap
|
|
326
|
-
}) : null, renderTabBarItem ? renderTabBarItem(props) : /*#__PURE__*/React.createElement(TabBarItem, props));
|
|
299
|
+
jumpTo(route.key);
|
|
327
300
|
},
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
contentOffset: {
|
|
331
|
-
x: this.scrollAmount
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
}], {
|
|
335
|
-
useNativeDriver: true
|
|
301
|
+
onLongPress: () => onTabLongPress === null || onTabLongPress === void 0 ? void 0 : onTabLongPress({
|
|
302
|
+
route
|
|
336
303
|
}),
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
304
|
+
labelStyle: labelStyle,
|
|
305
|
+
style: tabStyle,
|
|
306
|
+
// Calculate the deafult width for tab for FlatList to work
|
|
307
|
+
defaultTabWidth: !isWidthDynamic ? getComputedTabWidth(index, layout, routes, scrollEnabled, tabWidths, getFlattenedTabWidth(tabStyle)) : undefined
|
|
308
|
+
};
|
|
309
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, gap > 0 && index > 0 ? /*#__PURE__*/React.createElement(Separator, {
|
|
310
|
+
width: gap
|
|
311
|
+
}) : null, renderTabBarItem ? renderTabBarItem(props) : /*#__PURE__*/React.createElement(TabBarItem, props));
|
|
312
|
+
}, [activeColor, gap, getAccessibilityLabel, getAccessible, getLabelText, getTestID, inactiveColor, isWidthDynamic, jumpTo, labelStyle, layout, navigationState, onTabLongPress, onTabPress, position, pressColor, pressOpacity, renderBadge, renderIcon, renderLabel, renderTabBarItem, routes, scrollEnabled, tabStyle, tabWidths]);
|
|
313
|
+
const keyExtractor = React.useCallback(item => item.key, []);
|
|
314
|
+
const contentContainerStyleMemoized = React.useMemo(() => [styles.tabContent, scrollEnabled ? {
|
|
315
|
+
width: tabBarWidth > separatorsWidth ? tabBarWidth : tabBarWidthPercent
|
|
316
|
+
} : styles.container, contentContainerStyle], [contentContainerStyle, scrollEnabled, separatorsWidth, tabBarWidth, tabBarWidthPercent]);
|
|
317
|
+
const handleScroll = React.useMemo(() => Animated.event([{
|
|
318
|
+
nativeEvent: {
|
|
319
|
+
contentOffset: {
|
|
320
|
+
x: scrollAmount
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}], {
|
|
324
|
+
useNativeDriver: true
|
|
325
|
+
}), [scrollAmount]);
|
|
326
|
+
return /*#__PURE__*/React.createElement(Animated.View, {
|
|
327
|
+
onLayout: handleLayout,
|
|
328
|
+
style: [styles.tabBar, style]
|
|
329
|
+
}, /*#__PURE__*/React.createElement(Animated.View, {
|
|
330
|
+
pointerEvents: "none",
|
|
331
|
+
style: [styles.indicatorContainer, scrollEnabled ? {
|
|
332
|
+
transform: [{
|
|
333
|
+
translateX
|
|
334
|
+
}]
|
|
335
|
+
} : null, tabBarWidth > separatorsWidth ? {
|
|
336
|
+
width: tabBarWidth - separatorsWidth
|
|
337
|
+
} : scrollEnabled ? {
|
|
338
|
+
width: tabBarWidthPercent
|
|
339
|
+
} : null, indicatorContainerStyle]
|
|
340
|
+
}, renderIndicator({
|
|
341
|
+
position,
|
|
342
|
+
layout,
|
|
343
|
+
navigationState,
|
|
344
|
+
jumpTo,
|
|
345
|
+
width: isWidthDynamic ? 'auto' : `${(100 - separatorPercent) / routes.length}%`,
|
|
346
|
+
style: indicatorStyle,
|
|
347
|
+
getTabWidth: i => getComputedTabWidth(i, layout, routes, scrollEnabled, tabWidths, flattenedTabWidth),
|
|
348
|
+
gap
|
|
349
|
+
})), /*#__PURE__*/React.createElement(View, {
|
|
350
|
+
style: styles.scroll
|
|
351
|
+
}, /*#__PURE__*/React.createElement(Animated.FlatList, {
|
|
352
|
+
data: routes,
|
|
353
|
+
keyExtractor: keyExtractor,
|
|
354
|
+
horizontal: true,
|
|
355
|
+
accessibilityRole: "tablist",
|
|
356
|
+
keyboardShouldPersistTaps: "handled",
|
|
357
|
+
scrollEnabled: scrollEnabled,
|
|
358
|
+
bounces: bounces,
|
|
359
|
+
alwaysBounceHorizontal: false,
|
|
360
|
+
scrollsToTop: false,
|
|
361
|
+
showsHorizontalScrollIndicator: false,
|
|
362
|
+
showsVerticalScrollIndicator: false,
|
|
363
|
+
automaticallyAdjustContentInsets: false,
|
|
364
|
+
overScrollMode: "never",
|
|
365
|
+
contentContainerStyle: contentContainerStyleMemoized,
|
|
366
|
+
scrollEventThrottle: 16,
|
|
367
|
+
renderItem: renderItem,
|
|
368
|
+
onScroll: handleScroll,
|
|
369
|
+
ref: flatListRef
|
|
370
|
+
})));
|
|
341
371
|
}
|
|
342
|
-
|
|
343
|
-
_defineProperty(TabBar, "defaultProps", {
|
|
344
|
-
getLabelText: _ref3 => {
|
|
345
|
-
let {
|
|
346
|
-
route
|
|
347
|
-
} = _ref3;
|
|
348
|
-
return route.title;
|
|
349
|
-
},
|
|
350
|
-
getAccessible: _ref4 => {
|
|
351
|
-
let {
|
|
352
|
-
route
|
|
353
|
-
} = _ref4;
|
|
354
|
-
return typeof route.accessible !== 'undefined' ? route.accessible : true;
|
|
355
|
-
},
|
|
356
|
-
getAccessibilityLabel: _ref5 => {
|
|
357
|
-
let {
|
|
358
|
-
route
|
|
359
|
-
} = _ref5;
|
|
360
|
-
return typeof route.accessibilityLabel === 'string' ? route.accessibilityLabel : typeof route.title === 'string' ? route.title : undefined;
|
|
361
|
-
},
|
|
362
|
-
getTestID: _ref6 => {
|
|
363
|
-
let {
|
|
364
|
-
route
|
|
365
|
-
} = _ref6;
|
|
366
|
-
return route.testID;
|
|
367
|
-
},
|
|
368
|
-
renderIndicator: props => /*#__PURE__*/React.createElement(TabBarIndicator, props),
|
|
369
|
-
gap: 0
|
|
370
|
-
});
|
|
371
|
-
|
|
372
372
|
const styles = StyleSheet.create({
|
|
373
373
|
container: {
|
|
374
374
|
flex: 1
|