@momo-kits/foundation 0.80.8 → 0.81.1-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 (87) hide show
  1. package/Application/BottomSheet.tsx +212 -0
  2. package/Application/BottomTab/BottomTabBar.tsx +278 -0
  3. package/Application/BottomTab/index.tsx +143 -0
  4. package/Application/Components.tsx +384 -213
  5. package/Application/ModalScreen.tsx +14 -178
  6. package/Application/Navigation.ts +15 -19
  7. package/Application/NavigationContainer.tsx +66 -63
  8. package/Application/Navigator.ts +106 -53
  9. package/Application/StackScreen.tsx +123 -9
  10. package/Application/index.ts +19 -6
  11. package/Application/types.ts +83 -26
  12. package/Application/utils.tsx +62 -74
  13. package/Assets/icon.json +83 -5
  14. package/Assets/icon_bank.json +506 -0
  15. package/Assets/language.json +3 -1
  16. package/Badge/Badge.tsx +56 -0
  17. package/Badge/BadgeDot.tsx +11 -0
  18. package/Badge/BadgeRibbon.tsx +125 -0
  19. package/Badge/Shape.tsx +29 -0
  20. package/Badge/index.tsx +7 -0
  21. package/Badge/styles.ts +58 -0
  22. package/Badge/types.ts +63 -0
  23. package/Button/index.tsx +64 -28
  24. package/Button/styles.ts +19 -0
  25. package/CheckBox/index.tsx +37 -27
  26. package/CheckBox/types.ts +5 -3
  27. package/Consts/colors+spacing+radius.ts +18 -0
  28. package/Icon/index.tsx +14 -9
  29. package/Icon/types.ts +4 -3
  30. package/IconButton/index.tsx +24 -15
  31. package/Image/index.tsx +62 -47
  32. package/Image/styles.ts +1 -9
  33. package/Image/types.ts +5 -1
  34. package/Input/Input.tsx +104 -25
  35. package/Input/InputDropDown.tsx +115 -110
  36. package/Input/InputMoney.tsx +79 -18
  37. package/Input/InputOTP.tsx +190 -149
  38. package/Input/InputSearch.tsx +96 -44
  39. package/Input/InputTextArea.tsx +33 -17
  40. package/Input/common.tsx +26 -17
  41. package/Input/index.tsx +108 -41
  42. package/Input/styles.ts +5 -7
  43. package/Input/utils.ts +1 -1
  44. package/Layout/AnimatedInputSearch.tsx +44 -0
  45. package/Layout/Card.tsx +37 -13
  46. package/Layout/FloatingButton.tsx +168 -0
  47. package/Layout/GridSystem.tsx +2 -3
  48. package/Layout/Item.tsx +1 -2
  49. package/Layout/ItemList.tsx +55 -0
  50. package/Layout/ItemSectionList.tsx +39 -0
  51. package/Layout/Screen.tsx +404 -181
  52. package/Layout/Section.tsx +22 -22
  53. package/Layout/TextTyping.tsx +114 -0
  54. package/Layout/index.ts +12 -2
  55. package/Layout/styles.ts +46 -13
  56. package/Layout/types.ts +13 -5
  57. package/Layout/utils.ts +7 -12
  58. package/Loader/index.tsx +2 -0
  59. package/Pagination/PaginationDot.tsx +6 -1
  60. package/Pagination/PaginationNumber.tsx +7 -4
  61. package/Pagination/PaginationScroll.tsx +0 -1
  62. package/Pagination/PaginationWhiteDot.tsx +6 -1
  63. package/Pagination/styles.ts +3 -0
  64. package/Pagination/types.ts +2 -0
  65. package/Popup/PopupNotify.tsx +108 -40
  66. package/Popup/PopupPromotion.tsx +45 -10
  67. package/Popup/types.ts +13 -10
  68. package/Radio/index.tsx +35 -21
  69. package/Radio/types.ts +7 -5
  70. package/Skeleton/index.tsx +1 -1
  71. package/Switch/index.tsx +32 -19
  72. package/Switch/types.ts +5 -3
  73. package/Tag/index.tsx +2 -4
  74. package/Text/index.tsx +26 -6
  75. package/Text/styles.ts +38 -0
  76. package/Text/types.ts +25 -13
  77. package/Title/index.tsx +177 -64
  78. package/Title/styles.ts +48 -15
  79. package/Title/types.ts +16 -7
  80. package/code-scanner.js +125 -16
  81. package/index.ts +9 -0
  82. package/migrate_typo.js +56 -0
  83. package/package.json +8 -7
  84. package/publish.sh +21 -16
  85. package/tsconfig.json +1 -2
  86. package/verify.js +24 -6
  87. package/Application/BottomTab.tsx +0 -65
@@ -1,127 +1,132 @@
1
- import React, {forwardRef, useContext, useRef} from 'react';
1
+ import React, {useContext} from 'react';
2
2
  import {TextInput, TouchableOpacity, View} from 'react-native';
3
- import {ApplicationContext} from '../Application';
4
- import styles from './styles';
5
- import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
6
- import {InputDropDownProps} from './index';
3
+ import {ApplicationContext, ComponentContext} from '../Application';
4
+ import {Styles} from '../Consts';
7
5
  import {Icon} from '../Icon';
8
6
  import {Loader} from '../Loader';
9
- import {Styles} from '../Consts';
7
+ import {ErrorView, FloatingView, getSizeStyle} from './common';
8
+ import {InputDropDownProps} from './index';
9
+ import styles from './styles';
10
10
 
11
- const InputDropDown = forwardRef(
12
- (
13
- {
14
- value,
15
- floatingValue,
16
- floatingIcon,
17
- size,
18
- onPress,
19
- placeholder,
20
- errorMessage,
21
- icon = 'arrow_chevron_down_small',
22
- disabled,
23
- floatingIconColor,
24
- iconColor,
25
- required,
26
- errorSpacing,
27
- loading,
28
- leadingIcon,
29
- leadingIconColor,
30
- ...props
31
- }: InputDropDownProps,
32
- ref,
33
- ) => {
34
- const {theme} = useContext(ApplicationContext);
35
- const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
36
- const full = !!value || !!placeholder;
37
- const renderIcon = (color: string | undefined) => {
38
- if (loading) {
39
- return <Loader type={'spinner'} color={color} />;
40
- }
41
- if (icon) {
42
- return <Icon color={color} source={icon} size={24} />;
43
- }
44
- };
11
+ const InputDropDown = ({
12
+ value,
13
+ floatingValue,
14
+ floatingIcon,
15
+ size = 'small',
16
+ onPress,
17
+ placeholder,
18
+ errorMessage,
19
+ icon = 'arrow_chevron_down_small',
20
+ disabled = false,
21
+ floatingIconColor,
22
+ iconColor,
23
+ required = false,
24
+ errorSpacing,
25
+ loading = false,
26
+ leadingIcon,
27
+ leadingIconColor,
28
+ style,
29
+ params,
30
+ accessibilityLabel,
31
+ hintText,
32
+ ...props
33
+ }: InputDropDownProps) => {
34
+ const {theme} = useContext(ApplicationContext);
35
+ const full = !!value || !!placeholder;
45
36
 
46
- const renderInputView = () => {
47
- const disabledColor = theme.colors.text.disable;
48
- let textColor = theme.colors.text.default;
49
- let placeholderColor = theme.colors.text.hint;
50
- let iconTintColor = iconColor;
37
+ const renderIcon = (color: string | undefined) => {
38
+ if (loading) {
39
+ return <Loader type={'spinner'} color={color} />;
40
+ }
41
+ if (icon) {
42
+ return <Icon color={color} source={icon} size={24} />;
43
+ }
44
+ };
51
45
 
52
- if (disabled) {
53
- textColor = disabledColor;
54
- placeholderColor = disabledColor;
55
- iconTintColor = disabledColor;
56
- }
46
+ const renderInputView = () => {
47
+ const disabledColor = theme.colors.text.disable;
48
+ let textColor = theme.colors.text.default;
49
+ let placeholderColor = theme.colors.text.hint;
50
+ let iconTintColor = iconColor;
57
51
 
58
- return (
59
- <View
60
- style={[
61
- styles.inputWrapper,
62
- {backgroundColor: theme.colors.background.surface},
63
- getSizeStyle(size),
64
- getBorderColor(theme, false, errorMessage, disabled),
65
- ]}>
66
- <FloatingView
67
- floatingValue={floatingValue}
68
- floatingIconColor={floatingIconColor}
69
- disabled={disabled}
70
- required={required}
71
- floatingIcon={floatingIcon}
72
- />
73
- <View style={full ? styles.inputView : Styles.row}>
74
- {!!leadingIcon && (
75
- <View style={styles.leadingIconContainer}>
76
- <Icon
77
- color={leadingIconColor}
78
- source={leadingIcon}
79
- size={size === 'small' ? 24 : 32}
80
- />
81
- </View>
82
- )}
83
- {full && (
84
- <TextInput
85
- {...props}
86
- onPressIn={onPress}
87
- accessibilityLabel={`TextInput`}
88
- editable={false}
89
- textAlignVertical="top"
90
- ref={inputRef}
91
- style={[
92
- styles.input,
93
- {
94
- color: textColor,
95
- fontFamily: `${theme.font}-Regular`,
96
- },
97
- ]}
98
- textBreakStrategy="highQuality"
99
- value={value}
100
- placeholder={placeholder}
101
- selectionColor={theme.colors.primary}
102
- placeholderTextColor={placeholderColor}
52
+ if (disabled) {
53
+ textColor = disabledColor;
54
+ placeholderColor = disabledColor;
55
+ iconTintColor = disabledColor;
56
+ }
57
+
58
+ return (
59
+ <View
60
+ style={[
61
+ styles.inputWrapper,
62
+ {backgroundColor: theme.colors.background.surface},
63
+ getSizeStyle(size),
64
+ // getBorderColor(theme, false, errorMessage, disabled),
65
+ ]}>
66
+ <FloatingView
67
+ floatingValue={floatingValue}
68
+ floatingIconColor={floatingIconColor}
69
+ disabled={disabled}
70
+ required={required}
71
+ floatingIcon={floatingIcon}
72
+ />
73
+ <View style={full ? styles.inputView : Styles.row}>
74
+ {!!leadingIcon && (
75
+ <View style={styles.leadingIconContainer}>
76
+ <Icon
77
+ color={leadingIconColor}
78
+ source={leadingIcon}
79
+ size={size === 'small' ? 24 : 32}
103
80
  />
104
- )}
105
- </View>
106
- <View style={styles.iconView}>{renderIcon(iconTintColor)}</View>
81
+ </View>
82
+ )}
83
+ {full && (
84
+ <TextInput
85
+ {...props}
86
+ accessibilityLabel={accessibilityLabel}
87
+ onPressIn={onPress}
88
+ editable={false}
89
+ style={[
90
+ styles.input,
91
+ {
92
+ color: textColor,
93
+ fontFamily: `${theme.font}-Regular`,
94
+ },
95
+ ]}
96
+ textBreakStrategy="highQuality"
97
+ value={value}
98
+ placeholder={placeholder}
99
+ selectionColor={theme.colors.primary}
100
+ placeholderTextColor={placeholderColor}
101
+ />
102
+ )}
107
103
  </View>
108
- );
109
- };
104
+ <View style={styles.iconView}>{renderIcon(iconTintColor)}</View>
105
+ </View>
106
+ );
107
+ };
110
108
 
111
- return (
109
+ return (
110
+ <ComponentContext.Provider
111
+ value={{
112
+ componentName: 'InputDropDown',
113
+ params,
114
+ state: 'enabled',
115
+ componentLabel: floatingValue,
116
+ componentId: accessibilityLabel,
117
+ }}>
112
118
  <TouchableOpacity
113
119
  onPress={onPress}
114
- style={full && styles.wrapper}
115
- accessibilityLabel={`InputDropDown/${floatingValue}`}>
120
+ style={[style, full && styles.wrapper]}>
116
121
  {renderInputView()}
117
- <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
122
+ <ErrorView
123
+ errorMessage={errorMessage}
124
+ errorSpacing={errorSpacing}
125
+ hintText={hintText}
126
+ />
118
127
  </TouchableOpacity>
119
- );
120
- },
121
- );
122
-
123
- InputDropDown.defaultProps = {
124
- size: 'small',
128
+ </ComponentContext.Provider>
129
+ );
125
130
  };
126
131
 
127
132
  export default InputDropDown;
@@ -1,4 +1,11 @@
1
- import React, {forwardRef, useContext, useRef, useState} from 'react';
1
+ import React, {
2
+ forwardRef,
3
+ useContext,
4
+ useEffect,
5
+ useImperativeHandle,
6
+ useRef,
7
+ useState,
8
+ } from 'react';
2
9
  import {
3
10
  NativeSyntheticEvent,
4
11
  TextInput,
@@ -6,11 +13,11 @@ import {
6
13
  TouchableOpacity,
7
14
  View,
8
15
  } from 'react-native';
9
- import {ApplicationContext} from '../Application';
10
- import styles from './styles';
16
+ import {ApplicationContext, ComponentContext} from '../Application';
17
+ import {Icon} from '../Icon';
11
18
  import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
12
19
  import {InputMoneyProps} from './index';
13
- import {Icon} from '../Icon';
20
+ import styles from './styles';
14
21
  import {formatMoneyToNumber, formatNumberToMoney} from './utils';
15
22
 
16
23
  const InputMoney = forwardRef(
@@ -24,33 +31,64 @@ const InputMoney = forwardRef(
24
31
  onFocus,
25
32
  errorMessage,
26
33
  icon,
27
- disabled,
34
+ disabled = false,
28
35
  floatingIconColor,
29
36
  iconColor,
30
- required,
37
+ required = false,
31
38
  errorSpacing,
39
+ style,
40
+ params,
41
+ defaultValue = '',
42
+ accessibilityLabel,
43
+ hintText,
44
+ value: _value,
32
45
  ...props
33
46
  }: InputMoneyProps,
34
47
  ref,
35
48
  ) => {
36
49
  const {theme} = useContext(ApplicationContext);
37
50
  const [focused, setFocused] = useState(false);
38
- const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
39
- const [value, setValue] = useState('');
51
+ const inputRef = useRef<TextInput>(null);
52
+
53
+ useEffect(() => {
54
+ if (_value) {
55
+ setValue(validateText(_value));
56
+ onChangeText?.(formatMoneyToNumber(_value, 'đ').toString());
57
+ }
58
+ }, [_value]);
59
+
60
+ const validateText = (text: string) => {
61
+ const valueFormat = formatMoneyToNumber(text, 'đ');
62
+ return formatNumberToMoney(valueFormat, 'đ');
63
+ };
64
+
65
+ const [value, setValue] = useState(
66
+ defaultValue ? validateText(defaultValue) : '',
67
+ );
68
+
40
69
  const onClearText = () => {
41
70
  inputRef?.current?.clear();
42
71
  setValue('');
43
72
  onChangeText?.('');
44
73
  };
74
+
45
75
  const _onChangeText = (text: string) => {
46
76
  if (text.length < value.length && value.indexOf(text) === 0) {
47
77
  text = value.slice(0, -2) + 'đ';
48
78
  }
49
- const valueFormat = formatMoneyToNumber(text, 'đ');
50
- setValue(formatNumberToMoney(valueFormat, 'đ'));
79
+ setValue(validateText(text));
51
80
  onChangeText?.(formatMoneyToNumber(text, 'đ').toString());
52
81
  };
53
82
 
83
+ useImperativeHandle(ref, () => {
84
+ return {
85
+ clear: onClearText,
86
+ focus: () => inputRef.current?.focus(),
87
+ blur: () => inputRef.current?.blur(),
88
+ setText: _onChangeText,
89
+ };
90
+ });
91
+
54
92
  const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
55
93
  setFocused(true);
56
94
  onFocus?.(e);
@@ -91,9 +129,8 @@ const InputMoney = forwardRef(
91
129
  <View style={styles.inputView}>
92
130
  <TextInput
93
131
  {...props}
94
- accessibilityLabel={`TextInput`}
132
+ accessibilityLabel={accessibilityLabel}
95
133
  editable={!disabled}
96
- textAlignVertical="top"
97
134
  ref={inputRef}
98
135
  keyboardType={'number-pad'}
99
136
  style={[
@@ -129,13 +166,37 @@ const InputMoney = forwardRef(
129
166
  );
130
167
  };
131
168
 
169
+ let inputState = 'active';
170
+
171
+ if (value && value?.length > 0) {
172
+ inputState = 'filled';
173
+ }
174
+ if (errorMessage && errorMessage?.length > 0) {
175
+ inputState = 'error';
176
+ }
177
+
178
+ if (disabled) {
179
+ inputState = 'disabled';
180
+ }
181
+
132
182
  return (
133
- <View
134
- style={styles.wrapper}
135
- accessibilityLabel={`InputMoney/${floatingValue}`}>
136
- {renderInputView()}
137
- <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
138
- </View>
183
+ <ComponentContext.Provider
184
+ value={{
185
+ componentName: 'InputMoney',
186
+ params,
187
+ componentLabel: floatingValue,
188
+ state: inputState,
189
+ componentId: accessibilityLabel,
190
+ }}>
191
+ <View style={[style, styles.wrapper]}>
192
+ {renderInputView()}
193
+ <ErrorView
194
+ errorMessage={errorMessage}
195
+ errorSpacing={errorSpacing}
196
+ hintText={hintText}
197
+ />
198
+ </View>
199
+ </ComponentContext.Provider>
139
200
  );
140
201
  },
141
202
  );