@react-navigation/bottom-tabs 7.0.0-alpha.2 → 7.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/commonjs/TransitionConfigs/SceneStyleInterpolators.js +47 -0
- package/lib/commonjs/TransitionConfigs/SceneStyleInterpolators.js.map +1 -0
- package/lib/commonjs/TransitionConfigs/TransitionPresets.js +17 -0
- package/lib/commonjs/TransitionConfigs/TransitionPresets.js.map +1 -0
- package/lib/commonjs/TransitionConfigs/TransitionSpecs.js +22 -0
- package/lib/commonjs/TransitionConfigs/TransitionSpecs.js.map +1 -0
- package/lib/commonjs/index.js +9 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/navigators/createBottomTabNavigator.js +11 -6
- package/lib/commonjs/navigators/createBottomTabNavigator.js.map +1 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/utils/BottomTabBarHeightCallbackContext.js +3 -4
- package/lib/commonjs/utils/BottomTabBarHeightCallbackContext.js.map +1 -1
- package/lib/commonjs/utils/BottomTabBarHeightContext.js +3 -4
- package/lib/commonjs/utils/BottomTabBarHeightContext.js.map +1 -1
- package/lib/commonjs/utils/useAnimatedHashMap.js +31 -0
- package/lib/commonjs/utils/useAnimatedHashMap.js.map +1 -0
- package/lib/commonjs/utils/useBottomTabBarHeight.js +2 -2
- package/lib/commonjs/utils/useBottomTabBarHeight.js.map +1 -1
- package/lib/commonjs/utils/useIsKeyboardShown.js +2 -2
- package/lib/commonjs/utils/useIsKeyboardShown.js.map +1 -1
- package/lib/commonjs/views/Badge.js +2 -2
- package/lib/commonjs/views/Badge.js.map +1 -1
- package/lib/commonjs/views/BottomTabBar.js +65 -27
- package/lib/commonjs/views/BottomTabBar.js.map +1 -1
- package/lib/commonjs/views/BottomTabItem.js +32 -54
- package/lib/commonjs/views/BottomTabItem.js.map +1 -1
- package/lib/commonjs/views/BottomTabView.js +120 -18
- package/lib/commonjs/views/BottomTabView.js.map +1 -1
- package/lib/commonjs/views/ScreenFallback.js +10 -14
- package/lib/commonjs/views/ScreenFallback.js.map +1 -1
- package/lib/commonjs/views/TabBarIcon.js +12 -17
- package/lib/commonjs/views/TabBarIcon.js.map +1 -1
- package/lib/module/TransitionConfigs/SceneStyleInterpolators.js +40 -0
- package/lib/module/TransitionConfigs/SceneStyleInterpolators.js.map +1 -0
- package/lib/module/TransitionConfigs/TransitionPresets.js +11 -0
- package/lib/module/TransitionConfigs/TransitionPresets.js.map +1 -0
- package/lib/module/TransitionConfigs/TransitionSpecs.js +16 -0
- package/lib/module/TransitionConfigs/TransitionSpecs.js.map +1 -0
- package/lib/module/index.js +9 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/navigators/createBottomTabNavigator.js +8 -2
- package/lib/module/navigators/createBottomTabNavigator.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/module/utils/BottomTabBarHeightCallbackContext.js.map +1 -1
- package/lib/module/utils/BottomTabBarHeightContext.js.map +1 -1
- package/lib/module/utils/useAnimatedHashMap.js +23 -0
- package/lib/module/utils/useAnimatedHashMap.js.map +1 -0
- package/lib/module/utils/useBottomTabBarHeight.js.map +1 -1
- package/lib/module/utils/useIsKeyboardShown.js.map +1 -1
- package/lib/module/views/Badge.js.map +1 -1
- package/lib/module/views/BottomTabBar.js +68 -30
- package/lib/module/views/BottomTabBar.js.map +1 -1
- package/lib/module/views/BottomTabItem.js +34 -56
- package/lib/module/views/BottomTabItem.js.map +1 -1
- package/lib/module/views/BottomTabView.js +119 -17
- package/lib/module/views/BottomTabView.js.map +1 -1
- package/lib/module/views/ScreenFallback.js +8 -12
- package/lib/module/views/ScreenFallback.js.map +1 -1
- package/lib/module/views/TabBarIcon.js +12 -17
- package/lib/module/views/TabBarIcon.js.map +1 -1
- package/lib/typescript/src/TransitionConfigs/SceneStyleInterpolators.d.ts +10 -0
- package/lib/typescript/src/TransitionConfigs/SceneStyleInterpolators.d.ts.map +1 -0
- package/lib/typescript/src/TransitionConfigs/TransitionPresets.d.ts +4 -0
- package/lib/typescript/src/TransitionConfigs/TransitionPresets.d.ts.map +1 -0
- package/lib/typescript/src/TransitionConfigs/TransitionSpecs.d.ts +4 -0
- package/lib/typescript/src/TransitionConfigs/TransitionSpecs.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +8 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/navigators/createBottomTabNavigator.d.ts +15 -9
- package/lib/typescript/src/navigators/createBottomTabNavigator.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +71 -4
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/utils/useAnimatedHashMap.d.ts +4 -0
- package/lib/typescript/src/utils/useAnimatedHashMap.d.ts.map +1 -0
- package/lib/typescript/src/views/Badge.d.ts +3 -2
- package/lib/typescript/src/views/Badge.d.ts.map +1 -1
- package/lib/typescript/src/views/BottomTabBar.d.ts +5 -4
- package/lib/typescript/src/views/BottomTabBar.d.ts.map +1 -1
- package/lib/typescript/src/views/BottomTabItem.d.ts +3 -3
- package/lib/typescript/src/views/BottomTabItem.d.ts.map +1 -1
- package/lib/typescript/src/views/BottomTabView.d.ts +2 -1
- package/lib/typescript/src/views/BottomTabView.d.ts.map +1 -1
- package/lib/typescript/src/views/ScreenFallback.d.ts +5 -5
- package/lib/typescript/src/views/ScreenFallback.d.ts.map +1 -1
- package/lib/typescript/src/views/TabBarIcon.d.ts +2 -2
- package/lib/typescript/src/views/TabBarIcon.d.ts.map +1 -1
- package/package.json +17 -18
- package/src/TransitionConfigs/SceneStyleInterpolators.tsx +44 -0
- package/src/TransitionConfigs/TransitionPresets.tsx +13 -0
- package/src/TransitionConfigs/TransitionSpecs.tsx +19 -0
- package/src/index.tsx +10 -0
- package/src/navigators/createBottomTabNavigator.tsx +40 -12
- package/src/types.tsx +102 -5
- package/src/utils/useAnimatedHashMap.tsx +25 -0
- package/src/utils/useIsKeyboardShown.tsx +1 -1
- package/src/views/Badge.tsx +6 -1
- package/src/views/BottomTabBar.tsx +125 -47
- package/src/views/BottomTabItem.tsx +52 -82
- package/src/views/BottomTabView.tsx +163 -14
- package/src/views/ScreenFallback.tsx +12 -13
- package/src/views/TabBarIcon.tsx +16 -24
|
@@ -9,19 +9,25 @@ import type {
|
|
|
9
9
|
TabNavigationState,
|
|
10
10
|
} from '@react-navigation/native';
|
|
11
11
|
import * as React from 'react';
|
|
12
|
-
import { Platform, StyleSheet } from 'react-native';
|
|
12
|
+
import { Animated, Platform, StyleSheet } from 'react-native';
|
|
13
13
|
import { SafeAreaInsetsContext } from 'react-native-safe-area-context';
|
|
14
14
|
|
|
15
|
+
import {
|
|
16
|
+
FadeTransition,
|
|
17
|
+
ShiftTransition,
|
|
18
|
+
} from '../TransitionConfigs/TransitionPresets';
|
|
15
19
|
import type {
|
|
16
20
|
BottomTabBarProps,
|
|
17
21
|
BottomTabDescriptorMap,
|
|
18
22
|
BottomTabHeaderProps,
|
|
19
23
|
BottomTabNavigationConfig,
|
|
20
24
|
BottomTabNavigationHelpers,
|
|
25
|
+
BottomTabNavigationOptions,
|
|
21
26
|
BottomTabNavigationProp,
|
|
22
27
|
} from '../types';
|
|
23
28
|
import { BottomTabBarHeightCallbackContext } from '../utils/BottomTabBarHeightCallbackContext';
|
|
24
29
|
import { BottomTabBarHeightContext } from '../utils/BottomTabBarHeightContext';
|
|
30
|
+
import { useAnimatedHashMap } from '../utils/useAnimatedHashMap';
|
|
25
31
|
import { BottomTabBar, getTabBarHeight } from './BottomTabBar';
|
|
26
32
|
import { MaybeScreen, MaybeScreenContainer } from './ScreenFallback';
|
|
27
33
|
|
|
@@ -31,6 +37,33 @@ type Props = BottomTabNavigationConfig & {
|
|
|
31
37
|
descriptors: BottomTabDescriptorMap;
|
|
32
38
|
};
|
|
33
39
|
|
|
40
|
+
const EPSILON = 1e-5;
|
|
41
|
+
const STATE_INACTIVE = 0;
|
|
42
|
+
const STATE_TRANSITIONING_OR_BELOW_TOP = 1;
|
|
43
|
+
const STATE_ON_TOP = 2;
|
|
44
|
+
|
|
45
|
+
const NAMED_TRANSITIONS_PRESETS = {
|
|
46
|
+
fade: FadeTransition,
|
|
47
|
+
shift: ShiftTransition,
|
|
48
|
+
none: {
|
|
49
|
+
sceneStyleInterpolator: undefined,
|
|
50
|
+
transitionSpec: {
|
|
51
|
+
animation: 'timing',
|
|
52
|
+
config: { duration: 0 },
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
} as const;
|
|
56
|
+
|
|
57
|
+
const hasAnimation = (options: BottomTabNavigationOptions) => {
|
|
58
|
+
const { animation, transitionSpec } = options;
|
|
59
|
+
|
|
60
|
+
if (animation) {
|
|
61
|
+
return animation !== 'none';
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return !transitionSpec;
|
|
65
|
+
};
|
|
66
|
+
|
|
34
67
|
export function BottomTabView(props: Props) {
|
|
35
68
|
const {
|
|
36
69
|
tabBar = (props: BottomTabBarProps) => <BottomTabBar {...props} />,
|
|
@@ -45,12 +78,65 @@ export function BottomTabView(props: Props) {
|
|
|
45
78
|
} = props;
|
|
46
79
|
|
|
47
80
|
const focusedRouteKey = state.routes[state.index].key;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* List of loaded tabs, tabs will be loaded when navigated to.
|
|
84
|
+
*/
|
|
48
85
|
const [loaded, setLoaded] = React.useState([focusedRouteKey]);
|
|
49
86
|
|
|
50
87
|
if (!loaded.includes(focusedRouteKey)) {
|
|
88
|
+
// Set the current tab to be loaded if it was not loaded before
|
|
51
89
|
setLoaded([...loaded, focusedRouteKey]);
|
|
52
90
|
}
|
|
53
91
|
|
|
92
|
+
const previousRouteKeyRef = React.useRef(focusedRouteKey);
|
|
93
|
+
const tabAnims = useAnimatedHashMap(state);
|
|
94
|
+
|
|
95
|
+
React.useEffect(() => {
|
|
96
|
+
const previousRouteKey = previousRouteKeyRef.current;
|
|
97
|
+
|
|
98
|
+
previousRouteKeyRef.current = focusedRouteKey;
|
|
99
|
+
|
|
100
|
+
const animateToIndex = () => {
|
|
101
|
+
Animated.parallel(
|
|
102
|
+
state.routes
|
|
103
|
+
.map((route, index) => {
|
|
104
|
+
const { options } = descriptors[route.key];
|
|
105
|
+
const {
|
|
106
|
+
animation = 'none',
|
|
107
|
+
transitionSpec = NAMED_TRANSITIONS_PRESETS[animation]
|
|
108
|
+
.transitionSpec,
|
|
109
|
+
} = options;
|
|
110
|
+
|
|
111
|
+
let spec = transitionSpec;
|
|
112
|
+
|
|
113
|
+
if (
|
|
114
|
+
route.key !== previousRouteKey &&
|
|
115
|
+
route.key !== focusedRouteKey
|
|
116
|
+
) {
|
|
117
|
+
// Don't animate if the screen is not previous one or new one
|
|
118
|
+
// This will avoid flicker for screens not involved in the transition
|
|
119
|
+
spec = NAMED_TRANSITIONS_PRESETS.none.transitionSpec;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
spec = spec ?? NAMED_TRANSITIONS_PRESETS.none.transitionSpec;
|
|
123
|
+
|
|
124
|
+
const toValue =
|
|
125
|
+
index === state.index ? 0 : index >= state.index ? 1 : -1;
|
|
126
|
+
|
|
127
|
+
return Animated[spec.animation](tabAnims[route.key], {
|
|
128
|
+
...spec.config,
|
|
129
|
+
toValue,
|
|
130
|
+
useNativeDriver: true,
|
|
131
|
+
});
|
|
132
|
+
})
|
|
133
|
+
.filter(Boolean) as Animated.CompositeAnimation[]
|
|
134
|
+
).start();
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
animateToIndex();
|
|
138
|
+
}, [descriptors, focusedRouteKey, state.index, state.routes, tabAnims]);
|
|
139
|
+
|
|
54
140
|
const dimensions = SafeAreaProviderCompat.initialMetrics.frame;
|
|
55
141
|
const [tabBarHeight, setTabBarHeight] = React.useState(() =>
|
|
56
142
|
getTabBarHeight({
|
|
@@ -88,24 +174,55 @@ export function BottomTabView(props: Props) {
|
|
|
88
174
|
|
|
89
175
|
const { routes } = state;
|
|
90
176
|
|
|
177
|
+
// If there is no animation, we only have 2 states: visible and invisible
|
|
178
|
+
const hasTwoStates = !routes.some((route) =>
|
|
179
|
+
hasAnimation(descriptors[route.key].options)
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
const { tabBarPosition = 'bottom' } = descriptors[focusedRouteKey].options;
|
|
183
|
+
|
|
91
184
|
return (
|
|
92
|
-
<SafeAreaProviderCompat
|
|
185
|
+
<SafeAreaProviderCompat
|
|
186
|
+
style={
|
|
187
|
+
tabBarPosition === 'left'
|
|
188
|
+
? styles.start
|
|
189
|
+
: tabBarPosition === 'right'
|
|
190
|
+
? styles.end
|
|
191
|
+
: null
|
|
192
|
+
}
|
|
193
|
+
>
|
|
194
|
+
{tabBarPosition === 'top' ? (
|
|
195
|
+
<BottomTabBarHeightCallbackContext.Provider value={setTabBarHeight}>
|
|
196
|
+
{renderTabBar()}
|
|
197
|
+
</BottomTabBarHeightCallbackContext.Provider>
|
|
198
|
+
) : null}
|
|
93
199
|
<MaybeScreenContainer
|
|
94
200
|
enabled={detachInactiveScreens}
|
|
95
|
-
hasTwoStates
|
|
96
|
-
style={styles.
|
|
201
|
+
hasTwoStates={hasTwoStates}
|
|
202
|
+
style={styles.screens}
|
|
97
203
|
>
|
|
98
204
|
{routes.map((route, index) => {
|
|
99
205
|
const descriptor = descriptors[route.key];
|
|
100
|
-
const {
|
|
206
|
+
const {
|
|
207
|
+
lazy = true,
|
|
208
|
+
unmountOnBlur,
|
|
209
|
+
animation = 'none',
|
|
210
|
+
sceneStyleInterpolator = NAMED_TRANSITIONS_PRESETS[animation]
|
|
211
|
+
.sceneStyleInterpolator,
|
|
212
|
+
} = descriptor.options;
|
|
101
213
|
const isFocused = state.index === index;
|
|
102
214
|
|
|
103
215
|
if (unmountOnBlur && !isFocused) {
|
|
104
216
|
return null;
|
|
105
217
|
}
|
|
106
218
|
|
|
107
|
-
if (
|
|
108
|
-
|
|
219
|
+
if (
|
|
220
|
+
lazy &&
|
|
221
|
+
!loaded.includes(route.key) &&
|
|
222
|
+
!isFocused &&
|
|
223
|
+
!state.preloadedRouteKeys.includes(route.key)
|
|
224
|
+
) {
|
|
225
|
+
// Don't render a lazy screen if we've never navigated to it or it wasn't preloaded
|
|
109
226
|
return null;
|
|
110
227
|
}
|
|
111
228
|
|
|
@@ -123,15 +240,39 @@ export function BottomTabView(props: Props) {
|
|
|
123
240
|
headerTransparent,
|
|
124
241
|
} = descriptor.options;
|
|
125
242
|
|
|
243
|
+
const { sceneStyle } =
|
|
244
|
+
sceneStyleInterpolator?.({
|
|
245
|
+
current: {
|
|
246
|
+
progress: tabAnims[route.key],
|
|
247
|
+
},
|
|
248
|
+
}) ?? {};
|
|
249
|
+
|
|
250
|
+
const animationEnabled = hasAnimation(descriptor.options);
|
|
251
|
+
const activityState = isFocused
|
|
252
|
+
? STATE_ON_TOP // the screen is on top after the transition
|
|
253
|
+
: animationEnabled // is animation is not enabled, immediately move to inactive state
|
|
254
|
+
? tabAnims[route.key].interpolate({
|
|
255
|
+
inputRange: [0, 1 - EPSILON, 1],
|
|
256
|
+
outputRange: [
|
|
257
|
+
STATE_TRANSITIONING_OR_BELOW_TOP, // screen visible during transition
|
|
258
|
+
STATE_TRANSITIONING_OR_BELOW_TOP,
|
|
259
|
+
STATE_INACTIVE, // the screen is detached after transition
|
|
260
|
+
],
|
|
261
|
+
extrapolate: 'extend',
|
|
262
|
+
})
|
|
263
|
+
: STATE_INACTIVE;
|
|
264
|
+
|
|
126
265
|
return (
|
|
127
266
|
<MaybeScreen
|
|
128
267
|
key={route.key}
|
|
129
268
|
style={[StyleSheet.absoluteFill, { zIndex: isFocused ? 0 : -1 }]}
|
|
130
|
-
|
|
269
|
+
active={activityState}
|
|
131
270
|
enabled={detachInactiveScreens}
|
|
132
271
|
freezeOnBlur={freezeOnBlur}
|
|
133
272
|
>
|
|
134
|
-
<BottomTabBarHeightContext.Provider
|
|
273
|
+
<BottomTabBarHeightContext.Provider
|
|
274
|
+
value={tabBarPosition === 'bottom' ? tabBarHeight : 0}
|
|
275
|
+
>
|
|
135
276
|
<Screen
|
|
136
277
|
focused={isFocused}
|
|
137
278
|
route={descriptor.route}
|
|
@@ -146,7 +287,7 @@ export function BottomTabView(props: Props) {
|
|
|
146
287
|
descriptor.navigation as BottomTabNavigationProp<ParamListBase>,
|
|
147
288
|
options: descriptor.options,
|
|
148
289
|
})}
|
|
149
|
-
style={sceneContainerStyle}
|
|
290
|
+
style={[sceneContainerStyle, animationEnabled && sceneStyle]}
|
|
150
291
|
>
|
|
151
292
|
{descriptor.render()}
|
|
152
293
|
</Screen>
|
|
@@ -155,15 +296,23 @@ export function BottomTabView(props: Props) {
|
|
|
155
296
|
);
|
|
156
297
|
})}
|
|
157
298
|
</MaybeScreenContainer>
|
|
158
|
-
|
|
159
|
-
{
|
|
160
|
-
|
|
299
|
+
{tabBarPosition !== 'top' ? (
|
|
300
|
+
<BottomTabBarHeightCallbackContext.Provider value={setTabBarHeight}>
|
|
301
|
+
{renderTabBar()}
|
|
302
|
+
</BottomTabBarHeightCallbackContext.Provider>
|
|
303
|
+
) : null}
|
|
161
304
|
</SafeAreaProviderCompat>
|
|
162
305
|
);
|
|
163
306
|
}
|
|
164
307
|
|
|
165
308
|
const styles = StyleSheet.create({
|
|
166
|
-
|
|
309
|
+
start: {
|
|
310
|
+
flexDirection: 'row-reverse',
|
|
311
|
+
},
|
|
312
|
+
end: {
|
|
313
|
+
flexDirection: 'row',
|
|
314
|
+
},
|
|
315
|
+
screens: {
|
|
167
316
|
flex: 1,
|
|
168
317
|
overflow: 'hidden',
|
|
169
318
|
},
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
import { ResourceSavingView } from '@react-navigation/elements';
|
|
2
1
|
import * as React from 'react';
|
|
3
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Animated,
|
|
4
|
+
type StyleProp,
|
|
5
|
+
View,
|
|
6
|
+
type ViewProps,
|
|
7
|
+
type ViewStyle,
|
|
8
|
+
} from 'react-native';
|
|
4
9
|
|
|
5
10
|
type Props = {
|
|
6
|
-
visible: boolean;
|
|
7
|
-
children: React.ReactNode;
|
|
8
11
|
enabled: boolean;
|
|
12
|
+
active: 0 | 1 | 2 | Animated.AnimatedInterpolation<0 | 1>;
|
|
13
|
+
children: React.ReactNode;
|
|
9
14
|
freezeOnBlur?: boolean;
|
|
10
15
|
style?: StyleProp<ViewStyle>;
|
|
11
16
|
};
|
|
@@ -33,18 +38,12 @@ export const MaybeScreenContainer = ({
|
|
|
33
38
|
return <View {...rest} />;
|
|
34
39
|
};
|
|
35
40
|
|
|
36
|
-
export function MaybeScreen({
|
|
41
|
+
export function MaybeScreen({ enabled, active, ...rest }: ViewProps & Props) {
|
|
37
42
|
if (Screens?.screensEnabled?.()) {
|
|
38
43
|
return (
|
|
39
|
-
<Screens.Screen activityState={
|
|
40
|
-
{children}
|
|
41
|
-
</Screens.Screen>
|
|
44
|
+
<Screens.Screen enabled={enabled} activityState={active} {...rest} />
|
|
42
45
|
);
|
|
43
46
|
}
|
|
44
47
|
|
|
45
|
-
return
|
|
46
|
-
<ResourceSavingView visible={visible} {...rest}>
|
|
47
|
-
{children}
|
|
48
|
-
</ResourceSavingView>
|
|
49
|
-
);
|
|
48
|
+
return <View {...rest} />;
|
|
50
49
|
}
|
package/src/views/TabBarIcon.tsx
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { Route } from '@react-navigation/native';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import {
|
|
4
|
-
StyleProp,
|
|
4
|
+
type StyleProp,
|
|
5
5
|
StyleSheet,
|
|
6
|
-
TextStyle,
|
|
6
|
+
type TextStyle,
|
|
7
7
|
View,
|
|
8
|
-
ViewStyle,
|
|
8
|
+
type ViewStyle,
|
|
9
9
|
} from 'react-native';
|
|
10
10
|
|
|
11
11
|
import { Badge } from './Badge';
|
|
@@ -27,6 +27,8 @@ type Props = {
|
|
|
27
27
|
style: StyleProp<ViewStyle>;
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
+
const ICON_SIZE = 25;
|
|
31
|
+
|
|
30
32
|
export function TabBarIcon({
|
|
31
33
|
route: _,
|
|
32
34
|
horizontal,
|
|
@@ -39,8 +41,6 @@ export function TabBarIcon({
|
|
|
39
41
|
renderIcon,
|
|
40
42
|
style,
|
|
41
43
|
}: Props) {
|
|
42
|
-
const size = 25;
|
|
43
|
-
|
|
44
44
|
// We render the icon twice at the same position on top of each other:
|
|
45
45
|
// active and inactive one, so we can fade between them.
|
|
46
46
|
return (
|
|
@@ -50,25 +50,21 @@ export function TabBarIcon({
|
|
|
50
50
|
<View style={[styles.icon, { opacity: activeOpacity }]}>
|
|
51
51
|
{renderIcon({
|
|
52
52
|
focused: true,
|
|
53
|
-
size,
|
|
53
|
+
size: ICON_SIZE,
|
|
54
54
|
color: activeTintColor,
|
|
55
55
|
})}
|
|
56
56
|
</View>
|
|
57
57
|
<View style={[styles.icon, { opacity: inactiveOpacity }]}>
|
|
58
58
|
{renderIcon({
|
|
59
59
|
focused: false,
|
|
60
|
-
size,
|
|
60
|
+
size: ICON_SIZE,
|
|
61
61
|
color: inactiveTintColor,
|
|
62
62
|
})}
|
|
63
63
|
</View>
|
|
64
64
|
<Badge
|
|
65
65
|
visible={badge != null}
|
|
66
|
-
style={[
|
|
67
|
-
|
|
68
|
-
horizontal ? styles.badgeHorizontal : styles.badgeVertical,
|
|
69
|
-
badgeStyle,
|
|
70
|
-
]}
|
|
71
|
-
size={(size * 3) / 4}
|
|
66
|
+
style={[styles.badge, badgeStyle]}
|
|
67
|
+
size={ICON_SIZE * 0.75}
|
|
72
68
|
>
|
|
73
69
|
{badge}
|
|
74
70
|
</Badge>
|
|
@@ -88,23 +84,19 @@ const styles = StyleSheet.create({
|
|
|
88
84
|
height: '100%',
|
|
89
85
|
width: '100%',
|
|
90
86
|
// Workaround for react-native >= 0.54 layout bug
|
|
91
|
-
minWidth:
|
|
87
|
+
minWidth: ICON_SIZE,
|
|
92
88
|
},
|
|
93
89
|
iconVertical: {
|
|
94
|
-
|
|
90
|
+
width: ICON_SIZE,
|
|
91
|
+
height: ICON_SIZE,
|
|
95
92
|
},
|
|
96
93
|
iconHorizontal: {
|
|
97
|
-
|
|
98
|
-
|
|
94
|
+
width: ICON_SIZE,
|
|
95
|
+
height: ICON_SIZE,
|
|
99
96
|
},
|
|
100
97
|
badge: {
|
|
101
98
|
position: 'absolute',
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
badgeVertical: {
|
|
105
|
-
top: 3,
|
|
106
|
-
},
|
|
107
|
-
badgeHorizontal: {
|
|
108
|
-
top: 7,
|
|
99
|
+
end: -5,
|
|
100
|
+
top: -5,
|
|
109
101
|
},
|
|
110
102
|
});
|