@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.
- package/Application/BottomSheet.tsx +212 -0
- package/Application/BottomTab/BottomTabBar.tsx +278 -0
- package/Application/BottomTab/index.tsx +143 -0
- package/Application/Components.tsx +384 -213
- package/Application/ModalScreen.tsx +14 -178
- package/Application/Navigation.ts +15 -19
- package/Application/NavigationContainer.tsx +66 -63
- package/Application/Navigator.ts +106 -53
- package/Application/StackScreen.tsx +123 -9
- package/Application/index.ts +19 -6
- package/Application/types.ts +83 -26
- package/Application/utils.tsx +62 -74
- package/Assets/icon.json +83 -5
- package/Assets/icon_bank.json +506 -0
- package/Assets/language.json +3 -1
- package/Badge/Badge.tsx +56 -0
- package/Badge/BadgeDot.tsx +11 -0
- package/Badge/BadgeRibbon.tsx +125 -0
- package/Badge/Shape.tsx +29 -0
- package/Badge/index.tsx +7 -0
- package/Badge/styles.ts +58 -0
- package/Badge/types.ts +63 -0
- package/Button/index.tsx +64 -28
- package/Button/styles.ts +19 -0
- package/CheckBox/index.tsx +37 -27
- package/CheckBox/types.ts +5 -3
- package/Consts/colors+spacing+radius.ts +18 -0
- package/Icon/index.tsx +14 -9
- package/Icon/types.ts +4 -3
- package/IconButton/index.tsx +24 -15
- package/Image/index.tsx +62 -47
- package/Image/styles.ts +1 -9
- package/Image/types.ts +5 -1
- package/Input/Input.tsx +104 -25
- package/Input/InputDropDown.tsx +115 -110
- package/Input/InputMoney.tsx +79 -18
- package/Input/InputOTP.tsx +190 -149
- package/Input/InputSearch.tsx +96 -44
- package/Input/InputTextArea.tsx +33 -17
- package/Input/common.tsx +26 -17
- package/Input/index.tsx +108 -41
- package/Input/styles.ts +5 -7
- package/Input/utils.ts +1 -1
- package/Layout/AnimatedInputSearch.tsx +44 -0
- package/Layout/Card.tsx +37 -13
- package/Layout/FloatingButton.tsx +168 -0
- package/Layout/GridSystem.tsx +2 -3
- package/Layout/Item.tsx +1 -2
- package/Layout/ItemList.tsx +55 -0
- package/Layout/ItemSectionList.tsx +39 -0
- package/Layout/Screen.tsx +404 -181
- package/Layout/Section.tsx +22 -22
- package/Layout/TextTyping.tsx +114 -0
- package/Layout/index.ts +12 -2
- package/Layout/styles.ts +46 -13
- package/Layout/types.ts +13 -5
- package/Layout/utils.ts +7 -12
- package/Loader/index.tsx +2 -0
- package/Pagination/PaginationDot.tsx +6 -1
- package/Pagination/PaginationNumber.tsx +7 -4
- package/Pagination/PaginationScroll.tsx +0 -1
- package/Pagination/PaginationWhiteDot.tsx +6 -1
- package/Pagination/styles.ts +3 -0
- package/Pagination/types.ts +2 -0
- package/Popup/PopupNotify.tsx +108 -40
- package/Popup/PopupPromotion.tsx +45 -10
- package/Popup/types.ts +13 -10
- package/Radio/index.tsx +35 -21
- package/Radio/types.ts +7 -5
- package/Skeleton/index.tsx +1 -1
- package/Switch/index.tsx +32 -19
- package/Switch/types.ts +5 -3
- package/Tag/index.tsx +2 -4
- package/Text/index.tsx +26 -6
- package/Text/styles.ts +38 -0
- package/Text/types.ts +25 -13
- package/Title/index.tsx +177 -64
- package/Title/styles.ts +48 -15
- package/Title/types.ts +16 -7
- package/code-scanner.js +125 -16
- package/index.ts +9 -0
- package/migrate_typo.js +56 -0
- package/package.json +8 -7
- package/publish.sh +21 -16
- package/tsconfig.json +1 -2
- package/verify.js +24 -6
- package/Application/BottomTab.tsx +0 -65
package/Input/InputTextArea.tsx
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import 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
|
|
15
|
+
import {ApplicationContext} from '../Application';
|
|
16
|
+
import {Icon} from '../Icon';
|
|
10
17
|
import {Text} from '../Text';
|
|
11
18
|
import {
|
|
12
19
|
DEFAULT_HEIGHT,
|
|
@@ -16,8 +23,7 @@ import {
|
|
|
16
23
|
MAX_LENGTH,
|
|
17
24
|
} from './common';
|
|
18
25
|
import {InputTextAreaProps} from './index';
|
|
19
|
-
import
|
|
20
|
-
import {ApplicationContext} from '../Application';
|
|
26
|
+
import styles from './styles';
|
|
21
27
|
|
|
22
28
|
const InputTextArea = forwardRef(
|
|
23
29
|
(
|
|
@@ -29,14 +35,16 @@ const InputTextArea = forwardRef(
|
|
|
29
35
|
floatingValue,
|
|
30
36
|
onFocus,
|
|
31
37
|
onBlur,
|
|
32
|
-
disabled,
|
|
38
|
+
disabled = false,
|
|
33
39
|
value,
|
|
34
40
|
defaultValue,
|
|
35
41
|
height,
|
|
36
42
|
placeholder,
|
|
37
|
-
maxLength,
|
|
43
|
+
maxLength = MAX_LENGTH,
|
|
38
44
|
required,
|
|
39
45
|
errorSpacing,
|
|
46
|
+
style,
|
|
47
|
+
hintText,
|
|
40
48
|
...props
|
|
41
49
|
}: InputTextAreaProps,
|
|
42
50
|
ref,
|
|
@@ -44,7 +52,7 @@ const InputTextArea = forwardRef(
|
|
|
44
52
|
const {theme} = useContext(ApplicationContext);
|
|
45
53
|
const [focused, setFocused] = useState(false);
|
|
46
54
|
const [inputValue, setInputValue] = useState(defaultValue ?? '');
|
|
47
|
-
const inputRef =
|
|
55
|
+
const inputRef = useRef<TextInput | null>(null);
|
|
48
56
|
|
|
49
57
|
const onClearText = () => {
|
|
50
58
|
inputRef?.current?.clear();
|
|
@@ -66,10 +74,21 @@ const InputTextArea = forwardRef(
|
|
|
66
74
|
onBlur?.(e);
|
|
67
75
|
};
|
|
68
76
|
|
|
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
|
+
|
|
69
86
|
const renderCountingView = () => {
|
|
70
87
|
return (
|
|
71
88
|
<View style={styles.countingView}>
|
|
72
|
-
<Text
|
|
89
|
+
<Text
|
|
90
|
+
color={theme.colors.text.hint}
|
|
91
|
+
typography={'description_xs_regular'}>
|
|
73
92
|
{`${inputValue.length}/${maxLength}`}
|
|
74
93
|
</Text>
|
|
75
94
|
</View>
|
|
@@ -106,7 +125,6 @@ const InputTextArea = forwardRef(
|
|
|
106
125
|
<View style={styles.textAreaView}>
|
|
107
126
|
<TextInput
|
|
108
127
|
{...props}
|
|
109
|
-
accessibilityLabel={`TextInput`}
|
|
110
128
|
ref={inputRef}
|
|
111
129
|
editable={!disabled}
|
|
112
130
|
textAlignVertical="top"
|
|
@@ -146,18 +164,16 @@ const InputTextArea = forwardRef(
|
|
|
146
164
|
};
|
|
147
165
|
|
|
148
166
|
return (
|
|
149
|
-
<View
|
|
150
|
-
style={styles.wrapper}
|
|
151
|
-
accessibilityLabel={`InputTextArea/${floatingValue}`}>
|
|
167
|
+
<View style={[style, styles.wrapper]}>
|
|
152
168
|
{renderInputView()}
|
|
153
|
-
<ErrorView
|
|
169
|
+
<ErrorView
|
|
170
|
+
errorMessage={errorMessage}
|
|
171
|
+
errorSpacing={errorSpacing}
|
|
172
|
+
hintText={hintText}
|
|
173
|
+
/>
|
|
154
174
|
</View>
|
|
155
175
|
);
|
|
156
176
|
},
|
|
157
177
|
);
|
|
158
178
|
|
|
159
|
-
InputTextArea.defaultProps = {
|
|
160
|
-
maxLength: MAX_LENGTH,
|
|
161
|
-
};
|
|
162
|
-
|
|
163
179
|
export default InputTextArea;
|
package/Input/common.tsx
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {View, ViewStyle} from 'react-native';
|
|
2
|
-
import styles from './styles';
|
|
3
|
-
import {Text} from '../Text';
|
|
4
1
|
import React, {FC, useContext} from 'react';
|
|
2
|
+
import {View, ViewStyle} from 'react-native';
|
|
5
3
|
import {ApplicationContext} from '../Application';
|
|
6
|
-
import {Icon} from '../Icon';
|
|
7
|
-
import {Styles} from '../Consts';
|
|
8
4
|
import {Theme} from '../Application/types';
|
|
5
|
+
import {Styles} from '../Consts';
|
|
6
|
+
import {Icon} from '../Icon';
|
|
7
|
+
import {scaleSize, Text} from '../Text';
|
|
8
|
+
import styles from './styles';
|
|
9
9
|
|
|
10
10
|
type FloatingViewProps = {
|
|
11
11
|
floatingValue?: string;
|
|
@@ -16,7 +16,7 @@ type FloatingViewProps = {
|
|
|
16
16
|
style?: ViewStyle;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
export const DEFAULT_HEIGHT =
|
|
19
|
+
export const DEFAULT_HEIGHT = scaleSize(104);
|
|
20
20
|
export const MAX_LENGTH = 300;
|
|
21
21
|
|
|
22
22
|
export const getBorderColor = (
|
|
@@ -48,24 +48,31 @@ export const getSizeStyle = (size?: 'small' | 'large') => {
|
|
|
48
48
|
}
|
|
49
49
|
return styles.container;
|
|
50
50
|
};
|
|
51
|
-
export const ErrorView: FC<{
|
|
52
|
-
errorMessage
|
|
53
|
-
errorSpacing
|
|
54
|
-
|
|
51
|
+
export const ErrorView: FC<{
|
|
52
|
+
errorMessage?: string;
|
|
53
|
+
errorSpacing?: boolean;
|
|
54
|
+
hintText?: string;
|
|
55
|
+
}> = ({errorMessage, errorSpacing, hintText}) => {
|
|
55
56
|
const {theme} = useContext(ApplicationContext);
|
|
56
57
|
const errorColor = theme.colors.error.primary;
|
|
57
|
-
|
|
58
|
+
const hintColor = theme.colors.text.hint;
|
|
59
|
+
const hintTextDefault = hintText ?? 'Không thể chỉnh sửa';
|
|
60
|
+
if (errorMessage || hintText) {
|
|
58
61
|
return (
|
|
59
62
|
<View style={styles.errorView}>
|
|
60
63
|
<View style={styles.errorIcon}>
|
|
61
|
-
<Icon
|
|
64
|
+
<Icon
|
|
65
|
+
color={errorMessage ? errorColor : hintColor}
|
|
66
|
+
source="ic_error"
|
|
67
|
+
size={16}
|
|
68
|
+
/>
|
|
62
69
|
</View>
|
|
63
70
|
<Text
|
|
64
71
|
style={Styles.flex}
|
|
65
|
-
color={errorColor}
|
|
72
|
+
color={errorMessage ? errorColor : hintColor}
|
|
66
73
|
numberOfLines={2}
|
|
67
|
-
typography={'
|
|
68
|
-
{errorMessage}
|
|
74
|
+
typography={'description_default_regular'}>
|
|
75
|
+
{errorMessage ?? hintTextDefault}
|
|
69
76
|
</Text>
|
|
70
77
|
</View>
|
|
71
78
|
);
|
|
@@ -104,10 +111,12 @@ export const FloatingView: FC<FloatingViewProps> = ({
|
|
|
104
111
|
},
|
|
105
112
|
style,
|
|
106
113
|
]}>
|
|
107
|
-
<Text color={floatingTextColor} typography={'
|
|
114
|
+
<Text color={floatingTextColor} typography={'label_s_medium'}>
|
|
108
115
|
{floatingValue}
|
|
109
116
|
{required && (
|
|
110
|
-
<Text
|
|
117
|
+
<Text
|
|
118
|
+
typography={'label_s_medium'}
|
|
119
|
+
color={theme.colors.error.primary}>
|
|
111
120
|
*
|
|
112
121
|
</Text>
|
|
113
122
|
)}
|
package/Input/index.tsx
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import {GestureResponderEvent, TextInputProps, ViewStyle} from 'react-native';
|
|
1
2
|
import Input from './Input';
|
|
2
|
-
import
|
|
3
|
-
import InputSearch from './InputSearch';
|
|
3
|
+
import InputDropDown from './InputDropDown';
|
|
4
4
|
import InputMoney from './InputMoney';
|
|
5
5
|
import InputOTP from './InputOTP';
|
|
6
|
-
import
|
|
7
|
-
import
|
|
6
|
+
import InputSearch from './InputSearch';
|
|
7
|
+
import InputTextArea from './InputTextArea';
|
|
8
8
|
|
|
9
9
|
export interface InputProps extends TextInputProps {
|
|
10
10
|
/**
|
|
@@ -76,20 +76,30 @@ export interface InputProps extends TextInputProps {
|
|
|
76
76
|
* Optional. Represents the color of the leading icon in the Input component.
|
|
77
77
|
*/
|
|
78
78
|
leadingIconColor?: string;
|
|
79
|
-
}
|
|
80
79
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Optional. Represents the font weight of the text in the Input component.
|
|
82
|
+
*/
|
|
83
|
+
fontWeight?: 'Regular' | 'Bold';
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Optional. callback function to be called when the icon is pressed.
|
|
87
|
+
*/
|
|
88
|
+
onPressIcon?: () => void;
|
|
85
89
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
/**
|
|
91
|
+
* Optional. params for element tracking.
|
|
92
|
+
*/
|
|
93
|
+
params?: any;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Optional. Represents text below the Input component.
|
|
97
|
+
*/
|
|
98
|
+
hintText?: string;
|
|
99
|
+
}
|
|
91
100
|
|
|
92
|
-
export interface InputTextAreaProps
|
|
101
|
+
export interface InputTextAreaProps
|
|
102
|
+
extends Omit<InputProps, 'size' | 'icon' | 'iconColor'> {
|
|
93
103
|
/**
|
|
94
104
|
* Optional. Defines the height of the InputTextArea component.
|
|
95
105
|
* It can be used to set a specific height for the text area.
|
|
@@ -97,7 +107,7 @@ export interface InputTextAreaProps extends InputPropsWithoutSizeAndIcon {
|
|
|
97
107
|
height?: number;
|
|
98
108
|
}
|
|
99
109
|
|
|
100
|
-
export interface InputSearchProps extends
|
|
110
|
+
export interface InputSearchProps extends TextInputProps {
|
|
101
111
|
/**
|
|
102
112
|
* Optional. Represents the text to be displayed on the search button within the InputSearch component.
|
|
103
113
|
*/
|
|
@@ -110,86 +120,131 @@ export interface InputSearchProps extends InputPropsOmitForSearch {
|
|
|
110
120
|
showButtonText?: boolean;
|
|
111
121
|
|
|
112
122
|
/**
|
|
113
|
-
* Optional.
|
|
114
|
-
* Defaults to `true` if not provided.
|
|
123
|
+
* Optional. Represents the value for the floating title in the InputSearch component.
|
|
115
124
|
*/
|
|
116
|
-
showBorder?: boolean;
|
|
117
|
-
|
|
118
125
|
onPressButtonText?: () => void;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Optional. Represents the color of the icon in the Input component.
|
|
129
|
+
*/
|
|
130
|
+
iconColor?: string;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Optional. Represents the name or key of the icon to be displayed in the Input component.
|
|
134
|
+
*/
|
|
135
|
+
icon?: string;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Optional. If `true`, the user won't be able to interact with the Input component.
|
|
139
|
+
*/
|
|
140
|
+
hasColorBG?: boolean;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Optional. Represents the style of the InputSearch component.
|
|
144
|
+
*/
|
|
145
|
+
params?: any;
|
|
146
|
+
|
|
147
|
+
typingData?: string[];
|
|
148
|
+
onPress?: (e: GestureResponderEvent) => void;
|
|
119
149
|
}
|
|
120
150
|
|
|
121
|
-
export interface InputMoneyProps extends
|
|
151
|
+
export interface InputMoneyProps extends Omit<InputProps, 'placeholder'> {}
|
|
122
152
|
|
|
123
153
|
export type OTPInputLength = 2 | 4 | 6 | 8 | 10;
|
|
124
154
|
|
|
125
|
-
export interface InputOTPProps
|
|
155
|
+
export interface InputOTPProps
|
|
156
|
+
extends Omit<InputProps, 'size' | 'icon' | 'iconColor'> {
|
|
157
|
+
/**
|
|
158
|
+
* Optional. Defines the length of the OTP (One Time Password) input.
|
|
159
|
+
* Can be 2, 4, 6, 8, or 10.
|
|
160
|
+
*/
|
|
126
161
|
length?: OTPInputLength;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Optional. Defines the data type of the OTP input.
|
|
165
|
+
* 'string' - The OTP input will be treated as a string.
|
|
166
|
+
* 'number' - The OTP input will be treated as a number.
|
|
167
|
+
*/
|
|
127
168
|
dataType?: 'string' | 'number';
|
|
169
|
+
|
|
170
|
+
floatingValue: string;
|
|
128
171
|
}
|
|
129
172
|
|
|
130
173
|
export type CaretProps = {
|
|
174
|
+
/**
|
|
175
|
+
* Optional. The index of the caret in the input field.
|
|
176
|
+
* Represents the position where the caret is located.
|
|
177
|
+
*/
|
|
131
178
|
index?: number;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Optional. The total length of the input field in which the caret is present.
|
|
182
|
+
* This dictates the maximum value of the 'index' property.
|
|
183
|
+
*/
|
|
132
184
|
length?: number;
|
|
133
185
|
};
|
|
134
186
|
|
|
135
|
-
export
|
|
187
|
+
export interface InputDropDownProps extends InputProps {
|
|
136
188
|
/**
|
|
137
|
-
*
|
|
189
|
+
* Optional. Defines the size of the InputDropDown component.
|
|
190
|
+
* 'small' - A smaller, less prominent input.
|
|
191
|
+
* 'large' - A larger, more prominent input.
|
|
138
192
|
*/
|
|
139
193
|
size?: 'small' | 'large';
|
|
140
194
|
|
|
141
195
|
/**
|
|
142
|
-
*
|
|
196
|
+
* Optional. The current value of the InputDropDown.
|
|
143
197
|
*/
|
|
144
198
|
value?: string;
|
|
145
199
|
|
|
146
200
|
/**
|
|
147
|
-
*
|
|
201
|
+
* Optional. Text that is displayed when there is no value set in the InputDropDown.
|
|
148
202
|
*/
|
|
149
203
|
placeholder?: string;
|
|
150
204
|
|
|
151
205
|
/**
|
|
152
|
-
*
|
|
206
|
+
* Optional. Function to be called when the InputDropDown is pressed.
|
|
153
207
|
*/
|
|
154
208
|
onPress?: () => void;
|
|
209
|
+
|
|
155
210
|
/**
|
|
156
|
-
* Optional. Represents the value for the floating title in the
|
|
211
|
+
* Optional. Represents the value for the floating title in the InputDropDown component.
|
|
157
212
|
*/
|
|
158
213
|
floatingValue?: string;
|
|
159
214
|
|
|
160
215
|
/**
|
|
161
|
-
* Optional. Represents the name or key of the floating icon to be displayed in the
|
|
216
|
+
* Optional. Represents the name or key of the floating icon to be displayed in the InputDropDown component.
|
|
162
217
|
*/
|
|
163
218
|
floatingIcon?: string;
|
|
164
219
|
|
|
165
220
|
/**
|
|
166
|
-
* Optional. Represents the error message to be displayed below the
|
|
221
|
+
* Optional. Represents the error message to be displayed below the InputDropDown component when there is an error.
|
|
167
222
|
*/
|
|
168
223
|
errorMessage?: string;
|
|
169
224
|
|
|
170
225
|
/**
|
|
171
|
-
* Optional. Represents the name or key of the icon to be displayed in the
|
|
226
|
+
* Optional. Represents the name or key of the icon to be displayed in the InputDropDown component.
|
|
172
227
|
*/
|
|
173
228
|
icon?: string;
|
|
174
229
|
|
|
175
230
|
/**
|
|
176
|
-
* Optional. Represents the color of the icon in the
|
|
231
|
+
* Optional. Represents the color of the icon in the InputDropDown component.
|
|
177
232
|
*/
|
|
178
233
|
iconColor?: string;
|
|
179
234
|
|
|
180
235
|
/**
|
|
181
|
-
* Optional. If `true`, the user won't be able to interact with the
|
|
236
|
+
* Optional. If `true`, the user won't be able to interact with the InputDropDown component.
|
|
182
237
|
* Defaults to `false` if not provided.
|
|
183
238
|
*/
|
|
184
239
|
disabled?: boolean;
|
|
185
240
|
|
|
186
241
|
/**
|
|
187
|
-
* Optional. Represents the color of the floating icon in the
|
|
242
|
+
* Optional. Represents the color of the floating icon in the InputDropDown component.
|
|
188
243
|
*/
|
|
189
244
|
floatingIconColor?: string;
|
|
190
245
|
|
|
191
246
|
/**
|
|
192
|
-
* Optional. If `true`, the
|
|
247
|
+
* Optional. If `true`, the InputDropDown component is marked as required,
|
|
193
248
|
* indicating that the user must provide a value before submitting a form.
|
|
194
249
|
* Defaults to `false` if not provided.
|
|
195
250
|
*/
|
|
@@ -197,25 +252,37 @@ export type InputDropDownProps = {
|
|
|
197
252
|
|
|
198
253
|
/**
|
|
199
254
|
* Optional. If `true`,
|
|
200
|
-
*
|
|
255
|
+
* includes spacing when InputDropDown does not have an error message.
|
|
201
256
|
* Defaults to `false` if not provided.
|
|
202
257
|
*/
|
|
203
258
|
errorSpacing?: boolean;
|
|
204
259
|
|
|
205
260
|
/**
|
|
206
|
-
*
|
|
261
|
+
* If `true`, the icon of the input will show an indicator for loading.
|
|
207
262
|
*/
|
|
208
263
|
loading?: boolean;
|
|
209
264
|
|
|
210
265
|
/**
|
|
211
|
-
*
|
|
266
|
+
* Optional. Represents the leading icon in the InputDropDown component.
|
|
212
267
|
*/
|
|
213
268
|
leadingIcon?: string;
|
|
214
269
|
|
|
215
270
|
/**
|
|
216
|
-
* Optional. Represents the color of the leading icon in the
|
|
271
|
+
* Optional. Represents the color of the leading icon in the InputDropDown component.
|
|
217
272
|
*/
|
|
218
273
|
leadingIconColor?: string;
|
|
219
|
-
};
|
|
220
274
|
|
|
221
|
-
|
|
275
|
+
/**
|
|
276
|
+
* Optional. params for element tracking.
|
|
277
|
+
*/
|
|
278
|
+
params?: {
|
|
279
|
+
[key: string]: any;
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Optional. Represents the style of the InputDropDown component.
|
|
284
|
+
*/
|
|
285
|
+
style?: ViewStyle | ViewStyle[];
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export {Input, InputDropDown, InputMoney, InputOTP, InputSearch, InputTextArea};
|
package/Input/styles.ts
CHANGED
|
@@ -7,8 +7,8 @@ export default StyleSheet.create({
|
|
|
7
7
|
input: {
|
|
8
8
|
flex: 1,
|
|
9
9
|
paddingLeft: Spacing.M,
|
|
10
|
+
fontSize: scaleSize(14),
|
|
10
11
|
height: '100%',
|
|
11
|
-
fontSize: scaleSize(15),
|
|
12
12
|
},
|
|
13
13
|
wrapper: {
|
|
14
14
|
width: '100%',
|
|
@@ -54,8 +54,7 @@ export default StyleSheet.create({
|
|
|
54
54
|
marginRight: Spacing.M,
|
|
55
55
|
},
|
|
56
56
|
icon: {
|
|
57
|
-
|
|
58
|
-
height: 24,
|
|
57
|
+
marginLeft: Spacing.S,
|
|
59
58
|
},
|
|
60
59
|
iconWrapper: {
|
|
61
60
|
width: 24,
|
|
@@ -77,7 +76,7 @@ export default StyleSheet.create({
|
|
|
77
76
|
flex: 1,
|
|
78
77
|
paddingRight: Spacing.XS,
|
|
79
78
|
paddingVertical: Spacing.XS,
|
|
80
|
-
fontSize: scaleSize(
|
|
79
|
+
fontSize: scaleSize(14),
|
|
81
80
|
},
|
|
82
81
|
textAreaWrapper: {
|
|
83
82
|
borderWidth: 1,
|
|
@@ -102,7 +101,6 @@ export default StyleSheet.create({
|
|
|
102
101
|
searchInputWrapper: {
|
|
103
102
|
flexDirection: 'row',
|
|
104
103
|
borderRadius: Radius.XL,
|
|
105
|
-
borderWidth: 1,
|
|
106
104
|
paddingHorizontal: Spacing.S,
|
|
107
105
|
alignItems: 'center',
|
|
108
106
|
flex: 1,
|
|
@@ -111,7 +109,7 @@ export default StyleSheet.create({
|
|
|
111
109
|
height: 36,
|
|
112
110
|
marginLeft: Spacing.S,
|
|
113
111
|
flex: 1,
|
|
114
|
-
fontSize: scaleSize(
|
|
112
|
+
fontSize: scaleSize(14),
|
|
115
113
|
paddingVertical: Spacing.XS,
|
|
116
114
|
},
|
|
117
115
|
searchInputView: {
|
|
@@ -148,7 +146,7 @@ export default StyleSheet.create({
|
|
|
148
146
|
},
|
|
149
147
|
otpFloatingView: {
|
|
150
148
|
position: 'absolute',
|
|
151
|
-
top: -Spacing.
|
|
149
|
+
top: scaleSize(-Spacing.M + 2),
|
|
152
150
|
alignSelf: 'center',
|
|
153
151
|
paddingHorizontal: Spacing.S,
|
|
154
152
|
},
|
package/Input/utils.ts
CHANGED
|
@@ -61,7 +61,7 @@ const formatMoneyToNumber = (money: string, currencyUnit: string) => {
|
|
|
61
61
|
};
|
|
62
62
|
const checkTyping = (text: string, value: boolean, setValue: any) => {
|
|
63
63
|
let typing = text?.length > 0;
|
|
64
|
-
if (typing
|
|
64
|
+
if (typing !== value) {
|
|
65
65
|
setValue(typing);
|
|
66
66
|
}
|
|
67
67
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React, {FC} from 'react';
|
|
2
|
+
import {InputSearch} from '../Input';
|
|
3
|
+
import {Animated, Dimensions} from 'react-native';
|
|
4
|
+
import {AnimatedInputSearchProps} from './types';
|
|
5
|
+
import {Spacing} from '../Consts';
|
|
6
|
+
import {scaleSize} from '../Text';
|
|
7
|
+
|
|
8
|
+
const {width: screenWidth} = Dimensions.get('window');
|
|
9
|
+
const SCREEN_PADDING = 12;
|
|
10
|
+
const BACK_WIDTH = scaleSize(28);
|
|
11
|
+
|
|
12
|
+
const AnimatedInputSearch: FC<AnimatedInputSearchProps> = ({
|
|
13
|
+
animatedValue,
|
|
14
|
+
headerRightWidth,
|
|
15
|
+
inputSearchProps,
|
|
16
|
+
}) => {
|
|
17
|
+
const translateX = animatedValue.interpolate({
|
|
18
|
+
inputRange: [0, 100],
|
|
19
|
+
outputRange: [SCREEN_PADDING, BACK_WIDTH + SCREEN_PADDING * 2],
|
|
20
|
+
extrapolate: 'clamp',
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const width = animatedValue.interpolate({
|
|
24
|
+
inputRange: [0, 100],
|
|
25
|
+
outputRange: [
|
|
26
|
+
screenWidth - SCREEN_PADDING * 2,
|
|
27
|
+
screenWidth - SCREEN_PADDING * 3 - BACK_WIDTH - headerRightWidth,
|
|
28
|
+
],
|
|
29
|
+
extrapolate: 'clamp',
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<Animated.View
|
|
34
|
+
style={{
|
|
35
|
+
transform: [{translateX}],
|
|
36
|
+
marginVertical: Spacing.S,
|
|
37
|
+
width,
|
|
38
|
+
}}>
|
|
39
|
+
<InputSearch {...inputSearchProps} showButtonText={false} />
|
|
40
|
+
</Animated.View>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default AnimatedInputSearch;
|
package/Layout/Card.tsx
CHANGED
|
@@ -7,17 +7,29 @@ import Item from './Item';
|
|
|
7
7
|
import {Image} from '../Image';
|
|
8
8
|
import {ApplicationContext} from '../Application';
|
|
9
9
|
import styles from './styles';
|
|
10
|
-
import {Colors, Spacing} from '../Consts';
|
|
10
|
+
import {Colors, Radius, Shadow, Spacing} from '../Consts';
|
|
11
|
+
import ItemList from './ItemList';
|
|
11
12
|
|
|
12
13
|
export interface CardProps extends ViewProps {
|
|
13
14
|
/**
|
|
14
15
|
* Optional. Background image for the card.
|
|
15
16
|
*/
|
|
16
17
|
backgroundImage?: string;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Optional. Use shadow for the card.
|
|
21
|
+
*/
|
|
22
|
+
useShadow?: boolean;
|
|
17
23
|
}
|
|
18
24
|
|
|
19
|
-
const Card: React.FC<CardProps> = ({
|
|
20
|
-
|
|
25
|
+
const Card: React.FC<CardProps> = ({
|
|
26
|
+
children,
|
|
27
|
+
style,
|
|
28
|
+
backgroundImage,
|
|
29
|
+
useShadow = false,
|
|
30
|
+
...props
|
|
31
|
+
}) => {
|
|
32
|
+
const {showGrid, theme} = useContext(ApplicationContext);
|
|
21
33
|
const {numberOfColumns} = useGridSystem();
|
|
22
34
|
|
|
23
35
|
const gutterSize = 8;
|
|
@@ -30,12 +42,12 @@ const Card: React.FC<CardProps> = ({children, style, backgroundImage}) => {
|
|
|
30
42
|
const gridContext: GridContextProps = {
|
|
31
43
|
numberOfColumns,
|
|
32
44
|
gutterSize,
|
|
33
|
-
margin,
|
|
34
45
|
sizePerSpan,
|
|
35
46
|
getSizeSpan: span => {
|
|
36
47
|
return span * sizePerSpan + (span - 1) * gutterSize;
|
|
37
48
|
},
|
|
38
49
|
};
|
|
50
|
+
|
|
39
51
|
/**
|
|
40
52
|
* render overlay only dev mode
|
|
41
53
|
*/
|
|
@@ -74,7 +86,7 @@ const Card: React.FC<CardProps> = ({children, style, backgroundImage}) => {
|
|
|
74
86
|
{rows.map((i: React.ReactElement, index: number) => {
|
|
75
87
|
return (
|
|
76
88
|
<View key={`Item${cursor}${index}`} style={{flexDirection: 'row'}}>
|
|
77
|
-
{index
|
|
89
|
+
{index !== 0 && (
|
|
78
90
|
<View style={{width: gridContext.gutterSize}}></View>
|
|
79
91
|
)}
|
|
80
92
|
{i}
|
|
@@ -96,8 +108,9 @@ const Card: React.FC<CardProps> = ({children, style, backgroundImage}) => {
|
|
|
96
108
|
if (Array.isArray(children)) {
|
|
97
109
|
let cursor = 0;
|
|
98
110
|
let rows: any[] = [];
|
|
99
|
-
|
|
100
|
-
|
|
111
|
+
const arrayChild = children.filter(item => !!item);
|
|
112
|
+
for (let i = 0; i < arrayChild.length; ++i) {
|
|
113
|
+
const item = arrayChild[i];
|
|
101
114
|
const totalSpan = rows
|
|
102
115
|
.concat([item])
|
|
103
116
|
.map(i => i.props?.widthSpan)
|
|
@@ -113,14 +126,14 @@ const Card: React.FC<CardProps> = ({children, style, backgroundImage}) => {
|
|
|
113
126
|
rows = [item];
|
|
114
127
|
}
|
|
115
128
|
|
|
116
|
-
if (i
|
|
129
|
+
if (i === arrayChild.length - 1) {
|
|
117
130
|
cursor += 1;
|
|
118
131
|
element.push(addRowView(rows, cursor, true));
|
|
119
132
|
}
|
|
120
133
|
}
|
|
121
134
|
} else {
|
|
122
135
|
element.push(children);
|
|
123
|
-
if (children?.type
|
|
136
|
+
if (children?.type === Fragment) {
|
|
124
137
|
return renderView(children?.props.children);
|
|
125
138
|
}
|
|
126
139
|
}
|
|
@@ -130,22 +143,33 @@ const Card: React.FC<CardProps> = ({children, style, backgroundImage}) => {
|
|
|
130
143
|
return (
|
|
131
144
|
<GridContext.Provider value={gridContext}>
|
|
132
145
|
<View
|
|
133
|
-
|
|
146
|
+
{...props}
|
|
147
|
+
onLayout={undefined}
|
|
134
148
|
style={[
|
|
149
|
+
{backgroundColor: theme.colors.background.surface},
|
|
135
150
|
style,
|
|
151
|
+
styles.protectedStyle,
|
|
136
152
|
styles.card,
|
|
137
153
|
{
|
|
138
154
|
width: widthSection,
|
|
139
|
-
marginHorizontal:
|
|
155
|
+
marginHorizontal: margin,
|
|
140
156
|
},
|
|
157
|
+
!!backgroundImage && {backgroundColor: undefined},
|
|
158
|
+
useShadow && Shadow.Light,
|
|
141
159
|
]}>
|
|
142
160
|
{!!backgroundImage && (
|
|
143
161
|
<Image
|
|
144
162
|
source={{uri: backgroundImage}}
|
|
145
|
-
style={[
|
|
163
|
+
style={[
|
|
164
|
+
styles.imageBackground,
|
|
165
|
+
{
|
|
166
|
+
width: widthSection,
|
|
167
|
+
borderRadius: Radius.M,
|
|
168
|
+
},
|
|
169
|
+
]}
|
|
146
170
|
/>
|
|
147
171
|
)}
|
|
148
|
-
{renderView(validateChildren(children, [Item]))}
|
|
172
|
+
{renderView(validateChildren(children, [Item, ItemList]))}
|
|
149
173
|
{showGrid && renderOverlay()}
|
|
150
174
|
</View>
|
|
151
175
|
</GridContext.Provider>
|