@react-navigation/bottom-tabs 7.9.0 → 8.0.0-alpha.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.
Files changed (139) hide show
  1. package/lib/module/index.js +3 -2
  2. package/lib/module/index.js.map +1 -1
  3. package/lib/module/navigators/createBottomTabNavigator.js +27 -9
  4. package/lib/module/navigators/createBottomTabNavigator.js.map +1 -1
  5. package/lib/module/utils/BottomTabAnimationContext.js +5 -0
  6. package/lib/module/utils/BottomTabAnimationContext.js.map +1 -0
  7. package/lib/module/utils/useBottomTabAnimation.js +12 -0
  8. package/lib/module/utils/useBottomTabAnimation.js.map +1 -0
  9. package/lib/module/utils/useTabBarPosition.js +34 -0
  10. package/lib/module/utils/useTabBarPosition.js.map +1 -0
  11. package/lib/module/views/BottomTabBar.js +46 -49
  12. package/lib/module/views/BottomTabBar.js.map +1 -1
  13. package/lib/module/views/BottomTabItem.js +17 -15
  14. package/lib/module/views/BottomTabItem.js.map +1 -1
  15. package/lib/module/views/BottomTabViewCommon.js +16 -0
  16. package/lib/module/views/BottomTabViewCommon.js.map +1 -0
  17. package/lib/module/views/{BottomTabView.js → BottomTabViewCustom.js} +107 -106
  18. package/lib/module/views/BottomTabViewCustom.js.map +1 -0
  19. package/lib/module/views/BottomTabViewNative.android.js +4 -0
  20. package/lib/module/views/BottomTabViewNative.android.js.map +1 -0
  21. package/lib/module/views/BottomTabViewNative.ios.js +4 -0
  22. package/lib/module/views/BottomTabViewNative.ios.js.map +1 -0
  23. package/lib/module/views/BottomTabViewNative.js +5 -0
  24. package/lib/module/views/BottomTabViewNative.js.map +1 -0
  25. package/lib/module/{unstable/NativeBottomTabView.native.js → views/BottomTabViewNativeImpl.js} +95 -77
  26. package/lib/module/views/BottomTabViewNativeImpl.js.map +1 -0
  27. package/lib/module/views/ScreenContent.js +39 -0
  28. package/lib/module/views/ScreenContent.js.map +1 -0
  29. package/lib/module/views/TabBarIcon.js +40 -4
  30. package/lib/module/views/TabBarIcon.js.map +1 -1
  31. package/lib/typescript/src/index.d.ts +4 -3
  32. package/lib/typescript/src/index.d.ts.map +1 -1
  33. package/lib/typescript/src/navigators/createBottomTabNavigator.d.ts +10 -6
  34. package/lib/typescript/src/navigators/createBottomTabNavigator.d.ts.map +1 -1
  35. package/lib/typescript/src/types.d.ts +383 -115
  36. package/lib/typescript/src/types.d.ts.map +1 -1
  37. package/lib/typescript/src/utils/BottomTabAnimationContext.d.ts +4 -0
  38. package/lib/typescript/src/utils/BottomTabAnimationContext.d.ts.map +1 -0
  39. package/lib/typescript/src/utils/useBottomTabAnimation.d.ts +2 -0
  40. package/lib/typescript/src/utils/useBottomTabAnimation.d.ts.map +1 -0
  41. package/lib/typescript/src/utils/useTabBarPosition.d.ts +3 -0
  42. package/lib/typescript/src/utils/useTabBarPosition.d.ts.map +1 -0
  43. package/lib/typescript/src/views/BottomTabBar.d.ts +4 -4
  44. package/lib/typescript/src/views/BottomTabBar.d.ts.map +1 -1
  45. package/lib/typescript/src/views/BottomTabItem.d.ts +16 -14
  46. package/lib/typescript/src/views/BottomTabItem.d.ts.map +1 -1
  47. package/lib/typescript/src/views/{BottomTabView.d.ts → BottomTabViewCommon.d.ts} +2 -2
  48. package/lib/typescript/src/views/BottomTabViewCommon.d.ts.map +1 -0
  49. package/lib/typescript/src/views/BottomTabViewCustom.d.ts +10 -0
  50. package/lib/typescript/src/views/BottomTabViewCustom.d.ts.map +1 -0
  51. package/lib/typescript/src/views/BottomTabViewNative.android.d.ts +2 -0
  52. package/lib/typescript/src/views/BottomTabViewNative.android.d.ts.map +1 -0
  53. package/lib/typescript/src/views/BottomTabViewNative.d.ts +3 -0
  54. package/lib/typescript/src/views/BottomTabViewNative.d.ts.map +1 -0
  55. package/lib/typescript/src/views/BottomTabViewNative.ios.d.ts +2 -0
  56. package/lib/typescript/src/views/BottomTabViewNative.ios.d.ts.map +1 -0
  57. package/lib/typescript/src/views/BottomTabViewNativeImpl.d.ts +10 -0
  58. package/lib/typescript/src/views/BottomTabViewNativeImpl.d.ts.map +1 -0
  59. package/lib/typescript/src/views/ScreenContent.d.ts +13 -0
  60. package/lib/typescript/src/views/ScreenContent.d.ts.map +1 -0
  61. package/lib/typescript/src/views/TabBarIcon.d.ts +9 -9
  62. package/lib/typescript/src/views/TabBarIcon.d.ts.map +1 -1
  63. package/package.json +11 -16
  64. package/src/index.tsx +7 -2
  65. package/src/navigators/createBottomTabNavigator.tsx +78 -27
  66. package/src/types.tsx +417 -122
  67. package/src/utils/BottomTabAnimationContext.tsx +7 -0
  68. package/src/utils/useBottomTabAnimation.tsx +15 -0
  69. package/src/utils/useTabBarPosition.tsx +41 -0
  70. package/src/views/BottomTabBar.tsx +68 -67
  71. package/src/views/BottomTabItem.tsx +39 -34
  72. package/src/views/BottomTabViewCommon.tsx +26 -0
  73. package/src/views/{BottomTabView.tsx → BottomTabViewCustom.tsx} +142 -129
  74. package/src/views/BottomTabViewNative.android.tsx +1 -0
  75. package/src/views/BottomTabViewNative.ios.tsx +1 -0
  76. package/src/views/BottomTabViewNative.tsx +3 -0
  77. package/src/{unstable/NativeBottomTabView.native.tsx → views/BottomTabViewNativeImpl.tsx} +139 -116
  78. package/src/views/ScreenContent.tsx +58 -0
  79. package/src/views/TabBarIcon.tsx +63 -10
  80. package/lib/module/unstable/NativeBottomTabView.js +0 -6
  81. package/lib/module/unstable/NativeBottomTabView.js.map +0 -1
  82. package/lib/module/unstable/NativeBottomTabView.native.js.map +0 -1
  83. package/lib/module/unstable/NativeScreen/NativeScreen.js +0 -152
  84. package/lib/module/unstable/NativeScreen/NativeScreen.js.map +0 -1
  85. package/lib/module/unstable/NativeScreen/debounce.js +0 -12
  86. package/lib/module/unstable/NativeScreen/debounce.js.map +0 -1
  87. package/lib/module/unstable/NativeScreen/types.js +0 -4
  88. package/lib/module/unstable/NativeScreen/types.js.map +0 -1
  89. package/lib/module/unstable/NativeScreen/useAnimatedHeaderHeight.js +0 -12
  90. package/lib/module/unstable/NativeScreen/useAnimatedHeaderHeight.js.map +0 -1
  91. package/lib/module/unstable/NativeScreen/useHeaderConfig.js +0 -304
  92. package/lib/module/unstable/NativeScreen/useHeaderConfig.js.map +0 -1
  93. package/lib/module/unstable/createNativeBottomTabNavigator.js +0 -6
  94. package/lib/module/unstable/createNativeBottomTabNavigator.js.map +0 -1
  95. package/lib/module/unstable/createNativeBottomTabNavigator.native.js +0 -65
  96. package/lib/module/unstable/createNativeBottomTabNavigator.native.js.map +0 -1
  97. package/lib/module/unstable/index.js +0 -16
  98. package/lib/module/unstable/index.js.map +0 -1
  99. package/lib/module/unstable/types.js +0 -4
  100. package/lib/module/unstable/types.js.map +0 -1
  101. package/lib/module/views/BottomTabView.js.map +0 -1
  102. package/lib/module/views/ScreenFallback.js +0 -42
  103. package/lib/module/views/ScreenFallback.js.map +0 -1
  104. package/lib/typescript/src/unstable/NativeBottomTabView.d.ts +0 -10
  105. package/lib/typescript/src/unstable/NativeBottomTabView.d.ts.map +0 -1
  106. package/lib/typescript/src/unstable/NativeBottomTabView.native.d.ts +0 -10
  107. package/lib/typescript/src/unstable/NativeBottomTabView.native.d.ts.map +0 -1
  108. package/lib/typescript/src/unstable/NativeScreen/NativeScreen.d.ts +0 -8
  109. package/lib/typescript/src/unstable/NativeScreen/NativeScreen.d.ts.map +0 -1
  110. package/lib/typescript/src/unstable/NativeScreen/debounce.d.ts +0 -2
  111. package/lib/typescript/src/unstable/NativeScreen/debounce.d.ts.map +0 -1
  112. package/lib/typescript/src/unstable/NativeScreen/types.d.ts +0 -523
  113. package/lib/typescript/src/unstable/NativeScreen/types.d.ts.map +0 -1
  114. package/lib/typescript/src/unstable/NativeScreen/useAnimatedHeaderHeight.d.ts +0 -5
  115. package/lib/typescript/src/unstable/NativeScreen/useAnimatedHeaderHeight.d.ts.map +0 -1
  116. package/lib/typescript/src/unstable/NativeScreen/useHeaderConfig.d.ts +0 -11
  117. package/lib/typescript/src/unstable/NativeScreen/useHeaderConfig.d.ts.map +0 -1
  118. package/lib/typescript/src/unstable/createNativeBottomTabNavigator.d.ts +0 -2
  119. package/lib/typescript/src/unstable/createNativeBottomTabNavigator.d.ts.map +0 -1
  120. package/lib/typescript/src/unstable/createNativeBottomTabNavigator.native.d.ts +0 -16
  121. package/lib/typescript/src/unstable/createNativeBottomTabNavigator.native.d.ts.map +0 -1
  122. package/lib/typescript/src/unstable/index.d.ts +0 -13
  123. package/lib/typescript/src/unstable/index.d.ts.map +0 -1
  124. package/lib/typescript/src/unstable/types.d.ts +0 -319
  125. package/lib/typescript/src/unstable/types.d.ts.map +0 -1
  126. package/lib/typescript/src/views/BottomTabView.d.ts.map +0 -1
  127. package/lib/typescript/src/views/ScreenFallback.d.ts +0 -18
  128. package/lib/typescript/src/views/ScreenFallback.d.ts.map +0 -1
  129. package/src/unstable/NativeBottomTabView.tsx +0 -20
  130. package/src/unstable/NativeScreen/NativeScreen.tsx +0 -212
  131. package/src/unstable/NativeScreen/debounce.tsx +0 -14
  132. package/src/unstable/NativeScreen/types.ts +0 -573
  133. package/src/unstable/NativeScreen/useAnimatedHeaderHeight.tsx +0 -18
  134. package/src/unstable/NativeScreen/useHeaderConfig.tsx +0 -434
  135. package/src/unstable/createNativeBottomTabNavigator.native.tsx +0 -116
  136. package/src/unstable/createNativeBottomTabNavigator.tsx +0 -4
  137. package/src/unstable/index.tsx +0 -23
  138. package/src/unstable/types.tsx +0 -405
  139. package/src/views/ScreenFallback.tsx +0 -50
@@ -0,0 +1,7 @@
1
+ import * as React from 'react';
2
+
3
+ import type { BottomTabSceneInterpolationProps } from '../types';
4
+
5
+ export const BottomTabAnimationContext = React.createContext<
6
+ BottomTabSceneInterpolationProps | undefined
7
+ >(undefined);
@@ -0,0 +1,15 @@
1
+ import * as React from 'react';
2
+
3
+ import { BottomTabAnimationContext } from './BottomTabAnimationContext';
4
+
5
+ export function useBottomTabAnimation() {
6
+ const animation = React.useContext(BottomTabAnimationContext);
7
+
8
+ if (animation === undefined) {
9
+ throw new Error(
10
+ "Couldn't find values for tab animation. Are you inside a screen in a Bottom Tab navigator?"
11
+ );
12
+ }
13
+
14
+ return animation;
15
+ }
@@ -0,0 +1,41 @@
1
+ import { useLocale } from '@react-navigation/native';
2
+
3
+ import type { BottomTabNavigationOptions } from '../types';
4
+
5
+ export function useTabBarPosition({
6
+ tabBarPosition: customTabBarPosition,
7
+ tabBarControllerMode,
8
+ }: BottomTabNavigationOptions) {
9
+ const { direction } = useLocale();
10
+
11
+ let tabBarPosition: 'left' | 'right' | 'top' | 'bottom';
12
+
13
+ if (tabBarControllerMode != null) {
14
+ if (tabBarControllerMode === 'tabSidebar') {
15
+ if (customTabBarPosition === 'left' || customTabBarPosition === 'right') {
16
+ tabBarPosition = customTabBarPosition;
17
+ } else {
18
+ tabBarPosition = direction === 'rtl' ? 'right' : 'left';
19
+ }
20
+ } else {
21
+ if (customTabBarPosition === 'top' || customTabBarPosition === 'bottom') {
22
+ tabBarPosition = customTabBarPosition;
23
+ } else {
24
+ tabBarPosition = 'bottom';
25
+ }
26
+ }
27
+
28
+ if (
29
+ customTabBarPosition != null &&
30
+ customTabBarPosition !== tabBarPosition
31
+ ) {
32
+ throw new Error(
33
+ `The '${customTabBarPosition}' position for the tab bar is not supported when 'tabBarControllerMode' is set to '${tabBarControllerMode}'.`
34
+ );
35
+ }
36
+ } else {
37
+ tabBarPosition = customTabBarPosition ?? 'bottom';
38
+ }
39
+
40
+ return tabBarPosition;
41
+ }
@@ -1,13 +1,11 @@
1
1
  import {
2
2
  getDefaultSidebarWidth,
3
3
  getLabel,
4
- MissingIcon,
5
4
  useFrameSize,
6
5
  } from '@react-navigation/elements';
7
6
  import {
8
7
  CommonActions,
9
- NavigationContext,
10
- NavigationRouteContext,
8
+ NavigationProvider,
11
9
  type ParamListBase,
12
10
  type TabNavigationState,
13
11
  useLinkBuilder,
@@ -24,11 +22,15 @@ import {
24
22
  View,
25
23
  type ViewStyle,
26
24
  } from 'react-native';
27
- import { type EdgeInsets } from 'react-native-safe-area-context';
25
+ import {
26
+ type EdgeInsets,
27
+ useSafeAreaInsets,
28
+ } from 'react-native-safe-area-context';
28
29
 
29
30
  import type { BottomTabBarProps, BottomTabDescriptorMap } from '../types';
30
31
  import { BottomTabBarHeightCallbackContext } from '../utils/BottomTabBarHeightCallbackContext';
31
32
  import { useIsKeyboardShown } from '../utils/useIsKeyboardShown';
33
+ import { useTabBarPosition } from '../utils/useTabBarPosition';
32
34
  import { BottomTabItem } from './BottomTabItem';
33
35
 
34
36
  type Props = BottomTabBarProps & {
@@ -46,14 +48,15 @@ const useNativeDriver = Platform.OS !== 'web';
46
48
  type Options = {
47
49
  state: TabNavigationState<ParamListBase>;
48
50
  descriptors: BottomTabDescriptorMap;
49
- dimensions: { height: number; width: number };
50
51
  };
51
52
 
52
53
  const shouldUseHorizontalLabels = ({
53
54
  state,
54
55
  descriptors,
55
56
  dimensions,
56
- }: Options) => {
57
+ }: Options & {
58
+ dimensions: { height: number; width: number };
59
+ }) => {
57
60
  const { tabBarLabelPosition } =
58
61
  descriptors[state.routes[state.index].key].options;
59
62
 
@@ -89,7 +92,11 @@ const shouldUseHorizontalLabels = ({
89
92
  }
90
93
  };
91
94
 
92
- const isCompact = ({ state, descriptors, dimensions }: Options): boolean => {
95
+ const isCompact = ({
96
+ state,
97
+ descriptors,
98
+ dimensions,
99
+ }: Options & { dimensions: { height: number; width: number } }): boolean => {
93
100
  const { tabBarPosition, tabBarVariant } =
94
101
  descriptors[state.routes[state.index].key].options;
95
102
 
@@ -128,6 +135,7 @@ export const getTabBarHeight = ({
128
135
  style,
129
136
  }: Options & {
130
137
  insets: EdgeInsets;
138
+ dimensions: { height: number; width: number };
131
139
  style: Animated.WithAnimatedValue<StyleProp<ViewStyle>> | undefined;
132
140
  }) => {
133
141
  const { tabBarPosition } = descriptors[state.routes[state.index].key].options;
@@ -151,13 +159,7 @@ export const getTabBarHeight = ({
151
159
  return TABBAR_HEIGHT_UIKIT + inset;
152
160
  };
153
161
 
154
- export function BottomTabBar({
155
- state,
156
- navigation,
157
- descriptors,
158
- insets,
159
- style,
160
- }: Props) {
162
+ export function BottomTabBar({ state, navigation, descriptors, style }: Props) {
161
163
  const { colors } = useTheme();
162
164
  const { direction } = useLocale();
163
165
  const { buildHref } = useLinkBuilder();
@@ -167,9 +169,8 @@ export function BottomTabBar({
167
169
  const focusedOptions = focusedDescriptor.options;
168
170
 
169
171
  const {
170
- tabBarPosition = 'bottom',
171
- tabBarShowLabel,
172
172
  tabBarLabelPosition,
173
+ tabBarLabelVisibilityMode,
173
174
  tabBarHideOnKeyboard = false,
174
175
  tabBarVisibilityAnimationConfig,
175
176
  tabBarVariant = 'uikit',
@@ -181,6 +182,8 @@ export function BottomTabBar({
181
182
  tabBarInactiveBackgroundColor,
182
183
  } = focusedOptions;
183
184
 
185
+ const tabBarPosition = useTabBarPosition(focusedOptions);
186
+
184
187
  if (
185
188
  tabBarVariant === 'material' &&
186
189
  tabBarPosition !== 'left' &&
@@ -201,6 +204,7 @@ export function BottomTabBar({
201
204
  );
202
205
  }
203
206
 
207
+ const insets = useSafeAreaInsets();
204
208
  const isKeyboardShown = useIsKeyboardShown();
205
209
 
206
210
  const onHeightChange = React.useContext(BottomTabBarHeightCallbackContext);
@@ -380,12 +384,14 @@ export function BottomTabBar({
380
384
  paddingHorizontal: Math.max(insets.left, insets.right),
381
385
  },
382
386
  ],
387
+ {
388
+ pointerEvents: isTabBarHidden ? 'none' : 'auto',
389
+ },
383
390
  tabBarStyle,
384
391
  ]}
385
- pointerEvents={isTabBarHidden ? 'none' : 'auto'}
386
392
  onLayout={sidebar ? undefined : handleLayout}
387
393
  >
388
- <View pointerEvents="none" style={StyleSheet.absoluteFill}>
394
+ <View style={[StyleSheet.absoluteFill, { pointerEvents: 'none' }]}>
389
395
  {tabBarBackgroundElement}
390
396
  </View>
391
397
  <View
@@ -434,57 +440,52 @@ export function BottomTabBar({
434
440
  : undefined;
435
441
 
436
442
  return (
437
- <NavigationContext.Provider
443
+ <NavigationProvider
438
444
  key={route.key}
439
- value={descriptors[route.key].navigation}
445
+ navigation={descriptors[route.key].navigation}
446
+ route={route}
440
447
  >
441
- <NavigationRouteContext.Provider value={route}>
442
- <BottomTabItem
443
- href={buildHref(route.name, route.params)}
444
- route={route}
445
- descriptor={descriptors[route.key]}
446
- focused={focused}
447
- horizontal={hasHorizontalLabels}
448
- compact={compact}
449
- sidebar={sidebar}
450
- variant={tabBarVariant}
451
- onPress={onPress}
452
- onLongPress={onLongPress}
453
- accessibilityLabel={accessibilityLabel}
454
- testID={options.tabBarButtonTestID}
455
- allowFontScaling={options.tabBarAllowFontScaling}
456
- activeTintColor={tabBarActiveTintColor}
457
- inactiveTintColor={tabBarInactiveTintColor}
458
- activeBackgroundColor={tabBarActiveBackgroundColor}
459
- inactiveBackgroundColor={tabBarInactiveBackgroundColor}
460
- button={options.tabBarButton}
461
- icon={
462
- options.tabBarIcon ??
463
- (({ color, size }) => (
464
- <MissingIcon color={color} size={size} />
465
- ))
466
- }
467
- badge={options.tabBarBadge}
468
- badgeStyle={options.tabBarBadgeStyle}
469
- label={label}
470
- showLabel={tabBarShowLabel}
471
- labelStyle={options.tabBarLabelStyle}
472
- iconStyle={options.tabBarIconStyle}
473
- style={[
474
- sidebar
475
- ? {
476
- marginVertical: hasHorizontalLabels
477
- ? tabBarVariant === 'material'
478
- ? 0
479
- : 1
480
- : spacing / 2,
481
- }
482
- : styles.bottomItem,
483
- options.tabBarItemStyle,
484
- ]}
485
- />
486
- </NavigationRouteContext.Provider>
487
- </NavigationContext.Provider>
448
+ <BottomTabItem
449
+ href={buildHref(route.name, route.params)}
450
+ route={route}
451
+ descriptor={descriptors[route.key]}
452
+ focused={focused}
453
+ horizontal={hasHorizontalLabels}
454
+ compact={compact}
455
+ sidebar={sidebar}
456
+ variant={tabBarVariant}
457
+ onPress={onPress}
458
+ onLongPress={onLongPress}
459
+ accessibilityLabel={accessibilityLabel}
460
+ testID={options.tabBarButtonTestID}
461
+ allowFontScaling={options.tabBarAllowFontScaling}
462
+ activeTintColor={tabBarActiveTintColor}
463
+ inactiveTintColor={tabBarInactiveTintColor}
464
+ activeBackgroundColor={tabBarActiveBackgroundColor}
465
+ inactiveBackgroundColor={tabBarInactiveBackgroundColor}
466
+ rippleColor={options.tabBarRippleColor}
467
+ button={options.tabBarButton}
468
+ icon={options.tabBarIcon}
469
+ badge={options.tabBarBadge}
470
+ badgeStyle={options.tabBarBadgeStyle}
471
+ label={label}
472
+ labelVisibilityMode={tabBarLabelVisibilityMode}
473
+ labelStyle={options.tabBarLabelStyle}
474
+ iconStyle={options.tabBarIconStyle}
475
+ style={[
476
+ sidebar
477
+ ? {
478
+ marginVertical: hasHorizontalLabels
479
+ ? tabBarVariant === 'material'
480
+ ? 0
481
+ : 1
482
+ : spacing / 2,
483
+ }
484
+ : styles.bottomItem,
485
+ options.tabBarItemStyle,
486
+ ]}
487
+ />
488
+ </NavigationProvider>
488
489
  );
489
490
  })}
490
491
  </View>
@@ -1,8 +1,9 @@
1
1
  import { getLabel, Label, PlatformPressable } from '@react-navigation/elements';
2
+ import { Color } from '@react-navigation/elements/internal';
2
3
  import { type Route, useTheme } from '@react-navigation/native';
3
- import Color from 'color';
4
4
  import React from 'react';
5
5
  import {
6
+ type ColorValue,
6
7
  type GestureResponderEvent,
7
8
  Platform,
8
9
  type StyleProp,
@@ -11,13 +12,14 @@ import {
11
12
  View,
12
13
  type ViewStyle,
13
14
  } from 'react-native';
15
+ import type { TabBarItemLabelVisibilityMode } from 'react-native-screens';
14
16
 
15
17
  import type {
16
18
  BottomTabBarButtonProps,
17
19
  BottomTabDescriptor,
18
20
  LabelPosition,
19
21
  } from '../types';
20
- import { TabBarIcon } from './TabBarIcon';
22
+ import { TabBarIcon, type TabBarIconProps } from './TabBarIcon';
21
23
 
22
24
  type Props = {
23
25
  /**
@@ -43,18 +45,14 @@ type Props = {
43
45
  | string
44
46
  | ((props: {
45
47
  focused: boolean;
46
- color: string;
48
+ color: ColorValue;
47
49
  position: LabelPosition;
48
50
  children: string;
49
51
  }) => React.ReactNode);
50
52
  /**
51
53
  * Icon to display for the tab.
52
54
  */
53
- icon: (props: {
54
- focused: boolean;
55
- size: number;
56
- color: string;
57
- }) => React.ReactNode;
55
+ icon: TabBarIconProps['icon'] | undefined;
58
56
  /**
59
57
  * Text to show in a badge on the tab icon.
60
58
  */
@@ -107,23 +105,27 @@ type Props = {
107
105
  /**
108
106
  * Color for the icon and label when the item is active.
109
107
  */
110
- activeTintColor?: string;
108
+ activeTintColor?: ColorValue;
111
109
  /**
112
110
  * Color for the icon and label when the item is inactive.
113
111
  */
114
- inactiveTintColor?: string;
112
+ inactiveTintColor?: ColorValue;
115
113
  /**
116
114
  * Background color for item when its active.
117
115
  */
118
- activeBackgroundColor?: string;
116
+ activeBackgroundColor?: ColorValue;
119
117
  /**
120
118
  * Background color for item when its inactive.
121
119
  */
122
- inactiveBackgroundColor?: string;
120
+ inactiveBackgroundColor?: ColorValue;
123
121
  /**
124
- * Whether to show the label text for the tab.
122
+ * Color of tab bar item's ripple effect.
125
123
  */
126
- showLabel?: boolean;
124
+ rippleColor?: ColorValue;
125
+ /**
126
+ * Label visibility mode for the tab bar item.
127
+ */
128
+ labelVisibilityMode?: TabBarItemLabelVisibilityMode;
127
129
  /**
128
130
  * Whether to allow scaling the font for the label for accessibility purposes.
129
131
  * Defaults to `false` on iOS 13+ where it uses `largeContentTitle`.
@@ -172,7 +174,8 @@ export function BottomTabItem({
172
174
  inactiveTintColor: customInactiveTintColor,
173
175
  activeBackgroundColor: customActiveBackgroundColor,
174
176
  inactiveBackgroundColor = 'transparent',
175
- showLabel = true,
177
+ rippleColor,
178
+ labelVisibilityMode,
176
179
  // On iOS 13+, we use `largeContentTitle` for accessibility
177
180
  // So we don't need the font to scale up
178
181
  // https://developer.apple.com/documentation/uikit/uiview/3183939-largecontenttitle
@@ -183,25 +186,25 @@ export function BottomTabItem({
183
186
  }: Props) {
184
187
  const { colors, fonts } = useTheme();
185
188
 
186
- const activeTintColor =
189
+ const activeTintColor: ColorValue =
187
190
  customActiveTintColor ??
188
191
  (variant === 'uikit' && sidebar && horizontal
189
- ? Color(colors.primary).isDark()
192
+ ? Color(colors.primary)?.isDark()
190
193
  ? 'white'
191
- : Color(colors.primary).darken(0.71).string()
194
+ : (Color(colors.primary)?.darken(0.71).string() ?? 'white')
192
195
  : colors.primary);
193
196
 
194
- const inactiveTintColor =
197
+ const inactiveTintColor: ColorValue =
195
198
  customInactiveTintColor === undefined
196
199
  ? variant === 'material'
197
- ? Color(colors.text).alpha(0.68).rgb().string()
198
- : Color(colors.text).mix(Color(colors.card), 0.5).hex()
200
+ ? (Color(colors.text)?.alpha(0.68).string() ?? 'rgba(0, 0, 0, 0.68)')
201
+ : (Color(colors.text)?.alpha(0.5).string() ?? 'rgba(0, 0, 0, 0.5)')
199
202
  : customInactiveTintColor;
200
203
 
201
- const activeBackgroundColor =
204
+ const activeBackgroundColor: ColorValue =
202
205
  customActiveBackgroundColor ??
203
206
  (variant === 'material'
204
- ? Color(activeTintColor).alpha(0.12).rgb().string()
207
+ ? (Color(activeTintColor)?.alpha(0.12).string() ?? 'rgba(0, 0, 0, 0.06)')
205
208
  : sidebar && horizontal
206
209
  ? colors.primary
207
210
  : 'transparent');
@@ -232,7 +235,7 @@ export function BottomTabItem({
232
235
  }
233
236
 
234
237
  const renderLabel = ({ focused }: { focused: boolean }) => {
235
- if (showLabel === false) {
238
+ if (labelVisibilityMode === 'unlabeled') {
236
239
  return null;
237
240
  }
238
241
 
@@ -296,7 +299,7 @@ export function BottomTabItem({
296
299
  inactiveOpacity={inactiveOpacity}
297
300
  activeTintColor={activeTintColor}
298
301
  inactiveTintColor={iconInactiveTintColor}
299
- renderIcon={icon}
302
+ icon={icon}
300
303
  style={iconStyle}
301
304
  />
302
305
  );
@@ -335,18 +338,20 @@ export function BottomTabItem({
335
338
  onLongPress,
336
339
  testID,
337
340
  'aria-label': accessibilityLabel,
338
- 'accessibilityLargeContentTitle': labelString,
339
- 'accessibilityShowsLargeContentViewer': true,
341
+ accessibilityLargeContentTitle: labelString,
342
+ accessibilityShowsLargeContentViewer: true,
340
343
  // FIXME: role: 'tab' doesn't seem to work as expected on iOS
341
- 'role': Platform.select({ ios: 'button', default: 'tab' }),
344
+ role: Platform.select({ ios: 'button', default: 'tab' }),
342
345
  'aria-selected': focused,
343
- 'android_ripple': { borderless: true },
344
- 'hoverEffect':
345
- variant === 'material' || (sidebar && horizontal)
346
+ android_ripple: { borderless: true },
347
+ pressColor: rippleColor,
348
+ hoverEffect:
349
+ (variant === 'material' || (sidebar && horizontal)) &&
350
+ typeof colors.text === 'string'
346
351
  ? { color: colors.text }
347
352
  : undefined,
348
- 'pressOpacity': 1,
349
- 'style': [
353
+ pressOpacity: 1,
354
+ style: [
350
355
  styles.tab,
351
356
  { flex, backgroundColor, borderRadius },
352
357
  sidebar
@@ -363,7 +368,7 @@ export function BottomTabItem({
363
368
  ? styles.tabHorizontalUiKit
364
369
  : styles.tabVerticalUiKit,
365
370
  ],
366
- 'children': (
371
+ children: (
367
372
  <React.Fragment>
368
373
  {renderIcon(scene)}
369
374
  {renderLabel(scene)}
@@ -0,0 +1,26 @@
1
+ import type {
2
+ ParamListBase,
3
+ TabNavigationState,
4
+ } from '@react-navigation/native';
5
+
6
+ import type {
7
+ BottomTabDescriptorMap,
8
+ BottomTabNavigationConfig,
9
+ BottomTabNavigationHelpers,
10
+ } from '../types';
11
+ import { BottomTabViewCustom } from './BottomTabViewCustom';
12
+ import { BottomTabViewNative } from './BottomTabViewNative';
13
+
14
+ type Props = BottomTabNavigationConfig & {
15
+ state: TabNavigationState<ParamListBase>;
16
+ navigation: BottomTabNavigationHelpers;
17
+ descriptors: BottomTabDescriptorMap;
18
+ };
19
+
20
+ export function BottomTabView(props: Props) {
21
+ if (props.implementation === 'custom') {
22
+ return <BottomTabViewCustom {...props} />;
23
+ }
24
+
25
+ return <BottomTabViewNative {...props} />;
26
+ }