@momo-kits/foundation 0.75.1-beta.9 → 0.75.3-beta.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 +225 -0
- package/Application/BottomTab/BottomTabBar.tsx +291 -0
- package/Application/BottomTab/index.tsx +138 -0
- package/Application/Components.tsx +555 -0
- package/Application/ModalScreen.tsx +97 -0
- package/Application/Navigation.ts +50 -0
- package/Application/NavigationContainer.tsx +121 -0
- package/Application/Navigator.ts +151 -0
- package/Application/StackScreen.tsx +148 -0
- package/Application/index.ts +37 -0
- package/{Navigation → Application}/types.ts +101 -33
- package/Application/utils.tsx +153 -0
- package/Assets/DotAnimation.json +256 -0
- package/Assets/SpinnerAnimation.json +1027 -0
- package/Assets/icon.json +89 -5
- package/Assets/icon_bank.json +506 -0
- package/Assets/language.json +202 -0
- 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 +91 -40
- package/Button/styles.ts +19 -0
- package/CheckBox/index.tsx +58 -43
- package/CheckBox/styles.ts +1 -1
- package/CheckBox/types.ts +6 -4
- package/Consts/colors+spacing+radius.ts +18 -0
- package/Consts/styles.ts +0 -26
- package/Consts/theme.ts +5 -1
- package/Divider/index.tsx +3 -1
- package/Icon/index.tsx +15 -10
- package/Icon/types.ts +4 -3
- package/IconButton/index.tsx +24 -15
- package/Image/index.tsx +63 -45
- package/Image/styles.ts +1 -9
- package/Image/types.ts +5 -1
- package/Input/Input.tsx +227 -115
- package/Input/InputDropDown.tsx +132 -0
- package/Input/InputMoney.tsx +173 -110
- package/Input/InputOTP.tsx +257 -0
- package/Input/InputSearch.tsx +160 -130
- package/Input/InputTextArea.tsx +149 -121
- package/Input/common.tsx +36 -18
- package/Input/index.tsx +212 -17
- package/Input/styles.ts +44 -7
- package/Input/utils.ts +2 -2
- package/Layout/Card.tsx +76 -37
- package/Layout/FloatingButton.tsx +168 -0
- package/Layout/GridSystem.tsx +35 -23
- package/Layout/Item.tsx +29 -33
- package/Layout/ItemList.tsx +55 -0
- package/Layout/ItemSectionList.tsx +39 -0
- package/Layout/Screen.tsx +390 -0
- package/Layout/Section.tsx +73 -35
- package/Layout/index.ts +13 -3
- package/Layout/styles.ts +101 -0
- package/Layout/types.ts +1 -37
- package/Layout/utils.ts +38 -43
- package/Loader/DotLoader.tsx +37 -0
- package/Loader/Loader.tsx +13 -0
- package/Loader/ProgressBar.tsx +44 -0
- package/Loader/Spinner.tsx +29 -0
- package/Loader/index.tsx +4 -0
- package/Loader/styles.ts +10 -0
- package/Loader/types.ts +35 -0
- package/Loader/utils.ts +25 -0
- package/Pagination/Dot.tsx +1 -1
- package/Pagination/PaginationDot.tsx +8 -3
- package/Pagination/PaginationNumber.tsx +8 -7
- package/Pagination/PaginationScroll.tsx +1 -1
- package/Pagination/PaginationWhiteDot.tsx +8 -5
- package/Pagination/styles.ts +3 -0
- package/Pagination/types.ts +2 -0
- package/Popup/PopupNotify.tsx +108 -46
- package/Popup/PopupPromotion.tsx +63 -22
- package/Popup/types.ts +15 -4
- package/Radio/index.tsx +35 -21
- package/Radio/types.ts +7 -5
- package/Skeleton/index.tsx +1 -1
- package/Skeleton/types.ts +3 -0
- package/Switch/index.tsx +35 -24
- package/Switch/types.ts +5 -3
- package/Tag/index.tsx +1 -1
- package/Text/index.tsx +32 -26
- package/Text/styles.ts +38 -0
- package/Text/types.ts +25 -13
- package/Text/utils.ts +14 -0
- package/Title/index.tsx +197 -0
- package/Title/styles.ts +79 -0
- package/Title/types.ts +20 -0
- package/code-scanner.js +143 -0
- package/index.ts +22 -2
- package/migrate_typo.js +56 -0
- package/package.json +44 -39
- package/publish.sh +2 -5
- package/tsconfig.json +24 -0
- package/verify.js +47 -0
- package/Assets/header-background.png +0 -0
- package/Layout/ScreenContainer.tsx +0 -121
- package/Navigation/BottomTab.tsx +0 -39
- package/Navigation/Components.tsx +0 -365
- package/Navigation/ModalScreen.tsx +0 -226
- package/Navigation/Navigation.ts +0 -44
- package/Navigation/NavigationButton.tsx +0 -54
- package/Navigation/NavigationContainer.tsx +0 -77
- package/Navigation/Navigator.ts +0 -82
- package/Navigation/Observer.ts +0 -79
- package/Navigation/StackScreen.tsx +0 -27
- package/Navigation/index.ts +0 -14
- package/Navigation/utils.tsx +0 -137
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import React, {useEffect, useRef, useState} from 'react';
|
|
2
|
+
import {SafeAreaProvider} from 'react-native-safe-area-context';
|
|
3
|
+
import {
|
|
4
|
+
NavigationContainer as ReactNavigationContainer,
|
|
5
|
+
NavigationContainerRef,
|
|
6
|
+
} from '@react-navigation/native';
|
|
7
|
+
import {createStackNavigator} from '@react-navigation/stack';
|
|
8
|
+
import {DeviceEventEmitter} from 'react-native';
|
|
9
|
+
import StackScreen from './StackScreen';
|
|
10
|
+
import ModalScreen from './ModalScreen';
|
|
11
|
+
import Navigator from './Navigator';
|
|
12
|
+
import {getDialogOptions, getModalOptions, getStackOptions} from './utils';
|
|
13
|
+
import {LocalizationObject, NavigationContainerProps} from './types';
|
|
14
|
+
import {ApplicationContext} from './index';
|
|
15
|
+
import kitLocalization from '../Assets/language.json';
|
|
16
|
+
|
|
17
|
+
const Stack = createStackNavigator();
|
|
18
|
+
|
|
19
|
+
const NavigationContainer: React.FC<NavigationContainerProps> = ({
|
|
20
|
+
screen,
|
|
21
|
+
theme,
|
|
22
|
+
options,
|
|
23
|
+
maxApi,
|
|
24
|
+
localization,
|
|
25
|
+
initialParams,
|
|
26
|
+
}) => {
|
|
27
|
+
const navigationRef = useRef<NavigationContainerRef>(null);
|
|
28
|
+
const isReady = useRef(false);
|
|
29
|
+
const navigator = useRef(new Navigator(navigationRef, isReady));
|
|
30
|
+
const [showGrid, setShowGrid] = useState(false);
|
|
31
|
+
const config = useRef<any>();
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* handle mini language & listen change
|
|
35
|
+
* engine only shake to enable grid view
|
|
36
|
+
*/
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
const subscription = DeviceEventEmitter.addListener(
|
|
39
|
+
'onChangeGrid',
|
|
40
|
+
enable => {
|
|
41
|
+
setShowGrid(!!enable);
|
|
42
|
+
},
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
return () => {
|
|
46
|
+
subscription?.remove?.();
|
|
47
|
+
};
|
|
48
|
+
}, []);
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* inject data for navigator
|
|
52
|
+
*/
|
|
53
|
+
navigator.current.maxApi = maxApi;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* translate
|
|
57
|
+
* @param key
|
|
58
|
+
*/
|
|
59
|
+
const translate = (key: string) => {
|
|
60
|
+
const language: 'vi' | 'en' = 'vi';
|
|
61
|
+
const mergedLocalization: LocalizationObject = {
|
|
62
|
+
vi: {...localization?.vi, ...kitLocalization.vi},
|
|
63
|
+
en: {...localization?.en, ...kitLocalization.en},
|
|
64
|
+
};
|
|
65
|
+
return mergedLocalization?.[language]?.[key] || key;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<SafeAreaProvider>
|
|
70
|
+
<ApplicationContext.Provider
|
|
71
|
+
value={{
|
|
72
|
+
navigator: navigator.current,
|
|
73
|
+
config: config.current,
|
|
74
|
+
theme,
|
|
75
|
+
showGrid,
|
|
76
|
+
translate,
|
|
77
|
+
}}>
|
|
78
|
+
<ReactNavigationContainer
|
|
79
|
+
theme={{
|
|
80
|
+
...theme,
|
|
81
|
+
colors: {
|
|
82
|
+
...theme.colors,
|
|
83
|
+
background: theme.colors.background.default,
|
|
84
|
+
card: theme.colors.background.surface,
|
|
85
|
+
text: theme.colors.text.default,
|
|
86
|
+
border: theme.colors.border.default,
|
|
87
|
+
notification: theme.colors.error.primary,
|
|
88
|
+
},
|
|
89
|
+
}}
|
|
90
|
+
ref={navigator.current?.ref}
|
|
91
|
+
onReady={() => {
|
|
92
|
+
isReady.current = true;
|
|
93
|
+
}}
|
|
94
|
+
independent={true}>
|
|
95
|
+
<Stack.Navigator initialRouteName="Stack" headerMode="screen">
|
|
96
|
+
<Stack.Screen
|
|
97
|
+
name="Stack"
|
|
98
|
+
component={StackScreen}
|
|
99
|
+
initialParams={{screen, initialParams}}
|
|
100
|
+
options={{...getStackOptions(), ...options}}
|
|
101
|
+
/>
|
|
102
|
+
<Stack.Screen
|
|
103
|
+
name="Dialog"
|
|
104
|
+
component={StackScreen}
|
|
105
|
+
options={getDialogOptions()}
|
|
106
|
+
initialParams={{screen}}
|
|
107
|
+
/>
|
|
108
|
+
<Stack.Screen
|
|
109
|
+
name="Modal"
|
|
110
|
+
component={ModalScreen}
|
|
111
|
+
options={getModalOptions()}
|
|
112
|
+
initialParams={{screen}}
|
|
113
|
+
/>
|
|
114
|
+
</Stack.Navigator>
|
|
115
|
+
</ReactNavigationContainer>
|
|
116
|
+
</ApplicationContext.Provider>
|
|
117
|
+
</SafeAreaProvider>
|
|
118
|
+
);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export {ApplicationContext, NavigationContainer};
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import {CommonActions, StackActions} from '@react-navigation/native';
|
|
2
|
+
import {
|
|
3
|
+
BottomSheetParams,
|
|
4
|
+
HeaderToolkitProps,
|
|
5
|
+
ModalParams,
|
|
6
|
+
ScreenParams,
|
|
7
|
+
} from './types';
|
|
8
|
+
|
|
9
|
+
class Navigator {
|
|
10
|
+
ref?: any;
|
|
11
|
+
isReady?: any;
|
|
12
|
+
toolkitConfig?: HeaderToolkitProps;
|
|
13
|
+
maxApi?: any;
|
|
14
|
+
dismissData?: any;
|
|
15
|
+
toolkitCallback?: (item: any) => void;
|
|
16
|
+
|
|
17
|
+
constructor(navigation: any, isReady: any) {
|
|
18
|
+
this.ref = navigation;
|
|
19
|
+
this.isReady = isReady;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* push new stack screen
|
|
24
|
+
* @param params
|
|
25
|
+
*/
|
|
26
|
+
push = (params: ScreenParams) => {
|
|
27
|
+
if (this.isReady.current) {
|
|
28
|
+
this.ref.current.dispatch(StackActions.push('Stack', params));
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* replace current screen with new screen
|
|
34
|
+
* @param params
|
|
35
|
+
*/
|
|
36
|
+
replace = (params: ScreenParams) => {
|
|
37
|
+
if (this.isReady.current) {
|
|
38
|
+
this.ref.current.dispatch(StackActions.replace('Stack', params));
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* pop to dismiss a screen
|
|
43
|
+
* @param count
|
|
44
|
+
*/
|
|
45
|
+
pop = (count?: number) => {
|
|
46
|
+
if (this.isReady.current) {
|
|
47
|
+
this.ref.current.dispatch(StackActions.pop(count ?? 1));
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* present a new screen, show from bottom iOS
|
|
53
|
+
* @param params
|
|
54
|
+
*/
|
|
55
|
+
present = (params: ScreenParams) => {
|
|
56
|
+
if (this.isReady.current) {
|
|
57
|
+
this.ref.current.dispatch(StackActions.push('Dialog', params));
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* show a modal popup
|
|
63
|
+
* @param params
|
|
64
|
+
*/
|
|
65
|
+
showModal = (params: ModalParams) => {
|
|
66
|
+
if (this.isReady.current) {
|
|
67
|
+
this.ref.current.dispatch(StackActions.push('Modal', params));
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* show a bottom sheet
|
|
73
|
+
* @param params
|
|
74
|
+
*/
|
|
75
|
+
showBottomSheet = (params: BottomSheetParams) => {
|
|
76
|
+
if (this.isReady.current) {
|
|
77
|
+
this.ref.current.dispatch(
|
|
78
|
+
StackActions.push('Modal', {
|
|
79
|
+
...params,
|
|
80
|
+
isBottomSheet: true,
|
|
81
|
+
}),
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* pop all screen route
|
|
88
|
+
*/
|
|
89
|
+
popToTop = () => {
|
|
90
|
+
if (this.isReady.current) {
|
|
91
|
+
this.ref.current.dispatch(StackActions.popToTop());
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* navigate
|
|
97
|
+
* @param name
|
|
98
|
+
* @param params
|
|
99
|
+
*/
|
|
100
|
+
navigate = (name: string, params: any) => {
|
|
101
|
+
if (this.isReady.current) {
|
|
102
|
+
this.ref.current.dispatch(
|
|
103
|
+
CommonActions.navigate({
|
|
104
|
+
name,
|
|
105
|
+
params,
|
|
106
|
+
}),
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* reset a navigation flow with new screen
|
|
113
|
+
* @param params
|
|
114
|
+
*/
|
|
115
|
+
reset = (params: ScreenParams) => {
|
|
116
|
+
if (this.isReady.current) {
|
|
117
|
+
this.ref.current.dispatch(
|
|
118
|
+
CommonActions.reset({
|
|
119
|
+
index: 0,
|
|
120
|
+
routes: [
|
|
121
|
+
{
|
|
122
|
+
name: 'Stack',
|
|
123
|
+
key: `Stack_${new Date().getTime()}`,
|
|
124
|
+
params,
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
}),
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* dismiss a feature data
|
|
134
|
+
* @param data
|
|
135
|
+
*/
|
|
136
|
+
setDismissData = (data: any) => {
|
|
137
|
+
this.dismissData = data;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* set callback function for toolkit
|
|
142
|
+
* @param callback
|
|
143
|
+
*/
|
|
144
|
+
setToolkitCallback = (
|
|
145
|
+
callback: (item: {key: string; action: string}) => void,
|
|
146
|
+
) => {
|
|
147
|
+
this.toolkitCallback = callback;
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export default Navigator;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import React, {useContext, useEffect, useLayoutEffect, useRef} from 'react';
|
|
2
|
+
import {ScreenParams} from './types';
|
|
3
|
+
import Navigation from './Navigation';
|
|
4
|
+
import {ApplicationContext, MiniAppContext, ScreenContext} from './index';
|
|
5
|
+
import {GridSystem} from '../Layout';
|
|
6
|
+
import {useHeaderHeight} from '@react-navigation/stack';
|
|
7
|
+
import {Alert, InteractionManager} from 'react-native';
|
|
8
|
+
|
|
9
|
+
const StackScreen: React.FC<ScreenParams> = props => {
|
|
10
|
+
const {theme, showGrid, navigator} = useContext(ApplicationContext);
|
|
11
|
+
const startTime = useRef(Date.now());
|
|
12
|
+
const endTime = useRef(Date.now());
|
|
13
|
+
const timeLoad = useRef(0);
|
|
14
|
+
const timeInteraction = useRef(0);
|
|
15
|
+
const timeoutLoad = useRef<any>();
|
|
16
|
+
const tracked = useRef<any>({
|
|
17
|
+
releaseLoad: undefined,
|
|
18
|
+
releaseInteraction: undefined,
|
|
19
|
+
timeoutLoad: undefined,
|
|
20
|
+
timeoutInteraction: undefined,
|
|
21
|
+
});
|
|
22
|
+
const interaction = useRef<any>();
|
|
23
|
+
const context = useContext<any>(MiniAppContext);
|
|
24
|
+
|
|
25
|
+
const {screen: Component, options, initialParams} = props.route.params;
|
|
26
|
+
const navigation = new Navigation(props.navigation, theme);
|
|
27
|
+
const heightHeader = useHeaderHeight();
|
|
28
|
+
|
|
29
|
+
const data = {
|
|
30
|
+
...initialParams,
|
|
31
|
+
...props.route.params,
|
|
32
|
+
navigation,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
delete data.screen;
|
|
36
|
+
delete data.initialParams;
|
|
37
|
+
|
|
38
|
+
const screenName = Component?.name || Component?.type?.name || 'Invalid';
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* set options for screen
|
|
42
|
+
*/
|
|
43
|
+
useLayoutEffect(() => {
|
|
44
|
+
if (options) {
|
|
45
|
+
navigation.setOptions(options);
|
|
46
|
+
}
|
|
47
|
+
}, [options]);
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* tracking for screen
|
|
51
|
+
*/
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
if (__DEV__ && (!screenName || screenName == 'Invalid')) {
|
|
54
|
+
Alert.alert('Design system', `Unvalidated screen name "${screenName}" !`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
navigator?.maxApi?.of?.({screenName});
|
|
58
|
+
|
|
59
|
+
tracked.current.timeoutLoad = setTimeout(() => {
|
|
60
|
+
onScreenLoad();
|
|
61
|
+
}, 5000);
|
|
62
|
+
tracked.current.timeoutInteraction = setTimeout(() => {
|
|
63
|
+
onScreenInteraction();
|
|
64
|
+
}, 5000);
|
|
65
|
+
|
|
66
|
+
return () => {
|
|
67
|
+
onScreenLoad();
|
|
68
|
+
onScreenInteraction();
|
|
69
|
+
};
|
|
70
|
+
}, []);
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* tracking for screen load
|
|
74
|
+
*/
|
|
75
|
+
const onScreenLoad = () => {
|
|
76
|
+
clearTimeout(tracked.current.timeoutLoad);
|
|
77
|
+
if (!tracked.current?.releaseLoad) {
|
|
78
|
+
context.autoTracking?.({
|
|
79
|
+
appId: context.appId,
|
|
80
|
+
code: context.code,
|
|
81
|
+
buildNumber: context.buildNumber,
|
|
82
|
+
screenName,
|
|
83
|
+
componentName: 'Screen',
|
|
84
|
+
state: 'load',
|
|
85
|
+
duration: timeLoad.current,
|
|
86
|
+
});
|
|
87
|
+
navigator?.maxApi?.showToastDebug?.({
|
|
88
|
+
appId: `auto - ${context.appId}`,
|
|
89
|
+
message: `${screenName} screen_load_time ${timeLoad.current}`,
|
|
90
|
+
});
|
|
91
|
+
tracked.current.releaseLoad = true;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* tracking for screen load
|
|
97
|
+
*/
|
|
98
|
+
const onScreenInteraction = () => {
|
|
99
|
+
clearTimeout(tracked.current.timeoutInteraction);
|
|
100
|
+
if (!tracked.current?.releaseInteraction) {
|
|
101
|
+
context.autoTracking?.({
|
|
102
|
+
appId: context.appId,
|
|
103
|
+
code: context.code,
|
|
104
|
+
buildNumber: context.buildNumber,
|
|
105
|
+
screenName,
|
|
106
|
+
componentName: 'Screen',
|
|
107
|
+
state: 'interaction',
|
|
108
|
+
duration: timeInteraction.current - timeLoad.current,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
navigator?.maxApi?.showToastDebug?.({
|
|
112
|
+
appId: `auto - ${context.appId}`,
|
|
113
|
+
message: `${screenName} screen_interaction_time ${timeInteraction.current}`,
|
|
114
|
+
});
|
|
115
|
+
tracked.current.releaseInteraction = true;
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
return (
|
|
120
|
+
<ScreenContext.Provider
|
|
121
|
+
value={{
|
|
122
|
+
screenName,
|
|
123
|
+
onElementLoad: () => {
|
|
124
|
+
endTime.current = Date.now();
|
|
125
|
+
interaction.current?.cancel?.();
|
|
126
|
+
interaction.current = InteractionManager.runAfterInteractions(() => {
|
|
127
|
+
timeInteraction.current = Date.now() - startTime.current;
|
|
128
|
+
});
|
|
129
|
+
clearTimeout(timeoutLoad.current);
|
|
130
|
+
timeoutLoad.current = setTimeout(() => {
|
|
131
|
+
if (timeLoad.current === 0) {
|
|
132
|
+
timeLoad.current = endTime.current - startTime.current;
|
|
133
|
+
}
|
|
134
|
+
}, 2000);
|
|
135
|
+
},
|
|
136
|
+
}}>
|
|
137
|
+
<Component
|
|
138
|
+
heightHeader={heightHeader}
|
|
139
|
+
{...data}
|
|
140
|
+
onScreenLoad={onScreenLoad}
|
|
141
|
+
onScreenInteraction={onScreenInteraction}
|
|
142
|
+
/>
|
|
143
|
+
{showGrid && <GridSystem />}
|
|
144
|
+
</ScreenContext.Provider>
|
|
145
|
+
);
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export default StackScreen;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {Platform} from 'react-native';
|
|
2
|
+
import {NavigationContainer} from './NavigationContainer';
|
|
3
|
+
import Screen from '../Layout/Screen';
|
|
4
|
+
import {
|
|
5
|
+
HeaderAnimated,
|
|
6
|
+
HeaderBackground,
|
|
7
|
+
HeaderCustom,
|
|
8
|
+
HeaderRightAction,
|
|
9
|
+
HeaderTitle,
|
|
10
|
+
NavigationButton,
|
|
11
|
+
} from './Components';
|
|
12
|
+
import BottomTab from './BottomTab';
|
|
13
|
+
import {createContext} from 'react';
|
|
14
|
+
import {defaultContext} from '../Consts';
|
|
15
|
+
|
|
16
|
+
const Context = createContext({});
|
|
17
|
+
const ApplicationContext = createContext(defaultContext);
|
|
18
|
+
|
|
19
|
+
const MiniAppContext = (Platform as any).MiniAppContext ?? createContext({});
|
|
20
|
+
const ScreenContext = (Platform as any).ScreenContext ?? createContext({});
|
|
21
|
+
const ComponentContext = (Platform as any).ComponentContext ?? Context;
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
ApplicationContext,
|
|
25
|
+
MiniAppContext,
|
|
26
|
+
ScreenContext,
|
|
27
|
+
ComponentContext,
|
|
28
|
+
NavigationContainer,
|
|
29
|
+
Screen,
|
|
30
|
+
BottomTab,
|
|
31
|
+
NavigationButton,
|
|
32
|
+
HeaderTitle,
|
|
33
|
+
HeaderBackground,
|
|
34
|
+
HeaderRightAction,
|
|
35
|
+
HeaderCustom,
|
|
36
|
+
HeaderAnimated,
|
|
37
|
+
};
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {StackNavigationOptions} from '@react-navigation/stack';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import
|
|
3
|
+
import {Animated, ViewProps} from 'react-native';
|
|
4
4
|
import {PopupNotifyProps} from '../Popup/types';
|
|
5
|
+
import Navigation from './Navigation';
|
|
6
|
+
import Navigator from './Navigator';
|
|
7
|
+
|
|
8
|
+
type Screen = React.ComponentType<NavigationScreenProps>;
|
|
5
9
|
|
|
6
10
|
export type Theme = {
|
|
7
11
|
dark: boolean;
|
|
@@ -59,71 +63,109 @@ export type Theme = {
|
|
|
59
63
|
};
|
|
60
64
|
|
|
61
65
|
export type Context = {
|
|
66
|
+
[key: string]: any;
|
|
62
67
|
theme: Theme;
|
|
63
68
|
navigator?: Navigator;
|
|
69
|
+
showGrid?: boolean;
|
|
70
|
+
translate?: (key: string) => string;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export type LocalizationObject = {
|
|
74
|
+
vi: {
|
|
75
|
+
[key: string]: string;
|
|
76
|
+
};
|
|
77
|
+
en: {
|
|
78
|
+
[key: string]: string;
|
|
79
|
+
};
|
|
64
80
|
};
|
|
65
81
|
|
|
66
82
|
export type NavigationContainerProps = {
|
|
67
|
-
screen:
|
|
83
|
+
screen: Screen;
|
|
68
84
|
options?: NavigationOptions;
|
|
69
85
|
theme: Theme;
|
|
70
|
-
maxApi
|
|
86
|
+
maxApi: any;
|
|
87
|
+
localization?: LocalizationObject;
|
|
88
|
+
initialParams?: any;
|
|
71
89
|
};
|
|
72
90
|
|
|
73
|
-
export
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
scrollViewProps?: ScrollViewProps;
|
|
79
|
-
footerComponent?: React.ElementType;
|
|
80
|
-
}
|
|
91
|
+
export type NavigationScreenProps = {
|
|
92
|
+
[key: string]: any;
|
|
93
|
+
options?: NavigationOptions;
|
|
94
|
+
navigation: Navigation;
|
|
95
|
+
};
|
|
81
96
|
|
|
82
97
|
export type ScreenParams = {
|
|
83
98
|
[key: string]: any;
|
|
84
|
-
screen:
|
|
99
|
+
screen: Screen;
|
|
85
100
|
options?: NavigationOptions;
|
|
86
101
|
};
|
|
87
102
|
|
|
88
|
-
export
|
|
103
|
+
export type ModalParams = {
|
|
89
104
|
[key: string]: any;
|
|
90
|
-
screen:
|
|
91
|
-
onDismiss?: (
|
|
105
|
+
screen: Screen;
|
|
106
|
+
onDismiss?: () => void;
|
|
92
107
|
barrierDismissible?: boolean;
|
|
93
|
-
}
|
|
108
|
+
};
|
|
94
109
|
|
|
95
|
-
export
|
|
110
|
+
export type BottomSheetParams = {
|
|
96
111
|
[key: string]: any;
|
|
97
|
-
|
|
98
|
-
|
|
112
|
+
screen: Screen;
|
|
113
|
+
options: {
|
|
114
|
+
title: string;
|
|
115
|
+
surface?: boolean;
|
|
116
|
+
};
|
|
117
|
+
snapPoint?: '30%' | '50%' | '70%' | '90%' | 'content';
|
|
118
|
+
surface?: boolean;
|
|
119
|
+
onDismiss?: (type?: string) => void;
|
|
120
|
+
barrierDismissible?: boolean;
|
|
121
|
+
draggable?: boolean;
|
|
122
|
+
dragOnContent?: boolean;
|
|
123
|
+
};
|
|
99
124
|
|
|
100
125
|
export type NavigationButtonProps = {
|
|
101
126
|
icon: string;
|
|
102
127
|
tintColor?: string;
|
|
103
|
-
backgroundColor?: string;
|
|
104
128
|
useBorder?: boolean;
|
|
105
129
|
onPress: () => void;
|
|
130
|
+
badgeType?: 'dot' | 'number';
|
|
131
|
+
badgeValue?: number;
|
|
106
132
|
accessibilityLabel?: string;
|
|
107
133
|
};
|
|
108
134
|
|
|
109
|
-
export type
|
|
135
|
+
export type PinnedToolType = {
|
|
136
|
+
key: string;
|
|
137
|
+
badgeValue?: number;
|
|
138
|
+
badgeType?: 'number' | 'dot';
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export type RuntimeToolType = {
|
|
142
|
+
title: {vi: string; en: string};
|
|
143
|
+
icon: string;
|
|
144
|
+
key: string;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export interface NavigationOptions extends StackNavigationOptions {
|
|
110
148
|
preventBack?: PopupNotifyProps;
|
|
149
|
+
onPressLeftHeader?: () => void;
|
|
111
150
|
surface?: boolean;
|
|
112
|
-
|
|
113
|
-
headerTitleAlign?: 'left' | 'center';
|
|
151
|
+
hiddenBack?: boolean;
|
|
114
152
|
customTitle?: TitleCustomProps;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
153
|
+
toolkitParams?: {
|
|
154
|
+
pinnedTool?: PinnedToolType;
|
|
155
|
+
runtimeTools?: RuntimeToolType[];
|
|
156
|
+
preventClose?: PopupNotifyProps;
|
|
157
|
+
};
|
|
158
|
+
}
|
|
118
159
|
|
|
119
160
|
export interface HeaderBackProps extends NavigationButtonProps {
|
|
120
161
|
preventBack?: PopupNotifyProps;
|
|
162
|
+
onPressLeftHeader?: () => void;
|
|
121
163
|
}
|
|
122
164
|
|
|
123
165
|
export type HeaderBackgroundProps = {
|
|
124
166
|
image?: string | null;
|
|
125
|
-
backgroundColor?: string | null;
|
|
126
167
|
animatedValue?: Animated.Value;
|
|
168
|
+
useSurface?: boolean;
|
|
127
169
|
};
|
|
128
170
|
|
|
129
171
|
export type TitleCustomProps = {
|
|
@@ -139,19 +181,45 @@ export type TitleCustomProps = {
|
|
|
139
181
|
export type HeaderToolkitProps = {
|
|
140
182
|
[key: string]: any;
|
|
141
183
|
appCode: string;
|
|
142
|
-
|
|
143
|
-
type: string;
|
|
144
|
-
onAction?: (action: string) => void;
|
|
184
|
+
configs: any[];
|
|
145
185
|
};
|
|
146
186
|
|
|
187
|
+
export interface HeaderAnimatedProps extends ViewProps {
|
|
188
|
+
animatedValue: Animated.Value;
|
|
189
|
+
image: string;
|
|
190
|
+
}
|
|
191
|
+
|
|
147
192
|
export type BottomTabItemProps = {
|
|
193
|
+
name: string;
|
|
148
194
|
label: string;
|
|
149
195
|
icon: string;
|
|
150
196
|
showDot?: boolean;
|
|
151
|
-
badgeLabel?: string;
|
|
152
|
-
screen:
|
|
197
|
+
badgeLabel?: string | number;
|
|
198
|
+
screen: Screen;
|
|
199
|
+
options: NavigationOptions;
|
|
153
200
|
};
|
|
154
201
|
|
|
155
202
|
export type BottomTabProps = {
|
|
203
|
+
nested?: boolean;
|
|
156
204
|
tabs: BottomTabItemProps[];
|
|
205
|
+
initialRouteName?: string;
|
|
206
|
+
navigation: Navigation;
|
|
207
|
+
listeners?: {
|
|
208
|
+
tabPress?: any;
|
|
209
|
+
focus?: any;
|
|
210
|
+
};
|
|
211
|
+
floatingButton?: FloatingButtonProps;
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
export type FloatingButtonProps = {
|
|
215
|
+
container?: React.ReactNode;
|
|
216
|
+
icon: string | React.ReactNode;
|
|
217
|
+
label: string;
|
|
218
|
+
onPress: () => void;
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
export type AnimatedHeader = {
|
|
222
|
+
type: 'default' | 'surface';
|
|
223
|
+
component?: (props?: any) => React.ReactElement;
|
|
224
|
+
headerTitle?: (props?: any) => React.ReactElement;
|
|
157
225
|
};
|