@momo-kits/foundation 0.81.51-beta.0 → 0.81.52

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 (71) hide show
  1. package/Application/{BottomTab/index.tsx → BottomTab.tsx} +18 -42
  2. package/Application/Components.tsx +91 -356
  3. package/Application/ModalScreen.tsx +185 -14
  4. package/Application/Navigation.ts +19 -5
  5. package/Application/NavigationContainer.tsx +72 -62
  6. package/Application/Navigator.ts +48 -154
  7. package/Application/StackScreen.tsx +32 -289
  8. package/Application/index.ts +15 -13
  9. package/Application/types.ts +35 -81
  10. package/Application/utils.tsx +30 -76
  11. package/Assets/icon_bank.json +1 -1
  12. package/Badge/Badge.tsx +1 -1
  13. package/Badge/index.tsx +1 -2
  14. package/Badge/styles.ts +6 -50
  15. package/Button/index.tsx +26 -44
  16. package/CheckBox/index.tsx +26 -37
  17. package/CheckBox/types.ts +3 -5
  18. package/Consts/colors+spacing+radius.ts +0 -14
  19. package/Icon/index.tsx +8 -9
  20. package/Icon/types.ts +2 -2
  21. package/IconButton/index.tsx +14 -24
  22. package/Image/index.tsx +8 -23
  23. package/Image/types.ts +0 -2
  24. package/Input/Input.tsx +26 -116
  25. package/Input/InputDropDown.tsx +51 -66
  26. package/Input/InputMoney.tsx +15 -106
  27. package/Input/InputOTP.tsx +26 -49
  28. package/Input/InputSearch.tsx +99 -252
  29. package/Input/InputTextArea.tsx +6 -26
  30. package/Input/common.tsx +22 -48
  31. package/Input/index.tsx +77 -112
  32. package/Input/styles.ts +11 -48
  33. package/Input/utils.ts +1 -1
  34. package/Layout/Card.tsx +3 -4
  35. package/Layout/GridSystem.tsx +1 -1
  36. package/Layout/ItemList.tsx +2 -3
  37. package/Layout/Screen.tsx +121 -242
  38. package/Layout/Section.tsx +3 -4
  39. package/Layout/styles.ts +13 -11
  40. package/Layout/types.ts +1 -1
  41. package/Layout/utils.ts +4 -4
  42. package/Loader/index.tsx +0 -2
  43. package/Pagination/PaginationScroll.tsx +2 -2
  44. package/Pagination/styles.ts +1 -1
  45. package/Popup/PopupNotify.tsx +46 -57
  46. package/Popup/PopupPromotion.tsx +8 -6
  47. package/Popup/types.ts +7 -1
  48. package/Radio/index.tsx +20 -35
  49. package/Radio/types.ts +3 -5
  50. package/Switch/index.tsx +18 -32
  51. package/Switch/types.ts +3 -5
  52. package/Tag/index.tsx +2 -9
  53. package/Tag/styles.ts +2 -3
  54. package/Tag/types.ts +0 -12
  55. package/Text/index.tsx +5 -24
  56. package/Text/styles.ts +8 -8
  57. package/Title/index.tsx +103 -170
  58. package/Title/styles.ts +9 -36
  59. package/Title/types.ts +48 -16
  60. package/code-scanner.js +16 -125
  61. package/index.ts +0 -7
  62. package/package.json +7 -8
  63. package/publish.sh +21 -16
  64. package/tsconfig.json +1 -1
  65. package/Application/BottomSheet.tsx +0 -216
  66. package/Application/BottomTab/BottomTabBar.tsx +0 -278
  67. package/Application/Localize.ts +0 -44
  68. package/Application/constants.ts +0 -9
  69. package/Badge/BadgeDotAnimation.tsx +0 -95
  70. package/Input/TextTyping.tsx +0 -113
  71. package/Layout/FloatingButton.tsx +0 -168
@@ -1,13 +1,4 @@
1
- import React, {
2
- FC,
3
- forwardRef,
4
- ForwardRefRenderFunction,
5
- useContext,
6
- useEffect,
7
- useImperativeHandle,
8
- useRef,
9
- useState,
10
- } from 'react';
1
+ import React, {forwardRef, useContext, useRef, useState} from 'react';
11
2
  import {
12
3
  NativeSyntheticEvent,
13
4
  TextInput,
@@ -15,271 +6,127 @@ import {
15
6
  TouchableOpacity,
16
7
  View,
17
8
  } from 'react-native';
18
- import {ApplicationContext, ComponentContext} from '../Application';
9
+ import {InputSearchProps} from './index';
10
+ import {ApplicationContext} from '../Application';
11
+ import styles from './styles';
19
12
  import {Icon} from '../Icon';
20
13
  import {Text} from '../Text';
21
- import {InputRef, InputSearchProps} from './index';
22
- import styles from './styles';
23
14
  import {checkTyping} from './utils';
24
- import {Styles} from '../Consts';
25
-
26
- const TextTyping: FC<any> = ({
27
- data = [],
28
- timeDelayEnd = 2000,
29
- timeDelayNextChar = 20,
30
- }) => {
31
- const textRef = useRef<TextInput>(null);
32
15
 
33
- const currentIndex = useRef<number>(0);
34
- const currentCharIndex = useRef<number>(0);
35
- const currentText = useRef('');
36
-
37
- useEffect(() => {
38
- setTimeout(() => {
39
- playAnimation();
40
- }, 1000);
41
- }, []);
42
-
43
- const playAnimation = () => {
44
- const handleResetList = () => {
45
- currentIndex.current = 0;
46
- handleAnimation();
16
+ const InputSearch = forwardRef(
17
+ (
18
+ {
19
+ placeholder,
20
+ onFocus,
21
+ onBlur,
22
+ iconColor,
23
+ value,
24
+ onChangeText,
25
+ icon,
26
+ buttonText = 'Hủy',
27
+ showButtonText = true,
28
+ style,
29
+ defaultValue,
30
+ onPressButtonText,
31
+ hasColorBG = true,
32
+ ...props
33
+ }: InputSearchProps,
34
+ ref,
35
+ ) => {
36
+ const {theme} = useContext(ApplicationContext);
37
+ const [focused, setFocused] = useState(false);
38
+ const [haveValue, setHaveValue] = useState(!!value || !!defaultValue);
39
+ const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
40
+
41
+ const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
42
+ setFocused(true);
43
+ onFocus?.(e);
47
44
  };
48
45
 
49
- const handleAnimation = () => {
50
- const listChar = data?.[currentIndex.current]?.split('') || [];
51
- listChar.length !== 0 && showChar(listChar?.[currentCharIndex.current]);
46
+ const _onBlur = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
47
+ setFocused(false);
48
+ onBlur?.(e);
52
49
  };
53
50
 
54
- currentIndex.current >= data?.length
55
- ? handleResetList()
56
- : handleAnimation();
57
- };
58
-
59
- const showChar = (char?: string) => {
60
- const handleResetString = () => {
61
- setTimeout(() => {
62
- reset();
63
- }, timeDelayEnd);
64
- };
65
-
66
- const handleShowChar = () => {
67
- setTimeout(() => {
68
- textRef.current?.setNativeProps?.({
69
- text: currentText.current + char,
70
- });
71
- currentText.current += char;
72
- currentCharIndex.current++;
73
- playAnimation();
74
- }, timeDelayNextChar);
75
- };
76
-
77
- currentCharIndex.current >= (data?.[currentIndex.current]?.length || 0)
78
- ? handleResetString()
79
- : handleShowChar();
80
- };
81
-
82
- const reset = () => {
83
- const handleNextString = () => {
84
- currentIndex.current++;
85
- playAnimation();
51
+ const onClearText = () => {
52
+ inputRef?.current?.clear();
53
+ _onChangeText('');
86
54
  };
87
55
 
88
- const handleReset = () => {
89
- setTimeout(() => {
90
- textRef.current?.setNativeProps?.({
91
- text: currentText.current.slice(0, -1),
92
- });
93
- currentText.current = currentText.current.slice(0, -1);
94
- currentCharIndex.current--;
95
- reset();
96
- }, timeDelayNextChar);
97
- };
98
-
99
- currentCharIndex.current <= 0 ? handleNextString() : handleReset();
100
- };
101
-
102
- return (
103
- <TextInput
104
- style={styles.inputStyle}
105
- ref={textRef}
106
- editable={false}
107
- autoCorrect={false}
108
- pointerEvents={'none'}
109
- numberOfLines={1}
110
- />
111
- );
112
- };
113
-
114
- const InputSearch: ForwardRefRenderFunction<InputRef, InputSearchProps> = (
115
- {
116
- placeholder,
117
- onFocus,
118
- onBlur,
119
- value,
120
- icon,
121
- iconColor,
122
- onPressIcon,
123
- trailing,
124
- trailingColor,
125
- onPressTrailing,
126
- onChangeText,
127
- buttonText = 'Hủy',
128
- showButtonText = true,
129
- style,
130
- defaultValue,
131
- onPressButtonText,
132
- params,
133
- hasColorBG = false,
134
- accessibilityLabel,
135
- onPress,
136
- typingData,
137
- ...props
138
- },
139
- ref
140
- ) => {
141
- const {theme} = useContext(ApplicationContext);
142
- const [focused, setFocused] = useState(false);
143
- const [haveValue, setHaveValue] = useState(!!value || !!defaultValue);
144
- const inputRef = useRef<TextInput | null>(null);
145
-
146
- const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
147
- setFocused(true);
148
- onFocus?.(e);
149
- };
150
-
151
- const _onBlur = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
152
- setFocused(false);
153
- onBlur?.(e);
154
- };
155
-
156
- const onClearText = () => {
157
- inputRef?.current?.clear();
158
- _onChangeText('');
159
- };
160
-
161
- const _onChangeText = (text: string) => {
162
- checkTyping(text, haveValue, setHaveValue);
163
- onChangeText?.(text);
164
- };
165
-
166
- useImperativeHandle(ref, () => {
167
- return {
168
- clear: onClearText,
169
- focus: () => inputRef.current?.focus(),
170
- blur: () => inputRef.current?.blur(),
171
- setText: (text: string) => _onChangeText(text),
56
+ const _onChangeText = (text: string) => {
57
+ checkTyping(text, haveValue, setHaveValue);
58
+ onChangeText?.(text);
172
59
  };
173
- });
174
60
 
175
- /**
176
- * Render the input view
177
- */
178
- const renderInputView = () => {
179
- if (typingData && typingData?.length > 0) {
61
+ const renderInputView = () => {
180
62
  return (
181
- <TouchableOpacity
63
+ <TextInput
64
+ {...props}
65
+ textAlignVertical="center"
66
+ ref={inputRef}
182
67
  style={[
183
68
  styles.searchInput,
184
69
  {
185
- justifyContent: 'center',
70
+ color: theme.colors.text.default,
186
71
  },
187
72
  ]}
188
- onPress={onPress}
189
- activeOpacity={onPress ? 0.6 : 1}>
190
- <TextTyping data={typingData} />
191
- </TouchableOpacity>
73
+ value={value}
74
+ onChangeText={_onChangeText}
75
+ onFocus={_onFocus}
76
+ onBlur={_onBlur}
77
+ placeholder={placeholder}
78
+ selectionColor={theme.colors.primary}
79
+ placeholderTextColor={theme.colors.text.hint}
80
+ />
192
81
  );
193
- }
194
-
195
- return (
196
- <TextInput
197
- {...props}
198
- accessibilityLabel={accessibilityLabel}
199
- textAlignVertical="center"
200
- ref={inputRef}
201
- style={[
202
- styles.searchInput,
203
- {
204
- color: theme.colors.text.default,
205
- },
206
- ]}
207
- value={value}
208
- onChangeText={_onChangeText}
209
- onFocus={_onFocus}
210
- onBlur={_onBlur}
211
- placeholder={placeholder}
212
- selectionColor={theme.colors.primary}
213
- placeholderTextColor={theme.colors.text.hint}
214
- />
215
- );
216
- };
217
-
218
- /**
219
- * Render trailing icon or text
220
- */
221
- const renderTrailing = () => {
222
- return (
223
- <View style={Styles.row}>
224
- {focused && haveValue && (
225
- <TouchableOpacity style={styles.iconWrapper} onPress={onClearText}>
226
- <Icon
227
- source="24_navigation_close_circle_full"
228
- size={16}
229
- color={theme.colors.text.hint}
230
- />
231
- </TouchableOpacity>
232
- )}
233
- {!!(icon || trailing) && (
234
- <TouchableOpacity
235
- style={Styles.row}
236
- onPress={onPressTrailing ?? onPressIcon}>
237
- <View
238
- style={[
239
- styles.divider,
240
- {
241
- backgroundColor: theme.colors.primary,
242
- },
243
- ]}
244
- />
245
- <Icon
246
- color={iconColor || trailingColor}
247
- source={(icon || trailing) as string}
248
- style={styles.iconSearchInput}
249
- />
250
- </TouchableOpacity>
251
- )}
252
- </View>
253
- );
254
- };
82
+ };
255
83
 
256
- let inputState = 'empty';
257
- if (focused) {
258
- inputState = 'focus';
259
- }
260
- if (value && value?.length > 0) {
261
- inputState = 'filled';
262
- }
84
+ const renderIconView = () => {
85
+ return (
86
+ <View
87
+ style={{
88
+ flexDirection: 'row',
89
+ }}>
90
+ {focused && haveValue && (
91
+ <TouchableOpacity style={styles.iconWrapper} onPress={onClearText}>
92
+ <Icon
93
+ source="24_navigation_close_circle_full"
94
+ size={16}
95
+ color={theme.colors.text.hint}
96
+ />
97
+ </TouchableOpacity>
98
+ )}
99
+ {!!icon && (
100
+ <View style={{flexDirection: 'row'}}>
101
+ <View
102
+ style={[
103
+ styles.divider,
104
+ {
105
+ backgroundColor: theme.colors.primary,
106
+ },
107
+ ]}
108
+ />
109
+ <Icon
110
+ color={iconColor}
111
+ source={icon}
112
+ style={styles.iconSearchInput}
113
+ />
114
+ </View>
115
+ )}
116
+ </View>
117
+ );
118
+ };
263
119
 
264
- const backgroundColor = hasColorBG
265
- ? theme.colors.background.default
266
- : theme.colors.background.surface;
120
+ const backgroundColor = hasColorBG ? theme.colors.background.default : theme.colors.background.surface
267
121
 
268
- return (
269
- <ComponentContext.Provider
270
- value={{
271
- componentName: 'InputSearch',
272
- params,
273
- state: inputState,
274
- componentId: accessibilityLabel,
275
- }}>
122
+ return (
276
123
  <View style={[style, styles.searchInputContainer]}>
277
124
  <View
278
125
  style={[
279
126
  styles.searchInputWrapper,
280
127
  {
281
128
  backgroundColor,
282
- },
129
+ }
283
130
  ]}>
284
131
  <Icon
285
132
  source={'navigation_search'}
@@ -287,7 +134,7 @@ const InputSearch: ForwardRefRenderFunction<InputRef, InputSearchProps> = (
287
134
  color={theme.colors.text.hint}
288
135
  />
289
136
  {renderInputView()}
290
- {renderTrailing()}
137
+ {renderIconView()}
291
138
  </View>
292
139
  {showButtonText && (
293
140
  <TouchableOpacity onPress={onPressButtonText}>
@@ -297,8 +144,8 @@ const InputSearch: ForwardRefRenderFunction<InputRef, InputSearchProps> = (
297
144
  </TouchableOpacity>
298
145
  )}
299
146
  </View>
300
- </ComponentContext.Provider>
301
- );
302
- };
147
+ );
148
+ },
149
+ );
303
150
 
304
- export default forwardRef(InputSearch);
151
+ export default InputSearch;
@@ -1,10 +1,4 @@
1
- import React, {
2
- forwardRef,
3
- useContext,
4
- useImperativeHandle,
5
- useRef,
6
- useState,
7
- } from 'react';
1
+ import React, {forwardRef, useContext, useRef, useState} from 'react';
8
2
  import {
9
3
  NativeSyntheticEvent,
10
4
  TextInput,
@@ -12,8 +6,7 @@ import {
12
6
  TouchableOpacity,
13
7
  View,
14
8
  } from 'react-native';
15
- import {ApplicationContext} from '../Application';
16
- import {Icon} from '../Icon';
9
+ import styles from './styles';
17
10
  import {Text} from '../Text';
18
11
  import {
19
12
  DEFAULT_HEIGHT,
@@ -23,7 +16,8 @@ import {
23
16
  MAX_LENGTH,
24
17
  } from './common';
25
18
  import {InputTextAreaProps} from './index';
26
- import styles from './styles';
19
+ import {Icon} from '../Icon';
20
+ import {ApplicationContext} from '../Application';
27
21
 
28
22
  const InputTextArea = forwardRef(
29
23
  (
@@ -44,7 +38,6 @@ const InputTextArea = forwardRef(
44
38
  required,
45
39
  errorSpacing,
46
40
  style,
47
- hintText,
48
41
  ...props
49
42
  }: InputTextAreaProps,
50
43
  ref,
@@ -52,7 +45,7 @@ const InputTextArea = forwardRef(
52
45
  const {theme} = useContext(ApplicationContext);
53
46
  const [focused, setFocused] = useState(false);
54
47
  const [inputValue, setInputValue] = useState(defaultValue ?? '');
55
- const inputRef = useRef<TextInput | null>(null);
48
+ const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
56
49
 
57
50
  const onClearText = () => {
58
51
  inputRef?.current?.clear();
@@ -74,15 +67,6 @@ const InputTextArea = forwardRef(
74
67
  onBlur?.(e);
75
68
  };
76
69
 
77
- useImperativeHandle(ref, () => {
78
- return {
79
- clear: onClearText,
80
- focus: () => inputRef.current?.focus(),
81
- blur: () => inputRef.current?.blur(),
82
- setText: (text: string) => _onChangeText(text),
83
- };
84
- });
85
-
86
70
  const renderCountingView = () => {
87
71
  return (
88
72
  <View style={styles.countingView}>
@@ -166,11 +150,7 @@ const InputTextArea = forwardRef(
166
150
  return (
167
151
  <View style={[style, styles.wrapper]}>
168
152
  {renderInputView()}
169
- <ErrorView
170
- errorMessage={errorMessage}
171
- errorSpacing={errorSpacing}
172
- hintText={hintText}
173
- />
153
+ <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
174
154
  </View>
175
155
  );
176
156
  },
package/Input/common.tsx CHANGED
@@ -1,16 +1,11 @@
1
+ import {View, ViewStyle} from 'react-native';
2
+ import styles from './styles';
3
+ import {scaleSize, Text} from '../Text';
1
4
  import React, {FC, useContext} from 'react';
2
- import {
3
- GestureResponderEvent,
4
- TouchableOpacity,
5
- View,
6
- ViewStyle,
7
- } from 'react-native';
8
5
  import {ApplicationContext} from '../Application';
9
- import {Theme} from '../Application/types';
10
- import {Styles} from '../Consts';
11
6
  import {Icon} from '../Icon';
12
- import {scaleSize, Text} from '../Text';
13
- import styles from './styles';
7
+ import {Styles} from '../Consts';
8
+ import {Theme} from '../Application/types';
14
9
 
15
10
  type FloatingViewProps = {
16
11
  floatingValue?: string;
@@ -19,7 +14,6 @@ type FloatingViewProps = {
19
14
  floatingIcon?: string;
20
15
  required?: boolean;
21
16
  style?: ViewStyle;
22
- onPress?: (e: GestureResponderEvent) => void;
23
17
  };
24
18
 
25
19
  export const DEFAULT_HEIGHT = scaleSize(104);
@@ -29,7 +23,7 @@ export const getBorderColor = (
29
23
  theme: Theme,
30
24
  focused: boolean,
31
25
  errorMessage?: string,
32
- disabled?: boolean
26
+ disabled?: boolean,
33
27
  ) => {
34
28
  let borderColor = theme.colors.border.default;
35
29
 
@@ -48,47 +42,30 @@ export const getBorderColor = (
48
42
  return {borderColor};
49
43
  };
50
44
 
51
- export const getSizeStyle = (
52
- size?: 'small' | 'large',
53
- multiline: boolean = false
54
- ) => {
55
- if (multiline)
56
- return [
57
- styles.multilineContainer,
58
- {
59
- minHeight: size === 'small' ? 48 : 56,
60
- },
61
- ];
62
-
45
+ export const getSizeStyle = (size?: 'small' | 'large') => {
63
46
  if (size === 'small') {
64
47
  return styles.smallContainer;
65
48
  }
66
49
  return styles.container;
67
50
  };
68
- export const ErrorView: FC<{
69
- errorMessage?: string;
70
- errorSpacing?: boolean;
71
- hintText?: string;
72
- }> = ({errorMessage, errorSpacing, hintText}) => {
51
+ export const ErrorView: FC<{errorMessage?: string; errorSpacing?: boolean}> = ({
52
+ errorMessage,
53
+ errorSpacing,
54
+ }) => {
73
55
  const {theme} = useContext(ApplicationContext);
74
56
  const errorColor = theme.colors.error.primary;
75
- const hintColor = theme.colors.text.hint;
76
- const hintTextDefault = hintText ?? 'Không thể chỉnh sửa';
77
- if (errorMessage || hintText) {
57
+ if (errorMessage) {
78
58
  return (
79
59
  <View style={styles.errorView}>
80
60
  <View style={styles.errorIcon}>
81
- <Icon
82
- color={errorMessage ? errorColor : hintColor}
83
- source="ic_error"
84
- size={16}
85
- />
61
+ <Icon color={errorColor} source="ic_error" size={16} />
86
62
  </View>
87
63
  <Text
88
64
  style={Styles.flex}
89
- color={errorMessage ? errorColor : hintColor}
65
+ color={errorColor}
66
+ numberOfLines={2}
90
67
  typography={'description_default_regular'}>
91
- {errorMessage ?? hintTextDefault}
68
+ {errorMessage}
92
69
  </Text>
93
70
  </View>
94
71
  );
@@ -106,7 +83,6 @@ export const FloatingView: FC<FloatingViewProps> = ({
106
83
  floatingIcon,
107
84
  required,
108
85
  style,
109
- onPress,
110
86
  }) => {
111
87
  const {theme} = useContext(ApplicationContext);
112
88
 
@@ -139,14 +115,12 @@ export const FloatingView: FC<FloatingViewProps> = ({
139
115
  )}
140
116
  </Text>
141
117
  {!!floatingIcon && (
142
- <TouchableOpacity activeOpacity={onPress ? 0.6 : 1} onPress={onPress}>
143
- <Icon
144
- color={floatingIconTintColor}
145
- source={floatingIcon}
146
- size={16}
147
- style={styles.floatingIcon}
148
- />
149
- </TouchableOpacity>
118
+ <Icon
119
+ color={floatingIconTintColor}
120
+ source={floatingIcon}
121
+ size={16}
122
+ style={styles.floatingIcon}
123
+ />
150
124
  )}
151
125
  </View>
152
126
  );