@react-navigation/bottom-tabs 8.0.0-alpha.2 → 8.0.0-alpha.21
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/module/navigators/createBottomTabNavigator.js +1 -18
- package/lib/module/navigators/createBottomTabNavigator.js.map +1 -1
- package/lib/module/utils/useBottomTabAnimation.js +1 -1
- package/lib/module/utils/useBottomTabAnimation.js.map +1 -1
- package/lib/module/utils/useBottomTabBarHeight.js +1 -1
- package/lib/module/utils/useBottomTabBarHeight.js.map +1 -1
- package/lib/module/views/BottomTabBar.js +13 -10
- package/lib/module/views/BottomTabBar.js.map +1 -1
- package/lib/module/views/BottomTabItem.js +1 -1
- package/lib/module/views/BottomTabItem.js.map +1 -1
- package/lib/module/views/BottomTabViewCustom.js +64 -66
- package/lib/module/views/BottomTabViewCustom.js.map +1 -1
- package/lib/module/views/BottomTabViewNativeImpl.js +117 -29
- package/lib/module/views/BottomTabViewNativeImpl.js.map +1 -1
- package/lib/module/views/ScreenContent.js.map +1 -1
- package/lib/module/views/TabBarIcon.js +5 -14
- package/lib/module/views/TabBarIcon.js.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/navigators/createBottomTabNavigator.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +63 -100
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/views/BottomTabBar.d.ts.map +1 -1
- package/lib/typescript/src/views/BottomTabItem.d.ts +16 -16
- package/lib/typescript/src/views/BottomTabItem.d.ts.map +1 -1
- package/lib/typescript/src/views/BottomTabViewCustom.d.ts +1 -1
- package/lib/typescript/src/views/BottomTabViewCustom.d.ts.map +1 -1
- package/lib/typescript/src/views/BottomTabViewNativeImpl.d.ts.map +1 -1
- package/lib/typescript/src/views/ScreenContent.d.ts +2 -2
- package/lib/typescript/src/views/ScreenContent.d.ts.map +1 -1
- package/lib/typescript/src/views/TabBarIcon.d.ts +6 -6
- package/lib/typescript/src/views/TabBarIcon.d.ts.map +1 -1
- package/package.json +16 -17
- package/src/index.tsx +0 -1
- package/src/navigators/createBottomTabNavigator.tsx +0 -28
- package/src/types.tsx +65 -109
- package/src/utils/useBottomTabAnimation.tsx +1 -1
- package/src/utils/useBottomTabBarHeight.tsx +1 -1
- package/src/views/BottomTabBar.tsx +19 -11
- package/src/views/BottomTabItem.tsx +17 -19
- package/src/views/BottomTabViewCustom.tsx +119 -117
- package/src/views/BottomTabViewNativeImpl.tsx +192 -48
- package/src/views/ScreenContent.tsx +1 -2
- package/src/views/TabBarIcon.tsx +17 -24
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { getLabel } from '@react-navigation/elements';
|
|
1
|
+
import { getLabel, type Icon } from '@react-navigation/elements';
|
|
2
2
|
import {
|
|
3
|
+
ActivityView,
|
|
3
4
|
Color,
|
|
4
|
-
Lazy,
|
|
5
5
|
SafeAreaProviderCompat,
|
|
6
6
|
} from '@react-navigation/elements/internal';
|
|
7
7
|
import {
|
|
@@ -15,7 +15,13 @@ import {
|
|
|
15
15
|
useTheme,
|
|
16
16
|
} from '@react-navigation/native';
|
|
17
17
|
import * as React from 'react';
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
Animated,
|
|
20
|
+
type ColorValue,
|
|
21
|
+
Platform,
|
|
22
|
+
PlatformColor,
|
|
23
|
+
StyleSheet,
|
|
24
|
+
} from 'react-native';
|
|
19
25
|
import {
|
|
20
26
|
type PlatformIcon,
|
|
21
27
|
Tabs,
|
|
@@ -24,7 +30,6 @@ import {
|
|
|
24
30
|
|
|
25
31
|
import type {
|
|
26
32
|
BottomTabDescriptorMap,
|
|
27
|
-
BottomTabIcon,
|
|
28
33
|
BottomTabNavigationConfig,
|
|
29
34
|
BottomTabNavigationHelpers,
|
|
30
35
|
} from '../types';
|
|
@@ -57,6 +62,18 @@ export function BottomTabViewNative({
|
|
|
57
62
|
const { dark, colors, fonts } = useTheme();
|
|
58
63
|
|
|
59
64
|
const focusedRouteKey = state.routes[state.index].key;
|
|
65
|
+
|
|
66
|
+
const [loaded, setLoaded] = React.useState([focusedRouteKey]);
|
|
67
|
+
|
|
68
|
+
if (!loaded.includes(focusedRouteKey)) {
|
|
69
|
+
setLoaded([...loaded, focusedRouteKey]);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const [pendingNavigation, setPendingNavigation] = React.useState<{
|
|
73
|
+
from: string;
|
|
74
|
+
to: string;
|
|
75
|
+
} | null>(null);
|
|
76
|
+
|
|
60
77
|
const previousRouteKeyRef = React.useRef(focusedRouteKey);
|
|
61
78
|
|
|
62
79
|
React.useEffect(() => {
|
|
@@ -75,11 +92,26 @@ export function BottomTabViewNative({
|
|
|
75
92
|
...StackActions.popToTop(),
|
|
76
93
|
target: prevRoute.state.key,
|
|
77
94
|
};
|
|
95
|
+
|
|
78
96
|
navigation.dispatch(popToTopAction);
|
|
79
97
|
}
|
|
80
98
|
}
|
|
81
99
|
|
|
82
100
|
previousRouteKeyRef.current = focusedRouteKey;
|
|
101
|
+
|
|
102
|
+
// Delay clearing `isAnimating`
|
|
103
|
+
// This will give time for `popToAction` to get handled before pause
|
|
104
|
+
const timer = setTimeout(() => {
|
|
105
|
+
setPendingNavigation((pending) => {
|
|
106
|
+
if (pending?.to === focusedRouteKey) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return pending;
|
|
111
|
+
});
|
|
112
|
+
}, 32);
|
|
113
|
+
|
|
114
|
+
return () => clearTimeout(timer);
|
|
83
115
|
}, [descriptors, focusedRouteKey, navigation, state.index, state.routes]);
|
|
84
116
|
|
|
85
117
|
const currentOptions = descriptors[state.routes[state.index].key]?.options;
|
|
@@ -95,18 +127,67 @@ export function BottomTabViewNative({
|
|
|
95
127
|
}),
|
|
96
128
|
fontSize,
|
|
97
129
|
fontStyle,
|
|
130
|
+
color: fontColor,
|
|
98
131
|
} = currentOptions.tabBarLabelStyle || {};
|
|
99
132
|
|
|
100
|
-
const
|
|
101
|
-
currentOptions.
|
|
133
|
+
const backgroundColor =
|
|
134
|
+
currentOptions.tabBarStyle?.backgroundColor ?? colors.background;
|
|
135
|
+
|
|
136
|
+
const shouldHideTabBar = currentOptions.tabBarStyle?.display === 'none';
|
|
137
|
+
|
|
138
|
+
let activeIndicatorColor = currentOptions?.tabBarActiveIndicatorColor;
|
|
139
|
+
let activeTintColor = currentOptions.tabBarActiveTintColor;
|
|
140
|
+
let inactiveTintColor = currentOptions.tabBarInactiveTintColor;
|
|
141
|
+
|
|
142
|
+
// Derive colors based on Material Design guidelines
|
|
143
|
+
// https://m3.material.io/components/navigation-bar/specs
|
|
144
|
+
if (Platform.OS === 'android') {
|
|
145
|
+
switch (getAndroidColorName(backgroundColor)) {
|
|
146
|
+
case 'system_surface_container_light':
|
|
147
|
+
case 'system_surface_container_high_light':
|
|
148
|
+
case 'system_surface_container_highest_light':
|
|
149
|
+
case 'system_surface_container_low_light':
|
|
150
|
+
case 'system_surface_container_lowest_light':
|
|
151
|
+
inactiveTintColor =
|
|
152
|
+
inactiveTintColor ??
|
|
153
|
+
PlatformColor('@android:color/system_on_surface_variant_light');
|
|
154
|
+
activeTintColor =
|
|
155
|
+
activeTintColor ??
|
|
156
|
+
PlatformColor('@android:color/system_on_secondary_container_light');
|
|
157
|
+
activeIndicatorColor =
|
|
158
|
+
activeIndicatorColor ??
|
|
159
|
+
PlatformColor('@android:color/system_secondary_container_light');
|
|
160
|
+
break;
|
|
161
|
+
case 'system_surface_container_dark':
|
|
162
|
+
case 'system_surface_container_high_dark':
|
|
163
|
+
case 'system_surface_container_highest_dark':
|
|
164
|
+
case 'system_surface_container_low_dark':
|
|
165
|
+
case 'system_surface_container_lowest_dark':
|
|
166
|
+
inactiveTintColor =
|
|
167
|
+
inactiveTintColor ??
|
|
168
|
+
PlatformColor('@android:color/system_on_surface_variant_dark');
|
|
169
|
+
activeTintColor =
|
|
170
|
+
activeTintColor ??
|
|
171
|
+
PlatformColor('@android:color/system_on_secondary_container_dark');
|
|
172
|
+
activeIndicatorColor =
|
|
173
|
+
activeIndicatorColor ??
|
|
174
|
+
PlatformColor('@android:color/system_secondary_container_dark');
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
102
178
|
|
|
103
|
-
|
|
104
|
-
|
|
179
|
+
inactiveTintColor =
|
|
180
|
+
inactiveTintColor ??
|
|
105
181
|
Platform.select({ ios: PlatformColor('label'), default: colors.text });
|
|
106
182
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
183
|
+
activeTintColor = activeTintColor ?? colors.primary;
|
|
184
|
+
|
|
185
|
+
activeIndicatorColor =
|
|
186
|
+
activeIndicatorColor ??
|
|
187
|
+
Platform.select({
|
|
188
|
+
android: Color(activeTintColor)?.alpha(0.075).string(),
|
|
189
|
+
default: undefined,
|
|
190
|
+
});
|
|
110
191
|
|
|
111
192
|
const onTransitionStart = ({ route }: { route: Route<string> }) => {
|
|
112
193
|
navigation.emit({
|
|
@@ -160,7 +241,7 @@ export function BottomTabViewNative({
|
|
|
160
241
|
? tabBarElement
|
|
161
242
|
: null}
|
|
162
243
|
<Tabs.Host
|
|
163
|
-
tabBarHidden={hasCustomTabBar}
|
|
244
|
+
tabBarHidden={hasCustomTabBar || shouldHideTabBar}
|
|
164
245
|
bottomAccessory={
|
|
165
246
|
bottomAccessory
|
|
166
247
|
? (environment) => bottomAccessory({ placement: environment })
|
|
@@ -174,16 +255,14 @@ export function BottomTabViewNative({
|
|
|
174
255
|
tabBarTintColor={activeTintColor}
|
|
175
256
|
tabBarItemIconColor={inactiveTintColor}
|
|
176
257
|
tabBarItemIconColorActive={activeTintColor}
|
|
177
|
-
tabBarItemTitleFontColor={inactiveTintColor}
|
|
258
|
+
tabBarItemTitleFontColor={inactiveTintColor ?? fontColor}
|
|
178
259
|
tabBarItemTitleFontColorActive={activeTintColor}
|
|
179
260
|
tabBarItemTitleFontFamily={fontFamily}
|
|
180
261
|
tabBarItemTitleFontWeight={fontWeight}
|
|
181
262
|
tabBarItemTitleFontSize={fontSize}
|
|
182
263
|
tabBarItemTitleFontSizeActive={fontSize}
|
|
183
264
|
tabBarItemTitleFontStyle={fontStyle}
|
|
184
|
-
tabBarBackgroundColor={
|
|
185
|
-
currentOptions.tabBarStyle?.backgroundColor ?? colors.card
|
|
186
|
-
}
|
|
265
|
+
tabBarBackgroundColor={backgroundColor}
|
|
187
266
|
tabBarItemActiveIndicatorColor={activeIndicatorColor}
|
|
188
267
|
tabBarItemActiveIndicatorEnabled={
|
|
189
268
|
currentOptions?.tabBarActiveIndicatorEnabled
|
|
@@ -213,6 +292,11 @@ export function BottomTabViewNative({
|
|
|
213
292
|
state.routes.findIndex((r) => r.key === route.key);
|
|
214
293
|
|
|
215
294
|
if (!isFocused) {
|
|
295
|
+
setPendingNavigation({
|
|
296
|
+
from: previousRouteKeyRef.current,
|
|
297
|
+
to: route.key,
|
|
298
|
+
});
|
|
299
|
+
|
|
216
300
|
navigation.dispatch({
|
|
217
301
|
...CommonActions.navigate(route.name, route.params),
|
|
218
302
|
target: state.key,
|
|
@@ -229,6 +313,7 @@ export function BottomTabViewNative({
|
|
|
229
313
|
const {
|
|
230
314
|
title,
|
|
231
315
|
lazy = true,
|
|
316
|
+
inactiveBehavior = 'pause',
|
|
232
317
|
tabBarLabel,
|
|
233
318
|
tabBarBadgeStyle,
|
|
234
319
|
tabBarIcon,
|
|
@@ -236,8 +321,11 @@ export function BottomTabViewNative({
|
|
|
236
321
|
tabBarSystemItem,
|
|
237
322
|
tabBarBlurEffect = dark ? 'systemMaterialDark' : 'systemMaterial',
|
|
238
323
|
tabBarStyle,
|
|
324
|
+
tabBarAccessibilityLabel,
|
|
325
|
+
tabBarButtonTestID,
|
|
239
326
|
sceneStyle,
|
|
240
327
|
scrollEdgeEffects,
|
|
328
|
+
overrideScrollViewContentInsetAdjustmentBehavior,
|
|
241
329
|
} = options;
|
|
242
330
|
|
|
243
331
|
const {
|
|
@@ -252,19 +340,21 @@ export function BottomTabViewNative({
|
|
|
252
340
|
? tabBarLabel
|
|
253
341
|
: getLabel({ label: tabBarLabel, title }, route.name);
|
|
254
342
|
|
|
343
|
+
const badgeBackgroundColor =
|
|
344
|
+
tabBarBadgeStyle?.backgroundColor ?? colors.notification;
|
|
345
|
+
const badgeTextColor =
|
|
346
|
+
tabBarBadgeStyle?.color ?? Color.foreground(badgeBackgroundColor);
|
|
347
|
+
|
|
255
348
|
const tabItemAppearance: TabsScreenItemStateAppearance = {
|
|
256
349
|
tabBarItemTitleFontFamily: fontFamily,
|
|
257
350
|
tabBarItemTitleFontSize: fontSize,
|
|
258
351
|
tabBarItemTitleFontWeight: fontWeight,
|
|
259
352
|
tabBarItemTitleFontStyle: fontStyle,
|
|
353
|
+
tabBarItemTitleFontColor: inactiveTintColor ?? fontColor,
|
|
354
|
+
tabBarItemIconColor: inactiveTintColor,
|
|
355
|
+
tabBarItemBadgeBackgroundColor: badgeBackgroundColor,
|
|
260
356
|
};
|
|
261
357
|
|
|
262
|
-
const badgeBackgroundColor =
|
|
263
|
-
tabBarBadgeStyle?.backgroundColor ?? colors.notification;
|
|
264
|
-
const badgeTextColor =
|
|
265
|
-
tabBarBadgeStyle?.color ??
|
|
266
|
-
(Color(badgeBackgroundColor)?.isLight() ? 'black' : 'white');
|
|
267
|
-
|
|
268
358
|
const getIcon = (selected: boolean) => {
|
|
269
359
|
if (typeof tabBarIcon === 'function') {
|
|
270
360
|
const result = tabBarIcon({
|
|
@@ -298,6 +388,15 @@ export function BottomTabViewNative({
|
|
|
298
388
|
const icon = getIcon(false);
|
|
299
389
|
const selectedIcon = getIcon(true);
|
|
300
390
|
|
|
391
|
+
// For preloaded screens and if lazy is false,
|
|
392
|
+
// Keep them active so that the effects can run
|
|
393
|
+
const isActive =
|
|
394
|
+
inactiveBehavior === 'none' ||
|
|
395
|
+
isPreloaded ||
|
|
396
|
+
pendingNavigation?.from === route.key ||
|
|
397
|
+
pendingNavigation?.to === route.key ||
|
|
398
|
+
(lazy === false && !loaded.includes(route.key));
|
|
399
|
+
|
|
301
400
|
return (
|
|
302
401
|
<Tabs.Screen
|
|
303
402
|
onWillAppear={() => onTransitionStart({ route })}
|
|
@@ -308,6 +407,8 @@ export function BottomTabViewNative({
|
|
|
308
407
|
selectedIcon={selectedIcon?.ios ?? selectedIcon?.shared}
|
|
309
408
|
tabBarItemBadgeBackgroundColor={badgeBackgroundColor}
|
|
310
409
|
tabBarItemBadgeTextColor={badgeTextColor}
|
|
410
|
+
tabBarItemAccessibilityLabel={tabBarAccessibilityLabel}
|
|
411
|
+
tabBarItemTestID={tabBarButtonTestID}
|
|
311
412
|
badgeValue={tabBarBadge?.toString()}
|
|
312
413
|
systemItem={tabBarSystemItem}
|
|
313
414
|
isFocused={isFocused}
|
|
@@ -330,9 +431,20 @@ export function BottomTabViewNative({
|
|
|
330
431
|
? 'automatic'
|
|
331
432
|
: scrollEdgeEffects?.right,
|
|
332
433
|
}}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
434
|
+
scrollEdgeAppearance={{
|
|
435
|
+
tabBarBackgroundColor,
|
|
436
|
+
tabBarShadowColor,
|
|
437
|
+
tabBarBlurEffect,
|
|
438
|
+
stacked: {
|
|
439
|
+
normal: tabItemAppearance,
|
|
440
|
+
},
|
|
441
|
+
inline: {
|
|
442
|
+
normal: tabItemAppearance,
|
|
443
|
+
},
|
|
444
|
+
compactInline: {
|
|
445
|
+
normal: tabItemAppearance,
|
|
446
|
+
},
|
|
447
|
+
}}
|
|
336
448
|
standardAppearance={{
|
|
337
449
|
tabBarBackgroundColor,
|
|
338
450
|
tabBarShadowColor,
|
|
@@ -353,25 +465,43 @@ export function BottomTabViewNative({
|
|
|
353
465
|
scrollToTop: true,
|
|
354
466
|
},
|
|
355
467
|
}}
|
|
468
|
+
overrideScrollViewContentInsetAdjustmentBehavior={
|
|
469
|
+
overrideScrollViewContentInsetAdjustmentBehavior
|
|
470
|
+
}
|
|
356
471
|
experimental_userInterfaceStyle={dark ? 'dark' : 'light'}
|
|
357
472
|
>
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
473
|
+
{lazy &&
|
|
474
|
+
!loaded.includes(route.key) &&
|
|
475
|
+
!isFocused &&
|
|
476
|
+
!isPreloaded ? null : (
|
|
477
|
+
<ActivityView
|
|
478
|
+
key={route.key}
|
|
479
|
+
mode={isFocused ? 'normal' : isActive ? 'inert' : 'paused'}
|
|
480
|
+
visible={
|
|
481
|
+
// We don't need to hide the content since it's handled natively
|
|
482
|
+
// Hiding may also cause flash due to lag after native tab switch
|
|
483
|
+
// So we leave it always visible
|
|
484
|
+
true
|
|
485
|
+
}
|
|
486
|
+
style={StyleSheet.absoluteFill}
|
|
365
487
|
>
|
|
366
|
-
<
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
488
|
+
<ScreenContent
|
|
489
|
+
isFocused={isFocused}
|
|
490
|
+
route={route}
|
|
491
|
+
navigation={navigation}
|
|
492
|
+
options={options}
|
|
493
|
+
style={sceneStyle}
|
|
494
|
+
>
|
|
495
|
+
<AnimatedScreenContent isFocused={isFocused}>
|
|
496
|
+
<BottomTabBarHeightContext.Provider value={0}>
|
|
497
|
+
<NavigationMetaContext.Provider value={meta}>
|
|
498
|
+
{render()}
|
|
499
|
+
</NavigationMetaContext.Provider>
|
|
500
|
+
</BottomTabBarHeightContext.Provider>
|
|
501
|
+
</AnimatedScreenContent>
|
|
502
|
+
</ScreenContent>
|
|
503
|
+
</ActivityView>
|
|
504
|
+
)}
|
|
375
505
|
</Tabs.Screen>
|
|
376
506
|
);
|
|
377
507
|
})}
|
|
@@ -382,6 +512,7 @@ export function BottomTabViewNative({
|
|
|
382
512
|
</SafeAreaProviderCompat>
|
|
383
513
|
);
|
|
384
514
|
}
|
|
515
|
+
|
|
385
516
|
function AnimatedScreenContent({
|
|
386
517
|
isFocused,
|
|
387
518
|
children,
|
|
@@ -415,7 +546,7 @@ function AnimatedScreenContent({
|
|
|
415
546
|
);
|
|
416
547
|
}
|
|
417
548
|
|
|
418
|
-
function getPlatformIcon(icon:
|
|
549
|
+
function getPlatformIcon(icon: Icon): PlatformIcon {
|
|
419
550
|
switch (icon.type) {
|
|
420
551
|
case 'sfSymbol':
|
|
421
552
|
return {
|
|
@@ -430,6 +561,9 @@ function getPlatformIcon(icon: BottomTabIcon): PlatformIcon {
|
|
|
430
561
|
type: 'imageSource',
|
|
431
562
|
imageSource: MaterialSymbol.getImageSource({
|
|
432
563
|
name: icon.name,
|
|
564
|
+
variant: icon.variant,
|
|
565
|
+
weight: icon.weight,
|
|
566
|
+
size: ICON_SIZE,
|
|
433
567
|
}),
|
|
434
568
|
},
|
|
435
569
|
shared: undefined,
|
|
@@ -452,12 +586,6 @@ function getPlatformIcon(icon: BottomTabIcon): PlatformIcon {
|
|
|
452
586
|
imageSource: icon.source,
|
|
453
587
|
},
|
|
454
588
|
};
|
|
455
|
-
case 'drawableResource':
|
|
456
|
-
return {
|
|
457
|
-
ios: undefined,
|
|
458
|
-
android: icon,
|
|
459
|
-
shared: undefined,
|
|
460
|
-
};
|
|
461
589
|
default: {
|
|
462
590
|
const _exhaustiveCheck: never = icon;
|
|
463
591
|
|
|
@@ -465,3 +593,19 @@ function getPlatformIcon(icon: BottomTabIcon): PlatformIcon {
|
|
|
465
593
|
}
|
|
466
594
|
}
|
|
467
595
|
}
|
|
596
|
+
|
|
597
|
+
function getAndroidColorName(color: ColorValue) {
|
|
598
|
+
const value = color as unknown;
|
|
599
|
+
|
|
600
|
+
if (
|
|
601
|
+
typeof value === 'object' &&
|
|
602
|
+
value != null &&
|
|
603
|
+
'resource_paths' in value &&
|
|
604
|
+
Array.isArray(value.resource_paths) &&
|
|
605
|
+
typeof value.resource_paths[0] === 'string'
|
|
606
|
+
) {
|
|
607
|
+
return value.resource_paths[0].replace('@android:color/', '');
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
return null;
|
|
611
|
+
}
|
|
@@ -2,7 +2,6 @@ import { getHeaderTitle, Header } from '@react-navigation/elements';
|
|
|
2
2
|
import { Screen } from '@react-navigation/elements/internal';
|
|
3
3
|
import type { ParamListBase, Route } from '@react-navigation/native';
|
|
4
4
|
import * as React from 'react';
|
|
5
|
-
import { type StyleProp, type ViewStyle } from 'react-native';
|
|
6
5
|
|
|
7
6
|
import type {
|
|
8
7
|
BottomTabNavigationOptions,
|
|
@@ -21,7 +20,7 @@ export function ScreenContent({
|
|
|
21
20
|
route: Route<string>;
|
|
22
21
|
navigation: BottomTabNavigationProp<ParamListBase>;
|
|
23
22
|
options: BottomTabNavigationOptions;
|
|
24
|
-
style?:
|
|
23
|
+
style?: React.ComponentProps<typeof Screen>['style'];
|
|
25
24
|
children: React.ReactNode;
|
|
26
25
|
}) {
|
|
27
26
|
const {
|
package/src/views/TabBarIcon.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Badge } from '@react-navigation/elements';
|
|
1
|
+
import { Badge, type Icon } from '@react-navigation/elements';
|
|
2
2
|
import { MissingIcon } from '@react-navigation/elements/internal';
|
|
3
3
|
import { MaterialSymbol, type Route, SFSymbol } from '@react-navigation/native';
|
|
4
4
|
import React from 'react';
|
|
@@ -12,26 +12,24 @@ import {
|
|
|
12
12
|
type ViewStyle,
|
|
13
13
|
} from 'react-native';
|
|
14
14
|
|
|
15
|
-
import type { BottomTabIcon } from '../types';
|
|
16
|
-
|
|
17
15
|
export type TabBarIconProps = {
|
|
18
16
|
route: Route<string>;
|
|
19
17
|
variant: 'uikit' | 'material';
|
|
20
18
|
size: 'compact' | 'regular';
|
|
21
|
-
badge?: string | number;
|
|
22
|
-
badgeStyle?: StyleProp<TextStyle
|
|
19
|
+
badge?: string | number | undefined;
|
|
20
|
+
badgeStyle?: StyleProp<TextStyle> | undefined;
|
|
23
21
|
activeOpacity: number;
|
|
24
22
|
inactiveOpacity: number;
|
|
25
23
|
activeTintColor: ColorValue;
|
|
26
24
|
inactiveTintColor: ColorValue;
|
|
27
25
|
icon:
|
|
28
|
-
|
|
|
26
|
+
| Icon
|
|
29
27
|
| ((props: {
|
|
30
28
|
focused: boolean;
|
|
31
29
|
color: ColorValue;
|
|
32
30
|
size: number;
|
|
33
|
-
}) =>
|
|
34
|
-
allowFontScaling?: boolean;
|
|
31
|
+
}) => Icon | React.ReactNode);
|
|
32
|
+
allowFontScaling?: boolean | undefined;
|
|
35
33
|
style: StyleProp<ViewStyle>;
|
|
36
34
|
};
|
|
37
35
|
|
|
@@ -43,8 +41,8 @@ const ICON_SIZE_WIDE = 31;
|
|
|
43
41
|
const ICON_SIZE_WIDE_COMPACT = 23;
|
|
44
42
|
const ICON_SIZE_TALL = 28;
|
|
45
43
|
const ICON_SIZE_TALL_COMPACT = 20;
|
|
46
|
-
const
|
|
47
|
-
const
|
|
44
|
+
const ICON_SIZE_SQUARE = 23;
|
|
45
|
+
const ICON_SIZE_SQUARE_COMPACT = 17;
|
|
48
46
|
const ICON_SIZE_MATERIAL = 24;
|
|
49
47
|
|
|
50
48
|
export function TabBarIcon({
|
|
@@ -65,8 +63,8 @@ export function TabBarIcon({
|
|
|
65
63
|
variant === 'material'
|
|
66
64
|
? ICON_SIZE_MATERIAL
|
|
67
65
|
: size === 'compact'
|
|
68
|
-
?
|
|
69
|
-
:
|
|
66
|
+
? ICON_SIZE_SQUARE_COMPACT
|
|
67
|
+
: ICON_SIZE_SQUARE;
|
|
70
68
|
|
|
71
69
|
// We render the icon twice at the same position on top of each other:
|
|
72
70
|
// active and inactive one, so we can fade between them.
|
|
@@ -153,22 +151,17 @@ function renderIcon({
|
|
|
153
151
|
}}
|
|
154
152
|
/>
|
|
155
153
|
);
|
|
156
|
-
case 'drawableResource':
|
|
157
|
-
return (
|
|
158
|
-
<Image
|
|
159
|
-
source={{ uri: iconValue.name }}
|
|
160
|
-
style={{
|
|
161
|
-
width: size,
|
|
162
|
-
height: size,
|
|
163
|
-
tintColor: iconValue.tinted === false ? undefined : color,
|
|
164
|
-
}}
|
|
165
|
-
/>
|
|
166
|
-
);
|
|
167
154
|
case 'sfSymbol':
|
|
168
155
|
return <SFSymbol name={iconValue.name} size={size} color={color} />;
|
|
169
156
|
case 'materialSymbol':
|
|
170
157
|
return (
|
|
171
|
-
<MaterialSymbol
|
|
158
|
+
<MaterialSymbol
|
|
159
|
+
name={iconValue.name}
|
|
160
|
+
variant={iconValue.variant}
|
|
161
|
+
weight={iconValue.weight}
|
|
162
|
+
size={size}
|
|
163
|
+
color={color}
|
|
164
|
+
/>
|
|
172
165
|
);
|
|
173
166
|
default: {
|
|
174
167
|
const _exhaustiveCheck: never = iconValue;
|