@momo-kits/foundation 0.92.7-rc.21 → 0.92.7-rc.22
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 +62 -223
- package/Application/BottomTab/index.tsx +15 -11
- package/Application/Components.tsx +291 -45
- package/Application/Localize.ts +44 -0
- package/Application/ModalScreen.tsx +11 -181
- package/Application/Navigation.ts +4 -18
- package/Application/NavigationContainer.tsx +10 -28
- package/Application/Navigator.ts +14 -16
- package/Application/StackScreen.tsx +222 -42
- package/Application/index.ts +5 -3
- package/Application/types.ts +47 -29
- package/Application/utils.tsx +61 -19
- package/Assets/icon_bank.json +1 -1
- package/Badge/BadgeDotAnimation.tsx +95 -0
- package/Badge/index.tsx +2 -1
- package/Badge/styles.ts +50 -6
- package/Button/index.tsx +7 -8
- package/Icon/index.tsx +1 -1
- package/Icon/types.ts +1 -2
- package/Image/index.tsx +0 -1
- package/Input/Input.tsx +51 -17
- package/Input/InputDropDown.tsx +42 -45
- package/Input/InputMoney.tsx +65 -6
- package/Input/InputOTP.tsx +14 -13
- package/Input/InputSearch.tsx +259 -146
- package/Input/InputTextArea.tsx +0 -1
- package/Input/TextTyping.tsx +113 -0
- package/Input/common.tsx +29 -10
- package/Input/index.tsx +84 -89
- package/Input/styles.ts +44 -7
- package/Input/utils.ts +1 -1
- package/Layout/Card.tsx +4 -3
- package/Layout/FloatingButton.tsx +3 -3
- package/Layout/GridSystem.tsx +1 -1
- package/Layout/ItemList.tsx +3 -2
- package/Layout/Screen.tsx +188 -102
- package/Layout/Section.tsx +4 -3
- package/Layout/styles.ts +0 -6
- package/Layout/types.ts +1 -1
- package/Layout/utils.ts +2 -2
- package/Loader/index.tsx +2 -0
- package/Pagination/PaginationScroll.tsx +2 -2
- package/Pagination/styles.ts +1 -1
- package/Popup/PopupNotify.tsx +7 -7
- package/Popup/PopupPromotion.tsx +1 -1
- package/Popup/types.ts +1 -1
- package/Tag/index.tsx +9 -2
- package/Tag/styles.ts +3 -2
- package/Tag/types.ts +12 -0
- package/Title/index.tsx +20 -7
- package/Title/styles.ts +4 -4
- package/code-scanner.js +141 -124
- package/index.ts +7 -0
- package/package.json +5 -4
- package/publish.sh +16 -21
- package/tsconfig.json +1 -1
package/Input/InputMoney.tsx
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React, {
|
|
2
2
|
forwardRef,
|
|
3
|
+
ReactNode,
|
|
3
4
|
useContext,
|
|
5
|
+
useEffect,
|
|
4
6
|
useImperativeHandle,
|
|
5
7
|
useRef,
|
|
6
8
|
useState,
|
|
@@ -18,6 +20,8 @@ import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
|
|
|
18
20
|
import {InputMoneyProps} from './index';
|
|
19
21
|
import styles from './styles';
|
|
20
22
|
import {formatMoneyToNumber, formatNumberToMoney} from './utils';
|
|
23
|
+
import {Text} from '../Text';
|
|
24
|
+
import {Loader} from '../Loader';
|
|
21
25
|
|
|
22
26
|
const InputMoney = forwardRef(
|
|
23
27
|
(
|
|
@@ -26,13 +30,18 @@ const InputMoney = forwardRef(
|
|
|
26
30
|
floatingValue,
|
|
27
31
|
floatingIcon,
|
|
28
32
|
size = 'small',
|
|
33
|
+
loading,
|
|
29
34
|
onBlur,
|
|
30
35
|
onFocus,
|
|
31
36
|
errorMessage,
|
|
32
37
|
icon,
|
|
38
|
+
iconColor,
|
|
39
|
+
onPressIcon,
|
|
40
|
+
trailing,
|
|
41
|
+
trailingColor,
|
|
42
|
+
onPressTrailing,
|
|
33
43
|
disabled = false,
|
|
34
44
|
floatingIconColor,
|
|
35
|
-
iconColor,
|
|
36
45
|
required = false,
|
|
37
46
|
errorSpacing,
|
|
38
47
|
style,
|
|
@@ -40,21 +49,30 @@ const InputMoney = forwardRef(
|
|
|
40
49
|
defaultValue = '',
|
|
41
50
|
accessibilityLabel,
|
|
42
51
|
hintText,
|
|
52
|
+
value: _value,
|
|
53
|
+
onPressFloatingIcon,
|
|
43
54
|
...props
|
|
44
55
|
}: InputMoneyProps,
|
|
45
|
-
ref
|
|
56
|
+
ref
|
|
46
57
|
) => {
|
|
47
58
|
const {theme} = useContext(ApplicationContext);
|
|
48
59
|
const [focused, setFocused] = useState(false);
|
|
49
60
|
const inputRef = useRef<TextInput>(null);
|
|
50
61
|
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (_value) {
|
|
64
|
+
setValue(validateText(_value));
|
|
65
|
+
onChangeText?.(formatMoneyToNumber(_value, 'đ').toString());
|
|
66
|
+
}
|
|
67
|
+
}, [_value]);
|
|
68
|
+
|
|
51
69
|
const validateText = (text: string) => {
|
|
52
70
|
const valueFormat = formatMoneyToNumber(text, 'đ');
|
|
53
71
|
return formatNumberToMoney(valueFormat, 'đ');
|
|
54
72
|
};
|
|
55
73
|
|
|
56
74
|
const [value, setValue] = useState(
|
|
57
|
-
defaultValue ? validateText(defaultValue) : ''
|
|
75
|
+
defaultValue ? validateText(defaultValue) : ''
|
|
58
76
|
);
|
|
59
77
|
|
|
60
78
|
const onClearText = () => {
|
|
@@ -90,11 +108,51 @@ const InputMoney = forwardRef(
|
|
|
90
108
|
onBlur?.(e);
|
|
91
109
|
};
|
|
92
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Render trailing icon or text
|
|
113
|
+
* @param color
|
|
114
|
+
*/
|
|
115
|
+
const renderTrailing = (color?: string) => {
|
|
116
|
+
if (loading) {
|
|
117
|
+
return <Loader type={'spinner'} color={color} style={styles.icon} />;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (icon || trailing) {
|
|
121
|
+
const renderIconTouchable = (icon: ReactNode) => {
|
|
122
|
+
return (
|
|
123
|
+
<TouchableOpacity
|
|
124
|
+
onPress={onPressTrailing ?? onPressIcon}
|
|
125
|
+
style={styles.icon}>
|
|
126
|
+
{icon}
|
|
127
|
+
</TouchableOpacity>
|
|
128
|
+
);
|
|
129
|
+
};
|
|
130
|
+
const trailingValue = icon || trailing;
|
|
131
|
+
if (trailingValue?.includes('_') || trailingValue?.includes('http')) {
|
|
132
|
+
return renderIconTouchable(
|
|
133
|
+
<Icon
|
|
134
|
+
color={color}
|
|
135
|
+
source={(icon || trailing) as string}
|
|
136
|
+
size={24}
|
|
137
|
+
/>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
return renderIconTouchable(
|
|
141
|
+
<Text
|
|
142
|
+
typography="action_xs_bold"
|
|
143
|
+
color={color ?? theme.colors.primary}
|
|
144
|
+
numberOfLines={1}>
|
|
145
|
+
{trailingValue!.substring(0, 15)}
|
|
146
|
+
</Text>
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
93
151
|
const renderInputView = () => {
|
|
94
152
|
const disabledColor = theme.colors.text.disable;
|
|
95
153
|
let textColor = theme.colors.text.default;
|
|
96
154
|
let placeholderColor = theme.colors.text.hint;
|
|
97
|
-
let iconTintColor = iconColor;
|
|
155
|
+
let iconTintColor = trailingColor ?? iconColor;
|
|
98
156
|
|
|
99
157
|
if (disabled) {
|
|
100
158
|
textColor = disabledColor;
|
|
@@ -116,6 +174,7 @@ const InputMoney = forwardRef(
|
|
|
116
174
|
disabled={disabled}
|
|
117
175
|
required={required}
|
|
118
176
|
floatingIcon={floatingIcon}
|
|
177
|
+
onPress={onPressFloatingIcon}
|
|
119
178
|
/>
|
|
120
179
|
<View style={styles.inputView}>
|
|
121
180
|
<TextInput
|
|
@@ -151,7 +210,7 @@ const InputMoney = forwardRef(
|
|
|
151
210
|
/>
|
|
152
211
|
</TouchableOpacity>
|
|
153
212
|
)}
|
|
154
|
-
{
|
|
213
|
+
{renderTrailing(iconTintColor)}
|
|
155
214
|
</View>
|
|
156
215
|
</View>
|
|
157
216
|
);
|
|
@@ -189,7 +248,7 @@ const InputMoney = forwardRef(
|
|
|
189
248
|
</View>
|
|
190
249
|
</ComponentContext.Provider>
|
|
191
250
|
);
|
|
192
|
-
}
|
|
251
|
+
}
|
|
193
252
|
);
|
|
194
253
|
|
|
195
254
|
export default InputMoney;
|
package/Input/InputOTP.tsx
CHANGED
|
@@ -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)) &&
|
|
@@ -71,12 +71,10 @@ const InputOTP = forwardRef(
|
|
|
71
71
|
errorMessage,
|
|
72
72
|
errorSpacing,
|
|
73
73
|
floatingValue = 'Label',
|
|
74
|
-
floatingIconColor,
|
|
75
|
-
floatingIcon,
|
|
76
74
|
placeholder,
|
|
77
75
|
onChangeText,
|
|
78
|
-
onFocus,
|
|
79
76
|
onBlur,
|
|
77
|
+
onFocus,
|
|
80
78
|
dataType = 'number',
|
|
81
79
|
params,
|
|
82
80
|
style,
|
|
@@ -84,7 +82,7 @@ const InputOTP = forwardRef(
|
|
|
84
82
|
hintText,
|
|
85
83
|
...props
|
|
86
84
|
}: InputOTPProps,
|
|
87
|
-
ref
|
|
85
|
+
ref
|
|
88
86
|
) => {
|
|
89
87
|
const MAX_LENGTH = 10;
|
|
90
88
|
const [value, setValue] = useState('');
|
|
@@ -96,7 +94,10 @@ const InputOTP = forwardRef(
|
|
|
96
94
|
onChangeText: (text: string) => {
|
|
97
95
|
_onChangeText(text);
|
|
98
96
|
},
|
|
99
|
-
focus: () =>
|
|
97
|
+
focus: () => {
|
|
98
|
+
setFocused(true);
|
|
99
|
+
inputRef.current?.focus()
|
|
100
|
+
},
|
|
100
101
|
blur: () => inputRef.current?.blur(),
|
|
101
102
|
setText: (text: string) => _onChangeText(text),
|
|
102
103
|
}));
|
|
@@ -125,16 +126,16 @@ const InputOTP = forwardRef(
|
|
|
125
126
|
onChangeText?.(text);
|
|
126
127
|
};
|
|
127
128
|
|
|
128
|
-
const renderInputs = (
|
|
129
|
+
const renderInputs = (inputLength: number) => {
|
|
129
130
|
const TextInputs: React.ReactNode[] = [];
|
|
130
|
-
for (let i = 0; i <
|
|
131
|
+
for (let i = 0; i < inputLength; i++) {
|
|
131
132
|
TextInputs.push(
|
|
132
133
|
<View>
|
|
133
134
|
{focused && value.length === i ? (
|
|
134
|
-
<OTPCaret index={i} length={
|
|
135
|
+
<OTPCaret index={i} length={inputLength} />
|
|
135
136
|
) : (
|
|
136
137
|
<Text
|
|
137
|
-
style={i !==
|
|
138
|
+
style={i !== inputLength - 1 && {marginRight: Spacing.L}}
|
|
138
139
|
color={
|
|
139
140
|
!!value[i]
|
|
140
141
|
? theme.colors.text.default
|
|
@@ -146,7 +147,7 @@ const InputOTP = forwardRef(
|
|
|
146
147
|
{value[i] || '-'}
|
|
147
148
|
</Text>
|
|
148
149
|
)}
|
|
149
|
-
</View
|
|
150
|
+
</View>
|
|
150
151
|
);
|
|
151
152
|
}
|
|
152
153
|
return TextInputs;
|
|
@@ -218,7 +219,7 @@ const InputOTP = forwardRef(
|
|
|
218
219
|
value={value}
|
|
219
220
|
onChangeText={_onChangeText}
|
|
220
221
|
keyboardType={dataType === 'number' ? 'number-pad' : 'default'}
|
|
221
|
-
onFocus={
|
|
222
|
+
onFocus={onFocus}
|
|
222
223
|
onBlur={onBlurInput}
|
|
223
224
|
style={{opacity: 0}}
|
|
224
225
|
selectionColor={theme.colors.primary}
|
|
@@ -251,7 +252,7 @@ const InputOTP = forwardRef(
|
|
|
251
252
|
</TouchableOpacity>
|
|
252
253
|
</ComponentContext.Provider>
|
|
253
254
|
);
|
|
254
|
-
}
|
|
255
|
+
}
|
|
255
256
|
);
|
|
256
257
|
|
|
257
258
|
export default InputOTP;
|
package/Input/InputSearch.tsx
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import React, {
|
|
2
|
+
FC,
|
|
2
3
|
forwardRef,
|
|
4
|
+
ForwardRefRenderFunction,
|
|
3
5
|
useContext,
|
|
6
|
+
useEffect,
|
|
4
7
|
useImperativeHandle,
|
|
5
8
|
useRef,
|
|
6
9
|
useState,
|
|
@@ -15,177 +18,287 @@ import {
|
|
|
15
18
|
import {ApplicationContext, ComponentContext} from '../Application';
|
|
16
19
|
import {Icon} from '../Icon';
|
|
17
20
|
import {Text} from '../Text';
|
|
18
|
-
import {InputSearchProps} from './index';
|
|
21
|
+
import {InputRef, InputSearchProps} from './index';
|
|
19
22
|
import styles from './styles';
|
|
20
23
|
import {checkTyping} from './utils';
|
|
24
|
+
import {Styles} from '../Consts';
|
|
21
25
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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);
|
|
48
|
-
|
|
49
|
-
const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
|
|
50
|
-
setFocused(true);
|
|
51
|
-
onFocus?.(e);
|
|
26
|
+
const TextTyping: FC<any> = ({
|
|
27
|
+
data = [],
|
|
28
|
+
timeDelayEnd = 2000,
|
|
29
|
+
timeDelayNextChar = 20,
|
|
30
|
+
}) => {
|
|
31
|
+
const textRef = useRef<TextInput>(null);
|
|
32
|
+
|
|
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();
|
|
52
47
|
};
|
|
53
48
|
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
const handleAnimation = () => {
|
|
50
|
+
const listChar = data?.[currentIndex.current]?.split('') || [];
|
|
51
|
+
listChar.length !== 0 && showChar(listChar?.[currentCharIndex.current]);
|
|
57
52
|
};
|
|
58
53
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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);
|
|
62
64
|
};
|
|
63
65
|
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
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);
|
|
67
75
|
};
|
|
68
76
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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();
|
|
86
|
+
};
|
|
87
|
+
|
|
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
|
+
};
|
|
77
155
|
|
|
78
|
-
|
|
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),
|
|
172
|
+
};
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Render the input view
|
|
177
|
+
*/
|
|
178
|
+
const renderInputView = () => {
|
|
179
|
+
if (typingData && typingData?.length > 0) {
|
|
79
180
|
return (
|
|
80
|
-
<
|
|
81
|
-
{...props}
|
|
82
|
-
accessibilityLabel={accessibilityLabel}
|
|
83
|
-
textAlignVertical="center"
|
|
84
|
-
ref={inputRef}
|
|
181
|
+
<TouchableOpacity
|
|
85
182
|
style={[
|
|
86
183
|
styles.searchInput,
|
|
87
184
|
{
|
|
88
|
-
|
|
185
|
+
justifyContent: 'center',
|
|
89
186
|
},
|
|
90
187
|
]}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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>
|
|
188
|
+
onPress={onPress}
|
|
189
|
+
activeOpacity={onPress ? 0.6 : 1}>
|
|
190
|
+
<TextTyping data={typingData} />
|
|
191
|
+
</TouchableOpacity>
|
|
135
192
|
);
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
let inputState = 'empty';
|
|
139
|
-
|
|
140
|
-
if (focused) {
|
|
141
|
-
inputState = 'focus';
|
|
142
193
|
}
|
|
143
194
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
+
};
|
|
151
217
|
|
|
218
|
+
/**
|
|
219
|
+
* Render trailing icon or text
|
|
220
|
+
*/
|
|
221
|
+
const renderTrailing = () => {
|
|
152
222
|
return (
|
|
153
|
-
<
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
params,
|
|
157
|
-
state: inputState,
|
|
158
|
-
componentId: accessibilityLabel,
|
|
159
|
-
}}>
|
|
160
|
-
<View style={[style, styles.searchInputContainer]}>
|
|
161
|
-
<View
|
|
162
|
-
style={[
|
|
163
|
-
styles.searchInputWrapper,
|
|
164
|
-
{
|
|
165
|
-
backgroundColor,
|
|
166
|
-
},
|
|
167
|
-
]}>
|
|
223
|
+
<View style={Styles.row}>
|
|
224
|
+
{focused && haveValue && (
|
|
225
|
+
<TouchableOpacity style={styles.iconWrapper} onPress={onClearText}>
|
|
168
226
|
<Icon
|
|
169
|
-
source=
|
|
170
|
-
size={
|
|
227
|
+
source="24_navigation_close_circle_full"
|
|
228
|
+
size={16}
|
|
171
229
|
color={theme.colors.text.hint}
|
|
172
230
|
/>
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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>
|
|
187
253
|
);
|
|
188
|
-
}
|
|
189
|
-
|
|
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
|
+
}}>
|
|
276
|
+
<View style={[style, styles.searchInputContainer]}>
|
|
277
|
+
<View
|
|
278
|
+
style={[
|
|
279
|
+
styles.searchInputWrapper,
|
|
280
|
+
{
|
|
281
|
+
backgroundColor,
|
|
282
|
+
},
|
|
283
|
+
]}>
|
|
284
|
+
<Icon
|
|
285
|
+
source={'navigation_search'}
|
|
286
|
+
size={24}
|
|
287
|
+
color={theme.colors.text.hint}
|
|
288
|
+
/>
|
|
289
|
+
{renderInputView()}
|
|
290
|
+
{renderTrailing()}
|
|
291
|
+
</View>
|
|
292
|
+
{showButtonText && (
|
|
293
|
+
<TouchableOpacity onPress={onPressButtonText}>
|
|
294
|
+
<Text typography={'action_default_bold'} style={styles.textButton}>
|
|
295
|
+
{buttonText}
|
|
296
|
+
</Text>
|
|
297
|
+
</TouchableOpacity>
|
|
298
|
+
)}
|
|
299
|
+
</View>
|
|
300
|
+
</ComponentContext.Provider>
|
|
301
|
+
);
|
|
302
|
+
};
|
|
190
303
|
|
|
191
|
-
export default InputSearch;
|
|
304
|
+
export default forwardRef(InputSearch);
|