@react-navigation/bottom-tabs 7.0.0-alpha.2 → 7.0.0-alpha.4
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 +19 -0
- package/lib/commonjs/TransitionConfigs/TransitionPresets.js.map +1 -0
- package/lib/commonjs/TransitionConfigs/TransitionSpecs.js +24 -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/utils/useAnimatedHashMap.js +31 -0
- package/lib/commonjs/utils/useAnimatedHashMap.js.map +1 -0
- package/lib/commonjs/views/BottomTabBar.js +53 -13
- package/lib/commonjs/views/BottomTabBar.js.map +1 -1
- package/lib/commonjs/views/BottomTabItem.js +21 -27
- package/lib/commonjs/views/BottomTabItem.js.map +1 -1
- package/lib/commonjs/views/BottomTabView.js +89 -8
- package/lib/commonjs/views/BottomTabView.js.map +1 -1
- package/lib/commonjs/views/ScreenFallback.js +6 -8
- 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/utils/useAnimatedHashMap.js +23 -0
- package/lib/module/utils/useAnimatedHashMap.js.map +1 -0
- package/lib/module/views/BottomTabBar.js +55 -15
- package/lib/module/views/BottomTabBar.js.map +1 -1
- package/lib/module/views/BottomTabItem.js +22 -28
- package/lib/module/views/BottomTabItem.js.map +1 -1
- package/lib/module/views/BottomTabView.js +90 -9
- package/lib/module/views/BottomTabView.js.map +1 -1
- package/lib/module/views/ScreenFallback.js +6 -8
- 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 +7 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +54 -0
- 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/BottomTabBar.d.ts +1 -1
- package/lib/typescript/src/views/BottomTabBar.d.ts.map +1 -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/ScreenFallback.d.ts +4 -4
- package/lib/typescript/src/views/ScreenFallback.d.ts.map +1 -1
- package/lib/typescript/src/views/TabBarIcon.d.ts.map +1 -1
- package/package.json +5 -5
- 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 +9 -0
- package/src/types.tsx +75 -0
- package/src/utils/useAnimatedHashMap.tsx +25 -0
- package/src/views/BottomTabBar.tsx +109 -34
- package/src/views/BottomTabItem.tsx +31 -37
- package/src/views/BottomTabView.tsx +115 -10
- package/src/views/ScreenFallback.tsx +6 -13
- package/src/views/TabBarIcon.tsx +13 -21
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getLabel, Label } from '@react-navigation/elements';
|
|
1
2
|
import { CommonActions, Link, Route, useTheme } from '@react-navigation/native';
|
|
2
3
|
import Color from 'color';
|
|
3
4
|
import React from 'react';
|
|
@@ -7,7 +8,6 @@ import {
|
|
|
7
8
|
Pressable,
|
|
8
9
|
StyleProp,
|
|
9
10
|
StyleSheet,
|
|
10
|
-
Text,
|
|
11
11
|
TextStyle,
|
|
12
12
|
ViewStyle,
|
|
13
13
|
} from 'react-native';
|
|
@@ -195,7 +195,7 @@ export function BottomTabItem({
|
|
|
195
195
|
iconStyle,
|
|
196
196
|
style,
|
|
197
197
|
}: Props) {
|
|
198
|
-
const { colors
|
|
198
|
+
const { colors } = useTheme();
|
|
199
199
|
|
|
200
200
|
const activeTintColor =
|
|
201
201
|
customActiveTintColor === undefined
|
|
@@ -214,38 +214,38 @@ export function BottomTabItem({
|
|
|
214
214
|
|
|
215
215
|
const color = focused ? activeTintColor : inactiveTintColor;
|
|
216
216
|
|
|
217
|
-
if (typeof label
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
allowFontScaling={allowFontScaling}
|
|
229
|
-
>
|
|
230
|
-
{label}
|
|
231
|
-
</Text>
|
|
217
|
+
if (typeof label !== 'string') {
|
|
218
|
+
const { options } = descriptor;
|
|
219
|
+
const children = getLabel(
|
|
220
|
+
{
|
|
221
|
+
label:
|
|
222
|
+
typeof options.tabBarLabel === 'string'
|
|
223
|
+
? options.tabBarLabel
|
|
224
|
+
: undefined,
|
|
225
|
+
title: options.title,
|
|
226
|
+
},
|
|
227
|
+
route.name
|
|
232
228
|
);
|
|
233
|
-
}
|
|
234
229
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
?
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
230
|
+
return label({
|
|
231
|
+
focused,
|
|
232
|
+
color,
|
|
233
|
+
position: horizontal ? 'beside-icon' : 'below-icon',
|
|
234
|
+
children,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
242
237
|
|
|
243
|
-
return
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
238
|
+
return (
|
|
239
|
+
<Label
|
|
240
|
+
style={[
|
|
241
|
+
horizontal ? styles.labelBeside : styles.labelBeneath,
|
|
242
|
+
labelStyle,
|
|
243
|
+
]}
|
|
244
|
+
allowFontScaling={allowFontScaling}
|
|
245
|
+
>
|
|
246
|
+
{label}
|
|
247
|
+
</Label>
|
|
248
|
+
);
|
|
249
249
|
};
|
|
250
250
|
|
|
251
251
|
const renderIcon = ({ focused }: { focused: boolean }) => {
|
|
@@ -306,7 +306,6 @@ export function BottomTabItem({
|
|
|
306
306
|
|
|
307
307
|
const styles = StyleSheet.create({
|
|
308
308
|
tab: {
|
|
309
|
-
flex: 1,
|
|
310
309
|
alignItems: 'center',
|
|
311
310
|
},
|
|
312
311
|
tabPortrait: {
|
|
@@ -317,17 +316,12 @@ const styles = StyleSheet.create({
|
|
|
317
316
|
justifyContent: 'center',
|
|
318
317
|
flexDirection: 'row',
|
|
319
318
|
},
|
|
320
|
-
label: {
|
|
321
|
-
textAlign: 'center',
|
|
322
|
-
backgroundColor: 'transparent',
|
|
323
|
-
},
|
|
324
319
|
labelBeneath: {
|
|
325
320
|
fontSize: 10,
|
|
326
321
|
},
|
|
327
322
|
labelBeside: {
|
|
328
323
|
fontSize: 13,
|
|
329
324
|
marginLeft: 20,
|
|
330
|
-
marginTop: 3,
|
|
331
325
|
},
|
|
332
326
|
button: {
|
|
333
327
|
display: 'flex',
|
|
@@ -9,7 +9,7 @@ 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
15
|
import type {
|
|
@@ -18,12 +18,15 @@ import type {
|
|
|
18
18
|
BottomTabHeaderProps,
|
|
19
19
|
BottomTabNavigationConfig,
|
|
20
20
|
BottomTabNavigationHelpers,
|
|
21
|
+
BottomTabNavigationOptions,
|
|
21
22
|
BottomTabNavigationProp,
|
|
22
23
|
} from '../types';
|
|
23
24
|
import { BottomTabBarHeightCallbackContext } from '../utils/BottomTabBarHeightCallbackContext';
|
|
24
25
|
import { BottomTabBarHeightContext } from '../utils/BottomTabBarHeightContext';
|
|
26
|
+
import { useAnimatedHashMap } from '../utils/useAnimatedHashMap';
|
|
25
27
|
import { BottomTabBar, getTabBarHeight } from './BottomTabBar';
|
|
26
28
|
import { MaybeScreen, MaybeScreenContainer } from './ScreenFallback';
|
|
29
|
+
import CompositeAnimation = Animated.CompositeAnimation;
|
|
27
30
|
|
|
28
31
|
type Props = BottomTabNavigationConfig & {
|
|
29
32
|
state: TabNavigationState<ParamListBase>;
|
|
@@ -31,6 +34,21 @@ type Props = BottomTabNavigationConfig & {
|
|
|
31
34
|
descriptors: BottomTabDescriptorMap;
|
|
32
35
|
};
|
|
33
36
|
|
|
37
|
+
const EPSILON = 1e-5;
|
|
38
|
+
const STATE_INACTIVE = 0;
|
|
39
|
+
const STATE_TRANSITIONING_OR_BELOW_TOP = 1;
|
|
40
|
+
const STATE_ON_TOP = 2;
|
|
41
|
+
|
|
42
|
+
const hasAnimation = (options: BottomTabNavigationOptions) => {
|
|
43
|
+
const { animationEnabled, transitionSpec } = options;
|
|
44
|
+
|
|
45
|
+
if (animationEnabled === false || !transitionSpec) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return true;
|
|
50
|
+
};
|
|
51
|
+
|
|
34
52
|
export function BottomTabView(props: Props) {
|
|
35
53
|
const {
|
|
36
54
|
tabBar = (props: BottomTabBarProps) => <BottomTabBar {...props} />,
|
|
@@ -43,14 +61,54 @@ export function BottomTabView(props: Props) {
|
|
|
43
61
|
Platform.OS === 'ios',
|
|
44
62
|
sceneContainerStyle,
|
|
45
63
|
} = props;
|
|
46
|
-
|
|
47
64
|
const focusedRouteKey = state.routes[state.index].key;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* List of loaded tabs, tabs will be loaded when navigated to.
|
|
68
|
+
*/
|
|
48
69
|
const [loaded, setLoaded] = React.useState([focusedRouteKey]);
|
|
49
70
|
|
|
50
71
|
if (!loaded.includes(focusedRouteKey)) {
|
|
72
|
+
// Set the current tab to be loaded if it was not loaded before
|
|
51
73
|
setLoaded([...loaded, focusedRouteKey]);
|
|
52
74
|
}
|
|
53
75
|
|
|
76
|
+
const tabAnims = useAnimatedHashMap(state);
|
|
77
|
+
|
|
78
|
+
React.useEffect(() => {
|
|
79
|
+
const animateToIndex = () => {
|
|
80
|
+
Animated.parallel(
|
|
81
|
+
state.routes
|
|
82
|
+
.map((route, index) => {
|
|
83
|
+
const { options } = descriptors[route.key];
|
|
84
|
+
const { transitionSpec } = options;
|
|
85
|
+
|
|
86
|
+
const animationEnabled = hasAnimation(options);
|
|
87
|
+
|
|
88
|
+
const toValue =
|
|
89
|
+
index === state.index ? 0 : index >= state.index ? 1 : -1;
|
|
90
|
+
|
|
91
|
+
if (!animationEnabled || !transitionSpec) {
|
|
92
|
+
return Animated.timing(tabAnims[route.key], {
|
|
93
|
+
toValue,
|
|
94
|
+
duration: 0,
|
|
95
|
+
useNativeDriver: true,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return Animated[transitionSpec.animation](tabAnims[route.key], {
|
|
100
|
+
...transitionSpec.config,
|
|
101
|
+
toValue,
|
|
102
|
+
useNativeDriver: true,
|
|
103
|
+
});
|
|
104
|
+
})
|
|
105
|
+
.filter(Boolean) as CompositeAnimation[]
|
|
106
|
+
).start();
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
animateToIndex();
|
|
110
|
+
}, [descriptors, state.index, state.routes, tabAnims]);
|
|
111
|
+
|
|
54
112
|
const dimensions = SafeAreaProviderCompat.initialMetrics.frame;
|
|
55
113
|
const [tabBarHeight, setTabBarHeight] = React.useState(() =>
|
|
56
114
|
getTabBarHeight({
|
|
@@ -88,16 +146,35 @@ export function BottomTabView(props: Props) {
|
|
|
88
146
|
|
|
89
147
|
const { routes } = state;
|
|
90
148
|
|
|
149
|
+
// If there is no animation, we only have 2 states: visible and invisible
|
|
150
|
+
const hasTwoStates = !routes.some((route) =>
|
|
151
|
+
hasAnimation(descriptors[route.key].options)
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
const { tabBarPosition = 'bottom' } = descriptors[focusedRouteKey].options;
|
|
155
|
+
|
|
91
156
|
return (
|
|
92
|
-
<SafeAreaProviderCompat
|
|
157
|
+
<SafeAreaProviderCompat
|
|
158
|
+
style={
|
|
159
|
+
tabBarPosition === 'left'
|
|
160
|
+
? styles.left
|
|
161
|
+
: tabBarPosition === 'right'
|
|
162
|
+
? styles.right
|
|
163
|
+
: null
|
|
164
|
+
}
|
|
165
|
+
>
|
|
93
166
|
<MaybeScreenContainer
|
|
94
167
|
enabled={detachInactiveScreens}
|
|
95
|
-
hasTwoStates
|
|
96
|
-
style={styles.
|
|
168
|
+
hasTwoStates={hasTwoStates}
|
|
169
|
+
style={styles.screens}
|
|
97
170
|
>
|
|
98
171
|
{routes.map((route, index) => {
|
|
99
172
|
const descriptor = descriptors[route.key];
|
|
100
|
-
const {
|
|
173
|
+
const {
|
|
174
|
+
lazy = true,
|
|
175
|
+
unmountOnBlur,
|
|
176
|
+
sceneStyleInterpolator,
|
|
177
|
+
} = descriptor.options;
|
|
101
178
|
const isFocused = state.index === index;
|
|
102
179
|
|
|
103
180
|
if (unmountOnBlur && !isFocused) {
|
|
@@ -123,15 +200,37 @@ export function BottomTabView(props: Props) {
|
|
|
123
200
|
headerTransparent,
|
|
124
201
|
} = descriptor.options;
|
|
125
202
|
|
|
203
|
+
const { sceneStyle } =
|
|
204
|
+
sceneStyleInterpolator?.({
|
|
205
|
+
current: tabAnims[route.key],
|
|
206
|
+
}) ?? {};
|
|
207
|
+
|
|
208
|
+
const animationEnabled = hasAnimation(descriptor.options);
|
|
209
|
+
const activityState = isFocused
|
|
210
|
+
? STATE_ON_TOP // the screen is on top after the transition
|
|
211
|
+
: animationEnabled // is animation is not enabled, immediately move to inactive state
|
|
212
|
+
? tabAnims[route.key].interpolate({
|
|
213
|
+
inputRange: [0, 1 - EPSILON, 1],
|
|
214
|
+
outputRange: [
|
|
215
|
+
STATE_TRANSITIONING_OR_BELOW_TOP, // screen visible during transition
|
|
216
|
+
STATE_TRANSITIONING_OR_BELOW_TOP,
|
|
217
|
+
STATE_INACTIVE, // the screen is detached after transition
|
|
218
|
+
],
|
|
219
|
+
extrapolate: 'extend',
|
|
220
|
+
})
|
|
221
|
+
: STATE_INACTIVE;
|
|
222
|
+
|
|
126
223
|
return (
|
|
127
224
|
<MaybeScreen
|
|
128
225
|
key={route.key}
|
|
129
226
|
style={[StyleSheet.absoluteFill, { zIndex: isFocused ? 0 : -1 }]}
|
|
130
|
-
|
|
227
|
+
active={activityState}
|
|
131
228
|
enabled={detachInactiveScreens}
|
|
132
229
|
freezeOnBlur={freezeOnBlur}
|
|
133
230
|
>
|
|
134
|
-
<BottomTabBarHeightContext.Provider
|
|
231
|
+
<BottomTabBarHeightContext.Provider
|
|
232
|
+
value={tabBarPosition === 'bottom' ? tabBarHeight : 0}
|
|
233
|
+
>
|
|
135
234
|
<Screen
|
|
136
235
|
focused={isFocused}
|
|
137
236
|
route={descriptor.route}
|
|
@@ -146,7 +245,7 @@ export function BottomTabView(props: Props) {
|
|
|
146
245
|
descriptor.navigation as BottomTabNavigationProp<ParamListBase>,
|
|
147
246
|
options: descriptor.options,
|
|
148
247
|
})}
|
|
149
|
-
style={sceneContainerStyle}
|
|
248
|
+
style={[sceneContainerStyle, animationEnabled && sceneStyle]}
|
|
150
249
|
>
|
|
151
250
|
{descriptor.render()}
|
|
152
251
|
</Screen>
|
|
@@ -163,7 +262,13 @@ export function BottomTabView(props: Props) {
|
|
|
163
262
|
}
|
|
164
263
|
|
|
165
264
|
const styles = StyleSheet.create({
|
|
166
|
-
|
|
265
|
+
left: {
|
|
266
|
+
flexDirection: 'row-reverse',
|
|
267
|
+
},
|
|
268
|
+
right: {
|
|
269
|
+
flexDirection: 'row',
|
|
270
|
+
},
|
|
271
|
+
screens: {
|
|
167
272
|
flex: 1,
|
|
168
273
|
overflow: 'hidden',
|
|
169
274
|
},
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { ResourceSavingView } from '@react-navigation/elements';
|
|
2
1
|
import * as React from 'react';
|
|
3
|
-
import { StyleProp, View, ViewProps, ViewStyle } from 'react-native';
|
|
2
|
+
import { Animated, StyleProp, View, ViewProps, ViewStyle } from 'react-native';
|
|
4
3
|
|
|
5
4
|
type Props = {
|
|
6
|
-
visible: boolean;
|
|
7
|
-
children: React.ReactNode;
|
|
8
5
|
enabled: boolean;
|
|
6
|
+
active: 0 | 1 | 2 | Animated.AnimatedInterpolation<0 | 1>;
|
|
7
|
+
children: React.ReactNode;
|
|
9
8
|
freezeOnBlur?: boolean;
|
|
10
9
|
style?: StyleProp<ViewStyle>;
|
|
11
10
|
};
|
|
@@ -33,18 +32,12 @@ export const MaybeScreenContainer = ({
|
|
|
33
32
|
return <View {...rest} />;
|
|
34
33
|
};
|
|
35
34
|
|
|
36
|
-
export function MaybeScreen({
|
|
35
|
+
export function MaybeScreen({ enabled, active, ...rest }: ViewProps & Props) {
|
|
37
36
|
if (Screens?.screensEnabled?.()) {
|
|
38
37
|
return (
|
|
39
|
-
<Screens.Screen activityState={
|
|
40
|
-
{children}
|
|
41
|
-
</Screens.Screen>
|
|
38
|
+
<Screens.Screen enabled={enabled} activityState={active} {...rest} />
|
|
42
39
|
);
|
|
43
40
|
}
|
|
44
41
|
|
|
45
|
-
return
|
|
46
|
-
<ResourceSavingView visible={visible} {...rest}>
|
|
47
|
-
{children}
|
|
48
|
-
</ResourceSavingView>
|
|
49
|
-
);
|
|
42
|
+
return <View {...rest} />;
|
|
50
43
|
}
|
package/src/views/TabBarIcon.tsx
CHANGED
|
@@ -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
|
+
right: -5,
|
|
100
|
+
top: -5,
|
|
109
101
|
},
|
|
110
102
|
});
|