@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.
- package/Application/BottomSheet.tsx +216 -0
- package/Application/BottomTab/BottomTabBar.tsx +278 -0
- package/Application/{BottomTab.tsx → BottomTab/index.tsx} +42 -18
- package/Application/Components.tsx +356 -91
- package/Application/Localize.ts +44 -0
- package/Application/ModalScreen.tsx +14 -185
- package/Application/Navigation.ts +5 -19
- package/Application/NavigationContainer.tsx +62 -72
- package/Application/Navigator.ts +154 -48
- package/Application/StackScreen.tsx +289 -32
- package/Application/constants.ts +9 -0
- package/Application/index.ts +13 -15
- package/Application/types.ts +81 -35
- package/Application/utils.tsx +76 -30
- package/Assets/icon_bank.json +1 -1
- package/Badge/Badge.tsx +1 -1
- package/Badge/BadgeDotAnimation.tsx +95 -0
- package/Badge/index.tsx +2 -1
- package/Badge/styles.ts +50 -6
- package/Button/index.tsx +44 -26
- package/CheckBox/index.tsx +37 -26
- package/CheckBox/types.ts +5 -3
- package/Consts/colors+spacing+radius.ts +14 -0
- package/Icon/index.tsx +9 -8
- package/Icon/types.ts +2 -2
- package/IconButton/index.tsx +24 -14
- package/Image/index.tsx +23 -8
- package/Image/types.ts +2 -0
- package/Input/Input.tsx +116 -26
- package/Input/InputDropDown.tsx +66 -51
- package/Input/InputMoney.tsx +106 -15
- package/Input/InputOTP.tsx +49 -26
- package/Input/InputSearch.tsx +252 -99
- package/Input/InputTextArea.tsx +26 -6
- package/Input/TextTyping.tsx +113 -0
- package/Input/common.tsx +48 -22
- package/Input/index.tsx +112 -77
- package/Input/styles.ts +48 -11
- package/Input/utils.ts +1 -1
- package/Layout/Card.tsx +4 -3
- package/Layout/FloatingButton.tsx +168 -0
- package/Layout/GridSystem.tsx +1 -1
- package/Layout/ItemList.tsx +3 -2
- package/Layout/Screen.tsx +242 -121
- package/Layout/Section.tsx +4 -3
- package/Layout/styles.ts +11 -13
- package/Layout/types.ts +1 -1
- package/Layout/utils.ts +4 -4
- package/Loader/index.tsx +2 -0
- package/Pagination/PaginationScroll.tsx +2 -2
- package/Pagination/styles.ts +1 -1
- package/Popup/PopupNotify.tsx +57 -46
- package/Popup/PopupPromotion.tsx +6 -8
- package/Popup/types.ts +1 -7
- package/Radio/index.tsx +35 -20
- package/Radio/types.ts +5 -3
- package/Switch/index.tsx +32 -18
- package/Switch/types.ts +5 -3
- package/Tag/index.tsx +9 -2
- package/Tag/styles.ts +3 -2
- package/Tag/types.ts +12 -0
- package/Text/index.tsx +24 -5
- package/Text/styles.ts +8 -8
- package/Text/types.ts +19 -1
- package/Title/index.tsx +170 -103
- package/Title/styles.ts +36 -9
- package/Title/types.ts +16 -48
- package/code-scanner.js +125 -16
- package/index.ts +7 -0
- package/migrate_typo.js +56 -0
- package/package.json +10 -9
- package/publish.sh +16 -21
- package/tsconfig.json +1 -1
package/Input/InputOTP.tsx
CHANGED
|
@@ -15,12 +15,12 @@ import {
|
|
|
15
15
|
TouchableOpacity,
|
|
16
16
|
View,
|
|
17
17
|
} from 'react-native';
|
|
18
|
-
import {
|
|
18
|
+
import {ApplicationContext, ComponentContext} from '../Application';
|
|
19
|
+
import {Spacing} from '../Consts';
|
|
19
20
|
import {scaleSize, Text} from '../Text';
|
|
20
|
-
import styles from './styles';
|
|
21
21
|
import {ErrorView, getBorderColor} from './common';
|
|
22
|
-
import {
|
|
23
|
-
import
|
|
22
|
+
import {CaretProps, InputOTPProps} from './index';
|
|
23
|
+
import styles from './styles';
|
|
24
24
|
|
|
25
25
|
const OTPCaret: FC<CaretProps> = ({index, length}) => {
|
|
26
26
|
const DURATION = 300;
|
|
@@ -41,7 +41,7 @@ const OTPCaret: FC<CaretProps> = ({index, length}) => {
|
|
|
41
41
|
duration: DURATION,
|
|
42
42
|
useNativeDriver: true,
|
|
43
43
|
}),
|
|
44
|
-
])
|
|
44
|
+
])
|
|
45
45
|
).start();
|
|
46
46
|
}, []);
|
|
47
47
|
const spacingStyle = !isNaN(Number(length)) &&
|
|
@@ -70,29 +70,36 @@ const InputOTP = forwardRef(
|
|
|
70
70
|
length,
|
|
71
71
|
errorMessage,
|
|
72
72
|
errorSpacing,
|
|
73
|
-
floatingValue,
|
|
74
|
-
floatingIconColor,
|
|
75
|
-
floatingIcon,
|
|
73
|
+
floatingValue = 'Label',
|
|
76
74
|
placeholder,
|
|
77
75
|
onChangeText,
|
|
78
|
-
onFocus,
|
|
79
76
|
onBlur,
|
|
77
|
+
onFocus,
|
|
80
78
|
dataType = 'number',
|
|
79
|
+
params,
|
|
81
80
|
style,
|
|
81
|
+
accessibilityLabel,
|
|
82
|
+
hintText,
|
|
82
83
|
...props
|
|
83
84
|
}: InputOTPProps,
|
|
84
|
-
ref
|
|
85
|
+
ref
|
|
85
86
|
) => {
|
|
86
87
|
const MAX_LENGTH = 10;
|
|
87
88
|
const [value, setValue] = useState('');
|
|
88
89
|
const [focused, setFocused] = useState(false);
|
|
89
|
-
const inputRef = useRef<TextInput>(null);
|
|
90
|
+
const inputRef = useRef<TextInput | null>(null);
|
|
90
91
|
const {theme} = useContext(ApplicationContext);
|
|
91
92
|
|
|
92
93
|
useImperativeHandle(ref, () => ({
|
|
93
94
|
onChangeText: (text: string) => {
|
|
94
95
|
_onChangeText(text);
|
|
95
96
|
},
|
|
97
|
+
focus: () => {
|
|
98
|
+
setFocused(true);
|
|
99
|
+
inputRef.current?.focus()
|
|
100
|
+
},
|
|
101
|
+
blur: () => inputRef.current?.blur(),
|
|
102
|
+
setText: (text: string) => _onChangeText(text),
|
|
96
103
|
}));
|
|
97
104
|
|
|
98
105
|
const onFocusInput = () => {
|
|
@@ -119,16 +126,16 @@ const InputOTP = forwardRef(
|
|
|
119
126
|
onChangeText?.(text);
|
|
120
127
|
};
|
|
121
128
|
|
|
122
|
-
const renderInputs = (
|
|
129
|
+
const renderInputs = (inputLength: number) => {
|
|
123
130
|
const TextInputs: React.ReactNode[] = [];
|
|
124
|
-
for (let i = 0; i <
|
|
131
|
+
for (let i = 0; i < inputLength; i++) {
|
|
125
132
|
TextInputs.push(
|
|
126
133
|
<View>
|
|
127
134
|
{focused && value.length === i ? (
|
|
128
|
-
<OTPCaret index={i} length={
|
|
135
|
+
<OTPCaret index={i} length={inputLength} />
|
|
129
136
|
) : (
|
|
130
137
|
<Text
|
|
131
|
-
style={i !==
|
|
138
|
+
style={i !== inputLength - 1 && {marginRight: Spacing.L}}
|
|
132
139
|
color={
|
|
133
140
|
!!value[i]
|
|
134
141
|
? theme.colors.text.default
|
|
@@ -140,7 +147,7 @@ const InputOTP = forwardRef(
|
|
|
140
147
|
{value[i] || '-'}
|
|
141
148
|
</Text>
|
|
142
149
|
)}
|
|
143
|
-
</View
|
|
150
|
+
</View>
|
|
144
151
|
);
|
|
145
152
|
}
|
|
146
153
|
return TextInputs;
|
|
@@ -194,7 +201,9 @@ const InputOTP = forwardRef(
|
|
|
194
201
|
styles.otpFloatingView,
|
|
195
202
|
{backgroundColor: theme.colors.background.surface},
|
|
196
203
|
]}>
|
|
197
|
-
<Text
|
|
204
|
+
<Text
|
|
205
|
+
typography={'description_default_regular'}
|
|
206
|
+
color={theme.colors.text.hint}>
|
|
198
207
|
{floatingValue}
|
|
199
208
|
</Text>
|
|
200
209
|
</View>
|
|
@@ -205,11 +214,12 @@ const InputOTP = forwardRef(
|
|
|
205
214
|
<View style={styles.inputView}>
|
|
206
215
|
<TextInput
|
|
207
216
|
{...props}
|
|
217
|
+
accessibilityLabel={accessibilityLabel}
|
|
208
218
|
ref={inputRef}
|
|
209
219
|
value={value}
|
|
210
220
|
onChangeText={_onChangeText}
|
|
211
221
|
keyboardType={dataType === 'number' ? 'number-pad' : 'default'}
|
|
212
|
-
onFocus={
|
|
222
|
+
onFocus={onFocus}
|
|
213
223
|
onBlur={onBlurInput}
|
|
214
224
|
style={{opacity: 0}}
|
|
215
225
|
selectionColor={theme.colors.primary}
|
|
@@ -221,15 +231,28 @@ const InputOTP = forwardRef(
|
|
|
221
231
|
};
|
|
222
232
|
|
|
223
233
|
return (
|
|
224
|
-
<
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
234
|
+
<ComponentContext.Provider
|
|
235
|
+
value={{
|
|
236
|
+
componentName: 'InputOTP',
|
|
237
|
+
params,
|
|
238
|
+
componentLabel: floatingValue,
|
|
239
|
+
state: 'enabled',
|
|
240
|
+
componentId: accessibilityLabel,
|
|
241
|
+
}}>
|
|
242
|
+
<TouchableOpacity
|
|
243
|
+
activeOpacity={1}
|
|
244
|
+
onPress={onFocusInput}
|
|
245
|
+
style={[style, styles.otpWrapper]}>
|
|
246
|
+
{renderInputView()}
|
|
247
|
+
<ErrorView
|
|
248
|
+
errorMessage={errorMessage}
|
|
249
|
+
errorSpacing={errorSpacing}
|
|
250
|
+
hintText={hintText}
|
|
251
|
+
/>
|
|
252
|
+
</TouchableOpacity>
|
|
253
|
+
</ComponentContext.Provider>
|
|
231
254
|
);
|
|
232
|
-
}
|
|
255
|
+
}
|
|
233
256
|
);
|
|
234
257
|
|
|
235
258
|
export default InputOTP;
|
package/Input/InputSearch.tsx
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
FC,
|
|
3
|
+
forwardRef,
|
|
4
|
+
ForwardRefRenderFunction,
|
|
5
|
+
useContext,
|
|
6
|
+
useEffect,
|
|
7
|
+
useImperativeHandle,
|
|
8
|
+
useRef,
|
|
9
|
+
useState,
|
|
10
|
+
} from 'react';
|
|
2
11
|
import {
|
|
3
12
|
NativeSyntheticEvent,
|
|
4
13
|
TextInput,
|
|
@@ -6,127 +15,271 @@ import {
|
|
|
6
15
|
TouchableOpacity,
|
|
7
16
|
View,
|
|
8
17
|
} from 'react-native';
|
|
9
|
-
import {
|
|
10
|
-
import {ApplicationContext} from '../Application';
|
|
11
|
-
import styles from './styles';
|
|
18
|
+
import {ApplicationContext, ComponentContext} from '../Application';
|
|
12
19
|
import {Icon} from '../Icon';
|
|
13
20
|
import {Text} from '../Text';
|
|
21
|
+
import {InputRef, InputSearchProps} from './index';
|
|
22
|
+
import styles from './styles';
|
|
14
23
|
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);
|
|
15
32
|
|
|
16
|
-
const
|
|
17
|
-
(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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);
|
|
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();
|
|
44
47
|
};
|
|
45
48
|
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
const handleAnimation = () => {
|
|
50
|
+
const listChar = data?.[currentIndex.current]?.split('') || [];
|
|
51
|
+
listChar.length !== 0 && showChar(listChar?.[currentCharIndex.current]);
|
|
49
52
|
};
|
|
50
53
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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();
|
|
54
86
|
};
|
|
55
87
|
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
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),
|
|
59
172
|
};
|
|
173
|
+
});
|
|
60
174
|
|
|
61
|
-
|
|
175
|
+
/**
|
|
176
|
+
* Render the input view
|
|
177
|
+
*/
|
|
178
|
+
const renderInputView = () => {
|
|
179
|
+
if (typingData && typingData?.length > 0) {
|
|
62
180
|
return (
|
|
63
|
-
<
|
|
64
|
-
{...props}
|
|
65
|
-
textAlignVertical="center"
|
|
66
|
-
ref={inputRef}
|
|
181
|
+
<TouchableOpacity
|
|
67
182
|
style={[
|
|
68
183
|
styles.searchInput,
|
|
69
184
|
{
|
|
70
|
-
|
|
185
|
+
justifyContent: 'center',
|
|
71
186
|
},
|
|
72
187
|
]}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
placeholder={placeholder}
|
|
78
|
-
selectionColor={theme.colors.primary}
|
|
79
|
-
placeholderTextColor={theme.colors.text.hint}
|
|
80
|
-
/>
|
|
188
|
+
onPress={onPress}
|
|
189
|
+
activeOpacity={onPress ? 0.6 : 1}>
|
|
190
|
+
<TextTyping data={typingData} />
|
|
191
|
+
</TouchableOpacity>
|
|
81
192
|
);
|
|
82
|
-
}
|
|
193
|
+
}
|
|
83
194
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
},
|
|
107
|
-
]}
|
|
108
|
-
/>
|
|
109
|
-
<Icon
|
|
110
|
-
color={iconColor}
|
|
111
|
-
source={icon}
|
|
112
|
-
style={styles.iconSearchInput}
|
|
113
|
-
/>
|
|
114
|
-
</View>
|
|
115
|
-
)}
|
|
116
|
-
</View>
|
|
117
|
-
);
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
const backgroundColor = hasColorBG ? theme.colors.background.default : theme.colors.background.surface
|
|
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
|
+
};
|
|
121
217
|
|
|
218
|
+
/**
|
|
219
|
+
* Render trailing icon or text
|
|
220
|
+
*/
|
|
221
|
+
const renderTrailing = () => {
|
|
122
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
|
+
};
|
|
255
|
+
|
|
256
|
+
let inputState = 'empty';
|
|
257
|
+
if (focused) {
|
|
258
|
+
inputState = 'focus';
|
|
259
|
+
}
|
|
260
|
+
if (value && value?.length > 0) {
|
|
261
|
+
inputState = 'filled';
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const backgroundColor = hasColorBG
|
|
265
|
+
? theme.colors.background.default
|
|
266
|
+
: theme.colors.background.surface;
|
|
267
|
+
|
|
268
|
+
return (
|
|
269
|
+
<ComponentContext.Provider
|
|
270
|
+
value={{
|
|
271
|
+
componentName: 'InputSearch',
|
|
272
|
+
params,
|
|
273
|
+
state: inputState,
|
|
274
|
+
componentId: accessibilityLabel,
|
|
275
|
+
}}>
|
|
123
276
|
<View style={[style, styles.searchInputContainer]}>
|
|
124
277
|
<View
|
|
125
278
|
style={[
|
|
126
279
|
styles.searchInputWrapper,
|
|
127
280
|
{
|
|
128
281
|
backgroundColor,
|
|
129
|
-
}
|
|
282
|
+
},
|
|
130
283
|
]}>
|
|
131
284
|
<Icon
|
|
132
285
|
source={'navigation_search'}
|
|
@@ -134,7 +287,7 @@ const InputSearch = forwardRef(
|
|
|
134
287
|
color={theme.colors.text.hint}
|
|
135
288
|
/>
|
|
136
289
|
{renderInputView()}
|
|
137
|
-
{
|
|
290
|
+
{renderTrailing()}
|
|
138
291
|
</View>
|
|
139
292
|
{showButtonText && (
|
|
140
293
|
<TouchableOpacity onPress={onPressButtonText}>
|
|
@@ -144,8 +297,8 @@ const InputSearch = forwardRef(
|
|
|
144
297
|
</TouchableOpacity>
|
|
145
298
|
)}
|
|
146
299
|
</View>
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
300
|
+
</ComponentContext.Provider>
|
|
301
|
+
);
|
|
302
|
+
};
|
|
150
303
|
|
|
151
|
-
export default InputSearch;
|
|
304
|
+
export default forwardRef(InputSearch);
|
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
|
(
|
|
@@ -38,6 +44,7 @@ const InputTextArea = forwardRef(
|
|
|
38
44
|
required,
|
|
39
45
|
errorSpacing,
|
|
40
46
|
style,
|
|
47
|
+
hintText,
|
|
41
48
|
...props
|
|
42
49
|
}: InputTextAreaProps,
|
|
43
50
|
ref,
|
|
@@ -45,7 +52,7 @@ const InputTextArea = forwardRef(
|
|
|
45
52
|
const {theme} = useContext(ApplicationContext);
|
|
46
53
|
const [focused, setFocused] = useState(false);
|
|
47
54
|
const [inputValue, setInputValue] = useState(defaultValue ?? '');
|
|
48
|
-
const inputRef =
|
|
55
|
+
const inputRef = useRef<TextInput | null>(null);
|
|
49
56
|
|
|
50
57
|
const onClearText = () => {
|
|
51
58
|
inputRef?.current?.clear();
|
|
@@ -67,6 +74,15 @@ const InputTextArea = forwardRef(
|
|
|
67
74
|
onBlur?.(e);
|
|
68
75
|
};
|
|
69
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
|
+
|
|
70
86
|
const renderCountingView = () => {
|
|
71
87
|
return (
|
|
72
88
|
<View style={styles.countingView}>
|
|
@@ -150,7 +166,11 @@ const InputTextArea = forwardRef(
|
|
|
150
166
|
return (
|
|
151
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
|
},
|