@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.
Files changed (113) hide show
  1. package/Application/BottomSheet.tsx +225 -0
  2. package/Application/BottomTab/BottomTabBar.tsx +291 -0
  3. package/Application/BottomTab/index.tsx +138 -0
  4. package/Application/Components.tsx +555 -0
  5. package/Application/ModalScreen.tsx +97 -0
  6. package/Application/Navigation.ts +50 -0
  7. package/Application/NavigationContainer.tsx +121 -0
  8. package/Application/Navigator.ts +151 -0
  9. package/Application/StackScreen.tsx +148 -0
  10. package/Application/index.ts +37 -0
  11. package/{Navigation → Application}/types.ts +101 -33
  12. package/Application/utils.tsx +153 -0
  13. package/Assets/DotAnimation.json +256 -0
  14. package/Assets/SpinnerAnimation.json +1027 -0
  15. package/Assets/icon.json +89 -5
  16. package/Assets/icon_bank.json +506 -0
  17. package/Assets/language.json +202 -0
  18. package/Badge/Badge.tsx +56 -0
  19. package/Badge/BadgeDot.tsx +11 -0
  20. package/Badge/BadgeRibbon.tsx +125 -0
  21. package/Badge/Shape.tsx +29 -0
  22. package/Badge/index.tsx +7 -0
  23. package/Badge/styles.ts +58 -0
  24. package/Badge/types.ts +63 -0
  25. package/Button/index.tsx +91 -40
  26. package/Button/styles.ts +19 -0
  27. package/CheckBox/index.tsx +58 -43
  28. package/CheckBox/styles.ts +1 -1
  29. package/CheckBox/types.ts +6 -4
  30. package/Consts/colors+spacing+radius.ts +18 -0
  31. package/Consts/styles.ts +0 -26
  32. package/Consts/theme.ts +5 -1
  33. package/Divider/index.tsx +3 -1
  34. package/Icon/index.tsx +15 -10
  35. package/Icon/types.ts +4 -3
  36. package/IconButton/index.tsx +24 -15
  37. package/Image/index.tsx +63 -45
  38. package/Image/styles.ts +1 -9
  39. package/Image/types.ts +5 -1
  40. package/Input/Input.tsx +227 -115
  41. package/Input/InputDropDown.tsx +132 -0
  42. package/Input/InputMoney.tsx +173 -110
  43. package/Input/InputOTP.tsx +257 -0
  44. package/Input/InputSearch.tsx +160 -130
  45. package/Input/InputTextArea.tsx +149 -121
  46. package/Input/common.tsx +36 -18
  47. package/Input/index.tsx +212 -17
  48. package/Input/styles.ts +44 -7
  49. package/Input/utils.ts +2 -2
  50. package/Layout/Card.tsx +76 -37
  51. package/Layout/FloatingButton.tsx +168 -0
  52. package/Layout/GridSystem.tsx +35 -23
  53. package/Layout/Item.tsx +29 -33
  54. package/Layout/ItemList.tsx +55 -0
  55. package/Layout/ItemSectionList.tsx +39 -0
  56. package/Layout/Screen.tsx +390 -0
  57. package/Layout/Section.tsx +73 -35
  58. package/Layout/index.ts +13 -3
  59. package/Layout/styles.ts +101 -0
  60. package/Layout/types.ts +1 -37
  61. package/Layout/utils.ts +38 -43
  62. package/Loader/DotLoader.tsx +37 -0
  63. package/Loader/Loader.tsx +13 -0
  64. package/Loader/ProgressBar.tsx +44 -0
  65. package/Loader/Spinner.tsx +29 -0
  66. package/Loader/index.tsx +4 -0
  67. package/Loader/styles.ts +10 -0
  68. package/Loader/types.ts +35 -0
  69. package/Loader/utils.ts +25 -0
  70. package/Pagination/Dot.tsx +1 -1
  71. package/Pagination/PaginationDot.tsx +8 -3
  72. package/Pagination/PaginationNumber.tsx +8 -7
  73. package/Pagination/PaginationScroll.tsx +1 -1
  74. package/Pagination/PaginationWhiteDot.tsx +8 -5
  75. package/Pagination/styles.ts +3 -0
  76. package/Pagination/types.ts +2 -0
  77. package/Popup/PopupNotify.tsx +108 -46
  78. package/Popup/PopupPromotion.tsx +63 -22
  79. package/Popup/types.ts +15 -4
  80. package/Radio/index.tsx +35 -21
  81. package/Radio/types.ts +7 -5
  82. package/Skeleton/index.tsx +1 -1
  83. package/Skeleton/types.ts +3 -0
  84. package/Switch/index.tsx +35 -24
  85. package/Switch/types.ts +5 -3
  86. package/Tag/index.tsx +1 -1
  87. package/Text/index.tsx +32 -26
  88. package/Text/styles.ts +38 -0
  89. package/Text/types.ts +25 -13
  90. package/Text/utils.ts +14 -0
  91. package/Title/index.tsx +197 -0
  92. package/Title/styles.ts +79 -0
  93. package/Title/types.ts +20 -0
  94. package/code-scanner.js +143 -0
  95. package/index.ts +22 -2
  96. package/migrate_typo.js +56 -0
  97. package/package.json +44 -39
  98. package/publish.sh +2 -5
  99. package/tsconfig.json +24 -0
  100. package/verify.js +47 -0
  101. package/Assets/header-background.png +0 -0
  102. package/Layout/ScreenContainer.tsx +0 -121
  103. package/Navigation/BottomTab.tsx +0 -39
  104. package/Navigation/Components.tsx +0 -365
  105. package/Navigation/ModalScreen.tsx +0 -226
  106. package/Navigation/Navigation.ts +0 -44
  107. package/Navigation/NavigationButton.tsx +0 -54
  108. package/Navigation/NavigationContainer.tsx +0 -77
  109. package/Navigation/Navigator.ts +0 -82
  110. package/Navigation/Observer.ts +0 -79
  111. package/Navigation/StackScreen.tsx +0 -27
  112. package/Navigation/index.ts +0 -14
  113. 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 {Animated, ScrollViewProps, ViewProps} from 'react-native';
1
+ import {StackNavigationOptions} from '@react-navigation/stack';
2
2
  import React from 'react';
3
- import Navigator from './Navigator';
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: React.ElementType;
83
+ screen: Screen;
68
84
  options?: NavigationOptions;
69
85
  theme: Theme;
70
- maxApi?: any;
86
+ maxApi: any;
87
+ localization?: LocalizationObject;
88
+ initialParams?: any;
71
89
  };
72
90
 
73
- export interface ScreenContainerProps extends ViewProps {
74
- enableKeyboardAvoidingView?: boolean;
75
- headerBackground?: string;
76
- scrollable?: boolean;
77
- scrollY?: Animated.Value;
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: React.ElementType;
99
+ screen: Screen;
85
100
  options?: NavigationOptions;
86
101
  };
87
102
 
88
- export interface ModalParams extends ScreenParams {
103
+ export type ModalParams = {
89
104
  [key: string]: any;
90
- screen: React.ElementType;
91
- onDismiss?: (mounted?: boolean) => void;
105
+ screen: Screen;
106
+ onDismiss?: () => void;
92
107
  barrierDismissible?: boolean;
93
- }
108
+ };
94
109
 
95
- export interface BottomSheetParams extends ScreenParams {
110
+ export type BottomSheetParams = {
96
111
  [key: string]: any;
97
- onDismiss?: () => void;
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 NavigationOptions = {
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
- title?: string;
113
- headerTitleAlign?: 'left' | 'center';
151
+ hiddenBack?: boolean;
114
152
  customTitle?: TitleCustomProps;
115
- headerRight?: (props?: any) => React.ReactElement;
116
- animatedValue?: Animated.Value;
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
- hidden: boolean;
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: React.ComponentType<any>;
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
  };