@react-navigation/bottom-tabs 7.0.0-alpha.3 → 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/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 +15 -4
- package/lib/commonjs/views/BottomTabView.js.map +1 -1
- package/lib/commonjs/views/TabBarIcon.js +12 -17
- package/lib/commonjs/views/TabBarIcon.js.map +1 -1
- 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 +15 -4
- package/lib/module/views/BottomTabView.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/types.d.ts +4 -0
- package/lib/typescript/src/types.d.ts.map +1 -1
- 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/TabBarIcon.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/types.tsx +5 -0
- package/src/views/BottomTabBar.tsx +109 -34
- package/src/views/BottomTabItem.tsx +31 -37
- package/src/views/BottomTabView.tsx +22 -4
- package/src/views/TabBarIcon.tsx +13 -21
package/src/types.tsx
CHANGED
|
@@ -223,6 +223,11 @@ export type BottomTabNavigationOptions = HeaderOptions & {
|
|
|
223
223
|
*/
|
|
224
224
|
tabBarBackground?: () => React.ReactNode;
|
|
225
225
|
|
|
226
|
+
/**
|
|
227
|
+
* Position of the tab bar on the screen. Defaults to `bottom`.
|
|
228
|
+
*/
|
|
229
|
+
tabBarPosition?: 'bottom' | 'left' | 'right';
|
|
230
|
+
|
|
226
231
|
/**
|
|
227
232
|
* Whether this screens should render the first time it's accessed. Defaults to `true`.
|
|
228
233
|
* Set it to `false` if you want to render the screen on initial render.
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
getDefaultSidebarWidth,
|
|
3
|
+
getLabel,
|
|
4
|
+
MissingIcon,
|
|
5
|
+
} from '@react-navigation/elements';
|
|
2
6
|
import {
|
|
3
7
|
CommonActions,
|
|
4
8
|
NavigationContext,
|
|
@@ -8,6 +12,7 @@ import {
|
|
|
8
12
|
useLinkTools,
|
|
9
13
|
useTheme,
|
|
10
14
|
} from '@react-navigation/native';
|
|
15
|
+
import Color from 'color';
|
|
11
16
|
import React from 'react';
|
|
12
17
|
import {
|
|
13
18
|
Animated,
|
|
@@ -15,10 +20,11 @@ import {
|
|
|
15
20
|
Platform,
|
|
16
21
|
StyleProp,
|
|
17
22
|
StyleSheet,
|
|
23
|
+
useWindowDimensions,
|
|
18
24
|
View,
|
|
19
25
|
ViewStyle,
|
|
20
26
|
} from 'react-native';
|
|
21
|
-
import { EdgeInsets
|
|
27
|
+
import type { EdgeInsets } from 'react-native-safe-area-context';
|
|
22
28
|
|
|
23
29
|
import type { BottomTabBarProps, BottomTabDescriptorMap } from '../types';
|
|
24
30
|
import { BottomTabBarHeightCallbackContext } from '../utils/BottomTabBarHeightCallbackContext';
|
|
@@ -32,6 +38,7 @@ type Props = BottomTabBarProps & {
|
|
|
32
38
|
const DEFAULT_TABBAR_HEIGHT = 49;
|
|
33
39
|
const COMPACT_TABBAR_HEIGHT = 32;
|
|
34
40
|
const DEFAULT_MAX_TAB_ITEM_WIDTH = 125;
|
|
41
|
+
const SPACING = 5;
|
|
35
42
|
|
|
36
43
|
const useNativeDriver = Platform.OS !== 'web';
|
|
37
44
|
|
|
@@ -140,6 +147,7 @@ export function BottomTabBar({
|
|
|
140
147
|
const focusedOptions = focusedDescriptor.options;
|
|
141
148
|
|
|
142
149
|
const {
|
|
150
|
+
tabBarPosition = 'bottom',
|
|
143
151
|
tabBarShowLabel,
|
|
144
152
|
tabBarHideOnKeyboard = false,
|
|
145
153
|
tabBarVisibilityAnimationConfig,
|
|
@@ -147,11 +155,17 @@ export function BottomTabBar({
|
|
|
147
155
|
tabBarBackground,
|
|
148
156
|
tabBarActiveTintColor,
|
|
149
157
|
tabBarInactiveTintColor,
|
|
150
|
-
tabBarActiveBackgroundColor
|
|
158
|
+
tabBarActiveBackgroundColor = tabBarPosition !== 'bottom'
|
|
159
|
+
? Color(tabBarActiveTintColor ?? colors.primary)
|
|
160
|
+
.alpha(0.12)
|
|
161
|
+
.rgb()
|
|
162
|
+
.string()
|
|
163
|
+
: undefined,
|
|
151
164
|
tabBarInactiveBackgroundColor,
|
|
152
165
|
} = focusedOptions;
|
|
153
166
|
|
|
154
|
-
|
|
167
|
+
// FIXME: useSafeAreaFrame doesn't update values when window is resized on Web
|
|
168
|
+
const dimensions = useWindowDimensions();
|
|
155
169
|
const isKeyboardShown = useIsKeyboardShown();
|
|
156
170
|
|
|
157
171
|
const onHeightChange = React.useContext(BottomTabBarHeightCallbackContext);
|
|
@@ -256,42 +270,67 @@ export function BottomTabBar({
|
|
|
256
270
|
return (
|
|
257
271
|
<Animated.View
|
|
258
272
|
style={[
|
|
259
|
-
|
|
273
|
+
tabBarPosition === 'left'
|
|
274
|
+
? styles.left
|
|
275
|
+
: tabBarPosition === 'right'
|
|
276
|
+
? styles.right
|
|
277
|
+
: styles.bottom,
|
|
260
278
|
{
|
|
261
279
|
backgroundColor:
|
|
262
280
|
tabBarBackgroundElement != null ? 'transparent' : colors.card,
|
|
263
|
-
|
|
281
|
+
borderColor: colors.border,
|
|
264
282
|
},
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
283
|
+
tabBarPosition === 'bottom'
|
|
284
|
+
? [
|
|
285
|
+
{
|
|
286
|
+
transform: [
|
|
287
|
+
{
|
|
288
|
+
translateY: visible.interpolate({
|
|
289
|
+
inputRange: [0, 1],
|
|
290
|
+
outputRange: [
|
|
291
|
+
layout.height +
|
|
292
|
+
paddingBottom +
|
|
293
|
+
StyleSheet.hairlineWidth,
|
|
294
|
+
0,
|
|
295
|
+
],
|
|
296
|
+
}),
|
|
297
|
+
},
|
|
273
298
|
],
|
|
274
|
-
|
|
299
|
+
// Absolutely position the tab bar so that the content is below it
|
|
300
|
+
// This is needed to avoid gap at bottom when the tab bar is hidden
|
|
301
|
+
position: isTabBarHidden ? 'absolute' : undefined,
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
height: tabBarHeight,
|
|
305
|
+
paddingBottom,
|
|
306
|
+
paddingHorizontal: Math.max(insets.left, insets.right),
|
|
307
|
+
},
|
|
308
|
+
]
|
|
309
|
+
: {
|
|
310
|
+
paddingTop: insets.top,
|
|
311
|
+
paddingBottom: insets.bottom,
|
|
312
|
+
paddingLeft: tabBarPosition === 'left' ? insets.left : 0,
|
|
313
|
+
paddingRight: tabBarPosition === 'right' ? insets.right : 0,
|
|
314
|
+
minWidth: hasHorizontalLabels
|
|
315
|
+
? getDefaultSidebarWidth(dimensions)
|
|
316
|
+
: 0,
|
|
275
317
|
},
|
|
276
|
-
],
|
|
277
|
-
// Absolutely position the tab bar so that the content is below it
|
|
278
|
-
// This is needed to avoid gap at bottom when the tab bar is hidden
|
|
279
|
-
position: isTabBarHidden ? 'absolute' : (null as any),
|
|
280
|
-
},
|
|
281
|
-
{
|
|
282
|
-
height: tabBarHeight,
|
|
283
|
-
paddingBottom,
|
|
284
|
-
paddingHorizontal: Math.max(insets.left, insets.right),
|
|
285
|
-
},
|
|
286
318
|
tabBarStyle,
|
|
287
319
|
]}
|
|
288
320
|
pointerEvents={isTabBarHidden ? 'none' : 'auto'}
|
|
289
|
-
onLayout={handleLayout}
|
|
321
|
+
onLayout={tabBarPosition === 'bottom' ? handleLayout : undefined}
|
|
290
322
|
>
|
|
291
323
|
<View pointerEvents="none" style={StyleSheet.absoluteFill}>
|
|
292
324
|
{tabBarBackgroundElement}
|
|
293
325
|
</View>
|
|
294
|
-
<View
|
|
326
|
+
<View
|
|
327
|
+
accessibilityRole="tablist"
|
|
328
|
+
style={
|
|
329
|
+
tabBarPosition === 'bottom'
|
|
330
|
+
? styles.bottomContent
|
|
331
|
+
: styles.sideContent
|
|
332
|
+
}
|
|
333
|
+
>
|
|
295
334
|
{routes.map((route, index) => {
|
|
296
335
|
const focused = index === state.index;
|
|
297
336
|
const { options } = descriptors[route.key];
|
|
@@ -319,11 +358,12 @@ export function BottomTabBar({
|
|
|
319
358
|
};
|
|
320
359
|
|
|
321
360
|
const label =
|
|
322
|
-
options.tabBarLabel
|
|
361
|
+
typeof options.tabBarLabel === 'function'
|
|
323
362
|
? options.tabBarLabel
|
|
324
|
-
:
|
|
325
|
-
|
|
326
|
-
|
|
363
|
+
: getLabel(
|
|
364
|
+
{ label: options.tabBarLabel, title: options.title },
|
|
365
|
+
route.name
|
|
366
|
+
);
|
|
327
367
|
|
|
328
368
|
const accessibilityLabel =
|
|
329
369
|
options.tabBarAccessibilityLabel !== undefined
|
|
@@ -366,7 +406,17 @@ export function BottomTabBar({
|
|
|
366
406
|
showLabel={tabBarShowLabel}
|
|
367
407
|
labelStyle={options.tabBarLabelStyle}
|
|
368
408
|
iconStyle={options.tabBarIconStyle}
|
|
369
|
-
style={
|
|
409
|
+
style={[
|
|
410
|
+
tabBarPosition === 'bottom'
|
|
411
|
+
? styles.bottomItem
|
|
412
|
+
: [
|
|
413
|
+
styles.sideItem,
|
|
414
|
+
hasHorizontalLabels
|
|
415
|
+
? { justifyContent: 'flex-start' }
|
|
416
|
+
: null,
|
|
417
|
+
],
|
|
418
|
+
options.tabBarItemStyle,
|
|
419
|
+
]}
|
|
370
420
|
/>
|
|
371
421
|
</NavigationRouteContext.Provider>
|
|
372
422
|
</NavigationContext.Provider>
|
|
@@ -378,15 +428,40 @@ export function BottomTabBar({
|
|
|
378
428
|
}
|
|
379
429
|
|
|
380
430
|
const styles = StyleSheet.create({
|
|
381
|
-
|
|
431
|
+
left: {
|
|
432
|
+
top: 0,
|
|
433
|
+
bottom: 0,
|
|
434
|
+
left: 0,
|
|
435
|
+
borderRightWidth: StyleSheet.hairlineWidth,
|
|
436
|
+
},
|
|
437
|
+
right: {
|
|
438
|
+
top: 0,
|
|
439
|
+
bottom: 0,
|
|
440
|
+
right: 0,
|
|
441
|
+
borderLeftWidth: StyleSheet.hairlineWidth,
|
|
442
|
+
},
|
|
443
|
+
bottom: {
|
|
382
444
|
left: 0,
|
|
383
445
|
right: 0,
|
|
384
446
|
bottom: 0,
|
|
385
447
|
borderTopWidth: StyleSheet.hairlineWidth,
|
|
386
448
|
elevation: 8,
|
|
387
449
|
},
|
|
388
|
-
|
|
450
|
+
bottomContent: {
|
|
389
451
|
flex: 1,
|
|
390
452
|
flexDirection: 'row',
|
|
391
453
|
},
|
|
454
|
+
sideContent: {
|
|
455
|
+
flex: 1,
|
|
456
|
+
flexDirection: 'column',
|
|
457
|
+
padding: SPACING,
|
|
458
|
+
},
|
|
459
|
+
bottomItem: {
|
|
460
|
+
flex: 1,
|
|
461
|
+
},
|
|
462
|
+
sideItem: {
|
|
463
|
+
margin: SPACING,
|
|
464
|
+
padding: SPACING * 2,
|
|
465
|
+
borderRadius: 4,
|
|
466
|
+
},
|
|
392
467
|
});
|
|
@@ -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',
|
|
@@ -151,12 +151,22 @@ export function BottomTabView(props: Props) {
|
|
|
151
151
|
hasAnimation(descriptors[route.key].options)
|
|
152
152
|
);
|
|
153
153
|
|
|
154
|
+
const { tabBarPosition = 'bottom' } = descriptors[focusedRouteKey].options;
|
|
155
|
+
|
|
154
156
|
return (
|
|
155
|
-
<SafeAreaProviderCompat
|
|
157
|
+
<SafeAreaProviderCompat
|
|
158
|
+
style={
|
|
159
|
+
tabBarPosition === 'left'
|
|
160
|
+
? styles.left
|
|
161
|
+
: tabBarPosition === 'right'
|
|
162
|
+
? styles.right
|
|
163
|
+
: null
|
|
164
|
+
}
|
|
165
|
+
>
|
|
156
166
|
<MaybeScreenContainer
|
|
157
167
|
enabled={detachInactiveScreens}
|
|
158
168
|
hasTwoStates={hasTwoStates}
|
|
159
|
-
style={styles.
|
|
169
|
+
style={styles.screens}
|
|
160
170
|
>
|
|
161
171
|
{routes.map((route, index) => {
|
|
162
172
|
const descriptor = descriptors[route.key];
|
|
@@ -218,7 +228,9 @@ export function BottomTabView(props: Props) {
|
|
|
218
228
|
enabled={detachInactiveScreens}
|
|
219
229
|
freezeOnBlur={freezeOnBlur}
|
|
220
230
|
>
|
|
221
|
-
<BottomTabBarHeightContext.Provider
|
|
231
|
+
<BottomTabBarHeightContext.Provider
|
|
232
|
+
value={tabBarPosition === 'bottom' ? tabBarHeight : 0}
|
|
233
|
+
>
|
|
222
234
|
<Screen
|
|
223
235
|
focused={isFocused}
|
|
224
236
|
route={descriptor.route}
|
|
@@ -250,7 +262,13 @@ export function BottomTabView(props: Props) {
|
|
|
250
262
|
}
|
|
251
263
|
|
|
252
264
|
const styles = StyleSheet.create({
|
|
253
|
-
|
|
265
|
+
left: {
|
|
266
|
+
flexDirection: 'row-reverse',
|
|
267
|
+
},
|
|
268
|
+
right: {
|
|
269
|
+
flexDirection: 'row',
|
|
270
|
+
},
|
|
271
|
+
screens: {
|
|
254
272
|
flex: 1,
|
|
255
273
|
overflow: 'hidden',
|
|
256
274
|
},
|
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
|
});
|