@momo-kits/foundation 0.81.49 → 0.81.51-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 (73) hide show
  1. package/Application/BottomSheet.tsx +216 -0
  2. package/Application/BottomTab/BottomTabBar.tsx +278 -0
  3. package/Application/{BottomTab.tsx → BottomTab/index.tsx} +42 -18
  4. package/Application/Components.tsx +356 -91
  5. package/Application/Localize.ts +44 -0
  6. package/Application/ModalScreen.tsx +14 -185
  7. package/Application/Navigation.ts +5 -19
  8. package/Application/NavigationContainer.tsx +62 -72
  9. package/Application/Navigator.ts +154 -48
  10. package/Application/StackScreen.tsx +289 -32
  11. package/Application/constants.ts +9 -0
  12. package/Application/index.ts +13 -15
  13. package/Application/types.ts +81 -35
  14. package/Application/utils.tsx +76 -30
  15. package/Assets/icon_bank.json +1 -1
  16. package/Badge/Badge.tsx +1 -1
  17. package/Badge/BadgeDotAnimation.tsx +95 -0
  18. package/Badge/index.tsx +2 -1
  19. package/Badge/styles.ts +50 -6
  20. package/Button/index.tsx +44 -26
  21. package/CheckBox/index.tsx +37 -26
  22. package/CheckBox/types.ts +5 -3
  23. package/Consts/colors+spacing+radius.ts +14 -0
  24. package/Icon/index.tsx +9 -8
  25. package/Icon/types.ts +2 -2
  26. package/IconButton/index.tsx +24 -14
  27. package/Image/index.tsx +23 -8
  28. package/Image/types.ts +2 -0
  29. package/Input/Input.tsx +116 -26
  30. package/Input/InputDropDown.tsx +66 -51
  31. package/Input/InputMoney.tsx +106 -15
  32. package/Input/InputOTP.tsx +49 -26
  33. package/Input/InputSearch.tsx +252 -99
  34. package/Input/InputTextArea.tsx +26 -6
  35. package/Input/TextTyping.tsx +113 -0
  36. package/Input/common.tsx +48 -22
  37. package/Input/index.tsx +112 -77
  38. package/Input/styles.ts +48 -11
  39. package/Input/utils.ts +1 -1
  40. package/Layout/Card.tsx +4 -3
  41. package/Layout/FloatingButton.tsx +168 -0
  42. package/Layout/GridSystem.tsx +1 -1
  43. package/Layout/ItemList.tsx +3 -2
  44. package/Layout/Screen.tsx +242 -121
  45. package/Layout/Section.tsx +4 -3
  46. package/Layout/styles.ts +11 -13
  47. package/Layout/types.ts +1 -1
  48. package/Layout/utils.ts +4 -4
  49. package/Loader/index.tsx +2 -0
  50. package/Pagination/PaginationScroll.tsx +2 -2
  51. package/Pagination/styles.ts +1 -1
  52. package/Popup/PopupNotify.tsx +57 -46
  53. package/Popup/PopupPromotion.tsx +6 -8
  54. package/Popup/types.ts +1 -7
  55. package/Radio/index.tsx +35 -20
  56. package/Radio/types.ts +5 -3
  57. package/Switch/index.tsx +32 -18
  58. package/Switch/types.ts +5 -3
  59. package/Tag/index.tsx +9 -2
  60. package/Tag/styles.ts +3 -2
  61. package/Tag/types.ts +12 -0
  62. package/Text/index.tsx +24 -5
  63. package/Text/styles.ts +8 -8
  64. package/Text/types.ts +19 -1
  65. package/Title/index.tsx +170 -103
  66. package/Title/styles.ts +36 -9
  67. package/Title/types.ts +16 -48
  68. package/code-scanner.js +125 -16
  69. package/index.ts +7 -0
  70. package/migrate_typo.js +56 -0
  71. package/package.json +10 -9
  72. package/publish.sh +16 -21
  73. package/tsconfig.json +1 -1
package/Button/index.tsx CHANGED
@@ -6,9 +6,8 @@ import {
6
6
  TouchableOpacityProps,
7
7
  View,
8
8
  } from 'react-native';
9
-
10
9
  import LinearGradient from 'react-native-linear-gradient';
11
- import {ApplicationContext} from '../Application';
10
+ import {ApplicationContext, ComponentContext} from '../Application';
12
11
  import {Text} from '../Text';
13
12
  import {Typography} from '../Text/types';
14
13
  import {Colors, Spacing} from '../Consts';
@@ -59,7 +58,7 @@ export interface ButtonProps extends TouchableOpacityProps {
59
58
  /**
60
59
  * If true, the icon of button will use the tint color provided by its container.
61
60
  */
62
- useTintColor?: boolean;
61
+ tintColor?: string;
63
62
 
64
63
  /**
65
64
  * If true, the icon of button will use be show indicator loading.
@@ -70,30 +69,39 @@ export interface ButtonProps extends TouchableOpacityProps {
70
69
  * A callback function that is called when the button is pressed.
71
70
  */
72
71
  onPress: () => void;
72
+
73
+ params?: any;
73
74
  }
74
75
 
75
76
  const Button: FC<ButtonProps> = ({
76
77
  type = 'primary',
77
78
  size = 'large',
78
- useTintColor = true,
79
+ tintColor = null,
79
80
  full = true,
80
81
  iconRight,
81
82
  iconLeft,
82
83
  loading = false,
83
84
  title = 'Button',
84
85
  onPress,
86
+ params,
87
+ accessibilityLabel,
85
88
  ...rest
86
89
  }) => {
87
90
  const {theme, config} = useContext(ApplicationContext);
88
91
  const {gradient, color} = config?.navigationBar?.buttonColors ?? {};
89
92
  let gradientPros;
90
- if (gradient?.length > 0 && type == 'primary') {
93
+ let state = 'enabled';
94
+ if (loading) {
95
+ state = 'loading';
96
+ }
97
+ if (gradient?.length > 0 && type === 'primary') {
91
98
  gradientPros = {
92
99
  colors: gradient,
93
100
  start: {x: 1, y: 0.5},
94
101
  end: {x: 0, y: 0.5},
95
102
  };
96
103
  }
104
+
97
105
  const getSizeStyle = () => {
98
106
  const styleSheet: {[key: string]: any} = styles;
99
107
  return styleSheet[size ?? 'small'];
@@ -209,9 +217,9 @@ const Button: FC<ButtonProps> = ({
209
217
  */
210
218
  const renderTitle = () => {
211
219
  const typography = getTypography();
212
- const color = getTextColor();
220
+ const textColor = getTextColor();
213
221
  return (
214
- <Text typography={typography} color={color} numberOfLines={1}>
222
+ <Text typography={typography} color={textColor} numberOfLines={1}>
215
223
  {title}
216
224
  </Text>
217
225
  );
@@ -223,7 +231,7 @@ const Button: FC<ButtonProps> = ({
223
231
  const renderLeading = () => {
224
232
  const iconSize = getIconSize();
225
233
  const marginRight = getIconSpace();
226
- const color = useTintColor ? getTextColor() : undefined;
234
+ const textColor = tintColor ?? getTextColor();
227
235
 
228
236
  if (loading) {
229
237
  return (
@@ -237,7 +245,7 @@ const Button: FC<ButtonProps> = ({
237
245
  borderRadius: Spacing.M,
238
246
  },
239
247
  ]}>
240
- <Loader type="spinner" color={color} />
248
+ <Loader type="spinner" color={getTextColor()} />
241
249
  </View>
242
250
  );
243
251
  }
@@ -248,7 +256,7 @@ const Button: FC<ButtonProps> = ({
248
256
  styles.leading,
249
257
  {width: iconSize, height: iconSize, marginRight},
250
258
  ]}>
251
- <Icon color={color} source={iconLeft} size={iconSize} />
259
+ <Icon color={textColor} source={iconLeft} size={iconSize} />
252
260
  </View>
253
261
  );
254
262
  }
@@ -258,7 +266,7 @@ const Button: FC<ButtonProps> = ({
258
266
  * render trailing
259
267
  */
260
268
  const renderTrailing = () => {
261
- const color = useTintColor ? getTextColor() : undefined;
269
+ const textColor = tintColor ?? getTextColor();
262
270
  const marginLeft = getIconSpace();
263
271
 
264
272
  if (iconRight) {
@@ -269,7 +277,7 @@ const Button: FC<ButtonProps> = ({
269
277
  styles.trailing,
270
278
  {width: iconSize, height: iconSize, marginLeft},
271
279
  ]}>
272
- <Icon color={color} source={iconRight} size={iconSize} />
280
+ <Icon color={textColor} source={iconRight} size={iconSize} />
273
281
  </View>
274
282
  );
275
283
  }
@@ -289,21 +297,31 @@ const Button: FC<ButtonProps> = ({
289
297
  };
290
298
 
291
299
  const activeOpacity = type === 'disabled' ? 0.75 : 0.5;
292
-
293
300
  return (
294
- <TouchableOpacity
295
- {...rest}
296
- activeOpacity={activeOpacity}
297
- onPress={onPressButton}
298
- style={buttonStyle}>
299
- {renderLeading()}
300
- {renderTitle()}
301
- {renderTrailing()}
302
- {gradientPros && (
303
- <AnimationLinear {...gradientPros} style={styles.gradientView} />
304
- )}
305
- {gradientPros && <View style={styles.strokeView} />}
306
- </TouchableOpacity>
301
+ <ComponentContext.Provider
302
+ value={{
303
+ componentName: 'Button',
304
+ params,
305
+ state: state,
306
+ componentId: accessibilityLabel,
307
+ componentValue: title,
308
+ action: 'click',
309
+ }}>
310
+ <TouchableOpacity
311
+ {...rest}
312
+ accessibilityLabel={accessibilityLabel}
313
+ activeOpacity={activeOpacity}
314
+ onPress={onPressButton}
315
+ style={buttonStyle}>
316
+ {renderLeading()}
317
+ {renderTitle()}
318
+ {renderTrailing()}
319
+ {gradientPros && (
320
+ <AnimationLinear {...gradientPros} style={styles.gradientView} />
321
+ )}
322
+ {gradientPros && <View style={styles.strokeView} />}
323
+ </TouchableOpacity>
324
+ </ComponentContext.Provider>
307
325
  );
308
326
  };
309
327
 
@@ -2,17 +2,20 @@ import React, {FC, useContext} from 'react';
2
2
  import {TouchableOpacity, View} from 'react-native';
3
3
  import {CheckBoxProps} from './types';
4
4
  import styles from './styles';
5
- import {ApplicationContext} from '../Application';
5
+ import {ApplicationContext, ComponentContext} from '../Application';
6
6
  import {Text} from '../Text';
7
7
  import {Icon} from '../Icon';
8
+ import {formatNameLength} from '../Application/utils';
8
9
 
9
10
  const CheckBox: FC<CheckBoxProps> = ({
10
11
  value,
11
- disabled,
12
+ disabled = false,
12
13
  onChange,
13
14
  style,
14
15
  label,
15
16
  indeterminate,
17
+ params,
18
+ accessibilityLabel,
16
19
  }) => {
17
20
  const {theme} = useContext(ApplicationContext);
18
21
  const haveValue = value || indeterminate;
@@ -35,31 +38,39 @@ const CheckBox: FC<CheckBoxProps> = ({
35
38
  }
36
39
 
37
40
  return (
38
- <TouchableOpacity
39
- activeOpacity={0.8}
40
- onPress={() => onChange?.(!value)}
41
- disabled={disabled}
42
- style={[style, styles.container]}>
43
- <View
44
- style={[
45
- {borderColor, backgroundColor, borderWidth: 1},
46
- styles.checkbox,
47
- ]}>
48
- {haveValue && (
49
- <Icon
50
- color={theme.colors.background.surface}
51
- size={20}
52
- source={iconSource}
53
- />
54
- )}
55
- </View>
56
- {!!label && <Text typography={'body_default_regular'}>{label}</Text>}
57
- </TouchableOpacity>
41
+ <ComponentContext.Provider
42
+ value={{
43
+ componentName: 'CheckBox',
44
+ params,
45
+ state: disabled ? 'disabled' : 'filled',
46
+ componentId: accessibilityLabel,
47
+ action: 'click',
48
+ componentLabel: formatNameLength(label || ''),
49
+ componentValue: indeterminate ? 'undetermined' : value,
50
+ }}>
51
+ <TouchableOpacity
52
+ accessibilityLabel={accessibilityLabel}
53
+ activeOpacity={0.8}
54
+ onPress={() => onChange?.(!value)}
55
+ disabled={disabled}
56
+ style={[style, styles.container]}>
57
+ <View
58
+ style={[
59
+ {borderColor, backgroundColor, borderWidth: 1},
60
+ styles.checkbox,
61
+ ]}>
62
+ {haveValue && (
63
+ <Icon
64
+ color={theme.colors.background.surface}
65
+ size={20}
66
+ source={iconSource}
67
+ />
68
+ )}
69
+ </View>
70
+ {!!label && <Text typography={'body_default_regular'}>{label}</Text>}
71
+ </TouchableOpacity>
72
+ </ComponentContext.Provider>
58
73
  );
59
74
  };
60
75
 
61
- CheckBox.defaultProps = {
62
- disabled: false,
63
- };
64
-
65
76
  export {CheckBox};
package/CheckBox/types.ts CHANGED
@@ -1,6 +1,6 @@
1
- import {ViewStyle} from 'react-native';
1
+ import {TouchableOpacityProps, ViewStyle} from 'react-native';
2
2
 
3
- export type CheckBoxProps = {
3
+ export interface CheckBoxProps extends TouchableOpacityProps {
4
4
  /**
5
5
  * Represents whether the CheckBox is currently checked (`true`) or unchecked (`false`).
6
6
  */
@@ -35,4 +35,6 @@ export type CheckBoxProps = {
35
35
  * Accepts an object of style properties.
36
36
  */
37
37
  style?: ViewStyle;
38
- };
38
+
39
+ params?: any;
40
+ }
@@ -213,6 +213,20 @@ const Shadow = {
213
213
  elevation: 6,
214
214
  },
215
215
  }),
216
+
217
+ Pink: Platform.select({
218
+ ios: {
219
+ shadowColor: '#e27eb5',
220
+ shadowOffset: {width: 0, height: 6},
221
+ shadowOpacity: 0.25,
222
+ shadowRadius: 8,
223
+ },
224
+ android: {
225
+ elevation: 16,
226
+ shadowColor: '#e27eb5',
227
+ shadowOpacity: 0.25,
228
+ },
229
+ }),
216
230
  };
217
231
 
218
232
  export {Colors, Spacing, Radius, Shadow};
package/Icon/index.tsx CHANGED
@@ -5,7 +5,12 @@ import {IconProps} from './types';
5
5
  import {ApplicationContext} from '../Application';
6
6
  import {Image} from '../Image';
7
7
 
8
- const Icon: React.FC<IconProps> = ({source, size, color, style = {}}) => {
8
+ const Icon: React.FC<IconProps> = ({
9
+ source = 'ic_back',
10
+ size = 24,
11
+ color,
12
+ style = {},
13
+ }) => {
9
14
  const {theme} = useContext(ApplicationContext);
10
15
 
11
16
  /**
@@ -20,22 +25,18 @@ const Icon: React.FC<IconProps> = ({source, size, color, style = {}}) => {
20
25
  };
21
26
 
22
27
  const tintColorProps = color !== null && {
23
- tintColor: color ?? theme.colors.text.default
24
- }
28
+ tintColor: color ?? theme.colors.text.default,
29
+ };
25
30
 
26
31
  return (
27
32
  <Image
28
33
  loading={false}
29
34
  source={getIconSource()}
30
35
  style={[style, {width: size, height: size}]}
36
+ resizeMode="contain"
31
37
  {...tintColorProps}
32
38
  />
33
39
  );
34
40
  };
35
41
 
36
- Icon.defaultProps = {
37
- source: 'ic_back',
38
- size: 24,
39
- };
40
-
41
42
  export {Icon, IconSources, IconBankSources};
package/Icon/types.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import {ImageStyle} from 'react-native-fast-image';
2
+ import {StyleProp} from 'react-native';
2
3
 
3
4
  export type IconProps = {
4
5
  /**
@@ -15,7 +16,6 @@ export type IconProps = {
15
16
 
16
17
  /**
17
18
  * Optional. Represents the color of the icon.
18
- * It can be any valid color in @momo-kits/foundation.
19
19
  */
20
20
  color?: string | null;
21
21
 
@@ -23,5 +23,5 @@ export type IconProps = {
23
23
  * Optional. Used to apply custom styling to the Icon component.
24
24
  * Accepts an object of style properties.
25
25
  */
26
- style?: ImageStyle;
26
+ style?: StyleProp<ImageStyle>;
27
27
  };
@@ -5,7 +5,7 @@ import {
5
5
  TouchableOpacity,
6
6
  TouchableOpacityProps,
7
7
  } from 'react-native';
8
- import {ApplicationContext} from '../Application';
8
+ import {ApplicationContext, ComponentContext} from '../Application';
9
9
  import {Colors} from '../Consts';
10
10
  import {Icon} from '../Icon';
11
11
  import styles from './styles';
@@ -26,13 +26,17 @@ export interface IconButtonProps extends TouchableOpacityProps {
26
26
  * Optional. Defines the size of the IconButton.
27
27
  */
28
28
  size?: 'large' | 'small';
29
+
30
+ params?: any;
29
31
  }
30
32
 
31
33
  const IconButton: React.FC<IconButtonProps> = ({
32
- type,
34
+ type = 'primary',
33
35
  icon,
34
36
  size,
35
37
  onPress,
38
+ params,
39
+ accessibilityLabel,
36
40
  ...rest
37
41
  }) => {
38
42
  const {theme} = useContext(ApplicationContext);
@@ -121,19 +125,25 @@ const IconButton: React.FC<IconButtonProps> = ({
121
125
  const iconSize = size === 'small' ? 16 : 24;
122
126
 
123
127
  return (
124
- <TouchableOpacity
125
- {...rest}
126
- activeOpacity={activeOpacity}
127
- onPress={onPressButton}
128
- style={buttonStyle}>
129
- <Icon size={iconSize} source={icon} color={getIconColor()} />
130
- </TouchableOpacity>
128
+ <ComponentContext.Provider
129
+ value={{
130
+ componentName: 'IconButton',
131
+ params,
132
+ state: type === 'disabled' ? 'disabled' : 'enabled',
133
+ componentId: accessibilityLabel,
134
+ componentValue: icon,
135
+ action: 'click',
136
+ }}>
137
+ <TouchableOpacity
138
+ {...rest}
139
+ accessibilityLabel={accessibilityLabel}
140
+ activeOpacity={activeOpacity}
141
+ onPress={onPressButton}
142
+ style={buttonStyle}>
143
+ <Icon size={iconSize} source={icon} color={getIconColor()} />
144
+ </TouchableOpacity>
145
+ </ComponentContext.Provider>
131
146
  );
132
147
  };
133
148
 
134
- IconButton.defaultProps = {
135
- type: 'primary',
136
- disabled: false,
137
- };
138
-
139
149
  export {IconButton};
package/Image/index.tsx CHANGED
@@ -1,8 +1,12 @@
1
- import React, {useContext, useRef, useState} from 'react';
1
+ import React, {useContext, useEffect, useRef, useState} from 'react';
2
2
  import {StyleSheet, View} from 'react-native';
3
- import FastImage from 'react-native-fast-image';
3
+ import FastImage, {Source} from 'react-native-fast-image';
4
4
  import styles from './styles';
5
- import {ApplicationContext} from '../Application';
5
+ import {
6
+ ApplicationContext,
7
+ ComponentContext,
8
+ MiniAppContext,
9
+ } from '../Application';
6
10
  import {Skeleton} from '../Skeleton';
7
11
  import {Icon} from '../Icon';
8
12
  import {Styles} from '../Consts';
@@ -13,14 +17,28 @@ type Status = 'success' | 'loading' | 'error';
13
17
  const Image: React.FC<ImageProps> = ({
14
18
  style,
15
19
  source,
16
- loading,
20
+ loading = true,
17
21
  children,
22
+ accessibilityLabel,
18
23
  ...rest
19
24
  }) => {
20
25
  const {theme} = useContext(ApplicationContext);
26
+ const app = useContext<any>(MiniAppContext);
27
+ const component = useContext<any>(ComponentContext);
21
28
  const error = useRef(false);
22
29
  const [status, setStatus] = useState<Status>('success');
23
30
 
31
+ const test: any = {
32
+ accessibilityLabel: accessibilityLabel || `img|${(source as Source).uri}`,
33
+ };
34
+
35
+ useEffect(() => {
36
+ if (app.enableAutoId) {
37
+ component?.addChildren?.(test.accessibilityLabel, 'add');
38
+ return () => component?.addChildren?.(test.accessibilityLabel, 'remove');
39
+ }
40
+ }, []);
41
+
24
42
  /**
25
43
  * render content loading | fail | rendered
26
44
  */
@@ -44,6 +62,7 @@ const Image: React.FC<ImageProps> = ({
44
62
  return (
45
63
  <FastImage
46
64
  {...rest}
65
+ {...test}
47
66
  source={source}
48
67
  style={[styles.container, style]}
49
68
  onProgress={() => {
@@ -75,8 +94,4 @@ const Image: React.FC<ImageProps> = ({
75
94
  );
76
95
  };
77
96
 
78
- Image.defaultProps = {
79
- loading: true,
80
- };
81
-
82
97
  export {Image};
package/Image/types.ts CHANGED
@@ -2,4 +2,6 @@ import {FastImageProps} from 'react-native-fast-image';
2
2
 
3
3
  export interface ImageProps extends FastImageProps {
4
4
  loading?: boolean;
5
+ accessibilityLabel?: string;
6
+ params?: any;
5
7
  }