@momo-kits/foundation 0.81.1-beta.6 → 0.81.1-optimize.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/BottomTab.tsx +76 -23
- package/Application/Components.tsx +243 -198
- package/Application/ModalScreen.tsx +20 -65
- package/Application/Navigation.ts +15 -4
- package/Application/NavigationContainer.tsx +20 -20
- package/Application/Navigator.ts +61 -28
- package/Application/StackScreen.tsx +41 -23
- package/Application/index.ts +16 -6
- package/Application/types.ts +34 -19
- package/Application/utils.tsx +26 -0
- package/Assets/icon.json +83 -5
- package/Assets/icon_bank.json +506 -0
- package/Assets/language.json +3 -1
- package/Badge/Badge.tsx +56 -0
- package/Badge/BadgeDot.tsx +11 -0
- package/Badge/BadgeRibbon.tsx +125 -0
- package/Badge/Shape.tsx +29 -0
- package/Badge/index.tsx +7 -0
- package/Badge/styles.ts +58 -0
- package/Badge/types.ts +63 -0
- package/Button/index.tsx +26 -9
- package/Button/styles.ts +19 -0
- package/CheckBox/index.tsx +1 -2
- package/Consts/colors+spacing+radius.ts +3 -3
- package/Icon/index.tsx +7 -3
- package/Icon/types.ts +3 -3
- package/IconButton/index.tsx +0 -1
- package/Image/index.tsx +39 -49
- package/Image/styles.ts +1 -9
- package/Image/types.ts +3 -1
- package/Input/Input.tsx +37 -16
- package/Input/InputDropDown.tsx +5 -14
- package/Input/InputMoney.tsx +28 -11
- package/Input/InputOTP.tsx +169 -145
- package/Input/InputSearch.tsx +9 -13
- package/Input/InputTextArea.tsx +6 -12
- package/Input/common.tsx +5 -3
- package/Input/index.tsx +15 -9
- package/Input/styles.ts +1 -4
- package/Layout/Card.tsx +20 -11
- package/Layout/GridSystem.tsx +1 -2
- package/Layout/Item.tsx +0 -1
- package/Layout/ItemList.tsx +39 -40
- package/Layout/ItemSectionList.tsx +39 -0
- package/Layout/Screen.tsx +96 -45
- package/Layout/Section.tsx +17 -19
- package/Layout/index.ts +2 -1
- package/Layout/styles.ts +16 -15
- package/Layout/types.ts +2 -5
- package/Pagination/PaginationNumber.tsx +1 -1
- package/Pagination/PaginationScroll.tsx +0 -1
- package/Popup/PopupNotify.tsx +71 -14
- package/Popup/PopupPromotion.tsx +43 -6
- package/Popup/types.ts +12 -3
- package/Radio/index.tsx +1 -2
- package/Skeleton/index.tsx +1 -1
- package/Switch/index.tsx +0 -1
- package/Tag/index.tsx +2 -4
- package/Text/index.tsx +3 -2
- package/Text/styles.ts +38 -0
- package/Text/types.ts +25 -13
- package/Title/index.tsx +82 -38
- package/Title/styles.ts +16 -10
- package/Title/types.ts +2 -1
- package/index.ts +2 -0
- package/package.json +6 -6
- package/verify.js +15 -0
|
@@ -26,6 +26,9 @@ import {
|
|
|
26
26
|
import {HeaderBackground, HeaderLeft, HeaderTitle} from './Components';
|
|
27
27
|
|
|
28
28
|
const ModalScreen: React.FC<any> = props => {
|
|
29
|
+
/**
|
|
30
|
+
* dismiss callback when modal | bottom sheet dismissed
|
|
31
|
+
*/
|
|
29
32
|
useEffect(() => {
|
|
30
33
|
return () => {
|
|
31
34
|
props.route.params?.onDismiss?.();
|
|
@@ -39,10 +42,8 @@ const ModalScreen: React.FC<any> = props => {
|
|
|
39
42
|
};
|
|
40
43
|
|
|
41
44
|
const Modal: React.FC<ModalParams> = props => {
|
|
42
|
-
const
|
|
43
|
-
const {
|
|
44
|
-
const {screen, barrierDismissible, modalName}: ModalParams =
|
|
45
|
-
props.route.params;
|
|
45
|
+
const {theme, navigator} = useContext(ApplicationContext);
|
|
46
|
+
const {screen, barrierDismissible} = props.route.params;
|
|
46
47
|
const Component = useRef(screen).current;
|
|
47
48
|
const navigation = new Navigation(props.navigation, theme);
|
|
48
49
|
const params = {
|
|
@@ -52,37 +53,6 @@ const Modal: React.FC<ModalParams> = props => {
|
|
|
52
53
|
|
|
53
54
|
delete params.screen;
|
|
54
55
|
|
|
55
|
-
const navigationRoutes = props.navigation.getState()?.routes || [];
|
|
56
|
-
const routesLength = navigationRoutes.length;
|
|
57
|
-
let screen_name = navigationRoutes?.[0]?.params?.screen?.name;
|
|
58
|
-
if (routesLength > 1) {
|
|
59
|
-
screen_name = navigationRoutes[routesLength - 2]?.params?.screen?.name;
|
|
60
|
-
}
|
|
61
|
-
const error_code = (screen as Function)?.()?.props?.information;
|
|
62
|
-
|
|
63
|
-
useEffect(() => {
|
|
64
|
-
navigator?.maxApi?.trackEvent('service_component_displayed', {
|
|
65
|
-
...appInfo,
|
|
66
|
-
screen_name,
|
|
67
|
-
trigger_id: TRIGGER_ID,
|
|
68
|
-
component_type: 'popup',
|
|
69
|
-
component_name: modalName,
|
|
70
|
-
error_code,
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
return () => {
|
|
74
|
-
navigator?.maxApi?.trackEvent('service_icon_clicked', {
|
|
75
|
-
...appInfo,
|
|
76
|
-
screen_name,
|
|
77
|
-
trigger_id: '111154100000000001',
|
|
78
|
-
component_type: 'popup',
|
|
79
|
-
component_name: modalName,
|
|
80
|
-
error_code,
|
|
81
|
-
icon_name: 'close',
|
|
82
|
-
});
|
|
83
|
-
};
|
|
84
|
-
}, []);
|
|
85
|
-
|
|
86
56
|
const onDismiss = () => {
|
|
87
57
|
if (barrierDismissible) {
|
|
88
58
|
return;
|
|
@@ -104,7 +74,7 @@ const Modal: React.FC<ModalParams> = props => {
|
|
|
104
74
|
style={styles.modalSpaceVertical}
|
|
105
75
|
onPress={() => onDismiss()}
|
|
106
76
|
/>
|
|
107
|
-
<View style={styles.modalContent}
|
|
77
|
+
<View style={styles.modalContent}>
|
|
108
78
|
<Component {...params} />
|
|
109
79
|
</View>
|
|
110
80
|
<Pressable
|
|
@@ -123,9 +93,10 @@ const Modal: React.FC<ModalParams> = props => {
|
|
|
123
93
|
|
|
124
94
|
const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
125
95
|
const insets = useSafeAreaInsets();
|
|
126
|
-
const {theme, navigator
|
|
96
|
+
const {theme, navigator} = useContext(ApplicationContext);
|
|
127
97
|
const [keyboardSnap, setKeyboardSnap] = useState(0);
|
|
128
|
-
const {screen, options, snapPoint}: BottomSheetParams =
|
|
98
|
+
const {screen, options, snapPoint, indicatorColor}: BottomSheetParams =
|
|
99
|
+
props.route.params;
|
|
129
100
|
const Component = useRef(screen).current;
|
|
130
101
|
const navigation = new Navigation(props.navigation, theme);
|
|
131
102
|
const params = {
|
|
@@ -196,15 +167,8 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
196
167
|
bottomInset={Platform.OS === 'ios' ? bottomInset : 0}
|
|
197
168
|
handleComponent={null}
|
|
198
169
|
backdropComponent={backdropComponent}>
|
|
199
|
-
<BottomSheetView
|
|
200
|
-
<View
|
|
201
|
-
style={[
|
|
202
|
-
styles.sheetContainer,
|
|
203
|
-
{
|
|
204
|
-
backgroundColor,
|
|
205
|
-
paddingBottom: Math.min(insets.bottom, 20) + Spacing.S,
|
|
206
|
-
},
|
|
207
|
-
]}>
|
|
170
|
+
<BottomSheetView>
|
|
171
|
+
<View style={[styles.sheetContainer, {backgroundColor}]}>
|
|
208
172
|
<View style={styles.indicatorContainer}>
|
|
209
173
|
<View
|
|
210
174
|
style={[
|
|
@@ -214,7 +178,6 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
214
178
|
/>
|
|
215
179
|
</View>
|
|
216
180
|
<NavigationContainer
|
|
217
|
-
appInfo={appInfo}
|
|
218
181
|
maxApi={navigator?.maxApi}
|
|
219
182
|
theme={{
|
|
220
183
|
...theme,
|
|
@@ -226,23 +189,11 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
226
189
|
...{
|
|
227
190
|
headerLeft: (props: any) => {
|
|
228
191
|
if (props.canGoBack) {
|
|
229
|
-
return
|
|
230
|
-
<HeaderLeft
|
|
231
|
-
{...props}
|
|
232
|
-
useBorder={false}
|
|
233
|
-
backgroundColor="transparent"
|
|
234
|
-
accessibilityLabel={'BottomSheet/'}
|
|
235
|
-
/>
|
|
236
|
-
);
|
|
192
|
+
return <HeaderLeft {...props} useBorder={false} />;
|
|
237
193
|
}
|
|
238
194
|
},
|
|
239
195
|
headerTitle: (props: any) => {
|
|
240
|
-
return
|
|
241
|
-
<HeaderTitle
|
|
242
|
-
{...props}
|
|
243
|
-
accessibilityLabel={'BottomSheet/'}
|
|
244
|
-
/>
|
|
245
|
-
);
|
|
196
|
+
return <HeaderTitle {...props} />;
|
|
246
197
|
},
|
|
247
198
|
headerTintColor: theme.colors.text.default,
|
|
248
199
|
headerBackground: () => (
|
|
@@ -256,15 +207,19 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
256
207
|
<NavigationButton
|
|
257
208
|
{...props}
|
|
258
209
|
icon="24_navigation_close"
|
|
259
|
-
backgroundColor="transparent"
|
|
260
210
|
useBorder={false}
|
|
261
|
-
onPress={bottomSheetRef.current?.dismiss}
|
|
262
|
-
accessibilityLabel={'BottomSheet/Close'}
|
|
211
|
+
onPress={() => bottomSheetRef.current?.dismiss()}
|
|
263
212
|
/>
|
|
264
213
|
</HeaderRightAction>
|
|
265
214
|
),
|
|
266
215
|
}}
|
|
267
216
|
/>
|
|
217
|
+
<View
|
|
218
|
+
style={{
|
|
219
|
+
height: Math.min(insets.bottom, 20),
|
|
220
|
+
backgroundColor: indicatorColor ?? backgroundColor,
|
|
221
|
+
}}
|
|
222
|
+
/>
|
|
268
223
|
</View>
|
|
269
224
|
</BottomSheetView>
|
|
270
225
|
</BottomSheetModal>
|
|
@@ -14,6 +14,10 @@ class Navigation {
|
|
|
14
14
|
this.theme = theme;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* navigation options filter by design system rule
|
|
19
|
+
* @param params
|
|
20
|
+
*/
|
|
17
21
|
private filterParams = (params: NavigationOptions) => {
|
|
18
22
|
if (params.headerRight) {
|
|
19
23
|
const headerRight = params.headerRight?.({}) as React.ReactElement;
|
|
@@ -24,14 +28,21 @@ class Navigation {
|
|
|
24
28
|
);
|
|
25
29
|
}
|
|
26
30
|
}
|
|
31
|
+
|
|
32
|
+
if (params.headerLeft) {
|
|
33
|
+
console.warn('headerLeft not allow override render by design system!');
|
|
34
|
+
delete params.headerLeft;
|
|
35
|
+
}
|
|
36
|
+
|
|
27
37
|
return params;
|
|
28
38
|
};
|
|
29
39
|
|
|
40
|
+
/**
|
|
41
|
+
* navigation setOptions support props NavigationOptions base on react-navigation options
|
|
42
|
+
* @param params
|
|
43
|
+
*/
|
|
30
44
|
setOptions = (params: NavigationOptions) => {
|
|
31
|
-
|
|
32
|
-
params = this.filterParams(params);
|
|
33
|
-
}
|
|
34
|
-
params = getOptions(params, this.theme);
|
|
45
|
+
params = getOptions(this.filterParams(params), this.theme);
|
|
35
46
|
this.instance.setOptions(params);
|
|
36
47
|
};
|
|
37
48
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {useEffect, useRef, useState} from 'react';
|
|
1
|
+
import React, {useContext, useEffect, useRef, useState} from 'react';
|
|
2
2
|
import {BottomSheetModalProvider} from '@gorhom/bottom-sheet';
|
|
3
3
|
import {SafeAreaProvider} from 'react-native-safe-area-context';
|
|
4
4
|
import {
|
|
@@ -6,13 +6,13 @@ import {
|
|
|
6
6
|
NavigationContainerRef,
|
|
7
7
|
} from '@react-navigation/native';
|
|
8
8
|
import {createStackNavigator} from '@react-navigation/stack';
|
|
9
|
+
import {DeviceEventEmitter} from 'react-native';
|
|
9
10
|
import StackScreen from './StackScreen';
|
|
10
11
|
import ModalScreen from './ModalScreen';
|
|
11
12
|
import Navigator from './Navigator';
|
|
12
13
|
import {getDialogOptions, getModalOptions, getStackOptions} from './utils';
|
|
13
14
|
import {LocalizationObject, NavigationContainerProps} from './types';
|
|
14
|
-
import {ApplicationContext} from './index';
|
|
15
|
-
import {DeviceEventEmitter} from 'react-native';
|
|
15
|
+
import {ApplicationContext, MiniAppContext} from './index';
|
|
16
16
|
import kitLocalization from '../Assets/language.json';
|
|
17
17
|
|
|
18
18
|
const Stack = createStackNavigator();
|
|
@@ -23,13 +23,17 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
|
|
|
23
23
|
options,
|
|
24
24
|
maxApi,
|
|
25
25
|
localization,
|
|
26
|
-
appInfo,
|
|
27
26
|
}) => {
|
|
27
|
+
const context = useContext(MiniAppContext);
|
|
28
28
|
const navigationRef = React.useRef<NavigationContainerRef>(null);
|
|
29
29
|
const navigator = useRef(new Navigator(navigationRef));
|
|
30
30
|
const [showGrid, setShowGrid] = useState(false);
|
|
31
|
-
const
|
|
31
|
+
const config = useRef<any>();
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* handle mini language & listen change
|
|
35
|
+
* engine only shake to enable grid view
|
|
36
|
+
*/
|
|
33
37
|
useEffect(() => {
|
|
34
38
|
const subscription = DeviceEventEmitter.addListener(
|
|
35
39
|
'onChangeGrid',
|
|
@@ -37,26 +41,23 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
|
|
|
37
41
|
setShowGrid(!!enable);
|
|
38
42
|
},
|
|
39
43
|
);
|
|
40
|
-
return () => {
|
|
41
|
-
subscription.remove();
|
|
42
|
-
};
|
|
43
|
-
}, []);
|
|
44
44
|
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
maxApi?.getLanguage?.((lang: 'vi' | 'en') => {
|
|
47
|
-
setLanguage(lang);
|
|
48
|
-
});
|
|
49
|
-
const listener = maxApi?.observer?.('language', (lang: 'vi' | 'en') => {
|
|
50
|
-
setLanguage(lang);
|
|
51
|
-
});
|
|
52
45
|
return () => {
|
|
53
|
-
|
|
46
|
+
subscription?.remove?.();
|
|
54
47
|
};
|
|
55
48
|
}, []);
|
|
56
49
|
|
|
50
|
+
/**
|
|
51
|
+
* inject data for navigator
|
|
52
|
+
*/
|
|
57
53
|
navigator.current.maxApi = maxApi;
|
|
58
54
|
|
|
55
|
+
/**
|
|
56
|
+
* translate
|
|
57
|
+
* @param key
|
|
58
|
+
*/
|
|
59
59
|
const translate = (key: string) => {
|
|
60
|
+
const language: 'vi' | 'en' = context?.language ?? 'vi';
|
|
60
61
|
const mergedLocalization: LocalizationObject = {
|
|
61
62
|
vi: {...localization?.vi, ...kitLocalization.vi},
|
|
62
63
|
en: {...localization?.en, ...kitLocalization.en},
|
|
@@ -69,12 +70,11 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
|
|
|
69
70
|
<BottomSheetModalProvider>
|
|
70
71
|
<ApplicationContext.Provider
|
|
71
72
|
value={{
|
|
72
|
-
theme,
|
|
73
73
|
navigator: navigator.current,
|
|
74
|
+
config: config.current,
|
|
75
|
+
theme,
|
|
74
76
|
showGrid,
|
|
75
|
-
language,
|
|
76
77
|
translate,
|
|
77
|
-
appInfo,
|
|
78
78
|
}}>
|
|
79
79
|
<ReactNavigationContainer
|
|
80
80
|
theme={{
|
package/Application/Navigator.ts
CHANGED
|
@@ -10,31 +10,56 @@ class Navigator {
|
|
|
10
10
|
ref?: any;
|
|
11
11
|
toolkitConfig?: HeaderToolkitProps;
|
|
12
12
|
maxApi?: any;
|
|
13
|
+
dismissData?: any;
|
|
14
|
+
toolkitCallback?: (item: any) => void;
|
|
13
15
|
|
|
14
16
|
constructor(navigation: any) {
|
|
15
17
|
this.ref = navigation;
|
|
16
18
|
}
|
|
17
19
|
|
|
20
|
+
/**
|
|
21
|
+
* push new stack screen
|
|
22
|
+
* @param params
|
|
23
|
+
*/
|
|
18
24
|
push = (params: ScreenParams) => {
|
|
19
25
|
this.ref.current.dispatch(StackActions.push('Stack', params));
|
|
20
26
|
};
|
|
21
27
|
|
|
28
|
+
/**
|
|
29
|
+
* replace current screen with new screen
|
|
30
|
+
* @param params
|
|
31
|
+
*/
|
|
22
32
|
replace = (params: ScreenParams) => {
|
|
23
33
|
this.ref.current.dispatch(StackActions.replace('Stack', params));
|
|
24
34
|
};
|
|
25
|
-
|
|
35
|
+
/**
|
|
36
|
+
* pop to dismiss a screen
|
|
37
|
+
* @param count
|
|
38
|
+
*/
|
|
26
39
|
pop = (count?: number) => {
|
|
27
40
|
this.ref.current.dispatch(StackActions.pop(count ?? 1));
|
|
28
41
|
};
|
|
29
42
|
|
|
43
|
+
/**
|
|
44
|
+
* present a new screen, show from bottom iOS
|
|
45
|
+
* @param params
|
|
46
|
+
*/
|
|
30
47
|
present = (params: ScreenParams) => {
|
|
31
48
|
this.ref.current.dispatch(StackActions.push('Dialog', params));
|
|
32
49
|
};
|
|
33
50
|
|
|
51
|
+
/**
|
|
52
|
+
* show a modal popup
|
|
53
|
+
* @param params
|
|
54
|
+
*/
|
|
34
55
|
showModal = (params: ModalParams) => {
|
|
35
56
|
this.ref.current.dispatch(StackActions.push('Modal', params));
|
|
36
57
|
};
|
|
37
58
|
|
|
59
|
+
/**
|
|
60
|
+
* show a bottom sheet
|
|
61
|
+
* @param params
|
|
62
|
+
*/
|
|
38
63
|
showBottomSheet = (params: BottomSheetParams) => {
|
|
39
64
|
this.ref.current.dispatch(
|
|
40
65
|
StackActions.push('Modal', {
|
|
@@ -44,10 +69,31 @@ class Navigator {
|
|
|
44
69
|
);
|
|
45
70
|
};
|
|
46
71
|
|
|
72
|
+
/**
|
|
73
|
+
* pop all screen route
|
|
74
|
+
*/
|
|
47
75
|
popToTop = () => {
|
|
48
76
|
this.ref.current.dispatch(StackActions.popToTop());
|
|
49
77
|
};
|
|
50
78
|
|
|
79
|
+
/**
|
|
80
|
+
* navigate
|
|
81
|
+
* @param name
|
|
82
|
+
* @param params
|
|
83
|
+
*/
|
|
84
|
+
navigate = (name: string, params: any) => {
|
|
85
|
+
this.ref.current.dispatch(
|
|
86
|
+
CommonActions.navigate({
|
|
87
|
+
name,
|
|
88
|
+
params,
|
|
89
|
+
}),
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* reset a navigation flow with new screen
|
|
95
|
+
* @param params
|
|
96
|
+
*/
|
|
51
97
|
reset = (params: ScreenParams) => {
|
|
52
98
|
this.ref.current.dispatch(
|
|
53
99
|
CommonActions.reset({
|
|
@@ -63,35 +109,22 @@ class Navigator {
|
|
|
63
109
|
);
|
|
64
110
|
};
|
|
65
111
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
112
|
+
/**
|
|
113
|
+
* dismiss a feature data
|
|
114
|
+
* @param data
|
|
115
|
+
*/
|
|
116
|
+
setDismissData = (data: any) => {
|
|
117
|
+
this.dismissData = data;
|
|
73
118
|
};
|
|
74
119
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
this.requestApi('getToolkitConfig', [undefined], (config: any) => {
|
|
84
|
-
this.toolkitConfig = {
|
|
85
|
-
...config?.utilityToolConfig,
|
|
86
|
-
appCode: config?.appCode,
|
|
87
|
-
};
|
|
88
|
-
resolve(this.toolkitConfig);
|
|
89
|
-
});
|
|
90
|
-
} else {
|
|
91
|
-
resolve(undefined);
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
});
|
|
120
|
+
/**
|
|
121
|
+
* set callback function for toolkit
|
|
122
|
+
* @param callback
|
|
123
|
+
*/
|
|
124
|
+
setToolkitCallback = (
|
|
125
|
+
callback: (item: {key: string; action: string}) => void,
|
|
126
|
+
) => {
|
|
127
|
+
this.toolkitCallback = callback;
|
|
95
128
|
};
|
|
96
129
|
}
|
|
97
130
|
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import React, {useContext, useEffect, useLayoutEffect} from 'react';
|
|
2
2
|
import {ScreenParams} from './types';
|
|
3
3
|
import Navigation from './Navigation';
|
|
4
|
-
import {ApplicationContext} from './index';
|
|
4
|
+
import {ApplicationContext, MiniAppContext} from './index';
|
|
5
5
|
import {GridSystem} from '../Layout';
|
|
6
|
-
|
|
7
|
-
const TRIGGER_ID = '111378000000000000';
|
|
6
|
+
import {useHeaderHeight} from '@react-navigation/stack';
|
|
8
7
|
|
|
9
8
|
const StackScreen: React.FC<ScreenParams> = props => {
|
|
9
|
+
const {theme, showGrid, navigator} = useContext(ApplicationContext);
|
|
10
|
+
const context = useContext(MiniAppContext);
|
|
11
|
+
|
|
10
12
|
const {screen: Component, options}: ScreenParams = props.route.params;
|
|
11
|
-
const {theme, showGrid, navigator, appInfo} = useContext(ApplicationContext);
|
|
12
13
|
const navigation = new Navigation(props.navigation, theme);
|
|
14
|
+
const heightHeader = useHeaderHeight();
|
|
13
15
|
|
|
14
16
|
const params = {
|
|
15
17
|
...props.route.params,
|
|
@@ -18,33 +20,49 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
18
20
|
|
|
19
21
|
delete params.screen;
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (routesLength > 1) {
|
|
25
|
-
pre_screen_name = navigationRoutes[routesLength - 2]?.params?.screen?.name;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
useEffect(() => {
|
|
29
|
-
if (appInfo) {
|
|
30
|
-
navigator?.maxApi?.trackEvent('service_frame_displayed', {
|
|
31
|
-
...appInfo,
|
|
32
|
-
screen_name: Component.name,
|
|
33
|
-
pre_screen_name,
|
|
34
|
-
trigger_id: TRIGGER_ID,
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
}, []);
|
|
38
|
-
|
|
23
|
+
/**
|
|
24
|
+
* set options for screen
|
|
25
|
+
*/
|
|
39
26
|
useLayoutEffect(() => {
|
|
40
27
|
if (options) {
|
|
41
28
|
navigation.setOptions(options);
|
|
42
29
|
}
|
|
43
30
|
}, [options]);
|
|
44
31
|
|
|
32
|
+
/**
|
|
33
|
+
* tracking for screen
|
|
34
|
+
*/
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
const tracking = {
|
|
37
|
+
...context,
|
|
38
|
+
screen_name: Component.name,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const routes = props.navigation.getState()?.routes || [];
|
|
42
|
+
const routesLength = routes.length;
|
|
43
|
+
let pre_screen_name = '';
|
|
44
|
+
if (routesLength > 1) {
|
|
45
|
+
pre_screen_name = routes[routesLength - 2]?.params?.screen?.name;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
navigator?.maxApi?.trackEvent?.('service_frame_displayed', {
|
|
49
|
+
...tracking,
|
|
50
|
+
pre_screen_name,
|
|
51
|
+
trigger_id: '111378000000000000',
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
return props.navigation.addListener('beforeRemove', () => {
|
|
55
|
+
navigator?.maxApi?.trackEvent?.('service_icon_clicked', {
|
|
56
|
+
...tracking,
|
|
57
|
+
trigger_id: '111154000000000000',
|
|
58
|
+
icon_name: 'back',
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}, []);
|
|
62
|
+
|
|
45
63
|
return (
|
|
46
64
|
<>
|
|
47
|
-
<Component {...params} />
|
|
65
|
+
<Component heightHeader={heightHeader} {...params} />
|
|
48
66
|
{showGrid && <GridSystem />}
|
|
49
67
|
</>
|
|
50
68
|
);
|
package/Application/index.ts
CHANGED
|
@@ -1,23 +1,33 @@
|
|
|
1
1
|
import {NavigationContainer} from './NavigationContainer';
|
|
2
2
|
import Screen from '../Layout/Screen';
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
HeaderTitle,
|
|
6
|
-
HeaderLeft,
|
|
4
|
+
HeaderAnimated,
|
|
7
5
|
HeaderBackground,
|
|
6
|
+
HeaderCustom,
|
|
7
|
+
HeaderLeft,
|
|
8
8
|
HeaderRightAction,
|
|
9
|
+
HeaderTitle,
|
|
9
10
|
HeaderToolkitAction,
|
|
10
|
-
|
|
11
|
-
HeaderAnimated,
|
|
11
|
+
NavigationButton,
|
|
12
12
|
} from './Components';
|
|
13
13
|
import BottomTab from './BottomTab';
|
|
14
14
|
import {createContext} from 'react';
|
|
15
15
|
import {defaultContext} from '../Consts';
|
|
16
|
+
import {MiniAppInfo} from './types';
|
|
16
17
|
|
|
17
18
|
const ApplicationContext = createContext(defaultContext);
|
|
19
|
+
const MiniAppContext = createContext<MiniAppInfo>({
|
|
20
|
+
appId: '',
|
|
21
|
+
buildNumber: 0,
|
|
22
|
+
code: '',
|
|
23
|
+
toolkitConfig: {},
|
|
24
|
+
fromCode: '',
|
|
25
|
+
});
|
|
26
|
+
|
|
18
27
|
export {
|
|
19
|
-
NavigationContainer,
|
|
20
28
|
ApplicationContext,
|
|
29
|
+
MiniAppContext,
|
|
30
|
+
NavigationContainer,
|
|
21
31
|
Screen,
|
|
22
32
|
BottomTab,
|
|
23
33
|
NavigationButton,
|
package/Application/types.ts
CHANGED
|
@@ -63,12 +63,21 @@ export type Theme = {
|
|
|
63
63
|
};
|
|
64
64
|
|
|
65
65
|
export type Context = {
|
|
66
|
+
[key: string]: any;
|
|
66
67
|
theme: Theme;
|
|
67
68
|
navigator?: Navigator;
|
|
68
69
|
showGrid?: boolean;
|
|
69
|
-
language?: 'vi' | 'en';
|
|
70
70
|
translate?: (key: string) => string;
|
|
71
|
-
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export type MiniAppInfo = {
|
|
74
|
+
[key: string]: any;
|
|
75
|
+
code: string;
|
|
76
|
+
appId: string;
|
|
77
|
+
buildNumber: number;
|
|
78
|
+
flowPartnerId?: string;
|
|
79
|
+
toolkitConfig?: any;
|
|
80
|
+
fromCode?: string;
|
|
72
81
|
};
|
|
73
82
|
|
|
74
83
|
export type LocalizationObject = {
|
|
@@ -80,20 +89,12 @@ export type LocalizationObject = {
|
|
|
80
89
|
};
|
|
81
90
|
};
|
|
82
91
|
|
|
83
|
-
export type MiniAppInfo = {
|
|
84
|
-
feature_code: string;
|
|
85
|
-
app_id: string;
|
|
86
|
-
build_number: number;
|
|
87
|
-
flow_partner_id?: string;
|
|
88
|
-
};
|
|
89
|
-
|
|
90
92
|
export type NavigationContainerProps = {
|
|
91
93
|
screen: Screen;
|
|
92
94
|
options?: NavigationOptions;
|
|
93
95
|
theme: Theme;
|
|
94
96
|
maxApi: any;
|
|
95
97
|
localization?: LocalizationObject;
|
|
96
|
-
appInfo: MiniAppInfo;
|
|
97
98
|
};
|
|
98
99
|
|
|
99
100
|
export type NavigationScreenProps = {
|
|
@@ -106,12 +107,10 @@ export type ScreenParams = {
|
|
|
106
107
|
[key: string]: any;
|
|
107
108
|
screen: Screen;
|
|
108
109
|
options?: NavigationOptions;
|
|
109
|
-
tracking?: any;
|
|
110
110
|
};
|
|
111
111
|
|
|
112
112
|
export interface ModalParams extends ScreenParams {
|
|
113
113
|
[key: string]: any;
|
|
114
|
-
modalName?: string;
|
|
115
114
|
onDismiss?: () => void;
|
|
116
115
|
barrierDismissible?: boolean;
|
|
117
116
|
}
|
|
@@ -119,16 +118,29 @@ export interface ModalParams extends ScreenParams {
|
|
|
119
118
|
export interface BottomSheetParams extends ScreenParams {
|
|
120
119
|
[key: string]: any;
|
|
121
120
|
onDismiss?: () => void;
|
|
122
|
-
snapPoint?: '30%' | '50%' | '70%' | '90%';
|
|
121
|
+
snapPoint?: '30%' | '50%' | '70%' | '90%' | 'content';
|
|
122
|
+
indicatorColor?: string;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
export type NavigationButtonProps = {
|
|
126
126
|
icon: string;
|
|
127
127
|
tintColor?: string;
|
|
128
|
-
backgroundColor?: string;
|
|
129
128
|
useBorder?: boolean;
|
|
130
129
|
onPress: () => void;
|
|
131
|
-
|
|
130
|
+
badgeType?: 'dot' | 'number';
|
|
131
|
+
badgeValue?: number;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export type PinnedToolType = {
|
|
135
|
+
key: string;
|
|
136
|
+
badgeValue?: number;
|
|
137
|
+
badgeType?: 'number' | 'dot';
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export type RuntimeToolType = {
|
|
141
|
+
title: {vi: string; en: string};
|
|
142
|
+
icon: string;
|
|
143
|
+
key: string;
|
|
132
144
|
};
|
|
133
145
|
|
|
134
146
|
export interface NavigationOptions extends StackNavigationOptions {
|
|
@@ -137,12 +149,15 @@ export interface NavigationOptions extends StackNavigationOptions {
|
|
|
137
149
|
surface?: boolean;
|
|
138
150
|
hiddenBack?: boolean;
|
|
139
151
|
customTitle?: TitleCustomProps;
|
|
152
|
+
toolkitParams?: {
|
|
153
|
+
pinnedTool?: PinnedToolType;
|
|
154
|
+
runtimeTools?: RuntimeToolType[];
|
|
155
|
+
};
|
|
140
156
|
}
|
|
141
157
|
|
|
142
158
|
export interface HeaderBackProps extends NavigationButtonProps {
|
|
143
159
|
preventBack?: PopupNotifyProps;
|
|
144
160
|
onPressLeftHeader?: () => void;
|
|
145
|
-
accessibilityLabel?: string;
|
|
146
161
|
}
|
|
147
162
|
|
|
148
163
|
export type HeaderBackgroundProps = {
|
|
@@ -165,9 +180,7 @@ export type TitleCustomProps = {
|
|
|
165
180
|
export type HeaderToolkitProps = {
|
|
166
181
|
[key: string]: any;
|
|
167
182
|
appCode: string;
|
|
168
|
-
|
|
169
|
-
type: string;
|
|
170
|
-
onAction?: (action: string) => void;
|
|
183
|
+
configs: any[];
|
|
171
184
|
};
|
|
172
185
|
|
|
173
186
|
export type HeaderAnimatedProps = {
|
|
@@ -187,7 +200,9 @@ export type BottomTabItemProps = {
|
|
|
187
200
|
};
|
|
188
201
|
|
|
189
202
|
export type BottomTabProps = {
|
|
203
|
+
nested?: boolean;
|
|
190
204
|
tabs: BottomTabItemProps[];
|
|
205
|
+
initialRouteName?: string;
|
|
191
206
|
navigation: Navigation;
|
|
192
207
|
listeners?: {
|
|
193
208
|
tabPress?: any;
|