@momo-kits/foundation 0.112.1-beta.8 → 0.112.1-doc.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/Application/BottomSheet.tsx +47 -30
- package/Application/BottomTab/index.tsx +72 -58
- package/Application/Components/HeaderTitle.tsx +2 -2
- package/Application/NavigationContainer.tsx +166 -100
- package/Application/StackScreen.tsx +112 -61
- package/Application/index.ts +4 -2
- package/Application/types.ts +5 -0
- package/Application/utils.tsx +4 -3
- package/Button/index.tsx +11 -1
- package/Consts/colors+spacing+radius.ts +1 -31
- package/Icon/types.ts +1 -2
- package/Image/index.tsx +12 -2
- package/Layout/Screen.tsx +21 -24
- package/Layout/index.ts +2 -0
- package/Skeleton/index.tsx +42 -2
- package/Text/index.tsx +27 -21
- package/index.ts +0 -34
- package/package.json +13 -28
|
@@ -16,8 +16,16 @@ import {BottomSheetParams} from './types';
|
|
|
16
16
|
import {Colors, Radius, Spacing, Styles} from '../Consts';
|
|
17
17
|
import {Text} from '../Text';
|
|
18
18
|
import {Icon} from '../Icon';
|
|
19
|
-
import {useHeaderHeight} from '@react-navigation/
|
|
20
|
-
import Animated, {
|
|
19
|
+
import {useHeaderHeight} from '@react-navigation/elements';
|
|
20
|
+
import Animated, {
|
|
21
|
+
Easing,
|
|
22
|
+
Extrapolate,
|
|
23
|
+
useSharedValue,
|
|
24
|
+
useAnimatedStyle,
|
|
25
|
+
withTiming,
|
|
26
|
+
withSpring,
|
|
27
|
+
interpolate,
|
|
28
|
+
} from 'react-native-reanimated';
|
|
21
29
|
|
|
22
30
|
const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
23
31
|
const {theme, navigator} = useContext(ApplicationContext);
|
|
@@ -42,19 +50,25 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
42
50
|
const customEasingOpen = Easing.bezier(0.05, 0.7, 0.1, 1);
|
|
43
51
|
const customEasingClose = Easing.bezier(0.3, 0.0, 0.8, 0.15);
|
|
44
52
|
|
|
45
|
-
const translateY =
|
|
53
|
+
const translateY = useSharedValue(heightDevice);
|
|
46
54
|
|
|
47
|
-
const openAnimation =
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
const openAnimation = () => {
|
|
56
|
+
translateY.value = withTiming(0, {
|
|
57
|
+
duration: 350,
|
|
58
|
+
easing: customEasingOpen,
|
|
59
|
+
});
|
|
60
|
+
};
|
|
52
61
|
|
|
53
|
-
const closeAnimation =
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
62
|
+
const closeAnimation = (callback = () => {}) => {
|
|
63
|
+
translateY.value = withTiming(
|
|
64
|
+
heightDevice,
|
|
65
|
+
{
|
|
66
|
+
duration: 200,
|
|
67
|
+
easing: customEasingClose,
|
|
68
|
+
},
|
|
69
|
+
callback,
|
|
70
|
+
);
|
|
71
|
+
};
|
|
58
72
|
|
|
59
73
|
const panResponder = useRef(
|
|
60
74
|
PanResponder.create({
|
|
@@ -63,7 +77,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
63
77
|
draggable && gestureState.dy > 0,
|
|
64
78
|
onPanResponderMove: (_, gestureState) => {
|
|
65
79
|
if (gestureState.dy > 0) {
|
|
66
|
-
translateY.
|
|
80
|
+
translateY.value = gestureState.dy;
|
|
67
81
|
}
|
|
68
82
|
},
|
|
69
83
|
onPanResponderRelease: (_, gestureState) => {
|
|
@@ -71,18 +85,17 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
71
85
|
action.current = 'gesture';
|
|
72
86
|
onDismiss();
|
|
73
87
|
} else {
|
|
74
|
-
|
|
75
|
-
toValue: 0,
|
|
88
|
+
translateY.value = withSpring(0, {
|
|
76
89
|
damping: 20,
|
|
77
90
|
mass: 1,
|
|
78
91
|
stiffness: 100,
|
|
79
92
|
overshootClamping: false,
|
|
80
93
|
restSpeedThreshold: 0.001,
|
|
81
94
|
restDisplacementThreshold: 0.001,
|
|
82
|
-
})
|
|
95
|
+
});
|
|
83
96
|
}
|
|
84
97
|
},
|
|
85
|
-
})
|
|
98
|
+
}),
|
|
86
99
|
).current;
|
|
87
100
|
|
|
88
101
|
let Container: any = View;
|
|
@@ -98,8 +111,8 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
98
111
|
* emit dismiss event
|
|
99
112
|
*/
|
|
100
113
|
useEffect(() => {
|
|
101
|
-
translateY.
|
|
102
|
-
openAnimation
|
|
114
|
+
translateY.value = heightDevice;
|
|
115
|
+
openAnimation();
|
|
103
116
|
return () => {
|
|
104
117
|
props.route.params?.onDismiss?.(action.current);
|
|
105
118
|
};
|
|
@@ -112,7 +125,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
112
125
|
if (barrierDismissible && !force) {
|
|
113
126
|
return;
|
|
114
127
|
}
|
|
115
|
-
closeAnimation
|
|
128
|
+
closeAnimation(() => {
|
|
116
129
|
setImmediate(() => {
|
|
117
130
|
navigator?.pop();
|
|
118
131
|
callback?.();
|
|
@@ -176,6 +189,12 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
176
189
|
);
|
|
177
190
|
}, []);
|
|
178
191
|
|
|
192
|
+
const animatedStyle = useAnimatedStyle(() => {
|
|
193
|
+
return {
|
|
194
|
+
transform: [{translateY: translateY.value}],
|
|
195
|
+
};
|
|
196
|
+
});
|
|
197
|
+
|
|
179
198
|
return (
|
|
180
199
|
<Container
|
|
181
200
|
transparent
|
|
@@ -203,20 +222,18 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
203
222
|
style={[
|
|
204
223
|
styles.overlay,
|
|
205
224
|
{
|
|
206
|
-
opacity:
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
225
|
+
opacity: interpolate(
|
|
226
|
+
translateY.value,
|
|
227
|
+
[0, heightDevice],
|
|
228
|
+
[1, 0],
|
|
229
|
+
Extrapolate.CLAMP,
|
|
230
|
+
),
|
|
211
231
|
},
|
|
212
232
|
]}
|
|
213
233
|
/>
|
|
214
234
|
</Pressable>
|
|
215
235
|
|
|
216
|
-
<Animated.View
|
|
217
|
-
style={{
|
|
218
|
-
transform: [{translateY}],
|
|
219
|
-
}}>
|
|
236
|
+
<Animated.View style={animatedStyle}>
|
|
220
237
|
{renderHeader()}
|
|
221
238
|
<View style={{backgroundColor: backgroundColor}}>
|
|
222
239
|
<Screen
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
NavigationContainer,
|
|
4
|
+
NavigationIndependentTree,
|
|
5
|
+
useFocusEffect,
|
|
6
|
+
} from '@react-navigation/native';
|
|
3
7
|
import {createStackNavigator} from '@react-navigation/stack';
|
|
4
|
-
import React, {useContext, useEffect} from 'react';
|
|
8
|
+
import React, {useContext, useEffect, useRef} from 'react';
|
|
5
9
|
import {Animated, Platform, StatusBar} from 'react-native';
|
|
6
10
|
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
|
7
11
|
import {Colors} from '../../Consts';
|
|
@@ -11,7 +15,7 @@ import {ApplicationContext} from '../index';
|
|
|
11
15
|
import StackScreen from '../StackScreen';
|
|
12
16
|
import {BottomTabProps} from '../types';
|
|
13
17
|
import {getOptions, getStackOptions} from '../utils';
|
|
14
|
-
import BottomTabBar from './BottomTabBar';
|
|
18
|
+
// import BottomTabBar from './BottomTabBar';
|
|
15
19
|
|
|
16
20
|
const Tab = createBottomTabNavigator();
|
|
17
21
|
const Stack = createStackNavigator();
|
|
@@ -21,45 +25,42 @@ const TabScreen: React.FC<any> = ({route, navigation}) => {
|
|
|
21
25
|
|
|
22
26
|
const opacityValue = 0.3;
|
|
23
27
|
const scaleValue = 0.97;
|
|
24
|
-
const opacity = new Animated.Value(opacityValue);
|
|
25
|
-
const scale = new Animated.Value(scaleValue);
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
const opacity = useRef(new Animated.Value(opacityValue));
|
|
30
|
+
const scale = useRef(new Animated.Value(scaleValue));
|
|
31
|
+
|
|
32
|
+
useFocusEffect(
|
|
33
|
+
React.useCallback(() => {
|
|
29
34
|
Animated.parallel([
|
|
30
|
-
Animated.timing(opacity, {
|
|
35
|
+
Animated.timing(opacity.current, {
|
|
31
36
|
toValue: 1,
|
|
32
37
|
duration: 200,
|
|
33
38
|
useNativeDriver: true,
|
|
34
39
|
}),
|
|
35
|
-
Animated.timing(scale, {
|
|
40
|
+
Animated.timing(scale.current, {
|
|
36
41
|
toValue: 1,
|
|
37
42
|
duration: 200,
|
|
38
43
|
useNativeDriver: true,
|
|
39
44
|
}),
|
|
40
45
|
]).start();
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
unsubscribeFocus();
|
|
60
|
-
unsubscribeBlur();
|
|
61
|
-
};
|
|
62
|
-
}, [navigation]);
|
|
46
|
+
return () => {
|
|
47
|
+
if (navigation.getState().index !== route?.params.index) {
|
|
48
|
+
Animated.parallel([
|
|
49
|
+
Animated.timing(opacity.current, {
|
|
50
|
+
toValue: opacityValue,
|
|
51
|
+
duration: 200,
|
|
52
|
+
useNativeDriver: true,
|
|
53
|
+
}),
|
|
54
|
+
Animated.timing(scale.current, {
|
|
55
|
+
toValue: scaleValue,
|
|
56
|
+
duration: 200,
|
|
57
|
+
useNativeDriver: true,
|
|
58
|
+
}),
|
|
59
|
+
]).start();
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}, [navigation, route?.params.index]),
|
|
63
|
+
);
|
|
63
64
|
|
|
64
65
|
let stackOptions = {};
|
|
65
66
|
if (options) {
|
|
@@ -68,7 +69,12 @@ const TabScreen: React.FC<any> = ({route, navigation}) => {
|
|
|
68
69
|
|
|
69
70
|
if (nested) {
|
|
70
71
|
return (
|
|
71
|
-
<Animated.View
|
|
72
|
+
<Animated.View
|
|
73
|
+
style={{
|
|
74
|
+
flex: 1,
|
|
75
|
+
opacity: opacity.current,
|
|
76
|
+
transform: [{scale: scale.current}],
|
|
77
|
+
}}>
|
|
72
78
|
<Stack.Navigator>
|
|
73
79
|
<Stack.Screen
|
|
74
80
|
name="Stack"
|
|
@@ -86,21 +92,28 @@ const TabScreen: React.FC<any> = ({route, navigation}) => {
|
|
|
86
92
|
}
|
|
87
93
|
|
|
88
94
|
return (
|
|
89
|
-
<Animated.View
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
95
|
+
<Animated.View
|
|
96
|
+
style={{
|
|
97
|
+
flex: 1,
|
|
98
|
+
opacity: opacity.current,
|
|
99
|
+
transform: [{scale: scale.current}],
|
|
100
|
+
}}>
|
|
101
|
+
<NavigationIndependentTree>
|
|
102
|
+
<NavigationContainer>
|
|
103
|
+
<Stack.Navigator>
|
|
104
|
+
<Stack.Screen
|
|
105
|
+
name="Stack"
|
|
106
|
+
component={StackScreen}
|
|
107
|
+
initialParams={{
|
|
108
|
+
screen,
|
|
109
|
+
options: stackOptions,
|
|
110
|
+
initialParams,
|
|
111
|
+
}}
|
|
112
|
+
options={{...getStackOptions(), ...options}}
|
|
113
|
+
/>
|
|
114
|
+
</Stack.Navigator>
|
|
115
|
+
</NavigationContainer>
|
|
116
|
+
</NavigationIndependentTree>
|
|
104
117
|
</Animated.View>
|
|
105
118
|
);
|
|
106
119
|
};
|
|
@@ -113,7 +126,7 @@ const BottomTab: React.FC<BottomTabProps> = ({
|
|
|
113
126
|
initialRouteName,
|
|
114
127
|
floatingButton,
|
|
115
128
|
}) => {
|
|
116
|
-
const {theme} = useContext(ApplicationContext);
|
|
129
|
+
const {theme, navigator} = useContext(ApplicationContext);
|
|
117
130
|
const insets = useSafeAreaInsets();
|
|
118
131
|
|
|
119
132
|
useEffect(() => {
|
|
@@ -122,7 +135,7 @@ const BottomTab: React.FC<BottomTabProps> = ({
|
|
|
122
135
|
headerTransparent: true,
|
|
123
136
|
headerBackground: undefined,
|
|
124
137
|
});
|
|
125
|
-
}, []);
|
|
138
|
+
}, [navigation]);
|
|
126
139
|
|
|
127
140
|
const handler: {
|
|
128
141
|
tabPress?: (e: any) => void;
|
|
@@ -131,6 +144,7 @@ const BottomTab: React.FC<BottomTabProps> = ({
|
|
|
131
144
|
state?: (e: any) => void;
|
|
132
145
|
} = {
|
|
133
146
|
tabPress: e => {
|
|
147
|
+
navigator?.maxApi?.triggerEventVibration?.('light');
|
|
134
148
|
listeners?.tabPress?.(e);
|
|
135
149
|
},
|
|
136
150
|
focus: e => {
|
|
@@ -146,13 +160,13 @@ const BottomTab: React.FC<BottomTabProps> = ({
|
|
|
146
160
|
<Tab.Navigator
|
|
147
161
|
initialRouteName={initialRouteName}
|
|
148
162
|
backBehavior={'firstRoute'}
|
|
149
|
-
tabBar={props => (
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
)}
|
|
163
|
+
// tabBar={props => (
|
|
164
|
+
// <BottomTabBar
|
|
165
|
+
// {...props}
|
|
166
|
+
// floatingButton={floatingButton}
|
|
167
|
+
// inactiveTintColor={theme.colors.text.hint}
|
|
168
|
+
// />
|
|
169
|
+
// )}
|
|
156
170
|
tabBarOptions={{
|
|
157
171
|
style: {
|
|
158
172
|
height: 64 + Math.min(insets.bottom, 21),
|
|
@@ -163,7 +177,7 @@ const BottomTab: React.FC<BottomTabProps> = ({
|
|
|
163
177
|
},
|
|
164
178
|
inactiveTintColor: theme.colors.text.secondary,
|
|
165
179
|
}}>
|
|
166
|
-
{tabs.map(item => {
|
|
180
|
+
{tabs.map((item, index) => {
|
|
167
181
|
const isNum = !isNaN(parseInt(`${item?.badgeLabel}`));
|
|
168
182
|
const isDot = typeof item?.badgeLabel === 'string' && !item?.badgeLabel;
|
|
169
183
|
return (
|
|
@@ -171,7 +185,7 @@ const BottomTab: React.FC<BottomTabProps> = ({
|
|
|
171
185
|
key={item.name}
|
|
172
186
|
name={item.name}
|
|
173
187
|
component={TabScreen}
|
|
174
|
-
initialParams={{...item, nested}}
|
|
188
|
+
initialParams={{...item, nested, index}}
|
|
175
189
|
listeners={handler}
|
|
176
190
|
options={{
|
|
177
191
|
tabBarLabel: ({color, focused}) => {
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
TouchableOpacity,
|
|
7
7
|
View,
|
|
8
8
|
} from 'react-native';
|
|
9
|
-
import {ApplicationContext, MiniAppContext} from '../index';
|
|
9
|
+
import {ApplicationContext, MiniAppContext, setAutomationID} from '../index';
|
|
10
10
|
import {exportFontFamily, scaleSize, Text} from '../../Text';
|
|
11
11
|
import {Colors, Radius, Spacing, Styles} from '../../Consts';
|
|
12
12
|
import {TitleJourneyProps, TitleLocationProps, TitleUserProps} from '../types';
|
|
@@ -30,7 +30,7 @@ const HeaderTitle: React.FC<any> = props => {
|
|
|
30
30
|
<View pointerEvents={'none'} style={styles.headerTitleContainer}>
|
|
31
31
|
<Animated.Text
|
|
32
32
|
{...props}
|
|
33
|
-
|
|
33
|
+
{...setAutomationID('title_navigation_header')}
|
|
34
34
|
style={[
|
|
35
35
|
styles.title,
|
|
36
36
|
{
|