@react-navigation/bottom-tabs 7.19.2 → 7.21.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/module/unstable/Deferred.js +3 -10
- package/lib/module/unstable/Deferred.js.map +1 -1
- package/lib/module/unstable/NativeBottomTabView.native.js +309 -198
- package/lib/module/unstable/NativeBottomTabView.native.js.map +1 -1
- package/lib/module/views/BottomTabBar.js +111 -58
- package/lib/module/views/BottomTabBar.js.map +1 -1
- package/lib/module/views/BottomTabItem.js +2 -0
- package/lib/module/views/BottomTabItem.js.map +1 -1
- package/lib/module/views/BottomTabView.js +81 -60
- package/lib/module/views/BottomTabView.js.map +1 -1
- package/lib/module/views/TabBarIcon.js +6 -2
- package/lib/module/views/TabBarIcon.js.map +1 -1
- package/lib/typescript/src/types.d.ts +26 -1
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/unstable/Deferred.d.ts.map +1 -1
- package/lib/typescript/src/unstable/NativeBottomTabView.native.d.ts.map +1 -1
- package/lib/typescript/src/unstable/types.d.ts +148 -5
- package/lib/typescript/src/unstable/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 +5 -1
- package/lib/typescript/src/views/BottomTabItem.d.ts.map +1 -1
- package/lib/typescript/src/views/BottomTabView.d.ts.map +1 -1
- package/lib/typescript/src/views/TabBarIcon.d.ts +2 -1
- package/lib/typescript/src/views/TabBarIcon.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/types.tsx +36 -2
- package/src/unstable/Deferred.tsx +3 -11
- package/src/unstable/NativeBottomTabView.native.tsx +376 -217
- package/src/unstable/types.tsx +164 -6
- package/src/views/BottomTabBar.tsx +153 -72
- package/src/views/BottomTabItem.tsx +6 -0
- package/src/views/BottomTabView.tsx +101 -69
- package/src/views/TabBarIcon.tsx +9 -2
|
@@ -19,21 +19,14 @@ export function Deferred({
|
|
|
19
19
|
visible,
|
|
20
20
|
children
|
|
21
21
|
}) {
|
|
22
|
-
const [rendered, setRendered] = React.useState(
|
|
22
|
+
const [rendered, setRendered] = React.useState(visible);
|
|
23
23
|
const shouldRenderDeferred = !(lazy || visible || rendered);
|
|
24
|
-
React.
|
|
25
|
-
if (shouldRenderDeferred === false) {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
React.startTransition(() => {
|
|
29
|
-
setRendered(true);
|
|
30
|
-
});
|
|
31
|
-
}, [shouldRenderDeferred]);
|
|
24
|
+
const canRenderDeferred = React.useDeferredValue(shouldRenderDeferred, false);
|
|
32
25
|
if (visible && rendered === false) {
|
|
33
26
|
setRendered(true);
|
|
34
27
|
return children;
|
|
35
28
|
}
|
|
36
|
-
if (rendered) {
|
|
29
|
+
if (rendered || canRenderDeferred) {
|
|
37
30
|
return children;
|
|
38
31
|
}
|
|
39
32
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","Deferred","lazy","visible","children","rendered","setRendered","useState","shouldRenderDeferred","
|
|
1
|
+
{"version":3,"names":["React","Deferred","lazy","visible","children","rendered","setRendered","useState","shouldRenderDeferred","canRenderDeferred","useDeferredValue"],"sourceRoot":"../../../src","sources":["unstable/Deferred.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAiB9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,QAAQA,CAAC;EAAEC,IAAI;EAAEC,OAAO;EAAEC;AAAgB,CAAC,EAAE;EAC3D,MAAM,CAACC,QAAQ,EAAEC,WAAW,CAAC,GAAGN,KAAK,CAACO,QAAQ,CAACJ,OAAO,CAAC;EAEvD,MAAMK,oBAAoB,GAAG,EAAEN,IAAI,IAAIC,OAAO,IAAIE,QAAQ,CAAC;EAE3D,MAAMI,iBAAiB,GAAGT,KAAK,CAACU,gBAAgB,CAACF,oBAAoB,EAAE,KAAK,CAAC;EAE7E,IAAIL,OAAO,IAAIE,QAAQ,KAAK,KAAK,EAAE;IACjCC,WAAW,CAAC,IAAI,CAAC;IAEjB,OAAOF,QAAQ;EACjB;EAEA,IAAIC,QAAQ,IAAII,iBAAiB,EAAE;IACjC,OAAOL,QAAQ;EACjB;EAEA,OAAO,IAAI;AACb","ignoreList":[]}
|
|
@@ -12,6 +12,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
12
12
|
const meta = {
|
|
13
13
|
type: 'native-tabs'
|
|
14
14
|
};
|
|
15
|
+
const SUPPORTS_PROMINENT_TAB = Platform.OS === 'ios' && parseInt(Platform.Version, 10) >= 27;
|
|
15
16
|
function reducer(state, action) {
|
|
16
17
|
switch (action.type) {
|
|
17
18
|
case 'CONFIRM_STATE':
|
|
@@ -71,7 +72,8 @@ export function NativeBottomTabView({
|
|
|
71
72
|
const {
|
|
72
73
|
selectedScreenKey,
|
|
73
74
|
provenance,
|
|
74
|
-
actionOrigin
|
|
75
|
+
actionOrigin,
|
|
76
|
+
isRepeated
|
|
75
77
|
} = event.nativeEvent;
|
|
76
78
|
const confirmed = {
|
|
77
79
|
routeKey: selectedScreenKey,
|
|
@@ -83,9 +85,19 @@ export function NativeBottomTabView({
|
|
|
83
85
|
return;
|
|
84
86
|
}
|
|
85
87
|
if (actionOrigin === 'user') {
|
|
88
|
+
const {
|
|
89
|
+
tabBarRepeatedPressBehavior
|
|
90
|
+
} = descriptors[route.key].options;
|
|
86
91
|
navigation.emit({
|
|
87
92
|
type: 'tabPress',
|
|
88
|
-
target: route.key
|
|
93
|
+
target: route.key,
|
|
94
|
+
data: {
|
|
95
|
+
origin: 'native',
|
|
96
|
+
behavior: {
|
|
97
|
+
scrollToTop: isRepeated && tabBarRepeatedPressBehavior?.scrollToTop !== false,
|
|
98
|
+
popToTop: isRepeated && tabBarRepeatedPressBehavior?.popToTop !== false
|
|
99
|
+
}
|
|
100
|
+
}
|
|
89
101
|
});
|
|
90
102
|
}
|
|
91
103
|
if (actionOrigin === 'programmatic-js' || focusedRouteKey === route.key) {
|
|
@@ -138,7 +150,14 @@ export function NativeBottomTabView({
|
|
|
138
150
|
});
|
|
139
151
|
navigation.emit({
|
|
140
152
|
type: 'tabPress',
|
|
141
|
-
target: preventedScreenKey
|
|
153
|
+
target: preventedScreenKey,
|
|
154
|
+
data: {
|
|
155
|
+
origin: 'native',
|
|
156
|
+
behavior: {
|
|
157
|
+
scrollToTop: false,
|
|
158
|
+
popToTop: false
|
|
159
|
+
}
|
|
160
|
+
}
|
|
142
161
|
});
|
|
143
162
|
};
|
|
144
163
|
const currentOptions = descriptors[state.routes[state.index].key]?.options;
|
|
@@ -155,38 +174,27 @@ export function NativeBottomTabView({
|
|
|
155
174
|
fontStyle,
|
|
156
175
|
color: fontColor
|
|
157
176
|
} = currentOptions.tabBarLabelStyle || {};
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}) => {
|
|
168
|
-
navigation.emit({
|
|
169
|
-
type: 'transitionStart',
|
|
170
|
-
data: {
|
|
171
|
-
closing
|
|
172
|
-
},
|
|
173
|
-
target: route.key
|
|
174
|
-
});
|
|
175
|
-
};
|
|
176
|
-
const onTransitionEnd = ({
|
|
177
|
-
closing,
|
|
178
|
-
route
|
|
179
|
-
}) => {
|
|
180
|
-
navigation.emit({
|
|
181
|
-
type: 'transitionEnd',
|
|
182
|
-
data: {
|
|
183
|
-
closing
|
|
184
|
-
},
|
|
185
|
-
target: route.key
|
|
177
|
+
const {
|
|
178
|
+
activeIndicatorColor,
|
|
179
|
+
activeTintColor,
|
|
180
|
+
inactiveTintColor
|
|
181
|
+
} = React.useMemo(() => {
|
|
182
|
+
const activeTintColor = currentOptions.tabBarActiveTintColor ?? colors.primary;
|
|
183
|
+
const inactiveTintColor = currentOptions.tabBarInactiveTintColor ?? Platform.select({
|
|
184
|
+
ios: PlatformColor('label'),
|
|
185
|
+
default: colors.text
|
|
186
186
|
});
|
|
187
|
-
|
|
187
|
+
const activeIndicatorColor = currentOptions?.tabBarActiveIndicatorColor ?? (typeof activeTintColor === 'string' ? Color(activeTintColor)?.alpha(0.1).string() : undefined);
|
|
188
|
+
return {
|
|
189
|
+
activeIndicatorColor,
|
|
190
|
+
activeTintColor,
|
|
191
|
+
inactiveTintColor
|
|
192
|
+
};
|
|
193
|
+
}, [currentOptions?.tabBarActiveIndicatorColor, currentOptions.tabBarActiveTintColor, currentOptions.tabBarInactiveTintColor, colors.primary, colors.text]);
|
|
188
194
|
const tabBarControllerMode = currentOptions.tabBarControllerMode === 'auto' ? 'automatic' : currentOptions.tabBarControllerMode;
|
|
189
195
|
const tabBarMinimizeBehavior = currentOptions.tabBarMinimizeBehavior === 'auto' ? 'automatic' : currentOptions.tabBarMinimizeBehavior === 'none' ? 'never' : currentOptions.tabBarMinimizeBehavior;
|
|
196
|
+
const tabBarSidebarPreferredPlacement = currentOptions.tabBarSidebarPreferredPlacement === 'auto' ? 'automatic' : currentOptions.tabBarSidebarPreferredPlacement;
|
|
197
|
+
const prominentScreenKey = SUPPORTS_PROMINENT_TAB ? state.routes.find(route => descriptors[route.key]?.options.tabBarRole === 'prominent')?.key : undefined;
|
|
190
198
|
const shouldHideTabBar = currentOptions.tabBarStyle?.display === 'none';
|
|
191
199
|
const bottomAccessory = currentOptions.bottomAccessory;
|
|
192
200
|
return /*#__PURE__*/_jsx(SafeAreaProviderCompat, {
|
|
@@ -205,173 +213,265 @@ export function NativeBottomTabView({
|
|
|
205
213
|
backgroundColor: colors.background
|
|
206
214
|
},
|
|
207
215
|
ios: {
|
|
216
|
+
prominentScreenKey,
|
|
208
217
|
bottomAccessory: bottomAccessory ? environment => bottomAccessory({
|
|
209
218
|
placement: environment
|
|
210
219
|
}) : undefined,
|
|
220
|
+
tabBarHiddenAnimationEnabled: currentOptions.tabBarVisibilityAnimationEnabled,
|
|
211
221
|
tabBarControllerMode,
|
|
222
|
+
tabBarSidebarPreferredPlacement,
|
|
212
223
|
tabBarMinimizeBehavior,
|
|
213
224
|
tabBarTintColor: activeTintColor
|
|
214
225
|
},
|
|
215
226
|
children: state.routes.map((route, index) => {
|
|
216
|
-
const
|
|
217
|
-
options,
|
|
218
|
-
render,
|
|
219
|
-
navigation
|
|
220
|
-
} = descriptors[route.key];
|
|
227
|
+
const descriptor = descriptors[route.key];
|
|
221
228
|
const isFocused = state.index === index;
|
|
222
229
|
const isPreloaded = state.preloadedRouteKeys.includes(route.key);
|
|
223
230
|
const {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
label: tabBarLabel,
|
|
245
|
-
title
|
|
246
|
-
}, route.name);
|
|
247
|
-
const badgeBackgroundColor = tabBarBadgeStyle?.backgroundColor ?? colors.notification;
|
|
248
|
-
const badgeTextColor = tabBarBadgeStyle?.color ?? (typeof badgeBackgroundColor === 'string' ? Color(badgeBackgroundColor).isLight() ? 'black' : 'white' : undefined);
|
|
249
|
-
const tabItemAppearance = {
|
|
250
|
-
tabBarItemTitleFontFamily: fontFamily,
|
|
251
|
-
tabBarItemTitleFontSize: fontSize,
|
|
252
|
-
tabBarItemTitleFontWeight: fontWeight,
|
|
253
|
-
tabBarItemTitleFontStyle: fontStyle,
|
|
254
|
-
tabBarItemTitleFontColor: inactiveTintColor ?? fontColor,
|
|
255
|
-
tabBarItemIconColor: inactiveTintColor,
|
|
256
|
-
tabBarItemBadgeBackgroundColor: badgeBackgroundColor
|
|
257
|
-
};
|
|
258
|
-
const normalTabItemAppearance = {
|
|
259
|
-
tabBarItemTitleFontColor: inactiveTintColor ?? fontColor,
|
|
260
|
-
tabBarItemIconColor: inactiveTintColor
|
|
261
|
-
};
|
|
262
|
-
const selectedTabItemAppearance = {
|
|
263
|
-
tabBarItemTitleFontColor: activeTintColor,
|
|
264
|
-
tabBarItemIconColor: activeTintColor
|
|
265
|
-
};
|
|
266
|
-
const icon = typeof tabBarIcon === 'function' ? getPlatformIcon(tabBarIcon({
|
|
267
|
-
focused: false
|
|
268
|
-
})) : tabBarIcon != null ? getPlatformIcon(tabBarIcon) : undefined;
|
|
269
|
-
const selectedIcon = typeof tabBarIcon === 'function' ? getPlatformIcon(tabBarIcon({
|
|
270
|
-
focused: true
|
|
271
|
-
})) : undefined;
|
|
272
|
-
return /*#__PURE__*/_jsx(Tabs.Screen, {
|
|
273
|
-
onWillDisappear: () => onTransitionStart({
|
|
274
|
-
closing: true,
|
|
275
|
-
route
|
|
276
|
-
}),
|
|
277
|
-
onWillAppear: () => onTransitionStart({
|
|
278
|
-
closing: false,
|
|
279
|
-
route
|
|
280
|
-
}),
|
|
281
|
-
onDidAppear: () => onTransitionEnd({
|
|
282
|
-
closing: false,
|
|
283
|
-
route
|
|
284
|
-
}),
|
|
285
|
-
onDidDisappear: () => onTransitionEnd({
|
|
286
|
-
closing: true,
|
|
287
|
-
route
|
|
288
|
-
}),
|
|
289
|
-
screenKey: route.key,
|
|
290
|
-
preventNativeSelection: tabBarSelectionEnabled === false,
|
|
291
|
-
badgeValue: tabBarBadge?.toString(),
|
|
292
|
-
title: tabTitle,
|
|
293
|
-
nativeContainerStyle: {
|
|
294
|
-
backgroundColor: colors.background
|
|
295
|
-
},
|
|
296
|
-
specialEffects: {
|
|
297
|
-
repeatedTabSelection: {
|
|
298
|
-
popToRoot: true,
|
|
299
|
-
scrollToTop: true
|
|
300
|
-
}
|
|
301
|
-
},
|
|
302
|
-
android: {
|
|
303
|
-
icon: icon?.android ?? icon?.shared,
|
|
304
|
-
selectedIcon: selectedIcon?.android ?? selectedIcon?.shared,
|
|
305
|
-
standardAppearance: {
|
|
306
|
-
tabBarBackgroundColor: tabBarBackgroundColor ?? colors.card,
|
|
307
|
-
tabBarItemRippleColor: currentOptions?.tabBarRippleColor,
|
|
308
|
-
tabBarItemLabelVisibilityMode: currentOptions?.tabBarLabelVisibilityMode,
|
|
309
|
-
normal: normalTabItemAppearance,
|
|
310
|
-
selected: selectedTabItemAppearance,
|
|
311
|
-
tabBarItemActiveIndicatorColor: activeIndicatorColor,
|
|
312
|
-
tabBarItemActiveIndicatorEnabled: currentOptions?.tabBarActiveIndicatorEnabled,
|
|
313
|
-
tabBarItemTitleFontFamily: fontFamily,
|
|
314
|
-
tabBarItemTitleFontWeight: fontWeight,
|
|
315
|
-
tabBarItemTitleSmallLabelFontSize: fontSize,
|
|
316
|
-
tabBarItemTitleLargeLabelFontSize: fontSize,
|
|
317
|
-
tabBarItemTitleFontStyle: fontStyle,
|
|
318
|
-
tabBarItemBadgeBackgroundColor: badgeBackgroundColor,
|
|
319
|
-
tabBarItemBadgeTextColor: badgeTextColor
|
|
320
|
-
}
|
|
321
|
-
},
|
|
322
|
-
ios: {
|
|
323
|
-
icon: icon?.ios ?? icon?.shared,
|
|
324
|
-
selectedIcon: selectedIcon?.ios ?? selectedIcon?.shared,
|
|
325
|
-
systemItem: tabBarSystemItem,
|
|
326
|
-
scrollEdgeAppearance: {
|
|
327
|
-
tabBarBackgroundColor,
|
|
328
|
-
tabBarShadowColor,
|
|
329
|
-
tabBarBlurEffect,
|
|
330
|
-
stacked: {
|
|
331
|
-
normal: tabItemAppearance
|
|
332
|
-
},
|
|
333
|
-
inline: {
|
|
334
|
-
normal: tabItemAppearance
|
|
335
|
-
},
|
|
336
|
-
compactInline: {
|
|
337
|
-
normal: tabItemAppearance
|
|
338
|
-
}
|
|
339
|
-
},
|
|
340
|
-
standardAppearance: {
|
|
341
|
-
tabBarBackgroundColor,
|
|
342
|
-
tabBarShadowColor,
|
|
343
|
-
tabBarBlurEffect,
|
|
344
|
-
stacked: {
|
|
345
|
-
normal: tabItemAppearance
|
|
346
|
-
},
|
|
347
|
-
inline: {
|
|
348
|
-
normal: tabItemAppearance
|
|
349
|
-
},
|
|
350
|
-
compactInline: {
|
|
351
|
-
normal: tabItemAppearance
|
|
352
|
-
}
|
|
353
|
-
},
|
|
354
|
-
overrideScrollViewContentInsetAdjustmentBehavior
|
|
355
|
-
},
|
|
356
|
-
children: /*#__PURE__*/_jsx(Deferred, {
|
|
357
|
-
lazy: lazy,
|
|
358
|
-
visible: isFocused || isPreloaded,
|
|
359
|
-
children: /*#__PURE__*/_jsx(ScreenWithHeader, {
|
|
360
|
-
isFocused: isFocused,
|
|
361
|
-
route: route,
|
|
362
|
-
navigation: navigation,
|
|
363
|
-
options: options,
|
|
364
|
-
children: /*#__PURE__*/_jsx(NavigationMetaContext.Provider, {
|
|
365
|
-
value: meta,
|
|
366
|
-
children: render()
|
|
367
|
-
})
|
|
368
|
-
})
|
|
369
|
-
})
|
|
231
|
+
lazy = false
|
|
232
|
+
} = descriptor.options;
|
|
233
|
+
return /*#__PURE__*/_jsx(TabScene, {
|
|
234
|
+
route: route,
|
|
235
|
+
descriptor: descriptor,
|
|
236
|
+
navigation: navigation,
|
|
237
|
+
isFocused: isFocused,
|
|
238
|
+
lazy: lazy,
|
|
239
|
+
visible: isFocused || isPreloaded,
|
|
240
|
+
fontFamily: fontFamily,
|
|
241
|
+
fontWeight: fontWeight,
|
|
242
|
+
fontSize: fontSize,
|
|
243
|
+
fontStyle: fontStyle,
|
|
244
|
+
fontColor: fontColor,
|
|
245
|
+
activeTintColor: activeTintColor,
|
|
246
|
+
inactiveTintColor: inactiveTintColor,
|
|
247
|
+
activeIndicatorColor: activeIndicatorColor,
|
|
248
|
+
rippleColor: currentOptions.tabBarRippleColor,
|
|
249
|
+
labelVisibilityMode: currentOptions.tabBarLabelVisibilityMode,
|
|
250
|
+
activeIndicatorEnabled: currentOptions.tabBarActiveIndicatorEnabled
|
|
370
251
|
}, route.key);
|
|
371
252
|
})
|
|
372
253
|
})
|
|
373
254
|
});
|
|
374
255
|
}
|
|
256
|
+
const TabScene = /*#__PURE__*/React.memo(function TabScene({
|
|
257
|
+
route,
|
|
258
|
+
descriptor,
|
|
259
|
+
navigation,
|
|
260
|
+
isFocused,
|
|
261
|
+
lazy,
|
|
262
|
+
visible,
|
|
263
|
+
fontFamily,
|
|
264
|
+
fontWeight,
|
|
265
|
+
fontSize,
|
|
266
|
+
fontStyle,
|
|
267
|
+
fontColor,
|
|
268
|
+
activeTintColor,
|
|
269
|
+
inactiveTintColor,
|
|
270
|
+
activeIndicatorColor,
|
|
271
|
+
rippleColor,
|
|
272
|
+
labelVisibilityMode,
|
|
273
|
+
activeIndicatorEnabled
|
|
274
|
+
}) {
|
|
275
|
+
const {
|
|
276
|
+
dark,
|
|
277
|
+
colors
|
|
278
|
+
} = useTheme();
|
|
279
|
+
const onTransitionStart = ({
|
|
280
|
+
closing,
|
|
281
|
+
route
|
|
282
|
+
}) => {
|
|
283
|
+
navigation.emit({
|
|
284
|
+
type: 'transitionStart',
|
|
285
|
+
data: {
|
|
286
|
+
closing
|
|
287
|
+
},
|
|
288
|
+
target: route.key
|
|
289
|
+
});
|
|
290
|
+
};
|
|
291
|
+
const onTransitionEnd = ({
|
|
292
|
+
closing,
|
|
293
|
+
route
|
|
294
|
+
}) => {
|
|
295
|
+
navigation.emit({
|
|
296
|
+
type: 'transitionEnd',
|
|
297
|
+
data: {
|
|
298
|
+
closing
|
|
299
|
+
},
|
|
300
|
+
target: route.key
|
|
301
|
+
});
|
|
302
|
+
};
|
|
303
|
+
const {
|
|
304
|
+
options,
|
|
305
|
+
render
|
|
306
|
+
} = descriptor;
|
|
307
|
+
const {
|
|
308
|
+
title,
|
|
309
|
+
tabBarLabel,
|
|
310
|
+
tabBarLabelPositionAdjustment,
|
|
311
|
+
tabBarSelectionEnabled,
|
|
312
|
+
tabBarRepeatedPressBehavior,
|
|
313
|
+
tabBarBadgeStyle,
|
|
314
|
+
tabBarIcon,
|
|
315
|
+
tabBarIconSize,
|
|
316
|
+
tabBarActiveIndicatorWidth,
|
|
317
|
+
tabBarActiveIndicatorHeight,
|
|
318
|
+
tabBarBadge,
|
|
319
|
+
tabBarSystemItem,
|
|
320
|
+
tabBarRole,
|
|
321
|
+
tabBarSearchAutoFocus,
|
|
322
|
+
tabBarBlurEffect = dark ? 'systemMaterialDark' : 'systemMaterial',
|
|
323
|
+
tabBarStyle,
|
|
324
|
+
overrideScrollViewContentInsetAdjustmentBehavior
|
|
325
|
+
} = options;
|
|
326
|
+
const systemItem = tabBarSystemItem ?? (
|
|
327
|
+
// Setting the `role` to 'search' doesn't add title and icon automatically
|
|
328
|
+
// So we also set `tabBarSystemItem` to 'search' to match SwiftUI's behavior
|
|
329
|
+
tabBarRole === 'search' ? 'search' : undefined);
|
|
330
|
+
const {
|
|
331
|
+
backgroundColor: tabBarBackgroundColor,
|
|
332
|
+
shadowColor: tabBarShadowColor
|
|
333
|
+
} = tabBarStyle || {};
|
|
334
|
+
const tabTitle =
|
|
335
|
+
// On iOS, `systemItem` already provides a localized label
|
|
336
|
+
// So we should only use `tabBarLabel` if explicitly provided
|
|
337
|
+
Platform.OS === 'ios' && systemItem != null ? tabBarLabel : getLabel({
|
|
338
|
+
label: tabBarLabel,
|
|
339
|
+
title
|
|
340
|
+
}, route.name);
|
|
341
|
+
const badgeBackgroundColor = tabBarBadgeStyle?.backgroundColor ?? colors.notification;
|
|
342
|
+
const badgeTextColor = tabBarBadgeStyle?.color ?? (typeof badgeBackgroundColor === 'string' ? Color(badgeBackgroundColor).isLight() ? 'black' : 'white' : undefined);
|
|
343
|
+
const tabItemAppearance = {
|
|
344
|
+
tabBarItemTitleFontFamily: fontFamily,
|
|
345
|
+
tabBarItemTitleFontSize: fontSize,
|
|
346
|
+
tabBarItemTitleFontWeight: fontWeight,
|
|
347
|
+
tabBarItemTitleFontStyle: fontStyle,
|
|
348
|
+
tabBarItemTitleFontColor: inactiveTintColor ?? fontColor,
|
|
349
|
+
tabBarItemIconColor: inactiveTintColor,
|
|
350
|
+
tabBarItemBadgeBackgroundColor: badgeBackgroundColor
|
|
351
|
+
};
|
|
352
|
+
const tabItemLayoutAppearance = {
|
|
353
|
+
stacked: {
|
|
354
|
+
normal: {
|
|
355
|
+
...tabItemAppearance,
|
|
356
|
+
tabBarItemTitlePositionAdjustment: tabBarLabelPositionAdjustment?.stacked
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
inline: {
|
|
360
|
+
normal: {
|
|
361
|
+
...tabItemAppearance,
|
|
362
|
+
tabBarItemTitlePositionAdjustment: tabBarLabelPositionAdjustment?.inline
|
|
363
|
+
}
|
|
364
|
+
},
|
|
365
|
+
compactInline: {
|
|
366
|
+
normal: {
|
|
367
|
+
...tabItemAppearance,
|
|
368
|
+
tabBarItemTitlePositionAdjustment: tabBarLabelPositionAdjustment?.compactInline
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
const normalTabItemAppearance = {
|
|
373
|
+
tabBarItemTitleFontColor: inactiveTintColor ?? fontColor,
|
|
374
|
+
tabBarItemIconColor: inactiveTintColor
|
|
375
|
+
};
|
|
376
|
+
const selectedTabItemAppearance = {
|
|
377
|
+
tabBarItemTitleFontColor: activeTintColor,
|
|
378
|
+
tabBarItemIconColor: activeTintColor
|
|
379
|
+
};
|
|
380
|
+
const icon = typeof tabBarIcon === 'function' ? getPlatformIcon(tabBarIcon({
|
|
381
|
+
focused: false
|
|
382
|
+
})) : tabBarIcon != null ? getPlatformIcon(tabBarIcon) : undefined;
|
|
383
|
+
const selectedIcon = typeof tabBarIcon === 'function' ? getPlatformIcon(tabBarIcon({
|
|
384
|
+
focused: true
|
|
385
|
+
})) : undefined;
|
|
386
|
+
return /*#__PURE__*/_jsx(Tabs.Screen, {
|
|
387
|
+
onWillDisappear: () => onTransitionStart({
|
|
388
|
+
closing: true,
|
|
389
|
+
route
|
|
390
|
+
}),
|
|
391
|
+
onWillAppear: () => onTransitionStart({
|
|
392
|
+
closing: false,
|
|
393
|
+
route
|
|
394
|
+
}),
|
|
395
|
+
onDidAppear: () => onTransitionEnd({
|
|
396
|
+
closing: false,
|
|
397
|
+
route
|
|
398
|
+
}),
|
|
399
|
+
onDidDisappear: () => onTransitionEnd({
|
|
400
|
+
closing: true,
|
|
401
|
+
route
|
|
402
|
+
}),
|
|
403
|
+
screenKey: route.key,
|
|
404
|
+
preventNativeSelection: tabBarSelectionEnabled === false,
|
|
405
|
+
badgeValue: tabBarBadge?.toString(),
|
|
406
|
+
title: tabTitle,
|
|
407
|
+
style: {
|
|
408
|
+
backgroundColor: colors.background
|
|
409
|
+
},
|
|
410
|
+
specialEffects: {
|
|
411
|
+
repeatedTabSelection: {
|
|
412
|
+
popToRoot: tabBarRepeatedPressBehavior?.popToTop !== false,
|
|
413
|
+
scrollToTop: tabBarRepeatedPressBehavior?.scrollToTop !== false
|
|
414
|
+
}
|
|
415
|
+
},
|
|
416
|
+
android: {
|
|
417
|
+
icon: icon?.android ?? icon?.shared,
|
|
418
|
+
selectedIcon: selectedIcon?.android ?? selectedIcon?.shared,
|
|
419
|
+
standardAppearance: {
|
|
420
|
+
tabBarBackgroundColor: tabBarBackgroundColor ?? colors.card,
|
|
421
|
+
tabBarItemRippleColor: rippleColor,
|
|
422
|
+
tabBarItemLabelVisibilityMode: labelVisibilityMode,
|
|
423
|
+
normal: normalTabItemAppearance,
|
|
424
|
+
selected: selectedTabItemAppearance,
|
|
425
|
+
tabBarItemIconSize: tabBarIconSize,
|
|
426
|
+
tabBarItemActiveIndicatorColor: activeIndicatorColor,
|
|
427
|
+
tabBarItemActiveIndicatorEnabled: activeIndicatorEnabled,
|
|
428
|
+
tabBarItemActiveIndicatorWidth: tabBarActiveIndicatorWidth,
|
|
429
|
+
tabBarItemActiveIndicatorHeight: tabBarActiveIndicatorHeight,
|
|
430
|
+
tabBarItemTitleFontFamily: fontFamily,
|
|
431
|
+
tabBarItemTitleFontWeight: fontWeight,
|
|
432
|
+
tabBarItemTitleSmallLabelFontSize: fontSize,
|
|
433
|
+
tabBarItemTitleLargeLabelFontSize: fontSize,
|
|
434
|
+
tabBarItemTitleFontStyle: fontStyle,
|
|
435
|
+
tabBarItemBadgeBackgroundColor: badgeBackgroundColor,
|
|
436
|
+
tabBarItemBadgeTextColor: badgeTextColor
|
|
437
|
+
}
|
|
438
|
+
},
|
|
439
|
+
ios: {
|
|
440
|
+
icon: icon?.ios ?? icon?.shared,
|
|
441
|
+
selectedIcon: selectedIcon?.ios ?? selectedIcon?.shared,
|
|
442
|
+
systemItem,
|
|
443
|
+
role: tabBarRole === 'search' ? tabBarRole : undefined,
|
|
444
|
+
automaticallyActivatesSearch: tabBarSearchAutoFocus,
|
|
445
|
+
scrollEdgeAppearance: {
|
|
446
|
+
tabBarBackgroundColor,
|
|
447
|
+
tabBarShadowColor,
|
|
448
|
+
tabBarBlurEffect,
|
|
449
|
+
...tabItemLayoutAppearance
|
|
450
|
+
},
|
|
451
|
+
standardAppearance: {
|
|
452
|
+
tabBarBackgroundColor,
|
|
453
|
+
tabBarShadowColor,
|
|
454
|
+
tabBarBlurEffect,
|
|
455
|
+
...tabItemLayoutAppearance
|
|
456
|
+
},
|
|
457
|
+
overrideScrollViewContentInsetAdjustmentBehavior
|
|
458
|
+
},
|
|
459
|
+
children: /*#__PURE__*/_jsx(Deferred, {
|
|
460
|
+
lazy: lazy,
|
|
461
|
+
visible: visible,
|
|
462
|
+
children: /*#__PURE__*/_jsx(ScreenWithHeader, {
|
|
463
|
+
isFocused: isFocused,
|
|
464
|
+
route: route,
|
|
465
|
+
navigation: descriptor.navigation,
|
|
466
|
+
options: options,
|
|
467
|
+
children: /*#__PURE__*/_jsx(NavigationMetaContext.Provider, {
|
|
468
|
+
value: meta,
|
|
469
|
+
children: render()
|
|
470
|
+
})
|
|
471
|
+
})
|
|
472
|
+
})
|
|
473
|
+
});
|
|
474
|
+
});
|
|
375
475
|
function ScreenWithHeader({
|
|
376
476
|
isFocused,
|
|
377
477
|
route,
|
|
@@ -417,25 +517,36 @@ function getPlatformIcon(icon) {
|
|
|
417
517
|
switch (icon.type) {
|
|
418
518
|
case 'sfSymbol':
|
|
419
519
|
return {
|
|
420
|
-
ios:
|
|
520
|
+
ios: {
|
|
521
|
+
type: 'sfSymbol',
|
|
522
|
+
name: icon.name,
|
|
523
|
+
renderingMode: icon.renderingMode === 'multicolor' ? 'original' : icon.renderingMode
|
|
524
|
+
},
|
|
421
525
|
android: undefined,
|
|
422
526
|
shared: undefined
|
|
423
527
|
};
|
|
424
528
|
case 'image':
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
529
|
+
{
|
|
530
|
+
// A `{ uri: 'name' }` source maps to an Android drawable by name.
|
|
531
|
+
const drawableName = typeof icon.source === 'object' && 'uri' in icon.source && icon.source.uri?.includes(':') === false ? icon.source.uri : undefined;
|
|
532
|
+
return {
|
|
533
|
+
ios: {
|
|
534
|
+
type: 'imageSource',
|
|
535
|
+
imageSource: icon.source,
|
|
536
|
+
renderingMode: icon.tinted === false ? 'original' : 'template'
|
|
537
|
+
},
|
|
538
|
+
android: drawableName != null ? {
|
|
539
|
+
type: 'drawableResource',
|
|
540
|
+
name: drawableName,
|
|
541
|
+
tinting: icon.tinted === false ? 'original' : 'tinted'
|
|
542
|
+
} : {
|
|
543
|
+
type: 'imageSource',
|
|
544
|
+
imageSource: icon.source,
|
|
545
|
+
tinting: icon.tinted === false ? 'original' : 'tinted'
|
|
546
|
+
},
|
|
547
|
+
shared: undefined
|
|
548
|
+
};
|
|
549
|
+
}
|
|
439
550
|
default:
|
|
440
551
|
{
|
|
441
552
|
const _exhaustiveCheck = icon;
|