@momo-kits/foundation 0.92.7-rc.21 → 0.92.7-rc.22

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 (57) hide show
  1. package/Application/BottomSheet.tsx +216 -0
  2. package/Application/BottomTab/BottomTabBar.tsx +62 -223
  3. package/Application/BottomTab/index.tsx +15 -11
  4. package/Application/Components.tsx +291 -45
  5. package/Application/Localize.ts +44 -0
  6. package/Application/ModalScreen.tsx +11 -181
  7. package/Application/Navigation.ts +4 -18
  8. package/Application/NavigationContainer.tsx +10 -28
  9. package/Application/Navigator.ts +14 -16
  10. package/Application/StackScreen.tsx +222 -42
  11. package/Application/index.ts +5 -3
  12. package/Application/types.ts +47 -29
  13. package/Application/utils.tsx +61 -19
  14. package/Assets/icon_bank.json +1 -1
  15. package/Badge/BadgeDotAnimation.tsx +95 -0
  16. package/Badge/index.tsx +2 -1
  17. package/Badge/styles.ts +50 -6
  18. package/Button/index.tsx +7 -8
  19. package/Icon/index.tsx +1 -1
  20. package/Icon/types.ts +1 -2
  21. package/Image/index.tsx +0 -1
  22. package/Input/Input.tsx +51 -17
  23. package/Input/InputDropDown.tsx +42 -45
  24. package/Input/InputMoney.tsx +65 -6
  25. package/Input/InputOTP.tsx +14 -13
  26. package/Input/InputSearch.tsx +259 -146
  27. package/Input/InputTextArea.tsx +0 -1
  28. package/Input/TextTyping.tsx +113 -0
  29. package/Input/common.tsx +29 -10
  30. package/Input/index.tsx +84 -89
  31. package/Input/styles.ts +44 -7
  32. package/Input/utils.ts +1 -1
  33. package/Layout/Card.tsx +4 -3
  34. package/Layout/FloatingButton.tsx +3 -3
  35. package/Layout/GridSystem.tsx +1 -1
  36. package/Layout/ItemList.tsx +3 -2
  37. package/Layout/Screen.tsx +188 -102
  38. package/Layout/Section.tsx +4 -3
  39. package/Layout/styles.ts +0 -6
  40. package/Layout/types.ts +1 -1
  41. package/Layout/utils.ts +2 -2
  42. package/Loader/index.tsx +2 -0
  43. package/Pagination/PaginationScroll.tsx +2 -2
  44. package/Pagination/styles.ts +1 -1
  45. package/Popup/PopupNotify.tsx +7 -7
  46. package/Popup/PopupPromotion.tsx +1 -1
  47. package/Popup/types.ts +1 -1
  48. package/Tag/index.tsx +9 -2
  49. package/Tag/styles.ts +3 -2
  50. package/Tag/types.ts +12 -0
  51. package/Title/index.tsx +20 -7
  52. package/Title/styles.ts +4 -4
  53. package/code-scanner.js +141 -124
  54. package/index.ts +7 -0
  55. package/package.json +5 -4
  56. package/publish.sh +16 -21
  57. package/tsconfig.json +1 -1
@@ -4,29 +4,16 @@ import {
4
4
  Platform,
5
5
  Pressable,
6
6
  StyleSheet,
7
- TouchableOpacity,
8
7
  View,
9
8
  } from 'react-native';
10
- import {Modalize} from 'react-native-modalize';
11
- import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
12
9
 
13
10
  import {ApplicationContext} from './index';
14
- import {Radius, Spacing, Styles} from '../Consts';
15
- import {Icon} from '../Icon';
16
- import {Text} from '../Text';
11
+ import {Styles} from '../Consts';
17
12
  import Navigation from './Navigation';
18
- import {BottomSheetParams, ModalParams} from './types';
13
+ import {ModalParams} from './types';
14
+ import BottomSheet from './BottomSheet';
19
15
 
20
16
  const ModalScreen: React.FC<any> = props => {
21
- /**
22
- * dismiss callback when modal | bottom sheet dismissed
23
- */
24
- useEffect(() => {
25
- return () => {
26
- props.route.params?.onDismiss?.();
27
- };
28
- }, []);
29
-
30
17
  if (props.route?.params?.isBottomSheet) {
31
18
  return <BottomSheet {...props} />;
32
19
  }
@@ -34,17 +21,22 @@ const ModalScreen: React.FC<any> = props => {
34
21
  };
35
22
 
36
23
  const Modal: React.FC<ModalParams> = props => {
37
- const {theme, navigator} = useContext(ApplicationContext);
24
+ const {navigator} = useContext(ApplicationContext);
38
25
  const {screen, barrierDismissible} = props.route.params;
39
26
  const Component = useRef(screen).current;
40
- const navigation = new Navigation(props.navigation, theme);
27
+ const navigation = new Navigation(props.navigation);
41
28
  const params = {
42
29
  ...props.route.params,
43
30
  navigation,
44
31
  };
45
-
46
32
  delete params.screen;
47
33
 
34
+ useEffect(() => {
35
+ return () => {
36
+ props.route.params?.onDismiss?.();
37
+ };
38
+ }, []);
39
+
48
40
  const onDismiss = () => {
49
41
  if (barrierDismissible) {
50
42
  return;
@@ -83,118 +75,6 @@ const Modal: React.FC<ModalParams> = props => {
83
75
  );
84
76
  };
85
77
 
86
- const BottomSheet: React.FC<BottomSheetParams> = props => {
87
- const {theme, navigator} = useContext(ApplicationContext);
88
- const insets = useSafeAreaInsets();
89
-
90
- const {
91
- screen: Screen,
92
- options,
93
- footerComponent,
94
- scrollViewProps,
95
- surface,
96
- }: BottomSheetParams = props.route.params;
97
-
98
- const navigation = new Navigation(props.navigation, theme);
99
-
100
- const params = {
101
- ...props.route.params,
102
- navigation,
103
- };
104
-
105
- delete params.screen;
106
- const modalRef = useRef<Modalize>(null);
107
-
108
- useEffect(() => {
109
- modalRef.current?.open();
110
- }, []);
111
-
112
- const handleClose = () => {
113
- modalRef?.current?.close();
114
- };
115
-
116
- /**
117
- * build header
118
- * @param title
119
- * @param onClose
120
- */
121
- const headerDefault = (title: string, onClose: () => void) => {
122
- return (
123
- <View
124
- style={[
125
- styles.header,
126
- surface && {
127
- borderBottomColor: theme.colors.border.default,
128
- borderBottomWidth: 1,
129
- },
130
- ]}>
131
- <View style={styles.iconButton} />
132
- <Text
133
- style={styles.textOption}
134
- numberOfLines={1}
135
- typography="header_default_bold">
136
- {title ?? ''}
137
- </Text>
138
- <TouchableOpacity style={styles.iconButton} onPress={onClose}>
139
- <Icon source="navigation_close" />
140
- </TouchableOpacity>
141
- </View>
142
- );
143
- };
144
-
145
- /**
146
- * build footer
147
- * @param footerComponent
148
- */
149
- const footerDefault = (footerComponent: React.ReactNode) => {
150
- if (footerComponent) {
151
- return (
152
- <View
153
- style={{
154
- marginBottom: Math.min(insets.bottom, 21),
155
- paddingHorizontal: Spacing.M,
156
- paddingVertical: Spacing.S,
157
- }}>
158
- {footerComponent}
159
- </View>
160
- );
161
- }
162
- };
163
-
164
- return (
165
- <SafeAreaView style={Styles.flex}>
166
- <Modalize
167
- keyboardAvoidingOffset={-20}
168
- adjustToContentHeight
169
- closeOnOverlayTap
170
- closeSnapPointStraightEnabled
171
- onClosed={() => {
172
- navigator?.pop();
173
- }}
174
- handlePosition="inside"
175
- withHandle={true}
176
- disableScrollIfPossible={true}
177
- modalTopOffset={insets.top}
178
- ref={modalRef}
179
- scrollViewProps={scrollViewProps}
180
- HeaderComponent={headerDefault(
181
- options?.title ?? options?.customTitle?.title ?? '',
182
- handleClose,
183
- )}
184
- modalStyle={{
185
- backgroundColor: surface
186
- ? theme.colors.background.surface
187
- : theme.colors.background.default,
188
- }}
189
- FooterComponent={footerDefault(footerComponent)}>
190
- <View style={styles.bottomSheetContainer}>
191
- <Screen {...props} {...params} />
192
- </View>
193
- </Modalize>
194
- </SafeAreaView>
195
- );
196
- };
197
-
198
78
  const styles = StyleSheet.create({
199
79
  container: {flex: 1, flexDirection: 'row'},
200
80
  modalContent: {
@@ -212,56 +92,6 @@ const styles = StyleSheet.create({
212
92
  flex: 1,
213
93
  minHeight: '10%',
214
94
  },
215
- sheetContainer: {
216
- height: '100%',
217
- width: '100%',
218
- borderTopLeftRadius: Radius.M,
219
- borderTopRightRadius: Radius.M,
220
- overflow: 'hidden',
221
- },
222
- indicatorContainer: {
223
- width: '100%',
224
- paddingTop: Spacing.S,
225
- paddingBottom: Spacing.XS,
226
- alignItems: 'center',
227
- justifyContent: 'center',
228
- },
229
- indicator: {
230
- width: 40,
231
- height: 4,
232
- borderRadius: Radius.S,
233
- },
234
- bottomSheetContainer: {
235
- width: '100%',
236
- },
237
- header: {
238
- marginTop: 10,
239
- height: 56,
240
- width: '100%',
241
- alignItems: 'center',
242
- flexDirection: 'row',
243
- },
244
- textOption: {
245
- fontSize: 16,
246
- color: '#303233',
247
- textAlign: 'center',
248
- fontWeight: 'bold',
249
- paddingHorizontal: Spacing.L,
250
- flex: 1,
251
- },
252
- iconButton: {
253
- width: 24,
254
- height: 24,
255
- alignItems: 'center',
256
- justifyContent: 'center',
257
- marginHorizontal: Spacing.M,
258
- },
259
- icon: {
260
- width: 24,
261
- height: 24,
262
- tintColor: '#303233',
263
- backgroundColor: 'red',
264
- },
265
95
  });
266
96
 
267
97
  export default ModalScreen;
@@ -1,17 +1,13 @@
1
- import React from 'react';
2
1
  import {NavigationProp} from '@react-navigation/native';
3
- import {NavigationOptions, Theme} from './types';
4
- import {HeaderRightAction} from './index';
2
+ import {NavigationOptions} from './types';
5
3
  import {getOptions} from './utils';
6
- import {HeaderToolkitAction} from './Components';
7
4
 
8
5
  class Navigation {
9
6
  instance: NavigationProp<any>;
10
- readonly theme: Theme;
7
+ onHeaderRightChange?: (width: number) => void;
11
8
 
12
- constructor(instance: any, theme: Theme) {
9
+ constructor(instance: any) {
13
10
  this.instance = instance;
14
- this.theme = theme;
15
11
  }
16
12
 
17
13
  /**
@@ -19,16 +15,6 @@ class Navigation {
19
15
  * @param params
20
16
  */
21
17
  private filterParams = (params: NavigationOptions) => {
22
- if (params.headerRight) {
23
- const headerRight = params.headerRight?.({}) as React.ReactElement;
24
- const type = headerRight?.type;
25
- if (type !== HeaderRightAction && type !== HeaderToolkitAction) {
26
- console.warn(
27
- 'headerRight contains element type of HeaderRightAction | HeaderToolkitAction, Please check again.',
28
- );
29
- }
30
- }
31
-
32
18
  if (params.headerLeft) {
33
19
  console.warn('headerLeft not allow override render by design system!');
34
20
  delete params.headerLeft;
@@ -42,7 +28,7 @@ class Navigation {
42
28
  * @param params
43
29
  */
44
30
  setOptions = (params: NavigationOptions) => {
45
- params = getOptions(this.filterParams(params), this.theme);
31
+ params = getOptions(this.filterParams(params), this);
46
32
  this.instance.setOptions(params);
47
33
  };
48
34
  }
@@ -4,22 +4,15 @@ import {
4
4
  NavigationContainer as ReactNavigationContainer,
5
5
  NavigationContainerRef,
6
6
  } from '@react-navigation/native';
7
- import {BottomSheetModalProvider} from '@gorhom/bottom-sheet';
8
7
  import {createStackNavigator} from '@react-navigation/stack';
9
8
  import {DeviceEventEmitter} from 'react-native';
10
9
  import StackScreen from './StackScreen';
11
10
  import ModalScreen from './ModalScreen';
12
11
  import Navigator from './Navigator';
13
12
  import {getDialogOptions, getModalOptions, getStackOptions} from './utils';
14
- import {LocalizationObject, NavigationContainerProps} from './types';
13
+ import {NavigationContainerProps} from './types';
15
14
  import {ApplicationContext} from './index';
16
- import kitLocalization from '../Assets/language.json';
17
-
18
- /**
19
- * link for deprecated
20
- */
21
-
22
- console.log(typeof BottomSheetModalProvider);
15
+ import Localize from './Localize';
23
16
 
24
17
  const Stack = createStackNavigator();
25
18
 
@@ -28,15 +21,18 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
28
21
  theme,
29
22
  options,
30
23
  maxApi,
31
- localization,
32
24
  initialParams,
25
+ localize = new Localize({vi: {}, en: {}}),
33
26
  }) => {
34
27
  const navigationRef = useRef<NavigationContainerRef>(null);
35
28
  const isReady = useRef(false);
36
29
  const navigator = useRef(new Navigator(navigationRef, isReady));
37
30
  const [showGrid, setShowGrid] = useState(false);
38
31
  const config = useRef<any>();
39
-
32
+ /**
33
+ * inject data for navigator
34
+ */
35
+ navigator.current.maxApi = maxApi;
40
36
  /**
41
37
  * handle mini language & listen change
42
38
  * engine only shake to enable grid view
@@ -46,7 +42,7 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
46
42
  'onChangeGrid',
47
43
  enable => {
48
44
  setShowGrid(!!enable);
49
- },
45
+ }
50
46
  );
51
47
 
52
48
  return () => {
@@ -54,22 +50,8 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
54
50
  };
55
51
  }, []);
56
52
 
57
- /**
58
- * inject data for navigator
59
- */
60
- navigator.current.maxApi = maxApi;
61
-
62
- /**
63
- * translate
64
- * @param key
65
- */
66
53
  const translate = (key: string) => {
67
- const language: 'vi' | 'en' = 'vi';
68
- const mergedLocalization: LocalizationObject = {
69
- vi: {...localization?.vi, ...kitLocalization.vi},
70
- en: {...localization?.en, ...kitLocalization.en},
71
- };
72
- return mergedLocalization?.[language]?.[key] || key;
54
+ return localize?.translate(key);
73
55
  };
74
56
 
75
57
  return (
@@ -94,7 +76,7 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
94
76
  notification: theme.colors.error.primary,
95
77
  },
96
78
  }}
97
- ref={navigator.current?.ref}
79
+ ref={navigationRef}
98
80
  onReady={() => {
99
81
  isReady.current = true;
100
82
  }}
@@ -12,7 +12,7 @@ class Navigator {
12
12
  toolkitConfig?: HeaderToolkitProps;
13
13
  maxApi?: any;
14
14
  dismissData?: any;
15
- toolkitCallback?: (item: any) => void;
15
+ toolkitCallback?: (key: string) => void;
16
16
 
17
17
  constructor(navigation: any, isReady: any) {
18
18
  this.ref = navigation;
@@ -25,7 +25,7 @@ class Navigator {
25
25
  */
26
26
  push = (params: ScreenParams) => {
27
27
  if (this.isReady.current) {
28
- this.ref.current.dispatch(StackActions.push('Stack', params));
28
+ this.ref.current?.dispatch?.(StackActions.push('Stack', params));
29
29
  }
30
30
  };
31
31
 
@@ -35,7 +35,7 @@ class Navigator {
35
35
  */
36
36
  replace = (params: ScreenParams) => {
37
37
  if (this.isReady.current) {
38
- this.ref.current.dispatch(StackActions.replace('Stack', params));
38
+ this.ref.current?.dispatch?.(StackActions.replace('Stack', params));
39
39
  }
40
40
  };
41
41
  /**
@@ -44,7 +44,7 @@ class Navigator {
44
44
  */
45
45
  pop = (count?: number) => {
46
46
  if (this.isReady.current) {
47
- this.ref.current.dispatch(StackActions.pop(count ?? 1));
47
+ this.ref.current?.dispatch?.(StackActions.pop(count ?? 1));
48
48
  }
49
49
  };
50
50
 
@@ -54,7 +54,7 @@ class Navigator {
54
54
  */
55
55
  present = (params: ScreenParams) => {
56
56
  if (this.isReady.current) {
57
- this.ref.current.dispatch(StackActions.push('Dialog', params));
57
+ this.ref.current?.dispatch?.(StackActions.push('Dialog', params));
58
58
  }
59
59
  };
60
60
 
@@ -64,7 +64,7 @@ class Navigator {
64
64
  */
65
65
  showModal = (params: ModalParams) => {
66
66
  if (this.isReady.current) {
67
- this.ref.current.dispatch(StackActions.push('Modal', params));
67
+ this.ref.current?.dispatch?.(StackActions.push('Modal', params));
68
68
  }
69
69
  };
70
70
 
@@ -74,11 +74,11 @@ class Navigator {
74
74
  */
75
75
  showBottomSheet = (params: BottomSheetParams) => {
76
76
  if (this.isReady.current) {
77
- this.ref.current.dispatch(
77
+ this.ref.current?.dispatch?.(
78
78
  StackActions.push('Modal', {
79
79
  ...params,
80
80
  isBottomSheet: true,
81
- }),
81
+ })
82
82
  );
83
83
  }
84
84
  };
@@ -88,7 +88,7 @@ class Navigator {
88
88
  */
89
89
  popToTop = () => {
90
90
  if (this.isReady.current) {
91
- this.ref.current.dispatch(StackActions.popToTop());
91
+ this.ref.current?.dispatch?.(StackActions.popToTop());
92
92
  }
93
93
  };
94
94
 
@@ -99,11 +99,11 @@ class Navigator {
99
99
  */
100
100
  navigate = (name: string, params: any) => {
101
101
  if (this.isReady.current) {
102
- this.ref.current.dispatch(
102
+ this.ref.current?.dispatch?.(
103
103
  CommonActions.navigate({
104
104
  name,
105
105
  params,
106
- }),
106
+ })
107
107
  );
108
108
  }
109
109
  };
@@ -114,7 +114,7 @@ class Navigator {
114
114
  */
115
115
  reset = (params: ScreenParams) => {
116
116
  if (this.isReady.current) {
117
- this.ref.current.dispatch(
117
+ this.ref.current?.dispatch?.(
118
118
  CommonActions.reset({
119
119
  index: 0,
120
120
  routes: [
@@ -124,7 +124,7 @@ class Navigator {
124
124
  params,
125
125
  },
126
126
  ],
127
- }),
127
+ })
128
128
  );
129
129
  }
130
130
  };
@@ -141,9 +141,7 @@ class Navigator {
141
141
  * set callback function for toolkit
142
142
  * @param callback
143
143
  */
144
- setToolkitCallback = (
145
- callback: (item: {key: string; action: string}) => void,
146
- ) => {
144
+ setToolkitCallback = (callback: (key: string) => void) => {
147
145
  this.toolkitCallback = callback;
148
146
  };
149
147
  }