@momo-kits/foundation 0.111.1-beta.2 → 0.111.1-beta.20
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 +57 -44
- package/Application/Components/HeaderBackground.tsx +5 -7
- package/Application/Components/HeaderExtendHeader.tsx +5 -4
- package/Application/Components/HeaderRight.tsx +27 -18
- package/Application/ModalScreen.tsx +12 -5
- package/Application/NavigationContainer.tsx +89 -76
- package/Application/Navigator.ts +9 -5
- package/Application/index.ts +2 -0
- package/Application/types.ts +0 -1
- package/Application/utils.tsx +16 -27
- package/Input/Input.tsx +0 -8
- package/Popup/PopupNotify.tsx +7 -2
- package/Popup/PopupPromotion.tsx +15 -2
- package/Popup/types.ts +10 -0
- package/Text/index.tsx +3 -3
- package/Text/utils.ts +3 -15
- package/package.json +5 -3
- package/publish.sh +1 -0
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import React, {useCallback, useContext, useEffect, useRef} from 'react';
|
|
2
2
|
import {
|
|
3
|
-
Animated,
|
|
4
3
|
Dimensions,
|
|
5
|
-
Easing,
|
|
6
4
|
KeyboardAvoidingView,
|
|
7
5
|
Modal,
|
|
8
6
|
PanResponder,
|
|
@@ -18,12 +16,17 @@ import {BottomSheetParams} from './types';
|
|
|
18
16
|
import {Colors, Radius, Spacing, Styles} from '../Consts';
|
|
19
17
|
import {Text} from '../Text';
|
|
20
18
|
import {Icon} from '../Icon';
|
|
19
|
+
import {useHeaderHeight} from '@react-navigation/stack';
|
|
20
|
+
import Animated, {Easing, Extrapolate} from 'react-native-reanimated';
|
|
21
21
|
|
|
22
22
|
const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
23
23
|
const {theme, navigator} = useContext(ApplicationContext);
|
|
24
24
|
const heightDevice = Dimensions.get('screen').height;
|
|
25
25
|
const action = useRef<undefined | string>();
|
|
26
26
|
const insets = useSafeAreaInsets();
|
|
27
|
+
const heightHeader = useHeaderHeight();
|
|
28
|
+
const keyboardOffset = heightHeader - Math.min(insets.bottom, 21);
|
|
29
|
+
|
|
27
30
|
const {
|
|
28
31
|
screen: Screen,
|
|
29
32
|
options,
|
|
@@ -36,37 +39,50 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
36
39
|
keyboardVerticalOffset,
|
|
37
40
|
}: BottomSheetParams = props.route.params;
|
|
38
41
|
|
|
39
|
-
const pan = useRef(
|
|
40
|
-
new Animated.ValueXY({
|
|
41
|
-
y: heightDevice,
|
|
42
|
-
x: 0,
|
|
43
|
-
})
|
|
44
|
-
).current;
|
|
45
|
-
|
|
46
42
|
const customEasingOpen = Easing.bezier(0.05, 0.7, 0.1, 1);
|
|
47
43
|
const customEasingClose = Easing.bezier(0.3, 0.0, 0.8, 0.15);
|
|
48
44
|
|
|
45
|
+
const translateY = useRef(new Animated.Value(heightDevice)).current;
|
|
46
|
+
|
|
47
|
+
const openAnimation = Animated.timing(translateY, {
|
|
48
|
+
toValue: 0,
|
|
49
|
+
duration: 350,
|
|
50
|
+
easing: customEasingOpen,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const closeAnimation = Animated.timing(translateY, {
|
|
54
|
+
toValue: heightDevice,
|
|
55
|
+
duration: 200,
|
|
56
|
+
easing: customEasingClose,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const animatedStyle = {
|
|
60
|
+
transform: [{translateY}],
|
|
61
|
+
};
|
|
62
|
+
|
|
49
63
|
const panResponder = useRef(
|
|
50
64
|
PanResponder.create({
|
|
51
65
|
onStartShouldSetPanResponder: () => draggable,
|
|
52
|
-
onMoveShouldSetPanResponder: (_, gestureState) =>
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
e,
|
|
59
|
-
gestureState
|
|
60
|
-
);
|
|
66
|
+
onMoveShouldSetPanResponder: (_, gestureState) =>
|
|
67
|
+
draggable && gestureState.dy > 0,
|
|
68
|
+
onPanResponderMove: (_, gestureState) => {
|
|
69
|
+
if (gestureState.dy > 0) {
|
|
70
|
+
translateY.setValue(gestureState.dy);
|
|
71
|
+
}
|
|
61
72
|
},
|
|
62
73
|
onPanResponderRelease: (_, gestureState) => {
|
|
63
74
|
if (gestureState.dy > 100) {
|
|
64
75
|
action.current = 'gesture';
|
|
65
76
|
onDismiss();
|
|
66
77
|
} else {
|
|
67
|
-
Animated.spring(
|
|
68
|
-
toValue:
|
|
69
|
-
|
|
78
|
+
Animated.spring(translateY, {
|
|
79
|
+
toValue: 0,
|
|
80
|
+
damping: 20,
|
|
81
|
+
mass: 1,
|
|
82
|
+
stiffness: 100,
|
|
83
|
+
overshootClamping: false,
|
|
84
|
+
restSpeedThreshold: 0.001,
|
|
85
|
+
restDisplacementThreshold: 0.001,
|
|
70
86
|
}).start();
|
|
71
87
|
}
|
|
72
88
|
},
|
|
@@ -86,13 +102,8 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
86
102
|
* emit dismiss event
|
|
87
103
|
*/
|
|
88
104
|
useEffect(() => {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
useNativeDriver: false,
|
|
92
|
-
easing: customEasingOpen,
|
|
93
|
-
duration: 350,
|
|
94
|
-
}).start();
|
|
95
|
-
|
|
105
|
+
translateY.setValue(heightDevice);
|
|
106
|
+
openAnimation.start();
|
|
96
107
|
return () => {
|
|
97
108
|
props.route.params?.onDismiss?.(action.current);
|
|
98
109
|
};
|
|
@@ -105,16 +116,12 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
105
116
|
if (barrierDismissible && !force) {
|
|
106
117
|
return;
|
|
107
118
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
easing: customEasingClose,
|
|
115
|
-
duration: 200,
|
|
116
|
-
}).start(() => {
|
|
117
|
-
navigator?.pop();
|
|
119
|
+
|
|
120
|
+
closeAnimation.start(() => {
|
|
121
|
+
setImmediate(() => {
|
|
122
|
+
navigator?.pop();
|
|
123
|
+
callback?.();
|
|
124
|
+
});
|
|
118
125
|
});
|
|
119
126
|
};
|
|
120
127
|
|
|
@@ -184,12 +191,13 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
184
191
|
style={StyleSheet.absoluteFillObject}>
|
|
185
192
|
<KeyboardAvoidingView
|
|
186
193
|
behavior={Platform.select({
|
|
187
|
-
ios: '
|
|
194
|
+
ios: 'position',
|
|
188
195
|
android: undefined,
|
|
189
196
|
})}
|
|
190
|
-
keyboardVerticalOffset={keyboardVerticalOffset ??
|
|
197
|
+
keyboardVerticalOffset={keyboardVerticalOffset ?? keyboardOffset}
|
|
191
198
|
enabled={useKeyboardAvoidingView}
|
|
192
|
-
|
|
199
|
+
contentContainerStyle={styles.container}
|
|
200
|
+
style={styles.container}>
|
|
193
201
|
<Pressable
|
|
194
202
|
style={StyleSheet.absoluteFillObject}
|
|
195
203
|
onPress={() => {
|
|
@@ -200,10 +208,10 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
200
208
|
style={[
|
|
201
209
|
styles.overlay,
|
|
202
210
|
{
|
|
203
|
-
opacity:
|
|
211
|
+
opacity: translateY.interpolate({
|
|
204
212
|
inputRange: [0, heightDevice],
|
|
205
213
|
outputRange: [1, 0],
|
|
206
|
-
extrapolate:
|
|
214
|
+
extrapolate: Extrapolate.CLAMP,
|
|
207
215
|
}),
|
|
208
216
|
},
|
|
209
217
|
]}
|
|
@@ -212,7 +220,8 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
212
220
|
|
|
213
221
|
<Animated.View
|
|
214
222
|
style={{
|
|
215
|
-
transform: pan.getTranslateTransform(),
|
|
223
|
+
// transform: pan.getTranslateTransform(),
|
|
224
|
+
...animatedStyle,
|
|
216
225
|
}}>
|
|
217
226
|
{renderHeader()}
|
|
218
227
|
<View style={{backgroundColor: backgroundColor}}>
|
|
@@ -232,6 +241,10 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
232
241
|
};
|
|
233
242
|
|
|
234
243
|
const styles = StyleSheet.create({
|
|
244
|
+
container: {
|
|
245
|
+
flex: 1,
|
|
246
|
+
justifyContent: 'flex-end',
|
|
247
|
+
},
|
|
235
248
|
overlay: {
|
|
236
249
|
flex: 1,
|
|
237
250
|
backgroundColor: 'rgba(0, 0, 0, 0.6)',
|
|
@@ -12,7 +12,6 @@ const LinearGradientAnimated = Animated.createAnimatedComponent(LinearGradient);
|
|
|
12
12
|
* header background for default
|
|
13
13
|
*/
|
|
14
14
|
const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
15
|
-
image,
|
|
16
15
|
animatedValue = new Animated.Value(0),
|
|
17
16
|
useGradient = true,
|
|
18
17
|
useShadowHeader = true,
|
|
@@ -20,13 +19,8 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
|
20
19
|
headerBackground,
|
|
21
20
|
}) => {
|
|
22
21
|
const {theme} = useContext(ApplicationContext);
|
|
23
|
-
|
|
24
22
|
const gradientColor = customGradientColor ?? theme.colors.gradient;
|
|
25
|
-
|
|
26
|
-
let headerImage = headerBackground ?? theme.assets?.headerBackground;
|
|
27
|
-
if (image === null) {
|
|
28
|
-
headerImage = undefined;
|
|
29
|
-
}
|
|
23
|
+
const headerImage = headerBackground ?? theme.assets?.headerBackground;
|
|
30
24
|
|
|
31
25
|
const opacityBackground = animatedValue?.interpolate({
|
|
32
26
|
inputRange: [0, 52],
|
|
@@ -39,6 +33,10 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
|
39
33
|
extrapolate: 'clamp',
|
|
40
34
|
});
|
|
41
35
|
|
|
36
|
+
if (Platform.OS === 'android' && headerImage) {
|
|
37
|
+
useShadowHeader = false;
|
|
38
|
+
}
|
|
39
|
+
|
|
42
40
|
return (
|
|
43
41
|
<View style={Styles.flex}>
|
|
44
42
|
<Animated.View
|
|
@@ -46,7 +46,6 @@ const HeaderExtendHeader: React.FC<{
|
|
|
46
46
|
const gradientColor = customGradientColor ?? theme.colors.gradient;
|
|
47
47
|
const headerBackground = customBackground ?? theme.assets?.headerBackground;
|
|
48
48
|
const leftPosition = inputSearchProps?.leftPosition || BACK_WIDTH + 20;
|
|
49
|
-
const isIos = Platform.OS === 'ios';
|
|
50
49
|
|
|
51
50
|
const opacityBackground = animatedValue?.interpolate({
|
|
52
51
|
inputRange: [0, 52],
|
|
@@ -89,15 +88,17 @@ const HeaderExtendHeader: React.FC<{
|
|
|
89
88
|
extrapolate: 'clamp',
|
|
90
89
|
});
|
|
91
90
|
|
|
91
|
+
if (Platform.OS === 'android' && headerBackground) {
|
|
92
|
+
useShadowHeader = false;
|
|
93
|
+
}
|
|
94
|
+
|
|
92
95
|
if (inputSearchProps) {
|
|
93
96
|
return (
|
|
94
97
|
<>
|
|
95
98
|
<Animated.View style={{height: height}} />
|
|
96
99
|
<Animated.View
|
|
97
100
|
style={[
|
|
98
|
-
|
|
99
|
-
? styles.shadowHeader
|
|
100
|
-
: styles.dividerHeader,
|
|
101
|
+
useShadowHeader ? styles.shadowHeader : styles.dividerHeader,
|
|
101
102
|
{
|
|
102
103
|
position: 'absolute',
|
|
103
104
|
width: '100%',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {useContext, useEffect, useState} from 'react';
|
|
1
|
+
import React, {useCallback, useContext, useEffect, useState} from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Platform,
|
|
4
4
|
StyleSheet,
|
|
@@ -90,14 +90,17 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
90
90
|
/**
|
|
91
91
|
* check app is favorite
|
|
92
92
|
*/
|
|
93
|
-
const checkAppIsFavorite = (
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
93
|
+
const checkAppIsFavorite = useCallback(
|
|
94
|
+
() =>
|
|
95
|
+
navigator?.maxApi?.dispatchFunction?.(
|
|
96
|
+
'isFavoriteApp',
|
|
97
|
+
{code: context?.code},
|
|
98
|
+
(result: boolean) => {
|
|
99
|
+
setIsFavorite(result);
|
|
100
|
+
}
|
|
101
|
+
),
|
|
102
|
+
[context]
|
|
103
|
+
);
|
|
101
104
|
|
|
102
105
|
/**
|
|
103
106
|
* close navigation container
|
|
@@ -153,6 +156,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
153
156
|
item: {
|
|
154
157
|
key: 'onFavorite',
|
|
155
158
|
},
|
|
159
|
+
context,
|
|
156
160
|
},
|
|
157
161
|
({success}: {success: boolean}) => {
|
|
158
162
|
if (success) {
|
|
@@ -217,17 +221,22 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
217
221
|
screenName: currentRoute?.params?.screen?.name ?? currentRoute?.name,
|
|
218
222
|
});
|
|
219
223
|
|
|
220
|
-
navigator?.maxApi?.dispatchFunction?.(
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
pressedTool?.
|
|
227
|
-
|
|
224
|
+
navigator?.maxApi?.dispatchFunction?.(
|
|
225
|
+
'showTools',
|
|
226
|
+
tools,
|
|
227
|
+
context,
|
|
228
|
+
(key: string) => {
|
|
229
|
+
for (const group of tools) {
|
|
230
|
+
const pressedTool = group?.items?.find?.(
|
|
231
|
+
(tool: Tool) => tool?.key === key
|
|
232
|
+
);
|
|
233
|
+
if (pressedTool) {
|
|
234
|
+
pressedTool?.onPress();
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
228
237
|
}
|
|
229
238
|
}
|
|
230
|
-
|
|
239
|
+
);
|
|
231
240
|
};
|
|
232
241
|
|
|
233
242
|
let iconShortcut = isFavorite ? 'pin_star_checked' : 'pin_star';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, {useContext, useEffect, useRef} from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Animated,
|
|
4
|
+
Easing,
|
|
4
5
|
KeyboardAvoidingView,
|
|
5
6
|
Platform,
|
|
6
7
|
Pressable,
|
|
@@ -38,11 +39,13 @@ const Modal: React.FC<ModalParams> = props => {
|
|
|
38
39
|
Animated.parallel([
|
|
39
40
|
Animated.timing(opacity, {
|
|
40
41
|
toValue: 1,
|
|
41
|
-
duration:
|
|
42
|
+
duration: 250,
|
|
42
43
|
useNativeDriver: true,
|
|
43
44
|
}),
|
|
44
|
-
Animated.
|
|
45
|
+
Animated.timing(scale, {
|
|
45
46
|
toValue: 1,
|
|
47
|
+
duration: 250,
|
|
48
|
+
easing: Easing.bezier(0.2, 0.0, 0, 1.0),
|
|
46
49
|
useNativeDriver: true,
|
|
47
50
|
}),
|
|
48
51
|
]).start();
|
|
@@ -52,7 +55,7 @@ const Modal: React.FC<ModalParams> = props => {
|
|
|
52
55
|
};
|
|
53
56
|
}, [opacity, scale]);
|
|
54
57
|
|
|
55
|
-
const onDismiss = () => {
|
|
58
|
+
const onDismiss = (callback = () => {}) => {
|
|
56
59
|
if (barrierDismissible) {
|
|
57
60
|
return;
|
|
58
61
|
}
|
|
@@ -65,9 +68,11 @@ const Modal: React.FC<ModalParams> = props => {
|
|
|
65
68
|
Animated.timing(scale, {
|
|
66
69
|
toValue: 0.8,
|
|
67
70
|
duration: 200,
|
|
71
|
+
easing: Easing.linear,
|
|
68
72
|
useNativeDriver: true,
|
|
69
73
|
}),
|
|
70
74
|
]).start(() => {
|
|
75
|
+
callback();
|
|
71
76
|
navigator?.pop();
|
|
72
77
|
});
|
|
73
78
|
};
|
|
@@ -76,7 +81,9 @@ const Modal: React.FC<ModalParams> = props => {
|
|
|
76
81
|
<KeyboardAvoidingView
|
|
77
82
|
style={Styles.flexCenter}
|
|
78
83
|
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}>
|
|
79
|
-
<Pressable
|
|
84
|
+
<Pressable
|
|
85
|
+
style={StyleSheet.absoluteFillObject}
|
|
86
|
+
onPress={() => onDismiss()}>
|
|
80
87
|
<Animated.View style={[styles.overlayContent, {opacity}]} />
|
|
81
88
|
</Pressable>
|
|
82
89
|
<Animated.View
|
|
@@ -87,7 +94,7 @@ const Modal: React.FC<ModalParams> = props => {
|
|
|
87
94
|
},
|
|
88
95
|
modalStyle,
|
|
89
96
|
]}>
|
|
90
|
-
<Component {...params} />
|
|
97
|
+
<Component {...params} onRequestClose={onDismiss} />
|
|
91
98
|
</Animated.View>
|
|
92
99
|
</KeyboardAvoidingView>
|
|
93
100
|
);
|
|
@@ -34,6 +34,7 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
|
|
|
34
34
|
const isReady = useRef(false);
|
|
35
35
|
const navigator = useRef(new Navigator(navigationRef, isReady));
|
|
36
36
|
const [showGrid, setShowGrid] = useState(false);
|
|
37
|
+
const [currentContext, setCurrentContext] = useState({});
|
|
37
38
|
|
|
38
39
|
let config: any = null;
|
|
39
40
|
try {
|
|
@@ -107,88 +108,100 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
|
|
|
107
108
|
const headerBackground = config?.headerBar || theme.assets?.headerBackground;
|
|
108
109
|
const headerGradient = config?.headerGradient || theme.colors?.gradient;
|
|
109
110
|
|
|
111
|
+
navigator.current.setCurrentContext = setCurrentContext;
|
|
112
|
+
|
|
110
113
|
return (
|
|
111
114
|
<SafeAreaProvider>
|
|
112
|
-
<
|
|
115
|
+
<MiniAppContext.Provider
|
|
113
116
|
value={{
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
...theme,
|
|
117
|
-
colors: {
|
|
118
|
-
...theme.colors,
|
|
119
|
-
gradient: headerGradient,
|
|
120
|
-
},
|
|
121
|
-
assets: {
|
|
122
|
-
...theme.assets,
|
|
123
|
-
headerBackground,
|
|
124
|
-
},
|
|
125
|
-
},
|
|
126
|
-
showGrid,
|
|
127
|
-
translate,
|
|
117
|
+
...context,
|
|
118
|
+
...currentContext,
|
|
128
119
|
}}>
|
|
129
|
-
<
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
...theme
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
120
|
+
<ApplicationContext.Provider
|
|
121
|
+
value={{
|
|
122
|
+
navigator: navigator.current,
|
|
123
|
+
theme: {
|
|
124
|
+
...theme,
|
|
125
|
+
colors: {
|
|
126
|
+
...theme.colors,
|
|
127
|
+
gradient: headerGradient,
|
|
128
|
+
},
|
|
129
|
+
assets: {
|
|
130
|
+
...theme.assets,
|
|
131
|
+
headerBackground,
|
|
132
|
+
},
|
|
139
133
|
},
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
134
|
+
showGrid,
|
|
135
|
+
translate,
|
|
136
|
+
}}>
|
|
137
|
+
<ReactNavigationContainer
|
|
138
|
+
theme={{
|
|
139
|
+
...theme,
|
|
140
|
+
colors: {
|
|
141
|
+
...theme.colors,
|
|
142
|
+
background: theme.colors.background.default,
|
|
143
|
+
card: theme.colors.background.surface,
|
|
144
|
+
text: theme.colors.text.default,
|
|
145
|
+
border: theme.colors.border.default,
|
|
146
|
+
notification: theme.colors.error.primary,
|
|
147
|
+
},
|
|
148
|
+
}}
|
|
149
|
+
ref={navigationRef}
|
|
150
|
+
onReady={() => {
|
|
151
|
+
isReady.current = true;
|
|
152
|
+
routes.current = navigationRef.current?.getRootState?.()?.routes;
|
|
153
|
+
maxApi?.getDataObserver('CURRENT_SCREEN', (data: any) => {
|
|
154
|
+
onScreenNavigated(data?.screenName, screen?.name, 'push');
|
|
155
|
+
maxApi?.setObserver('CURRENT_SCREEN', {
|
|
156
|
+
screenName: screen?.name,
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
}}
|
|
160
|
+
onStateChange={state => {
|
|
161
|
+
const lastedRoute: any =
|
|
162
|
+
state?.routes?.[state?.routes?.length - 1];
|
|
163
|
+
const oldRoute: any =
|
|
164
|
+
routes.current?.[routes.current?.length - 1];
|
|
165
|
+
const lasted = lastedRoute?.params?.screen;
|
|
166
|
+
const previous = oldRoute?.params?.screen;
|
|
167
|
+
const preScreenName = previous?.name ?? previous?.type?.name;
|
|
168
|
+
const screenName = lasted?.name ?? lasted?.type?.name;
|
|
157
169
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
170
|
+
let action = 'push';
|
|
171
|
+
if (routes.current?.length > (state?.routes?.length ?? 0)) {
|
|
172
|
+
action = 'back';
|
|
173
|
+
}
|
|
174
|
+
onScreenNavigated(preScreenName, screenName, action);
|
|
175
|
+
maxApi?.setObserver('CURRENT_SCREEN', {screenName});
|
|
176
|
+
routes.current = state?.routes;
|
|
177
|
+
}}
|
|
178
|
+
independent={true}>
|
|
179
|
+
<Stack.Navigator initialRouteName="Stack" headerMode="screen">
|
|
180
|
+
<Stack.Screen
|
|
181
|
+
name="Stack"
|
|
182
|
+
component={StackScreen}
|
|
183
|
+
initialParams={{screen, initialParams}}
|
|
184
|
+
options={{
|
|
185
|
+
...getStackOptions(),
|
|
186
|
+
...(options as StackNavigationOptions),
|
|
187
|
+
}}
|
|
188
|
+
/>
|
|
189
|
+
<Stack.Screen
|
|
190
|
+
name="Dialog"
|
|
191
|
+
component={StackScreen}
|
|
192
|
+
options={getDialogOptions()}
|
|
193
|
+
initialParams={{screen}}
|
|
194
|
+
/>
|
|
195
|
+
<Stack.Screen
|
|
196
|
+
name="Modal"
|
|
197
|
+
component={ModalScreen}
|
|
198
|
+
options={getModalOptions()}
|
|
199
|
+
initialParams={{screen}}
|
|
200
|
+
/>
|
|
201
|
+
</Stack.Navigator>
|
|
202
|
+
</ReactNavigationContainer>
|
|
203
|
+
</ApplicationContext.Provider>
|
|
204
|
+
</MiniAppContext.Provider>
|
|
192
205
|
</SafeAreaProvider>
|
|
193
206
|
);
|
|
194
207
|
};
|
package/Application/Navigator.ts
CHANGED
|
@@ -6,7 +6,6 @@ class Navigator {
|
|
|
6
6
|
isReady?: any;
|
|
7
7
|
maxApi?: any;
|
|
8
8
|
dismissData?: any;
|
|
9
|
-
toolkitCallback?: (key: string) => void;
|
|
10
9
|
|
|
11
10
|
constructor(navigation: any, isReady: any) {
|
|
12
11
|
this.ref = navigation;
|
|
@@ -148,11 +147,16 @@ class Navigator {
|
|
|
148
147
|
};
|
|
149
148
|
|
|
150
149
|
/**
|
|
151
|
-
* set
|
|
152
|
-
* @param
|
|
150
|
+
* set app context using for features of kit
|
|
151
|
+
* @param context
|
|
153
152
|
*/
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
setCurrentContext = (context: {
|
|
154
|
+
code?: string;
|
|
155
|
+
name?: {vi: string; en: string};
|
|
156
|
+
description?: {vi: string; en: string};
|
|
157
|
+
icon?: string;
|
|
158
|
+
}) => {
|
|
159
|
+
console.log(context);
|
|
156
160
|
};
|
|
157
161
|
}
|
|
158
162
|
|
package/Application/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
HeaderTitle,
|
|
12
12
|
NavigationButton,
|
|
13
13
|
} from './Components';
|
|
14
|
+
import {setAutomationID} from './utils';
|
|
14
15
|
|
|
15
16
|
const Context = createContext({});
|
|
16
17
|
const ApplicationContext = createContext(defaultContext);
|
|
@@ -32,4 +33,5 @@ export {
|
|
|
32
33
|
Screen,
|
|
33
34
|
BottomTab,
|
|
34
35
|
HeaderAnimated,
|
|
36
|
+
setAutomationID,
|
|
35
37
|
};
|
package/Application/types.ts
CHANGED
package/Application/utils.tsx
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from './Components';
|
|
13
13
|
import {HeaderTitleProps, NavigationOptions} from './types';
|
|
14
14
|
import {Colors} from '../Consts';
|
|
15
|
-
import {Animated} from 'react-native';
|
|
15
|
+
import {Animated, Platform} from 'react-native';
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* default options for stack screen
|
|
@@ -26,32 +26,6 @@ const getStackOptions = (): StackNavigationOptions => {
|
|
|
26
26
|
headerRight: (props: any) => <HeaderRight {...props} />,
|
|
27
27
|
headerTintColor: Colors.black_17,
|
|
28
28
|
gestureEnabled: false,
|
|
29
|
-
cardStyleInterpolator: ({current: {progress}, layouts}) => ({
|
|
30
|
-
cardStyle: {
|
|
31
|
-
transform: [
|
|
32
|
-
{
|
|
33
|
-
translateX: progress.interpolate({
|
|
34
|
-
inputRange: [0, 1],
|
|
35
|
-
outputRange: [layouts.screen.width, 0],
|
|
36
|
-
}),
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
|
-
},
|
|
40
|
-
}),
|
|
41
|
-
transitionSpec: {
|
|
42
|
-
open: {
|
|
43
|
-
animation: 'timing',
|
|
44
|
-
config: {
|
|
45
|
-
duration: 300,
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
close: {
|
|
49
|
-
animation: 'timing',
|
|
50
|
-
config: {
|
|
51
|
-
duration: 300,
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
29
|
};
|
|
56
30
|
};
|
|
57
31
|
|
|
@@ -180,10 +154,25 @@ const exportHeaderTitle = (
|
|
|
180
154
|
return {};
|
|
181
155
|
};
|
|
182
156
|
|
|
157
|
+
const setAutomationID = (accessibilityLabel = '') => {
|
|
158
|
+
if (Platform.OS === 'ios') {
|
|
159
|
+
return {
|
|
160
|
+
accessible: true,
|
|
161
|
+
testID: accessibilityLabel,
|
|
162
|
+
accessibilityLabel: undefined,
|
|
163
|
+
};
|
|
164
|
+
} else {
|
|
165
|
+
return {
|
|
166
|
+
accessibilityLabel,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
183
171
|
export {
|
|
184
172
|
getStackOptions,
|
|
185
173
|
getDialogOptions,
|
|
186
174
|
getModalOptions,
|
|
187
175
|
getOptions,
|
|
188
176
|
exportHeaderTitle,
|
|
177
|
+
setAutomationID,
|
|
189
178
|
};
|
package/Input/Input.tsx
CHANGED
|
@@ -8,7 +8,6 @@ import React, {
|
|
|
8
8
|
} from 'react';
|
|
9
9
|
import {
|
|
10
10
|
NativeSyntheticEvent,
|
|
11
|
-
Platform,
|
|
12
11
|
TextInput,
|
|
13
12
|
TextInputFocusEventData,
|
|
14
13
|
TouchableOpacity,
|
|
@@ -176,13 +175,6 @@ const Input = forwardRef(
|
|
|
176
175
|
iconTintColor = disabledColor;
|
|
177
176
|
}
|
|
178
177
|
|
|
179
|
-
if (secureTextEntry) {
|
|
180
|
-
keyboardType = Platform.select({
|
|
181
|
-
ios: 'ascii-capable',
|
|
182
|
-
android: 'visible-password',
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
|
|
186
178
|
return (
|
|
187
179
|
<View
|
|
188
180
|
style={[
|
package/Popup/PopupNotify.tsx
CHANGED
|
@@ -24,6 +24,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
24
24
|
primary,
|
|
25
25
|
buttonDirection = 'row',
|
|
26
26
|
onIconClose,
|
|
27
|
+
onRequestClose,
|
|
27
28
|
}) => {
|
|
28
29
|
const context = useContext<any>(MiniAppContext);
|
|
29
30
|
const {theme, navigator, translate} = useContext(ApplicationContext);
|
|
@@ -73,8 +74,12 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
73
74
|
* @param callback
|
|
74
75
|
*/
|
|
75
76
|
const onAction = (callback?: () => void) => {
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
if (typeof onRequestClose === 'function') {
|
|
78
|
+
onRequestClose?.(callback);
|
|
79
|
+
} else {
|
|
80
|
+
navigator?.pop();
|
|
81
|
+
callback?.();
|
|
82
|
+
}
|
|
78
83
|
};
|
|
79
84
|
|
|
80
85
|
/**
|
package/Popup/PopupPromotion.tsx
CHANGED
|
@@ -10,6 +10,7 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({
|
|
|
10
10
|
id,
|
|
11
11
|
image,
|
|
12
12
|
onIconClose,
|
|
13
|
+
onRequestClose,
|
|
13
14
|
}) => {
|
|
14
15
|
const context = useContext<any>(MiniAppContext);
|
|
15
16
|
const {theme, navigator} = useContext(ApplicationContext);
|
|
@@ -45,6 +46,19 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({
|
|
|
45
46
|
};
|
|
46
47
|
}, []);
|
|
47
48
|
|
|
49
|
+
/**
|
|
50
|
+
* on action popup
|
|
51
|
+
* @param callback
|
|
52
|
+
*/
|
|
53
|
+
const onAction = (callback?: () => void) => {
|
|
54
|
+
if (typeof onRequestClose === 'function') {
|
|
55
|
+
onRequestClose?.(callback);
|
|
56
|
+
} else {
|
|
57
|
+
navigator?.pop();
|
|
58
|
+
callback?.();
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
48
62
|
/**
|
|
49
63
|
* build close action
|
|
50
64
|
*/
|
|
@@ -55,8 +69,7 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({
|
|
|
55
69
|
accessibilityLabel={'ic_popup_close'}
|
|
56
70
|
onPress={() => {
|
|
57
71
|
closeAction.current = 'icon_close';
|
|
58
|
-
|
|
59
|
-
onIconClose?.();
|
|
72
|
+
onAction(onIconClose);
|
|
60
73
|
}}
|
|
61
74
|
style={styles.iconButton}>
|
|
62
75
|
<View
|
package/Popup/types.ts
CHANGED
|
@@ -47,6 +47,11 @@ export type PopupNotifyProps = {
|
|
|
47
47
|
* `onIconClose`: Optional. A callback function that is called when the close icon in the PopupNotify component is pressed.
|
|
48
48
|
*/
|
|
49
49
|
onIconClose?: () => void;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* onRequestClose on request close for modal
|
|
53
|
+
*/
|
|
54
|
+
onRequestClose?: (callback?: () => void) => void;
|
|
50
55
|
};
|
|
51
56
|
|
|
52
57
|
export type PopupPromotionProps = {
|
|
@@ -64,6 +69,11 @@ export type PopupPromotionProps = {
|
|
|
64
69
|
* `onClose`: Optional. A callback function that is called when the PopupPromotion component is closed.
|
|
65
70
|
*/
|
|
66
71
|
onIconClose?: () => void;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* onRequestClose on request close for modal
|
|
75
|
+
*/
|
|
76
|
+
onRequestClose?: (callback?: () => void) => void;
|
|
67
77
|
};
|
|
68
78
|
|
|
69
79
|
type PopupAction = {
|
package/Text/index.tsx
CHANGED
|
@@ -2,8 +2,8 @@ import React, {useContext} from 'react';
|
|
|
2
2
|
import {Text as RNText, TextProps as RNTextProps} from 'react-native';
|
|
3
3
|
import styles from './styles';
|
|
4
4
|
import {Typography, TypographyWeight} from './types';
|
|
5
|
-
import {ApplicationContext} from '../Application';
|
|
6
|
-
import {
|
|
5
|
+
import {ApplicationContext, setAutomationID} from '../Application';
|
|
6
|
+
import {scaleSize} from './utils';
|
|
7
7
|
|
|
8
8
|
const SFProText: TypographyWeight = {
|
|
9
9
|
100: 'Thin',
|
|
@@ -155,7 +155,7 @@ const Text: React.FC<TextProps> = ({
|
|
|
155
155
|
return (
|
|
156
156
|
<RNText
|
|
157
157
|
{...rest}
|
|
158
|
-
{...
|
|
158
|
+
{...setAutomationID(rest.accessibilityLabel)}
|
|
159
159
|
style={[
|
|
160
160
|
style,
|
|
161
161
|
textStyle,
|
package/Text/utils.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Dimensions
|
|
1
|
+
import {Dimensions} from 'react-native';
|
|
2
2
|
|
|
3
3
|
const deviceWidth = Dimensions.get('window').width;
|
|
4
4
|
const DEFAULT_SCREEN_SIZE = 375;
|
|
@@ -11,17 +11,5 @@ const scaleSize = (size: number) => {
|
|
|
11
11
|
|
|
12
12
|
return size;
|
|
13
13
|
};
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return {
|
|
17
|
-
accessible: true,
|
|
18
|
-
testID: accessibilityLabel,
|
|
19
|
-
accessibilityLabel: undefined,
|
|
20
|
-
};
|
|
21
|
-
} else {
|
|
22
|
-
return {
|
|
23
|
-
accessibilityLabel,
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
export {scaleSize, getAccessibilityID};
|
|
14
|
+
|
|
15
|
+
export {scaleSize};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@momo-kits/foundation",
|
|
3
|
-
"version": "0.111.1-beta.
|
|
3
|
+
"version": "0.111.1-beta.20",
|
|
4
4
|
"description": "React Native Component Kits",
|
|
5
5
|
"main": "index.ts",
|
|
6
6
|
"scripts": {},
|
|
@@ -42,6 +42,8 @@
|
|
|
42
42
|
"react-scanner": "^1.1.0",
|
|
43
43
|
"@types/color": "3.0.6"
|
|
44
44
|
},
|
|
45
|
-
"
|
|
46
|
-
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"registry": "https://registry.npmjs.org/"
|
|
47
|
+
},
|
|
48
|
+
"license": "MoMo"
|
|
47
49
|
}
|