@react-navigation/bottom-tabs 7.0.0-rc.8 → 7.0.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/TransitionConfigs/TransitionPresets.js +2 -2
- package/lib/commonjs/index.js +9 -9
- package/lib/commonjs/navigators/createBottomTabNavigator.js +10 -12
- package/lib/commonjs/navigators/createBottomTabNavigator.js.map +1 -1
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/utils/useBottomTabBarHeight.js +1 -1
- package/lib/commonjs/views/Badge.js +6 -4
- package/lib/commonjs/views/Badge.js.map +1 -1
- package/lib/commonjs/views/BottomTabBar.js +149 -110
- package/lib/commonjs/views/BottomTabBar.js.map +1 -1
- package/lib/commonjs/views/BottomTabItem.js +99 -59
- package/lib/commonjs/views/BottomTabItem.js.map +1 -1
- package/lib/commonjs/views/BottomTabView.js +124 -100
- package/lib/commonjs/views/BottomTabView.js.map +1 -1
- package/lib/commonjs/views/ScreenFallback.js +15 -9
- package/lib/commonjs/views/ScreenFallback.js.map +1 -1
- package/lib/commonjs/views/TabBarIcon.js +59 -37
- package/lib/commonjs/views/TabBarIcon.js.map +1 -1
- package/lib/module/TransitionConfigs/SceneStyleInterpolators.js +2 -0
- package/lib/module/TransitionConfigs/SceneStyleInterpolators.js.map +1 -1
- package/lib/module/TransitionConfigs/TransitionPresets.js +4 -2
- package/lib/module/TransitionConfigs/TransitionPresets.js.map +1 -1
- package/lib/module/TransitionConfigs/TransitionSpecs.js +2 -0
- package/lib/module/TransitionConfigs/TransitionSpecs.js.map +1 -1
- package/lib/module/index.js +11 -9
- package/lib/module/index.js.map +1 -1
- package/lib/module/navigators/createBottomTabNavigator.js +12 -10
- package/lib/module/navigators/createBottomTabNavigator.js.map +1 -1
- package/lib/module/package.json +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/utils/BottomTabBarHeightCallbackContext.js +2 -0
- package/lib/module/utils/BottomTabBarHeightCallbackContext.js.map +1 -1
- package/lib/module/utils/BottomTabBarHeightContext.js +2 -0
- package/lib/module/utils/BottomTabBarHeightContext.js.map +1 -1
- package/lib/module/utils/useAnimatedHashMap.js +2 -0
- package/lib/module/utils/useAnimatedHashMap.js.map +1 -1
- package/lib/module/utils/useBottomTabBarHeight.js +3 -1
- package/lib/module/utils/useBottomTabBarHeight.js.map +1 -1
- package/lib/module/utils/useIsKeyboardShown.js +2 -0
- package/lib/module/utils/useIsKeyboardShown.js.map +1 -1
- package/lib/module/views/Badge.js +8 -4
- package/lib/module/views/Badge.js.map +1 -1
- package/lib/module/views/BottomTabBar.js +151 -110
- package/lib/module/views/BottomTabBar.js.map +1 -1
- package/lib/module/views/BottomTabItem.js +101 -59
- package/lib/module/views/BottomTabItem.js.map +1 -1
- package/lib/module/views/BottomTabView.js +126 -100
- package/lib/module/views/BottomTabView.js.map +1 -1
- package/lib/module/views/ScreenFallback.js +17 -9
- package/lib/module/views/ScreenFallback.js.map +1 -1
- package/lib/module/views/TabBarIcon.js +61 -37
- package/lib/module/views/TabBarIcon.js.map +1 -1
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/src/TransitionConfigs/SceneStyleInterpolators.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/TransitionConfigs/TransitionPresets.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/TransitionConfigs/TransitionSpecs.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -0
- package/lib/typescript/{src → commonjs/src}/navigators/createBottomTabNavigator.d.ts +3 -4
- package/lib/typescript/commonjs/src/navigators/createBottomTabNavigator.d.ts.map +1 -0
- package/lib/typescript/{src → commonjs/src}/types.d.ts +21 -4
- package/lib/typescript/commonjs/src/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/utils/BottomTabBarHeightCallbackContext.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/utils/BottomTabBarHeightContext.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/utils/useAnimatedHashMap.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/utils/useBottomTabBarHeight.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/utils/useIsKeyboardShown.d.ts.map +1 -0
- package/lib/typescript/{src → commonjs/src}/views/Badge.d.ts +1 -2
- package/lib/typescript/commonjs/src/views/Badge.d.ts.map +1 -0
- package/lib/typescript/{src → commonjs/src}/views/BottomTabBar.d.ts +2 -3
- package/lib/typescript/commonjs/src/views/BottomTabBar.d.ts.map +1 -0
- package/lib/typescript/{src → commonjs/src}/views/BottomTabItem.d.ts +9 -1
- package/lib/typescript/commonjs/src/views/BottomTabItem.d.ts.map +1 -0
- package/lib/typescript/{src → commonjs/src}/views/BottomTabView.d.ts +1 -2
- package/lib/typescript/commonjs/src/views/BottomTabView.d.ts.map +1 -0
- package/lib/typescript/{src → commonjs/src}/views/ScreenFallback.d.ts +2 -2
- package/lib/typescript/commonjs/src/views/ScreenFallback.d.ts.map +1 -0
- package/lib/typescript/{src → commonjs/src}/views/TabBarIcon.d.ts +3 -2
- package/lib/typescript/commonjs/src/views/TabBarIcon.d.ts.map +1 -0
- package/lib/typescript/commonjs/tsconfig.build.tsbuildinfo +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/src/TransitionConfigs/SceneStyleInterpolators.d.ts +10 -0
- package/lib/typescript/module/src/TransitionConfigs/SceneStyleInterpolators.d.ts.map +1 -0
- package/lib/typescript/module/src/TransitionConfigs/TransitionPresets.d.ts +4 -0
- package/lib/typescript/module/src/TransitionConfigs/TransitionPresets.d.ts.map +1 -0
- package/lib/typescript/module/src/TransitionConfigs/TransitionSpecs.d.ts +4 -0
- package/lib/typescript/module/src/TransitionConfigs/TransitionSpecs.d.ts.map +1 -0
- package/lib/typescript/module/src/index.d.ts +27 -0
- package/lib/typescript/module/src/index.d.ts.map +1 -0
- package/lib/typescript/module/src/navigators/createBottomTabNavigator.d.ts +17 -0
- package/lib/typescript/module/src/navigators/createBottomTabNavigator.d.ts.map +1 -0
- package/lib/typescript/module/src/types.d.ts +326 -0
- package/lib/typescript/module/src/types.d.ts.map +1 -0
- package/lib/typescript/module/src/utils/BottomTabBarHeightCallbackContext.d.ts +3 -0
- package/lib/typescript/module/src/utils/BottomTabBarHeightCallbackContext.d.ts.map +1 -0
- package/lib/typescript/module/src/utils/BottomTabBarHeightContext.d.ts +3 -0
- package/lib/typescript/module/src/utils/BottomTabBarHeightContext.d.ts.map +1 -0
- package/lib/typescript/module/src/utils/useAnimatedHashMap.d.ts +4 -0
- package/lib/typescript/module/src/utils/useAnimatedHashMap.d.ts.map +1 -0
- package/lib/typescript/module/src/utils/useBottomTabBarHeight.d.ts +2 -0
- package/lib/typescript/module/src/utils/useBottomTabBarHeight.d.ts.map +1 -0
- package/lib/typescript/module/src/utils/useIsKeyboardShown.d.ts +2 -0
- package/lib/typescript/module/src/utils/useIsKeyboardShown.d.ts.map +1 -0
- package/lib/typescript/module/src/views/Badge.d.ts +22 -0
- package/lib/typescript/module/src/views/Badge.d.ts.map +1 -0
- package/lib/typescript/module/src/views/BottomTabBar.d.ts +22 -0
- package/lib/typescript/module/src/views/BottomTabBar.d.ts.map +1 -0
- package/lib/typescript/module/src/views/BottomTabItem.d.ts +125 -0
- package/lib/typescript/module/src/views/BottomTabItem.d.ts.map +1 -0
- package/lib/typescript/module/src/views/BottomTabView.d.ts +10 -0
- package/lib/typescript/module/src/views/BottomTabView.d.ts.map +1 -0
- package/lib/typescript/module/src/views/ScreenFallback.d.ts +17 -0
- package/lib/typescript/module/src/views/ScreenFallback.d.ts.map +1 -0
- package/lib/typescript/module/src/views/TabBarIcon.d.ts +23 -0
- package/lib/typescript/module/src/views/TabBarIcon.d.ts.map +1 -0
- package/lib/typescript/module/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +41 -17
- package/src/navigators/createBottomTabNavigator.tsx +4 -7
- package/src/types.tsx +20 -4
- package/src/views/BottomTabBar.tsx +89 -47
- package/src/views/BottomTabItem.tsx +115 -31
- package/src/views/BottomTabView.tsx +22 -4
- package/src/views/TabBarIcon.tsx +55 -18
- package/lib/typescript/src/TransitionConfigs/SceneStyleInterpolators.d.ts.map +0 -1
- package/lib/typescript/src/TransitionConfigs/TransitionPresets.d.ts.map +0 -1
- package/lib/typescript/src/TransitionConfigs/TransitionSpecs.d.ts.map +0 -1
- package/lib/typescript/src/index.d.ts.map +0 -1
- package/lib/typescript/src/navigators/createBottomTabNavigator.d.ts.map +0 -1
- package/lib/typescript/src/types.d.ts.map +0 -1
- package/lib/typescript/src/utils/BottomTabBarHeightCallbackContext.d.ts.map +0 -1
- package/lib/typescript/src/utils/BottomTabBarHeightContext.d.ts.map +0 -1
- package/lib/typescript/src/utils/useAnimatedHashMap.d.ts.map +0 -1
- package/lib/typescript/src/utils/useBottomTabBarHeight.d.ts.map +0 -1
- package/lib/typescript/src/utils/useIsKeyboardShown.d.ts.map +0 -1
- package/lib/typescript/src/views/Badge.d.ts.map +0 -1
- package/lib/typescript/src/views/BottomTabBar.d.ts.map +0 -1
- package/lib/typescript/src/views/BottomTabItem.d.ts.map +0 -1
- package/lib/typescript/src/views/BottomTabView.d.ts.map +0 -1
- package/lib/typescript/src/views/ScreenFallback.d.ts.map +0 -1
- package/lib/typescript/src/views/TabBarIcon.d.ts.map +0 -1
- /package/lib/typescript/{src → commonjs/src}/TransitionConfigs/SceneStyleInterpolators.d.ts +0 -0
- /package/lib/typescript/{src → commonjs/src}/TransitionConfigs/TransitionPresets.d.ts +0 -0
- /package/lib/typescript/{src → commonjs/src}/TransitionConfigs/TransitionSpecs.d.ts +0 -0
- /package/lib/typescript/{src → commonjs/src}/index.d.ts +0 -0
- /package/lib/typescript/{src → commonjs/src}/utils/BottomTabBarHeightCallbackContext.d.ts +0 -0
- /package/lib/typescript/{src → commonjs/src}/utils/BottomTabBarHeightContext.d.ts +0 -0
- /package/lib/typescript/{src → commonjs/src}/utils/useAnimatedHashMap.d.ts +0 -0
- /package/lib/typescript/{src → commonjs/src}/utils/useBottomTabBarHeight.d.ts +0 -0
- /package/lib/typescript/{src → commonjs/src}/utils/useIsKeyboardShown.d.ts +0 -0
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
useLocale,
|
|
14
14
|
useTheme,
|
|
15
15
|
} from '@react-navigation/native';
|
|
16
|
-
import Color from 'color';
|
|
17
16
|
import React from 'react';
|
|
18
17
|
import {
|
|
19
18
|
Animated,
|
|
@@ -38,10 +37,11 @@ type Props = BottomTabBarProps & {
|
|
|
38
37
|
style?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
|
|
39
38
|
};
|
|
40
39
|
|
|
41
|
-
const
|
|
42
|
-
const
|
|
40
|
+
const TABBAR_HEIGHT_UIKIT = 49;
|
|
41
|
+
const TABBAR_HEIGHT_UIKIT_COMPACT = 32;
|
|
42
|
+
const SPACING_UIKIT = 15;
|
|
43
|
+
const SPACING_MATERIAL = 12;
|
|
43
44
|
const DEFAULT_MAX_TAB_ITEM_WIDTH = 125;
|
|
44
|
-
const SPACING = 12;
|
|
45
45
|
|
|
46
46
|
const useNativeDriver = Platform.OS !== 'web';
|
|
47
47
|
|
|
@@ -91,8 +91,36 @@ const shouldUseHorizontalLabels = ({
|
|
|
91
91
|
}
|
|
92
92
|
};
|
|
93
93
|
|
|
94
|
-
const
|
|
95
|
-
|
|
94
|
+
const isCompact = ({ state, descriptors, dimensions }: Options): boolean => {
|
|
95
|
+
const { tabBarPosition, tabBarVariant } =
|
|
96
|
+
descriptors[state.routes[state.index].key].options;
|
|
97
|
+
|
|
98
|
+
if (
|
|
99
|
+
tabBarPosition === 'left' ||
|
|
100
|
+
tabBarPosition === 'right' ||
|
|
101
|
+
tabBarVariant === 'material'
|
|
102
|
+
) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const isLandscape = dimensions.width > dimensions.height;
|
|
107
|
+
const horizontalLabels = shouldUseHorizontalLabels({
|
|
108
|
+
state,
|
|
109
|
+
descriptors,
|
|
110
|
+
dimensions,
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
if (
|
|
114
|
+
Platform.OS === 'ios' &&
|
|
115
|
+
!Platform.isPad &&
|
|
116
|
+
isLandscape &&
|
|
117
|
+
horizontalLabels
|
|
118
|
+
) {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return false;
|
|
123
|
+
};
|
|
96
124
|
|
|
97
125
|
export const getTabBarHeight = ({
|
|
98
126
|
state,
|
|
@@ -100,11 +128,12 @@ export const getTabBarHeight = ({
|
|
|
100
128
|
dimensions,
|
|
101
129
|
insets,
|
|
102
130
|
style,
|
|
103
|
-
...rest
|
|
104
131
|
}: Options & {
|
|
105
132
|
insets: EdgeInsets;
|
|
106
133
|
style: Animated.WithAnimatedValue<StyleProp<ViewStyle>> | undefined;
|
|
107
134
|
}) => {
|
|
135
|
+
const { tabBarPosition } = descriptors[state.routes[state.index].key].options;
|
|
136
|
+
|
|
108
137
|
const flattenedStyle = StyleSheet.flatten(style);
|
|
109
138
|
const customHeight =
|
|
110
139
|
flattenedStyle && 'height' in flattenedStyle
|
|
@@ -115,25 +144,13 @@ export const getTabBarHeight = ({
|
|
|
115
144
|
return customHeight;
|
|
116
145
|
}
|
|
117
146
|
|
|
118
|
-
const
|
|
119
|
-
const horizontalLabels = shouldUseHorizontalLabels({
|
|
120
|
-
state,
|
|
121
|
-
descriptors,
|
|
122
|
-
dimensions,
|
|
123
|
-
...rest,
|
|
124
|
-
});
|
|
125
|
-
const paddingBottom = getPaddingBottom(insets);
|
|
147
|
+
const inset = insets[tabBarPosition === 'top' ? 'top' : 'bottom'];
|
|
126
148
|
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
!Platform.isPad &&
|
|
130
|
-
isLandscape &&
|
|
131
|
-
horizontalLabels
|
|
132
|
-
) {
|
|
133
|
-
return COMPACT_TABBAR_HEIGHT + paddingBottom;
|
|
149
|
+
if (isCompact({ state, descriptors, dimensions })) {
|
|
150
|
+
return TABBAR_HEIGHT_UIKIT_COMPACT + inset;
|
|
134
151
|
}
|
|
135
152
|
|
|
136
|
-
return
|
|
153
|
+
return TABBAR_HEIGHT_UIKIT + inset;
|
|
137
154
|
};
|
|
138
155
|
|
|
139
156
|
export function BottomTabBar({
|
|
@@ -154,22 +171,38 @@ export function BottomTabBar({
|
|
|
154
171
|
const {
|
|
155
172
|
tabBarPosition = 'bottom',
|
|
156
173
|
tabBarShowLabel,
|
|
174
|
+
tabBarLabelPosition,
|
|
157
175
|
tabBarHideOnKeyboard = false,
|
|
158
176
|
tabBarVisibilityAnimationConfig,
|
|
177
|
+
tabBarVariant = 'uikit',
|
|
159
178
|
tabBarStyle,
|
|
160
179
|
tabBarBackground,
|
|
161
180
|
tabBarActiveTintColor,
|
|
162
181
|
tabBarInactiveTintColor,
|
|
163
|
-
tabBarActiveBackgroundColor
|
|
164
|
-
tabBarPosition !== 'top'
|
|
165
|
-
? Color(tabBarActiveTintColor ?? colors.primary)
|
|
166
|
-
.alpha(0.12)
|
|
167
|
-
.rgb()
|
|
168
|
-
.string()
|
|
169
|
-
: undefined,
|
|
182
|
+
tabBarActiveBackgroundColor,
|
|
170
183
|
tabBarInactiveBackgroundColor,
|
|
171
184
|
} = focusedOptions;
|
|
172
185
|
|
|
186
|
+
if (
|
|
187
|
+
tabBarVariant === 'material' &&
|
|
188
|
+
tabBarPosition !== 'left' &&
|
|
189
|
+
tabBarPosition !== 'right'
|
|
190
|
+
) {
|
|
191
|
+
throw new Error(
|
|
192
|
+
"The 'material' variant for tab bar is only supported when 'tabBarPosition' is set to 'left' or 'right'."
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (
|
|
197
|
+
tabBarLabelPosition === 'below-icon' &&
|
|
198
|
+
tabBarVariant === 'uikit' &&
|
|
199
|
+
(tabBarPosition === 'left' || tabBarPosition === 'right')
|
|
200
|
+
) {
|
|
201
|
+
throw new Error(
|
|
202
|
+
"The 'below-icon' label position for tab bar is only supported when 'tabBarPosition' is set to 'top' or 'bottom' when using the 'uikit' variant."
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
|
|
173
206
|
const dimensions = useSafeAreaFrame();
|
|
174
207
|
const isKeyboardShown = useIsKeyboardShown();
|
|
175
208
|
|
|
@@ -211,6 +244,7 @@ export function BottomTabBar({
|
|
|
211
244
|
}
|
|
212
245
|
});
|
|
213
246
|
} else {
|
|
247
|
+
// eslint-disable-next-line @eslint-react/hooks-extra/no-direct-set-state-in-use-effect
|
|
214
248
|
setIsTabBarHidden(true);
|
|
215
249
|
|
|
216
250
|
const animation =
|
|
@@ -249,7 +283,6 @@ export function BottomTabBar({
|
|
|
249
283
|
|
|
250
284
|
const { routes } = state;
|
|
251
285
|
|
|
252
|
-
const paddingBottom = getPaddingBottom(insets);
|
|
253
286
|
const tabBarHeight = getTabBarHeight({
|
|
254
287
|
state,
|
|
255
288
|
descriptors,
|
|
@@ -264,7 +297,10 @@ export function BottomTabBar({
|
|
|
264
297
|
dimensions,
|
|
265
298
|
});
|
|
266
299
|
|
|
267
|
-
const
|
|
300
|
+
const compact = isCompact({ state, descriptors, dimensions });
|
|
301
|
+
const sidebar = tabBarPosition === 'left' || tabBarPosition === 'right';
|
|
302
|
+
const spacing =
|
|
303
|
+
tabBarVariant === 'material' ? SPACING_MATERIAL : SPACING_UIKIT;
|
|
268
304
|
|
|
269
305
|
const tabBarBackgroundElement = tabBarBackground?.();
|
|
270
306
|
|
|
@@ -298,16 +334,16 @@ export function BottomTabBar({
|
|
|
298
334
|
tabBarBackgroundElement != null ? 'transparent' : colors.card,
|
|
299
335
|
borderColor: colors.border,
|
|
300
336
|
},
|
|
301
|
-
|
|
337
|
+
sidebar
|
|
302
338
|
? {
|
|
303
339
|
paddingTop:
|
|
304
|
-
(hasHorizontalLabels ?
|
|
340
|
+
(hasHorizontalLabels ? spacing : spacing / 2) + insets.top,
|
|
305
341
|
paddingBottom:
|
|
306
|
-
(hasHorizontalLabels ?
|
|
342
|
+
(hasHorizontalLabels ? spacing : spacing / 2) + insets.bottom,
|
|
307
343
|
paddingStart:
|
|
308
|
-
|
|
344
|
+
spacing + (tabBarPosition === 'left' ? insets.left : 0),
|
|
309
345
|
paddingEnd:
|
|
310
|
-
|
|
346
|
+
spacing + (tabBarPosition === 'right' ? insets.right : 0),
|
|
311
347
|
minWidth: hasHorizontalLabels
|
|
312
348
|
? getDefaultSidebarWidth(dimensions)
|
|
313
349
|
: 0,
|
|
@@ -320,7 +356,7 @@ export function BottomTabBar({
|
|
|
320
356
|
inputRange: [0, 1],
|
|
321
357
|
outputRange: [
|
|
322
358
|
layout.height +
|
|
323
|
-
|
|
359
|
+
insets[tabBarPosition === 'top' ? 'top' : 'bottom'] +
|
|
324
360
|
StyleSheet.hairlineWidth,
|
|
325
361
|
0,
|
|
326
362
|
],
|
|
@@ -333,21 +369,22 @@ export function BottomTabBar({
|
|
|
333
369
|
},
|
|
334
370
|
{
|
|
335
371
|
height: tabBarHeight,
|
|
336
|
-
paddingBottom,
|
|
372
|
+
paddingBottom: tabBarPosition === 'bottom' ? insets.bottom : 0,
|
|
373
|
+
paddingTop: tabBarPosition === 'top' ? insets.top : 0,
|
|
337
374
|
paddingHorizontal: Math.max(insets.left, insets.right),
|
|
338
375
|
},
|
|
339
376
|
],
|
|
340
377
|
tabBarStyle,
|
|
341
378
|
]}
|
|
342
379
|
pointerEvents={isTabBarHidden ? 'none' : 'auto'}
|
|
343
|
-
onLayout={
|
|
380
|
+
onLayout={sidebar ? undefined : handleLayout}
|
|
344
381
|
>
|
|
345
382
|
<View pointerEvents="none" style={StyleSheet.absoluteFill}>
|
|
346
383
|
{tabBarBackgroundElement}
|
|
347
384
|
</View>
|
|
348
385
|
<View
|
|
349
386
|
accessibilityRole="tablist"
|
|
350
|
-
style={
|
|
387
|
+
style={sidebar ? styles.sideContent : styles.bottomContent}
|
|
351
388
|
>
|
|
352
389
|
{routes.map((route, index) => {
|
|
353
390
|
const focused = index === state.index;
|
|
@@ -402,7 +439,9 @@ export function BottomTabBar({
|
|
|
402
439
|
descriptor={descriptors[route.key]}
|
|
403
440
|
focused={focused}
|
|
404
441
|
horizontal={hasHorizontalLabels}
|
|
405
|
-
|
|
442
|
+
compact={compact}
|
|
443
|
+
sidebar={sidebar}
|
|
444
|
+
variant={tabBarVariant}
|
|
406
445
|
onPress={onPress}
|
|
407
446
|
onLongPress={onLongPress}
|
|
408
447
|
accessibilityLabel={accessibilityLabel}
|
|
@@ -426,8 +465,14 @@ export function BottomTabBar({
|
|
|
426
465
|
labelStyle={options.tabBarLabelStyle}
|
|
427
466
|
iconStyle={options.tabBarIconStyle}
|
|
428
467
|
style={[
|
|
429
|
-
|
|
430
|
-
?
|
|
468
|
+
sidebar
|
|
469
|
+
? {
|
|
470
|
+
marginVertical: hasHorizontalLabels
|
|
471
|
+
? tabBarVariant === 'material'
|
|
472
|
+
? 0
|
|
473
|
+
: 1
|
|
474
|
+
: spacing / 2,
|
|
475
|
+
}
|
|
431
476
|
: styles.bottomItem,
|
|
432
477
|
options.tabBarItemStyle,
|
|
433
478
|
]}
|
|
@@ -469,7 +514,4 @@ const styles = StyleSheet.create({
|
|
|
469
514
|
bottomItem: {
|
|
470
515
|
flex: 1,
|
|
471
516
|
},
|
|
472
|
-
sideItemVertical: {
|
|
473
|
-
marginVertical: SPACING / 2,
|
|
474
|
-
},
|
|
475
517
|
});
|
|
@@ -90,6 +90,14 @@ type Props = {
|
|
|
90
90
|
* Whether the label should be aligned with the icon horizontally.
|
|
91
91
|
*/
|
|
92
92
|
horizontal: boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Whether to render the icon and label in compact mode.
|
|
95
|
+
*/
|
|
96
|
+
compact: boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Whether the tab is an item in a side bar.
|
|
99
|
+
*/
|
|
100
|
+
sidebar: boolean;
|
|
93
101
|
/**
|
|
94
102
|
* Variant of navigation bar styling
|
|
95
103
|
* - `uikit`: iOS UIKit style
|
|
@@ -134,6 +142,10 @@ type Props = {
|
|
|
134
142
|
style?: StyleProp<ViewStyle>;
|
|
135
143
|
};
|
|
136
144
|
|
|
145
|
+
const renderButtonDefault = (props: BottomTabBarButtonProps) => (
|
|
146
|
+
<PlatformPressable {...props} />
|
|
147
|
+
);
|
|
148
|
+
|
|
137
149
|
export function BottomTabItem({
|
|
138
150
|
route,
|
|
139
151
|
href,
|
|
@@ -143,16 +155,18 @@ export function BottomTabItem({
|
|
|
143
155
|
icon,
|
|
144
156
|
badge,
|
|
145
157
|
badgeStyle,
|
|
146
|
-
button =
|
|
158
|
+
button = renderButtonDefault,
|
|
147
159
|
accessibilityLabel,
|
|
148
160
|
testID,
|
|
149
161
|
onPress,
|
|
150
162
|
onLongPress,
|
|
151
163
|
horizontal,
|
|
164
|
+
compact,
|
|
165
|
+
sidebar,
|
|
152
166
|
variant,
|
|
153
167
|
activeTintColor: customActiveTintColor,
|
|
154
168
|
inactiveTintColor: customInactiveTintColor,
|
|
155
|
-
activeBackgroundColor
|
|
169
|
+
activeBackgroundColor: customActiveBackgroundColor,
|
|
156
170
|
inactiveBackgroundColor = 'transparent',
|
|
157
171
|
showLabel = true,
|
|
158
172
|
allowFontScaling,
|
|
@@ -163,21 +177,47 @@ export function BottomTabItem({
|
|
|
163
177
|
const { colors, fonts } = useTheme();
|
|
164
178
|
|
|
165
179
|
const activeTintColor =
|
|
166
|
-
customActiveTintColor
|
|
167
|
-
|
|
168
|
-
|
|
180
|
+
customActiveTintColor ??
|
|
181
|
+
(variant === 'uikit' && sidebar && horizontal
|
|
182
|
+
? Color(colors.primary).isDark()
|
|
183
|
+
? 'white'
|
|
184
|
+
: Color(colors.primary).darken(0.71).string()
|
|
185
|
+
: colors.primary);
|
|
169
186
|
|
|
170
187
|
const inactiveTintColor =
|
|
171
188
|
customInactiveTintColor === undefined
|
|
172
|
-
?
|
|
189
|
+
? variant === 'material'
|
|
190
|
+
? Color(colors.text).alpha(0.68).rgb().string()
|
|
191
|
+
: Color(colors.text).mix(Color(colors.card), 0.5).hex()
|
|
173
192
|
: customInactiveTintColor;
|
|
174
193
|
|
|
194
|
+
const activeBackgroundColor =
|
|
195
|
+
customActiveBackgroundColor ??
|
|
196
|
+
(variant === 'material'
|
|
197
|
+
? Color(activeTintColor).alpha(0.12).rgb().string()
|
|
198
|
+
: sidebar && horizontal
|
|
199
|
+
? colors.primary
|
|
200
|
+
: 'transparent');
|
|
201
|
+
|
|
202
|
+
let labelInactiveTintColor = inactiveTintColor;
|
|
203
|
+
let iconInactiveTintColor = inactiveTintColor;
|
|
204
|
+
|
|
205
|
+
if (
|
|
206
|
+
variant === 'uikit' &&
|
|
207
|
+
sidebar &&
|
|
208
|
+
horizontal &&
|
|
209
|
+
customInactiveTintColor === undefined
|
|
210
|
+
) {
|
|
211
|
+
iconInactiveTintColor = colors.primary;
|
|
212
|
+
labelInactiveTintColor = colors.text;
|
|
213
|
+
}
|
|
214
|
+
|
|
175
215
|
const renderLabel = ({ focused }: { focused: boolean }) => {
|
|
176
216
|
if (showLabel === false) {
|
|
177
217
|
return null;
|
|
178
218
|
}
|
|
179
219
|
|
|
180
|
-
const color = focused ? activeTintColor :
|
|
220
|
+
const color = focused ? activeTintColor : labelInactiveTintColor;
|
|
181
221
|
|
|
182
222
|
if (typeof label !== 'string') {
|
|
183
223
|
const { options } = descriptor;
|
|
@@ -206,11 +246,19 @@ export function BottomTabItem({
|
|
|
206
246
|
horizontal
|
|
207
247
|
? [
|
|
208
248
|
styles.labelBeside,
|
|
209
|
-
|
|
210
|
-
|
|
249
|
+
variant === 'material'
|
|
250
|
+
? styles.labelSidebarMaterial
|
|
251
|
+
: sidebar
|
|
252
|
+
? styles.labelSidebarUiKit
|
|
253
|
+
: compact
|
|
254
|
+
? styles.labelBesideUikitCompact
|
|
255
|
+
: styles.labelBesideUikit,
|
|
256
|
+
icon == null && { marginStart: 0 },
|
|
211
257
|
]
|
|
212
258
|
: styles.labelBeneath,
|
|
213
|
-
variant === '
|
|
259
|
+
compact || (variant === 'uikit' && sidebar && horizontal)
|
|
260
|
+
? fonts.regular
|
|
261
|
+
: fonts.medium,
|
|
214
262
|
labelStyle,
|
|
215
263
|
]}
|
|
216
264
|
allowFontScaling={allowFontScaling}
|
|
@@ -232,13 +280,14 @@ export function BottomTabItem({
|
|
|
232
280
|
return (
|
|
233
281
|
<TabBarIcon
|
|
234
282
|
route={route}
|
|
235
|
-
|
|
283
|
+
variant={variant}
|
|
284
|
+
size={compact ? 'compact' : 'regular'}
|
|
236
285
|
badge={badge}
|
|
237
286
|
badgeStyle={badgeStyle}
|
|
238
287
|
activeOpacity={activeOpacity}
|
|
239
288
|
inactiveOpacity={inactiveOpacity}
|
|
240
289
|
activeTintColor={activeTintColor}
|
|
241
|
-
inactiveTintColor={
|
|
290
|
+
inactiveTintColor={iconInactiveTintColor}
|
|
242
291
|
renderIcon={icon}
|
|
243
292
|
style={iconStyle}
|
|
244
293
|
/>
|
|
@@ -252,7 +301,14 @@ export function BottomTabItem({
|
|
|
252
301
|
: inactiveBackgroundColor;
|
|
253
302
|
|
|
254
303
|
const { flex } = StyleSheet.flatten(style || {});
|
|
255
|
-
const borderRadius =
|
|
304
|
+
const borderRadius =
|
|
305
|
+
variant === 'material'
|
|
306
|
+
? horizontal
|
|
307
|
+
? 56
|
|
308
|
+
: 16
|
|
309
|
+
: sidebar && horizontal
|
|
310
|
+
? 10
|
|
311
|
+
: 0;
|
|
256
312
|
|
|
257
313
|
return (
|
|
258
314
|
<View
|
|
@@ -278,20 +334,26 @@ export function BottomTabItem({
|
|
|
278
334
|
accessibilityStates: focused ? ['selected'] : [],
|
|
279
335
|
android_ripple: { borderless: true },
|
|
280
336
|
hoverEffect:
|
|
281
|
-
variant === 'material'
|
|
337
|
+
variant === 'material' || (sidebar && horizontal)
|
|
338
|
+
? { color: colors.text }
|
|
339
|
+
: undefined,
|
|
282
340
|
pressOpacity: 1,
|
|
283
341
|
style: [
|
|
284
342
|
styles.tab,
|
|
285
343
|
{ flex, backgroundColor, borderRadius },
|
|
286
|
-
|
|
287
|
-
?
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
styles.
|
|
293
|
-
|
|
294
|
-
|
|
344
|
+
sidebar
|
|
345
|
+
? variant === 'material'
|
|
346
|
+
? horizontal
|
|
347
|
+
? styles.tabBarSidebarMaterial
|
|
348
|
+
: styles.tabVerticalMaterial
|
|
349
|
+
: horizontal
|
|
350
|
+
? styles.tabBarSidebarUiKit
|
|
351
|
+
: styles.tabVerticalUiKit
|
|
352
|
+
: variant === 'material'
|
|
353
|
+
? styles.tabVerticalMaterial
|
|
354
|
+
: horizontal
|
|
355
|
+
? styles.tabHorizontalUiKit
|
|
356
|
+
: styles.tabVerticalUiKit,
|
|
295
357
|
],
|
|
296
358
|
children: (
|
|
297
359
|
<React.Fragment>
|
|
@@ -310,33 +372,55 @@ const styles = StyleSheet.create({
|
|
|
310
372
|
// Roundness for iPad hover effect
|
|
311
373
|
borderRadius: 10,
|
|
312
374
|
},
|
|
313
|
-
|
|
314
|
-
justifyContent: 'flex-
|
|
375
|
+
tabVerticalUiKit: {
|
|
376
|
+
justifyContent: 'flex-start',
|
|
315
377
|
flexDirection: 'column',
|
|
378
|
+
padding: 5,
|
|
316
379
|
},
|
|
317
380
|
tabVerticalMaterial: {
|
|
318
381
|
padding: 10,
|
|
319
382
|
},
|
|
320
|
-
|
|
383
|
+
tabHorizontalUiKit: {
|
|
321
384
|
justifyContent: 'center',
|
|
385
|
+
alignItems: 'center',
|
|
386
|
+
flexDirection: 'row',
|
|
387
|
+
padding: 5,
|
|
388
|
+
},
|
|
389
|
+
tabBarSidebarUiKit: {
|
|
390
|
+
justifyContent: 'flex-start',
|
|
391
|
+
alignItems: 'center',
|
|
392
|
+
flexDirection: 'row',
|
|
393
|
+
paddingVertical: 7,
|
|
394
|
+
paddingHorizontal: 5,
|
|
395
|
+
},
|
|
396
|
+
tabBarSidebarMaterial: {
|
|
397
|
+
justifyContent: 'flex-start',
|
|
398
|
+
alignItems: 'center',
|
|
322
399
|
flexDirection: 'row',
|
|
323
|
-
paddingVertical:
|
|
400
|
+
paddingVertical: 15,
|
|
324
401
|
paddingStart: 16,
|
|
325
402
|
paddingEnd: 24,
|
|
326
403
|
},
|
|
327
|
-
|
|
328
|
-
|
|
404
|
+
labelSidebarMaterial: {
|
|
405
|
+
marginStart: 12,
|
|
406
|
+
},
|
|
407
|
+
labelSidebarUiKit: {
|
|
408
|
+
fontSize: 17,
|
|
409
|
+
marginStart: 10,
|
|
329
410
|
},
|
|
330
411
|
labelBeneath: {
|
|
331
412
|
fontSize: 10,
|
|
332
413
|
},
|
|
333
414
|
labelBeside: {
|
|
334
415
|
marginEnd: 12,
|
|
335
|
-
marginVertical: 4,
|
|
336
416
|
lineHeight: 24,
|
|
337
|
-
marginStart: 20,
|
|
338
417
|
},
|
|
339
418
|
labelBesideUikit: {
|
|
340
419
|
fontSize: 13,
|
|
420
|
+
marginStart: 5,
|
|
421
|
+
},
|
|
422
|
+
labelBesideUikitCompact: {
|
|
423
|
+
fontSize: 12,
|
|
424
|
+
marginStart: 5,
|
|
341
425
|
},
|
|
342
426
|
});
|
|
@@ -64,12 +64,16 @@ const hasAnimation = (options: BottomTabNavigationOptions) => {
|
|
|
64
64
|
return animation !== 'none';
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
return
|
|
67
|
+
return Boolean(transitionSpec);
|
|
68
68
|
};
|
|
69
69
|
|
|
70
|
+
const renderTabBarDefault = (props: BottomTabBarProps) => (
|
|
71
|
+
<BottomTabBar {...props} />
|
|
72
|
+
);
|
|
73
|
+
|
|
70
74
|
export function BottomTabView(props: Props) {
|
|
71
75
|
const {
|
|
72
|
-
tabBar =
|
|
76
|
+
tabBar = renderTabBarDefault,
|
|
73
77
|
state,
|
|
74
78
|
navigation,
|
|
75
79
|
descriptors,
|
|
@@ -77,7 +81,6 @@ export function BottomTabView(props: Props) {
|
|
|
77
81
|
detachInactiveScreens = Platform.OS === 'web' ||
|
|
78
82
|
Platform.OS === 'android' ||
|
|
79
83
|
Platform.OS === 'ios',
|
|
80
|
-
sceneContainerStyle,
|
|
81
84
|
} = props;
|
|
82
85
|
|
|
83
86
|
const focusedRouteKey = state.routes[state.index].key;
|
|
@@ -119,6 +122,13 @@ export function BottomTabView(props: Props) {
|
|
|
119
122
|
}
|
|
120
123
|
|
|
121
124
|
const animateToIndex = () => {
|
|
125
|
+
if (previousRouteKey !== focusedRouteKey) {
|
|
126
|
+
navigation.emit({
|
|
127
|
+
type: 'transitionStart',
|
|
128
|
+
target: focusedRouteKey,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
122
132
|
Animated.parallel(
|
|
123
133
|
state.routes
|
|
124
134
|
.map((route, index) => {
|
|
@@ -156,6 +166,13 @@ export function BottomTabView(props: Props) {
|
|
|
156
166
|
if (finished && popToTopAction) {
|
|
157
167
|
navigation.dispatch(popToTopAction);
|
|
158
168
|
}
|
|
169
|
+
|
|
170
|
+
if (previousRouteKey !== focusedRouteKey) {
|
|
171
|
+
navigation.emit({
|
|
172
|
+
type: 'transitionEnd',
|
|
173
|
+
target: focusedRouteKey,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
159
176
|
});
|
|
160
177
|
};
|
|
161
178
|
|
|
@@ -268,6 +285,7 @@ export function BottomTabView(props: Props) {
|
|
|
268
285
|
headerShown,
|
|
269
286
|
headerStatusBarHeight,
|
|
270
287
|
headerTransparent,
|
|
288
|
+
sceneStyle: customSceneStyle,
|
|
271
289
|
} = descriptor.options;
|
|
272
290
|
|
|
273
291
|
const { sceneStyle } =
|
|
@@ -317,7 +335,7 @@ export function BottomTabView(props: Props) {
|
|
|
317
335
|
descriptor.navigation as BottomTabNavigationProp<ParamListBase>,
|
|
318
336
|
options: descriptor.options,
|
|
319
337
|
})}
|
|
320
|
-
style={[
|
|
338
|
+
style={[customSceneStyle, animationEnabled && sceneStyle]}
|
|
321
339
|
>
|
|
322
340
|
{descriptor.render()}
|
|
323
341
|
</Screen>
|