@momo-kits/foundation 0.76.1-beta.2 → 0.77.1-optimize.2

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 (100) hide show
  1. package/Application/BottomTab/BottomTabBar.tsx +478 -0
  2. package/Application/BottomTab/index.tsx +134 -0
  3. package/Application/Components.tsx +339 -161
  4. package/Application/ModalScreen.tsx +113 -99
  5. package/Application/Navigation.ts +22 -16
  6. package/Application/NavigationContainer.tsx +99 -48
  7. package/Application/Navigator.ts +110 -41
  8. package/Application/StackScreen.tsx +126 -8
  9. package/Application/index.ts +23 -4
  10. package/Application/types.ts +84 -33
  11. package/Application/utils.tsx +90 -50
  12. package/Assets/DotAnimation.json +256 -0
  13. package/Assets/SpinnerAnimation.json +1027 -0
  14. package/Assets/icon.json +83 -5
  15. package/Assets/icon_bank.json +506 -0
  16. package/Assets/language.json +202 -0
  17. package/Badge/Badge.tsx +56 -0
  18. package/Badge/BadgeDot.tsx +11 -0
  19. package/Badge/BadgeRibbon.tsx +125 -0
  20. package/Badge/Shape.tsx +29 -0
  21. package/Badge/index.tsx +7 -0
  22. package/Badge/styles.ts +58 -0
  23. package/Badge/types.ts +63 -0
  24. package/Button/index.tsx +90 -39
  25. package/Button/styles.ts +19 -0
  26. package/CheckBox/index.tsx +58 -43
  27. package/CheckBox/styles.ts +1 -1
  28. package/CheckBox/types.ts +6 -4
  29. package/Consts/colors+spacing+radius.ts +18 -0
  30. package/Consts/styles.ts +0 -26
  31. package/Consts/theme.ts +4 -0
  32. package/Divider/index.tsx +2 -0
  33. package/Icon/index.tsx +13 -9
  34. package/Icon/types.ts +4 -3
  35. package/IconButton/index.tsx +24 -15
  36. package/Image/index.tsx +60 -48
  37. package/Image/styles.ts +1 -9
  38. package/Image/types.ts +5 -1
  39. package/Input/Input.tsx +227 -116
  40. package/Input/InputDropDown.tsx +132 -0
  41. package/Input/InputMoney.tsx +174 -111
  42. package/Input/InputOTP.tsx +257 -0
  43. package/Input/InputSearch.tsx +160 -132
  44. package/Input/InputTextArea.tsx +150 -123
  45. package/Input/common.tsx +42 -17
  46. package/Input/index.tsx +204 -18
  47. package/Input/styles.ts +44 -7
  48. package/Input/utils.ts +2 -2
  49. package/Layout/Card.tsx +67 -29
  50. package/Layout/FloatingButton.tsx +128 -0
  51. package/Layout/GridSystem.tsx +31 -21
  52. package/Layout/Item.tsx +21 -25
  53. package/Layout/ItemList.tsx +55 -0
  54. package/Layout/ItemSectionList.tsx +39 -0
  55. package/Layout/Screen.tsx +348 -153
  56. package/Layout/Section.tsx +66 -34
  57. package/Layout/index.ts +13 -3
  58. package/Layout/styles.ts +101 -0
  59. package/Layout/types.ts +1 -39
  60. package/Layout/utils.ts +27 -52
  61. package/Loader/DotLoader.tsx +37 -0
  62. package/Loader/Loader.tsx +13 -0
  63. package/Loader/ProgressBar.tsx +44 -0
  64. package/Loader/Spinner.tsx +29 -0
  65. package/Loader/index.tsx +4 -0
  66. package/Loader/styles.ts +10 -0
  67. package/Loader/types.ts +35 -0
  68. package/Loader/utils.ts +25 -0
  69. package/Pagination/PaginationDot.tsx +7 -2
  70. package/Pagination/PaginationNumber.tsx +8 -6
  71. package/Pagination/PaginationScroll.tsx +0 -1
  72. package/Pagination/PaginationWhiteDot.tsx +8 -5
  73. package/Pagination/styles.ts +3 -0
  74. package/Pagination/types.ts +2 -0
  75. package/Popup/PopupNotify.tsx +102 -44
  76. package/Popup/PopupPromotion.tsx +63 -22
  77. package/Popup/types.ts +15 -4
  78. package/Radio/index.tsx +35 -21
  79. package/Radio/types.ts +7 -5
  80. package/Skeleton/index.tsx +1 -1
  81. package/Skeleton/types.ts +3 -0
  82. package/Switch/index.tsx +35 -24
  83. package/Switch/types.ts +5 -3
  84. package/Tag/index.tsx +2 -4
  85. package/Text/index.tsx +27 -22
  86. package/Text/styles.ts +38 -0
  87. package/Text/types.ts +25 -13
  88. package/Text/utils.ts +1 -1
  89. package/Title/index.tsx +186 -0
  90. package/Title/styles.ts +79 -0
  91. package/Title/types.ts +20 -0
  92. package/code-scanner.js +143 -0
  93. package/index.ts +8 -1
  94. package/migrate_typo.js +56 -0
  95. package/package.json +14 -9
  96. package/tsconfig.json +24 -0
  97. package/verify.js +47 -0
  98. package/Application/BottomTab.tsx +0 -52
  99. package/Application/NavigationButton.tsx +0 -54
  100. package/Assets/header-background.png +0 -0
@@ -1,4 +1,10 @@
1
- import React, {FC, useContext, useRef, useState} from 'react';
1
+ import React, {
2
+ forwardRef,
3
+ useContext,
4
+ useImperativeHandle,
5
+ useRef,
6
+ useState,
7
+ } from 'react';
2
8
  import {
3
9
  NativeSyntheticEvent,
4
10
  TextInput,
@@ -6,158 +12,180 @@ import {
6
12
  TouchableOpacity,
7
13
  View,
8
14
  } from 'react-native';
9
- import {InputSearchProps} from './index';
10
- import {ApplicationContext} from '../Application';
11
- import styles from './styles';
15
+ import {ApplicationContext, ComponentContext} from '../Application';
12
16
  import {Icon} from '../Icon';
13
17
  import {Text} from '../Text';
18
+ import {InputSearchProps} from './index';
19
+ import styles from './styles';
14
20
  import {checkTyping} from './utils';
15
21
 
16
- const InputSearch: FC<InputSearchProps> = ({
17
- placeholder,
18
- onFocus,
19
- onBlur,
20
- iconColor,
21
- value,
22
- onChangeText,
23
- icon,
24
- buttonText = 'Hủy',
25
- showButtonText = true,
26
- showBorder = true,
27
- style,
28
- defaultValue,
29
- onPressButtonText,
30
- ...props
31
- }) => {
32
- const {theme} = useContext(ApplicationContext);
33
- const [focused, setFocused] = useState(false);
34
- const [haveValue, setHaveValue] = useState(!!value || !!defaultValue);
35
- const inputRef = useRef<any>(null);
36
- let iconTintColor = iconColor;
22
+ const InputSearch = forwardRef(
23
+ (
24
+ {
25
+ placeholder,
26
+ onFocus,
27
+ onBlur,
28
+ iconColor,
29
+ value,
30
+ onChangeText,
31
+ icon,
32
+ buttonText = 'Hủy',
33
+ showButtonText = true,
34
+ style,
35
+ defaultValue,
36
+ onPressButtonText,
37
+ params,
38
+ hasColorBG = false,
39
+ accessibilityLabel,
40
+ ...props
41
+ }: InputSearchProps,
42
+ ref,
43
+ ) => {
44
+ const {theme} = useContext(ApplicationContext);
45
+ const [focused, setFocused] = useState(false);
46
+ const [haveValue, setHaveValue] = useState(!!value || !!defaultValue);
47
+ const inputRef = useRef<TextInput | null>(null);
37
48
 
38
- const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
39
- setFocused(true);
40
- onFocus?.(e);
41
- };
49
+ const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
50
+ setFocused(true);
51
+ onFocus?.(e);
52
+ };
42
53
 
43
- const _onBlur = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
44
- setFocused(false);
45
- onBlur?.(e);
46
- };
54
+ const _onBlur = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
55
+ setFocused(false);
56
+ onBlur?.(e);
57
+ };
47
58
 
48
- const onClearText = () => {
49
- inputRef?.current?.clear();
50
- _onChangeText('');
51
- };
59
+ const onClearText = () => {
60
+ inputRef?.current?.clear();
61
+ _onChangeText('');
62
+ };
52
63
 
53
- const _onChangeText = (text: string) => {
54
- checkTyping(text, haveValue, setHaveValue);
55
- onChangeText?.(text);
56
- };
64
+ const _onChangeText = (text: string) => {
65
+ checkTyping(text, haveValue, setHaveValue);
66
+ onChangeText?.(text);
67
+ };
57
68
 
58
- const getBorderColor = () => {
59
- let borderColor = showBorder
60
- ? theme.colors.border.default
61
- : theme.colors.background.surface;
69
+ useImperativeHandle(ref, () => {
70
+ return {
71
+ clear: onClearText,
72
+ focus: () => inputRef.current?.focus(),
73
+ blur: () => inputRef.current?.blur(),
74
+ setText: (text: string) => _onChangeText(text),
75
+ };
76
+ });
77
+
78
+ const renderInputView = () => {
79
+ return (
80
+ <TextInput
81
+ {...props}
82
+ accessibilityLabel={accessibilityLabel}
83
+ textAlignVertical="center"
84
+ ref={inputRef}
85
+ style={[
86
+ styles.searchInput,
87
+ {
88
+ color: theme.colors.text.default,
89
+ },
90
+ ]}
91
+ value={value}
92
+ onChangeText={_onChangeText}
93
+ onFocus={_onFocus}
94
+ onBlur={_onBlur}
95
+ placeholder={placeholder}
96
+ selectionColor={theme.colors.primary}
97
+ placeholderTextColor={theme.colors.text.hint}
98
+ />
99
+ );
100
+ };
101
+
102
+ const renderIconView = () => {
103
+ return (
104
+ <View
105
+ style={{
106
+ flexDirection: 'row',
107
+ }}>
108
+ {focused && haveValue && (
109
+ <TouchableOpacity style={styles.iconWrapper} onPress={onClearText}>
110
+ <Icon
111
+ source="24_navigation_close_circle_full"
112
+ size={16}
113
+ color={theme.colors.text.hint}
114
+ />
115
+ </TouchableOpacity>
116
+ )}
117
+ {!!icon && (
118
+ <View style={{flexDirection: 'row'}}>
119
+ <View
120
+ style={[
121
+ styles.divider,
122
+ {
123
+ backgroundColor: theme.colors.primary,
124
+ },
125
+ ]}
126
+ />
127
+ <Icon
128
+ color={iconColor}
129
+ source={icon}
130
+ style={styles.iconSearchInput}
131
+ />
132
+ </View>
133
+ )}
134
+ </View>
135
+ );
136
+ };
137
+
138
+ let inputState = 'empty';
62
139
 
63
140
  if (focused) {
64
- borderColor = theme.colors.primary;
141
+ inputState = 'focus';
65
142
  }
66
143
 
67
- return {borderColor};
68
- };
69
-
70
- const renderInputView = () => {
71
- let textColor = theme.colors.text.default;
72
- let placeholderColor = theme.colors.text.hint;
144
+ if (value && value?.length > 0) {
145
+ inputState = 'filled';
146
+ }
73
147
 
74
- return (
75
- <TextInput
76
- {...props}
77
- accessibilityLabel={`TextInput`}
78
- textAlignVertical="top"
79
- ref={inputRef}
80
- style={[
81
- styles.searchInput,
82
- {
83
- color: textColor,
84
- },
85
- ]}
86
- value={value}
87
- onChangeText={_onChangeText}
88
- onFocus={_onFocus}
89
- onBlur={_onBlur}
90
- placeholder={placeholder}
91
- selectionColor={theme.colors.primary}
92
- placeholderTextColor={placeholderColor}
93
- />
94
- );
95
- };
148
+ const backgroundColor = hasColorBG
149
+ ? theme.colors.background.default
150
+ : theme.colors.background.surface;
96
151
 
97
- const renderIconView = () => {
98
152
  return (
99
- <View
100
- style={{
101
- flexDirection: 'row',
153
+ <ComponentContext.Provider
154
+ value={{
155
+ componentName: 'InputSearch',
156
+ params,
157
+ state: inputState,
158
+ componentId: accessibilityLabel,
102
159
  }}>
103
- {focused && haveValue && (
104
- <TouchableOpacity style={styles.iconWrapper} onPress={onClearText}>
160
+ <View style={[style, styles.searchInputContainer]}>
161
+ <View
162
+ style={[
163
+ styles.searchInputWrapper,
164
+ {
165
+ backgroundColor,
166
+ },
167
+ ]}>
105
168
  <Icon
106
- source="24_navigation_close_circle_full"
107
- size={16}
169
+ source={'navigation_search'}
170
+ size={24}
108
171
  color={theme.colors.text.hint}
109
172
  />
110
- </TouchableOpacity>
111
- )}
112
- {!!icon && (
113
- <View style={{flexDirection: 'row'}}>
114
- <View
115
- style={[
116
- styles.divider,
117
- {
118
- backgroundColor: theme.colors.primary,
119
- },
120
- ]}
121
- />
122
- <Icon
123
- color={iconTintColor}
124
- source={icon}
125
- style={styles.iconSearchInput}
126
- />
173
+ {renderInputView()}
174
+ {renderIconView()}
127
175
  </View>
128
- )}
129
- </View>
176
+ {showButtonText && (
177
+ <TouchableOpacity onPress={onPressButtonText}>
178
+ <Text
179
+ typography={'action_default_bold'}
180
+ style={styles.textButton}>
181
+ {buttonText}
182
+ </Text>
183
+ </TouchableOpacity>
184
+ )}
185
+ </View>
186
+ </ComponentContext.Provider>
130
187
  );
131
- };
132
- return (
133
- <View
134
- style={[style, styles.searchInputContainer]}
135
- accessibilityLabel={`InputSearch`}>
136
- <View
137
- style={[
138
- getBorderColor(),
139
- styles.searchInputWrapper,
140
- {
141
- backgroundColor: theme.colors.background.surface,
142
- },
143
- ]}>
144
- <Icon
145
- source={'navigation_search'}
146
- size={24}
147
- color={theme.colors.text.hint}
148
- />
149
- {renderInputView()}
150
- {renderIconView()}
151
- </View>
152
- {showButtonText && (
153
- <TouchableOpacity onPress={onPressButtonText}>
154
- <Text typography={'action_default'} style={styles.textButton}>
155
- {buttonText}
156
- </Text>
157
- </TouchableOpacity>
158
- )}
159
- </View>
160
- );
161
- };
188
+ },
189
+ );
162
190
 
163
191
  export default InputSearch;
@@ -1,4 +1,10 @@
1
- import React, {FC, useContext, useRef, useState} from 'react';
1
+ import React, {
2
+ forwardRef,
3
+ useContext,
4
+ useImperativeHandle,
5
+ useRef,
6
+ useState,
7
+ } from 'react';
2
8
  import {
3
9
  NativeSyntheticEvent,
4
10
  TextInput,
@@ -6,7 +12,8 @@ import {
6
12
  TouchableOpacity,
7
13
  View,
8
14
  } from 'react-native';
9
- import styles from './styles';
15
+ import {ApplicationContext} from '../Application';
16
+ import {Icon} from '../Icon';
10
17
  import {Text} from '../Text';
11
18
  import {
12
19
  DEFAULT_HEIGHT,
@@ -16,138 +23,158 @@ import {
16
23
  MAX_LENGTH,
17
24
  } from './common';
18
25
  import {InputTextAreaProps} from './index';
19
- import {Icon} from '../Icon';
20
- import {ApplicationContext} from '../Application';
26
+ import styles from './styles';
21
27
 
22
- const InputTextArea: FC<InputTextAreaProps> = ({
23
- errorMessage,
24
- onChangeText,
25
- floatingIconColor,
26
- floatingIcon,
27
- floatingValue,
28
- onFocus,
29
- onBlur,
30
- disabled,
31
- value,
32
- defaultValue,
33
- height,
34
- placeholder,
35
- maxLength,
36
- required,
37
- ...props
38
- }) => {
39
- const {theme} = useContext(ApplicationContext);
40
- const [focused, setFocused] = useState(false);
41
- const [inputValue, setInputValue] = useState(defaultValue ?? '');
42
- const inputRef = useRef<any>(null);
28
+ const InputTextArea = forwardRef(
29
+ (
30
+ {
31
+ errorMessage,
32
+ onChangeText,
33
+ floatingIconColor,
34
+ floatingIcon,
35
+ floatingValue,
36
+ onFocus,
37
+ onBlur,
38
+ disabled = false,
39
+ value,
40
+ defaultValue,
41
+ height,
42
+ placeholder,
43
+ maxLength = MAX_LENGTH,
44
+ required,
45
+ errorSpacing,
46
+ style,
47
+ accessibilityLabel,
48
+ hintText,
49
+ ...props
50
+ }: InputTextAreaProps,
51
+ ref,
52
+ ) => {
53
+ const {theme} = useContext(ApplicationContext);
54
+ const [focused, setFocused] = useState(false);
55
+ const [inputValue, setInputValue] = useState(defaultValue ?? '');
56
+ const inputRef = useRef<TextInput | null>(null);
43
57
 
44
- const onClearText = () => {
45
- inputRef?.current?.clear();
46
- _onChangeText('');
47
- };
58
+ const onClearText = () => {
59
+ inputRef?.current?.clear();
60
+ _onChangeText('');
61
+ };
48
62
 
49
- const _onChangeText = (text: string) => {
50
- onChangeText?.(text);
51
- setInputValue(text);
52
- };
63
+ const _onChangeText = (text: string) => {
64
+ onChangeText?.(text);
65
+ setInputValue(text);
66
+ };
53
67
 
54
- const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
55
- setFocused(true);
56
- onFocus?.(e);
57
- };
68
+ const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
69
+ setFocused(true);
70
+ onFocus?.(e);
71
+ };
58
72
 
59
- const _onBlur = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
60
- setFocused(false);
61
- onBlur?.(e);
62
- };
73
+ const _onBlur = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
74
+ setFocused(false);
75
+ onBlur?.(e);
76
+ };
63
77
 
64
- const renderCountingView = () => {
65
- return (
66
- <View style={styles.countingView}>
67
- <Text color={theme.colors.text.hint} typography={'description_xs'}>
68
- {`${inputValue.length}/${maxLength}`}
69
- </Text>
70
- </View>
71
- );
72
- };
73
- const renderInputView = () => {
74
- const disabledColor = theme.colors.text.disable;
75
- let textColor = theme.colors.text.default;
76
- let placeholderColor = theme.colors.text.hint;
78
+ useImperativeHandle(ref, () => {
79
+ return {
80
+ clear: onClearText,
81
+ focus: () => inputRef.current?.focus(),
82
+ blur: () => inputRef.current?.blur(),
83
+ setText: (text: string) => _onChangeText(text),
84
+ };
85
+ });
86
+
87
+ const renderCountingView = () => {
88
+ return (
89
+ <View style={styles.countingView}>
90
+ <Text
91
+ color={theme.colors.text.hint}
92
+ typography={'description_xs_regular'}>
93
+ {`${inputValue.length}/${maxLength}`}
94
+ </Text>
95
+ </View>
96
+ );
97
+ };
98
+ const renderInputView = () => {
99
+ const disabledColor = theme.colors.text.disable;
100
+ let textColor = theme.colors.text.default;
101
+ let placeholderColor = theme.colors.text.hint;
77
102
 
78
- if (disabled) {
79
- textColor = disabledColor;
80
- placeholderColor = disabledColor;
81
- }
103
+ if (disabled) {
104
+ textColor = disabledColor;
105
+ placeholderColor = disabledColor;
106
+ }
82
107
 
83
- return (
84
- <View
85
- style={[
86
- getBorderColor(focused, errorMessage, disabled),
87
- styles.textAreaWrapper,
88
- {
89
- height: height || DEFAULT_HEIGHT,
90
- backgroundColor: theme.colors.background.surface,
91
- },
92
- ]}>
93
- <FloatingView
94
- floatingValue={floatingValue}
95
- floatingIconColor={floatingIconColor}
96
- disabled={disabled}
97
- floatingIcon={floatingIcon}
98
- required={required}
99
- />
100
- <View style={styles.rowArea}>
101
- <View style={styles.textAreaView}>
102
- <TextInput
103
- {...props}
104
- accessibilityLabel={`TextInput`}
105
- ref={inputRef}
106
- editable={!disabled}
107
- textAlignVertical="top"
108
- style={[
109
- styles.textArea,
110
- {
111
- color: textColor,
112
- },
113
- ]}
114
- maxLength={maxLength}
115
- textBreakStrategy="highQuality"
116
- multiline={true}
117
- value={value}
118
- onChangeText={_onChangeText}
119
- onFocus={_onFocus}
120
- onBlur={_onBlur}
121
- placeholder={placeholder}
122
- selectionColor={theme.colors.primary}
123
- placeholderTextColor={placeholderColor}
124
- />
125
- </View>
126
- {focused && inputValue.length > 0 && (
127
- <TouchableOpacity style={styles.iconWrapper} onPress={onClearText}>
128
- <Icon
129
- source="24_navigation_close_circle_full"
130
- size={16}
131
- color={theme.colors.text.hint}
108
+ return (
109
+ <View
110
+ style={[
111
+ styles.textAreaWrapper,
112
+ {
113
+ height: height || DEFAULT_HEIGHT,
114
+ backgroundColor: theme.colors.background.surface,
115
+ },
116
+ getBorderColor(theme, focused, errorMessage, disabled),
117
+ ]}>
118
+ <FloatingView
119
+ floatingValue={floatingValue}
120
+ floatingIconColor={floatingIconColor}
121
+ disabled={disabled}
122
+ floatingIcon={floatingIcon}
123
+ required={required}
124
+ />
125
+ <View style={styles.rowArea}>
126
+ <View style={styles.textAreaView}>
127
+ <TextInput
128
+ {...props}
129
+ ref={inputRef}
130
+ editable={!disabled}
131
+ textAlignVertical="top"
132
+ style={[
133
+ styles.textArea,
134
+ {
135
+ color: textColor,
136
+ },
137
+ ]}
138
+ maxLength={maxLength}
139
+ textBreakStrategy="highQuality"
140
+ multiline={true}
141
+ value={value}
142
+ onChangeText={_onChangeText}
143
+ onFocus={_onFocus}
144
+ onBlur={_onBlur}
145
+ placeholder={placeholder}
146
+ selectionColor={theme.colors.primary}
147
+ placeholderTextColor={placeholderColor}
132
148
  />
133
- </TouchableOpacity>
134
- )}
149
+ </View>
150
+ {focused && inputValue.length > 0 && (
151
+ <TouchableOpacity
152
+ style={styles.iconWrapper}
153
+ onPress={onClearText}>
154
+ <Icon
155
+ source="24_navigation_close_circle_full"
156
+ size={16}
157
+ color={theme.colors.text.hint}
158
+ />
159
+ </TouchableOpacity>
160
+ )}
161
+ </View>
162
+ {renderCountingView()}
135
163
  </View>
136
- {renderCountingView()}
164
+ );
165
+ };
166
+
167
+ return (
168
+ <View style={[style, styles.wrapper]}>
169
+ {renderInputView()}
170
+ <ErrorView
171
+ errorMessage={errorMessage}
172
+ errorSpacing={errorSpacing}
173
+ hintText={hintText}
174
+ />
137
175
  </View>
138
176
  );
139
- };
140
-
141
- return (
142
- <View style={styles.wrapper} accessibilityLabel={`InputTextArea`}>
143
- {renderInputView()}
144
- <ErrorView errorMessage={errorMessage} />
145
- </View>
146
- );
147
- };
148
-
149
- InputTextArea.defaultProps = {
150
- maxLength: MAX_LENGTH,
151
- };
177
+ },
178
+ );
152
179
 
153
180
  export default InputTextArea;