@momo-kits/foundation 0.162.2-test.8 → 0.162.3-test.1
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/Application/BottomSheet.tsx +5 -4
- package/Application/BottomTab/BottomTabBar.tsx +15 -15
- package/Application/BottomTab/index.tsx +32 -56
- package/Application/Components/BackgroundImageView.tsx +22 -6
- package/Application/Components/HeaderAnimated.tsx +29 -29
- package/Application/Components/HeaderBackground.tsx +20 -26
- package/Application/Components/HeaderExtendHeader.tsx +115 -94
- package/Application/Components/HeaderLeft.tsx +1 -1
- package/Application/Components/HeaderTitle.tsx +43 -10
- package/Application/Components/SearchHeader.tsx +13 -21
- package/Application/NavigationContainer.tsx +0 -6
- package/Application/types.ts +4 -3
- package/Application/utils.tsx +42 -2
- package/Badge/BadgeDotAnimation.tsx +53 -71
- package/Button/index.tsx +1 -4
- package/Input/Input.tsx +5 -1
- package/Input/InputOTP.tsx +38 -23
- package/Input/InputPhoneNumber.tsx +5 -1
- package/Layout/FloatingButton.tsx +64 -59
- package/Layout/Screen.tsx +67 -20
- package/Loader/ProgressBar.tsx +20 -18
- package/Pagination/Dot.tsx +2 -2
- package/Pagination/PaginationScroll.tsx +31 -27
- package/Skeleton/index.tsx +32 -24
- package/Text/utils.ts +7 -7
- package/package.json +1 -1
|
@@ -1,93 +1,75 @@
|
|
|
1
|
-
import React, { useEffect
|
|
2
|
-
import {
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import Animated, {
|
|
4
|
+
cancelAnimation,
|
|
5
|
+
useAnimatedStyle,
|
|
6
|
+
useSharedValue,
|
|
7
|
+
withRepeat,
|
|
8
|
+
withSequence,
|
|
9
|
+
withSpring,
|
|
10
|
+
withTiming,
|
|
11
|
+
} from 'react-native-reanimated';
|
|
3
12
|
import { BadgeDotProps } from './types';
|
|
4
13
|
import styles from './styles';
|
|
5
14
|
|
|
6
15
|
const DURATION = 500;
|
|
7
16
|
|
|
8
17
|
const BadgeDotAnimation = ({ size, style }: BadgeDotProps) => {
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const waveOpacityAnim = useRef(new Animated.Value(0)).current;
|
|
18
|
+
const scaleAnim = useSharedValue(1);
|
|
19
|
+
const waveScaleAnim = useSharedValue(1);
|
|
20
|
+
const waveOpacityAnim = useSharedValue(0);
|
|
13
21
|
|
|
14
22
|
const dotStyle =
|
|
15
23
|
size === 'small' ? styles.dotAnimationSmall : styles.dotAnimation;
|
|
16
24
|
const waveStyle = size === 'small' ? styles.waveSmall : styles.wave;
|
|
17
25
|
|
|
18
26
|
useEffect(() => {
|
|
19
|
-
|
|
20
|
-
const animation = Animated.loop(
|
|
21
|
-
Animated.parallel([
|
|
22
|
-
// Dot pulse animation
|
|
23
|
-
Animated.sequence([
|
|
24
|
-
Animated.spring(scaleAnim, {
|
|
25
|
-
toValue: 1, // Scale up slightly
|
|
26
|
-
friction: 5, // Controls the "bounciness" of the spring
|
|
27
|
-
tension: 30, // Controls the "stiffness" of the spring
|
|
28
|
-
useNativeDriver: true,
|
|
29
|
-
}),
|
|
30
|
-
Animated.spring(scaleAnim, {
|
|
31
|
-
toValue: 1.1,
|
|
32
|
-
friction: 5,
|
|
33
|
-
tension: 30,
|
|
34
|
-
useNativeDriver: true,
|
|
35
|
-
}),
|
|
36
|
-
]), // Wave animation
|
|
37
|
-
Animated.sequence([
|
|
38
|
-
Animated.timing(waveScaleAnim, {
|
|
39
|
-
toValue: 2.5,
|
|
40
|
-
duration: DURATION * 3,
|
|
41
|
-
useNativeDriver: true,
|
|
42
|
-
}),
|
|
43
|
-
Animated.timing(waveScaleAnim, {
|
|
44
|
-
toValue: 1, // Reset wave size
|
|
45
|
-
duration: 0,
|
|
46
|
-
useNativeDriver: true,
|
|
47
|
-
}),
|
|
48
|
-
]), // Wave opacity animation
|
|
49
|
-
Animated.sequence([
|
|
50
|
-
Animated.timing(waveOpacityAnim, {
|
|
51
|
-
toValue: 0.3, // Wave becomes visible
|
|
52
|
-
duration: DURATION * 2,
|
|
53
|
-
useNativeDriver: true,
|
|
54
|
-
}),
|
|
55
|
-
Animated.timing(waveOpacityAnim, {
|
|
56
|
-
toValue: 0, // Wave fades out
|
|
57
|
-
duration: DURATION,
|
|
58
|
-
useNativeDriver: true,
|
|
59
|
-
}),
|
|
60
|
-
]),
|
|
61
|
-
]),
|
|
62
|
-
);
|
|
63
|
-
animation.start();
|
|
27
|
+
const springCfg = { damping: 5, stiffness: 30, mass: 1 };
|
|
64
28
|
|
|
29
|
+
scaleAnim.value = withRepeat(
|
|
30
|
+
withSequence(
|
|
31
|
+
withSpring(1, springCfg),
|
|
32
|
+
withSpring(1.1, springCfg),
|
|
33
|
+
),
|
|
34
|
+
-1,
|
|
35
|
+
false,
|
|
36
|
+
);
|
|
37
|
+
waveScaleAnim.value = withRepeat(
|
|
38
|
+
withSequence(
|
|
39
|
+
withTiming(2.5, { duration: DURATION * 3 }),
|
|
40
|
+
withTiming(1, { duration: 0 }),
|
|
41
|
+
),
|
|
42
|
+
-1,
|
|
43
|
+
false,
|
|
44
|
+
);
|
|
45
|
+
waveOpacityAnim.value = withRepeat(
|
|
46
|
+
withSequence(
|
|
47
|
+
withTiming(0.3, { duration: DURATION * 2 }),
|
|
48
|
+
withTiming(0, { duration: DURATION }),
|
|
49
|
+
),
|
|
50
|
+
-1,
|
|
51
|
+
false,
|
|
52
|
+
);
|
|
65
53
|
return () => {
|
|
66
|
-
|
|
54
|
+
cancelAnimation(scaleAnim);
|
|
55
|
+
cancelAnimation(waveScaleAnim);
|
|
56
|
+
cancelAnimation(waveOpacityAnim);
|
|
67
57
|
};
|
|
68
58
|
}, [scaleAnim, waveOpacityAnim, waveScaleAnim]);
|
|
69
59
|
|
|
60
|
+
const waveAnimatedStyle = useAnimatedStyle(() => ({
|
|
61
|
+
transform: [{ scale: waveScaleAnim.value }],
|
|
62
|
+
opacity: waveOpacityAnim.value,
|
|
63
|
+
}));
|
|
64
|
+
|
|
65
|
+
const dotAnimatedStyle = useAnimatedStyle(() => ({
|
|
66
|
+
transform: [{ scale: scaleAnim.value }],
|
|
67
|
+
}));
|
|
68
|
+
|
|
70
69
|
return (
|
|
71
70
|
<View style={[styles.dotAnimationContainer, style]}>
|
|
72
|
-
{
|
|
73
|
-
<Animated.View
|
|
74
|
-
style={[
|
|
75
|
-
waveStyle,
|
|
76
|
-
{
|
|
77
|
-
transform: [{ scale: waveScaleAnim }],
|
|
78
|
-
opacity: waveOpacityAnim,
|
|
79
|
-
},
|
|
80
|
-
]}
|
|
81
|
-
/>
|
|
82
|
-
{/* Dot Animation */}
|
|
83
|
-
<Animated.View
|
|
84
|
-
style={[
|
|
85
|
-
dotStyle,
|
|
86
|
-
{
|
|
87
|
-
transform: [{ scale: scaleAnim }],
|
|
88
|
-
},
|
|
89
|
-
]}
|
|
90
|
-
/>
|
|
71
|
+
<Animated.View style={[waveStyle, waveAnimatedStyle]} />
|
|
72
|
+
<Animated.View style={[dotStyle, dotAnimatedStyle]} />
|
|
91
73
|
</View>
|
|
92
74
|
);
|
|
93
75
|
};
|
package/Button/index.tsx
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { FC, useContext, useRef } from 'react';
|
|
2
2
|
import {
|
|
3
|
-
Animated,
|
|
4
3
|
StyleSheet,
|
|
5
4
|
TouchableOpacity,
|
|
6
5
|
TouchableOpacityProps,
|
|
@@ -29,8 +28,6 @@ import Reanimated, {
|
|
|
29
28
|
withTiming,
|
|
30
29
|
} from 'react-native-reanimated';
|
|
31
30
|
|
|
32
|
-
const AnimationLinear = Animated.createAnimatedComponent(LinearGradient);
|
|
33
|
-
|
|
34
31
|
export interface ButtonProps extends TouchableOpacityProps {
|
|
35
32
|
/**
|
|
36
33
|
* Defines the visual style of the button.
|
|
@@ -359,7 +356,7 @@ const Button: FC<ButtonProps> = ({
|
|
|
359
356
|
{renderTitle()}
|
|
360
357
|
{renderIcon('right')}
|
|
361
358
|
{gradientPros && (
|
|
362
|
-
<
|
|
359
|
+
<LinearGradient {...gradientPros} style={styles.gradientView} />
|
|
363
360
|
)}
|
|
364
361
|
{gradientPros && <View style={styles.strokeView} />}
|
|
365
362
|
</Reanimated.View>
|
package/Input/Input.tsx
CHANGED
|
@@ -77,7 +77,8 @@ const Input = forwardRef(
|
|
|
77
77
|
const scaledFontSize = useScaleSize(14);
|
|
78
78
|
const scaleHeight = useScaleSize(size === 'small' ? 48 : 56);
|
|
79
79
|
const [focused, setFocused] = useState(false);
|
|
80
|
-
const
|
|
80
|
+
const [internalText, setInternalText] = useState(defaultValue || '');
|
|
81
|
+
const haveValue = value !== undefined ? !!value : !!internalText;
|
|
81
82
|
const inputRef = useRef<TextInput | null>(null);
|
|
82
83
|
const componentName = 'Input';
|
|
83
84
|
|
|
@@ -95,6 +96,9 @@ const Input = forwardRef(
|
|
|
95
96
|
};
|
|
96
97
|
|
|
97
98
|
const _onChangeText = (text: string) => {
|
|
99
|
+
if (value === undefined) {
|
|
100
|
+
setInternalText(text);
|
|
101
|
+
}
|
|
98
102
|
onChangeText?.(text);
|
|
99
103
|
};
|
|
100
104
|
|
package/Input/InputOTP.tsx
CHANGED
|
@@ -8,13 +8,22 @@ import React, {
|
|
|
8
8
|
useState,
|
|
9
9
|
} from 'react';
|
|
10
10
|
import {
|
|
11
|
-
Animated,
|
|
12
11
|
PixelRatio,
|
|
13
12
|
TextInput,
|
|
14
13
|
TextInputFocusEvent,
|
|
15
14
|
TouchableOpacity,
|
|
16
15
|
View,
|
|
17
16
|
} from 'react-native';
|
|
17
|
+
import Animated, {
|
|
18
|
+
cancelAnimation,
|
|
19
|
+
Easing,
|
|
20
|
+
useAnimatedStyle,
|
|
21
|
+
useSharedValue,
|
|
22
|
+
withDelay,
|
|
23
|
+
withRepeat,
|
|
24
|
+
withSequence,
|
|
25
|
+
withTiming,
|
|
26
|
+
} from 'react-native-reanimated';
|
|
18
27
|
import { useComponentId } from '../Application';
|
|
19
28
|
import { Spacing, Styles } from '../Consts';
|
|
20
29
|
import { useScaleSize, Text } from '../Text';
|
|
@@ -32,37 +41,43 @@ import {
|
|
|
32
41
|
const OTPCaret: FC<CaretProps> = ({ index, length }) => {
|
|
33
42
|
const DURATION = 300;
|
|
34
43
|
const { theme } = useContext(ApplicationContext);
|
|
35
|
-
const opacity =
|
|
44
|
+
const opacity = useSharedValue(0);
|
|
36
45
|
|
|
37
46
|
useEffect(() => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
).start();
|
|
47
|
+
opacity.value = withRepeat(
|
|
48
|
+
withSequence(
|
|
49
|
+
withTiming(1, { duration: DURATION, easing: Easing.linear }),
|
|
50
|
+
withDelay(
|
|
51
|
+
DURATION * 2,
|
|
52
|
+
withTiming(0, { duration: DURATION, easing: Easing.linear }),
|
|
53
|
+
),
|
|
54
|
+
),
|
|
55
|
+
-1,
|
|
56
|
+
false,
|
|
57
|
+
);
|
|
58
|
+
return () => {
|
|
59
|
+
cancelAnimation(opacity);
|
|
60
|
+
};
|
|
53
61
|
}, [opacity]);
|
|
62
|
+
|
|
63
|
+
const animatedStyle = useAnimatedStyle(() => ({
|
|
64
|
+
opacity: opacity.value,
|
|
65
|
+
}));
|
|
66
|
+
|
|
54
67
|
const spacingStyle = !isNaN(Number(length)) &&
|
|
55
68
|
index !== Number(length) - 1 && { marginRight: Spacing.L };
|
|
56
69
|
|
|
57
70
|
return (
|
|
58
71
|
<View style={[Styles.rowCenter, spacingStyle]}>
|
|
59
72
|
<Animated.View
|
|
60
|
-
style={
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
73
|
+
style={[
|
|
74
|
+
{
|
|
75
|
+
height: useScaleSize(12),
|
|
76
|
+
width: 1,
|
|
77
|
+
backgroundColor: theme.colors.primary,
|
|
78
|
+
},
|
|
79
|
+
animatedStyle,
|
|
80
|
+
]}
|
|
66
81
|
/>
|
|
67
82
|
<Text color={theme.colors.text.hint} typography={'body_default_regular'}>
|
|
68
83
|
-
|
|
@@ -69,7 +69,8 @@ const InputPhoneNumber = forwardRef(
|
|
|
69
69
|
const context = useContext<any>(MiniAppContext);
|
|
70
70
|
const scaleHeight = useScaleSize(size === 'small' ? 48 : 56);
|
|
71
71
|
const [focused, setFocused] = useState(false);
|
|
72
|
-
const
|
|
72
|
+
const [internalText, setInternalText] = useState(defaultValue || '');
|
|
73
|
+
const haveValue = value !== undefined ? !!value : !!internalText;
|
|
73
74
|
const inputRef = useRef<TextInput | null>(null);
|
|
74
75
|
const componentName = 'InputPhoneNumber';
|
|
75
76
|
|
|
@@ -86,6 +87,9 @@ const InputPhoneNumber = forwardRef(
|
|
|
86
87
|
};
|
|
87
88
|
|
|
88
89
|
const _onChangeText = (text: string) => {
|
|
90
|
+
if (value === undefined) {
|
|
91
|
+
setInternalText(text);
|
|
92
|
+
}
|
|
89
93
|
onChangeText?.(text);
|
|
90
94
|
};
|
|
91
95
|
|
|
@@ -1,20 +1,24 @@
|
|
|
1
|
+
import React, { useContext, useEffect, useState } from 'react';
|
|
1
2
|
import {
|
|
2
|
-
default as React,
|
|
3
|
-
useContext,
|
|
4
|
-
useEffect,
|
|
5
|
-
useRef,
|
|
6
|
-
useState,
|
|
7
|
-
} from 'react';
|
|
8
|
-
import {
|
|
9
|
-
Animated,
|
|
10
3
|
LayoutChangeEvent,
|
|
11
4
|
StyleSheet,
|
|
12
5
|
TouchableOpacity,
|
|
13
6
|
View,
|
|
14
7
|
} from 'react-native';
|
|
8
|
+
import Animated, {
|
|
9
|
+
useAnimatedReaction,
|
|
10
|
+
useAnimatedStyle,
|
|
11
|
+
useSharedValue,
|
|
12
|
+
withTiming,
|
|
13
|
+
runOnJS,
|
|
14
|
+
} from 'react-native-reanimated';
|
|
15
15
|
import { ApplicationContext } from '../Context';
|
|
16
16
|
import { Icon } from '../Icon';
|
|
17
17
|
import { useScaleSize } from '../Text';
|
|
18
|
+
import {
|
|
19
|
+
AnimatedCompatValue,
|
|
20
|
+
useNormalizedSharedValue,
|
|
21
|
+
} from '../Application/utils';
|
|
18
22
|
|
|
19
23
|
export interface FloatingButtonProps {
|
|
20
24
|
label?: string;
|
|
@@ -23,7 +27,7 @@ export interface FloatingButtonProps {
|
|
|
23
27
|
icon?: string;
|
|
24
28
|
iconColor?: string;
|
|
25
29
|
size?: 'small' | 'large';
|
|
26
|
-
animatedValue?:
|
|
30
|
+
animatedValue?: AnimatedCompatValue;
|
|
27
31
|
bottom?: number;
|
|
28
32
|
renderComponent?: () => React.ReactNode;
|
|
29
33
|
}
|
|
@@ -40,70 +44,71 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
|
|
|
40
44
|
bottom = 12,
|
|
41
45
|
}: FloatingButtonProps) => {
|
|
42
46
|
const { theme } = useContext(ApplicationContext);
|
|
47
|
+
const enabled = animatedValue != null;
|
|
48
|
+
const sharedValue = useNormalizedSharedValue(animatedValue);
|
|
43
49
|
const scaledFontSize = useScaleSize(16);
|
|
44
50
|
const scaledLineHeight = useScaleSize(22);
|
|
45
|
-
const maxWidth =
|
|
51
|
+
const maxWidth = useSharedValue(0);
|
|
46
52
|
const minWidth = size === 'small' ? 36 : 48;
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
const lastOffset =
|
|
50
|
-
const lastDirection =
|
|
51
|
-
const [showText, setShowText] =
|
|
53
|
+
const opacityAnimated = useSharedValue(0);
|
|
54
|
+
const widthAnimated = useSharedValue<number | null>(null);
|
|
55
|
+
const lastOffset = useSharedValue(0);
|
|
56
|
+
const lastDirection = useSharedValue<string | null>(null);
|
|
57
|
+
const [showText, setShowText] = useState(true);
|
|
52
58
|
|
|
53
59
|
useEffect(() => {
|
|
54
60
|
if (!label) return;
|
|
61
|
+
opacityAnimated.value = withTiming(1, { duration: 100 });
|
|
62
|
+
}, [label, opacityAnimated]);
|
|
55
63
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (lastDirection.current !== direction) {
|
|
67
|
-
lastDirection.current = direction;
|
|
64
|
+
useAnimatedReaction(
|
|
65
|
+
() => sharedValue.value,
|
|
66
|
+
(value) => {
|
|
67
|
+
'worklet';
|
|
68
|
+
if (!label || !enabled) return;
|
|
69
|
+
if (value !== lastOffset.value && value > 0) {
|
|
70
|
+
const direction = value > lastOffset.value ? 'down' : 'up';
|
|
71
|
+
lastOffset.value = value;
|
|
72
|
+
if (lastDirection.value !== direction) {
|
|
73
|
+
lastDirection.value = direction;
|
|
68
74
|
if (direction === 'down') {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
useNativeDriver: false,
|
|
78
|
-
}).start(() => setShowText(false));
|
|
75
|
+
opacityAnimated.value = withTiming(0, { duration: 100 });
|
|
76
|
+
widthAnimated.value = withTiming(
|
|
77
|
+
minWidth,
|
|
78
|
+
{ duration: 100 },
|
|
79
|
+
(finished) => {
|
|
80
|
+
if (finished) runOnJS(setShowText)(false);
|
|
81
|
+
},
|
|
82
|
+
);
|
|
79
83
|
} else {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
useNativeDriver: false,
|
|
89
|
-
}).start(() => setShowText(true));
|
|
84
|
+
opacityAnimated.value = withTiming(1, { duration: 100 });
|
|
85
|
+
widthAnimated.value = withTiming(
|
|
86
|
+
maxWidth.value,
|
|
87
|
+
{ duration: 100 },
|
|
88
|
+
(finished) => {
|
|
89
|
+
if (finished) runOnJS(setShowText)(true);
|
|
90
|
+
},
|
|
91
|
+
);
|
|
90
92
|
}
|
|
91
93
|
}
|
|
92
94
|
}
|
|
93
|
-
}
|
|
95
|
+
},
|
|
96
|
+
[label, enabled, minWidth],
|
|
97
|
+
);
|
|
94
98
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
const containerStyle = useAnimatedStyle(() => ({
|
|
100
|
+
width: widthAnimated.value ?? undefined,
|
|
101
|
+
}));
|
|
102
|
+
|
|
103
|
+
const labelStyle = useAnimatedStyle(() => ({
|
|
104
|
+
opacity: opacityAnimated.value,
|
|
105
|
+
}));
|
|
101
106
|
|
|
102
107
|
const handleLayout = (event: LayoutChangeEvent) => {
|
|
103
108
|
const layout = event.nativeEvent.layout;
|
|
104
|
-
if (widthAnimated) return;
|
|
105
|
-
maxWidth.
|
|
106
|
-
|
|
109
|
+
if (widthAnimated.value != null) return;
|
|
110
|
+
maxWidth.value = layout.width;
|
|
111
|
+
widthAnimated.value = layout.width;
|
|
107
112
|
};
|
|
108
113
|
|
|
109
114
|
if (renderComponent) {
|
|
@@ -132,11 +137,11 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
|
|
|
132
137
|
{
|
|
133
138
|
right: position === 'right' ? 12 : undefined,
|
|
134
139
|
alignSelf: position === 'center' ? 'center' : 'flex-end',
|
|
135
|
-
width: widthAnimated,
|
|
136
140
|
height: size === 'small' ? 36 : 48,
|
|
137
141
|
backgroundColor: theme.colors.primary,
|
|
138
142
|
bottom,
|
|
139
143
|
},
|
|
144
|
+
containerStyle,
|
|
140
145
|
]}
|
|
141
146
|
>
|
|
142
147
|
<TouchableOpacity
|
|
@@ -156,9 +161,9 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
|
|
|
156
161
|
{
|
|
157
162
|
fontSize: scaledFontSize,
|
|
158
163
|
lineHeight: scaledLineHeight,
|
|
159
|
-
opacity: opacityAnimated,
|
|
160
164
|
color: 'white',
|
|
161
165
|
},
|
|
166
|
+
labelStyle,
|
|
162
167
|
]}
|
|
163
168
|
numberOfLines={1}
|
|
164
169
|
>
|