@momo-kits/foundation 0.92.30 → 0.92.32
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/Components.tsx +8 -8
- package/Application/Navigator.ts +5 -7
- package/Application/StackScreen.tsx +41 -5
- package/Input/Input.tsx +51 -17
- package/Input/InputDropDown.tsx +42 -45
- package/Input/InputMoney.tsx +56 -6
- package/Input/InputOTP.tsx +4 -1
- package/Input/InputSearch.tsx +25 -17
- package/Input/common.tsx +29 -10
- package/Input/index.tsx +57 -74
- package/Input/styles.ts +29 -0
- package/Layout/Screen.tsx +11 -11
- package/Popup/PopupNotify.tsx +2 -2
- package/Title/styles.ts +4 -4
- package/package.json +1 -1
- package/publish.sh +0 -10
- package/verify.js +36 -42
|
@@ -65,7 +65,7 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
|
|
|
65
65
|
}, [badgeType, badgeValue]);
|
|
66
66
|
|
|
67
67
|
return (
|
|
68
|
-
<View style={{width:
|
|
68
|
+
<View style={{width: 28}}>
|
|
69
69
|
<TouchableOpacity
|
|
70
70
|
accessibilityLabel={accessibilityLabel}
|
|
71
71
|
style={[styles.navigationButton, buttonStyle]}
|
|
@@ -113,7 +113,7 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
113
113
|
useEffect(() => {
|
|
114
114
|
const backHandler = BackHandler.addEventListener(
|
|
115
115
|
'hardwareBackPress',
|
|
116
|
-
goBackSafe
|
|
116
|
+
goBackSafe
|
|
117
117
|
);
|
|
118
118
|
|
|
119
119
|
return () => backHandler.remove();
|
|
@@ -268,7 +268,7 @@ const HeaderRightAction: React.FC<any> = ({children, ...restProps}) => {
|
|
|
268
268
|
const valid = child?.type === NavigationButton || child?.type === Fragment;
|
|
269
269
|
if (__DEV__ && !valid) {
|
|
270
270
|
console.warn(
|
|
271
|
-
'HeaderRightAction contains element type of NavigationButton, Please check again.'
|
|
271
|
+
'HeaderRightAction contains element type of NavigationButton, Please check again.'
|
|
272
272
|
);
|
|
273
273
|
}
|
|
274
274
|
return child;
|
|
@@ -327,7 +327,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
327
327
|
(config: any) => {
|
|
328
328
|
navigator.toolkitConfig = config;
|
|
329
329
|
setToolConfig(navigator?.toolkitConfig);
|
|
330
|
-
}
|
|
330
|
+
}
|
|
331
331
|
);
|
|
332
332
|
};
|
|
333
333
|
|
|
@@ -338,9 +338,9 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
338
338
|
{runtimeTools},
|
|
339
339
|
(res: {item: {action?: string; key: string}}) => {
|
|
340
340
|
const {item} = res;
|
|
341
|
-
navigator?.toolkitCallback?.(item);
|
|
341
|
+
navigator?.toolkitCallback?.(item.key);
|
|
342
342
|
getToolkitConfig();
|
|
343
|
-
}
|
|
343
|
+
}
|
|
344
344
|
);
|
|
345
345
|
};
|
|
346
346
|
|
|
@@ -357,7 +357,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
357
357
|
navigator?.maxApi?.dispatchFunction?.(
|
|
358
358
|
'dismiss',
|
|
359
359
|
undefined,
|
|
360
|
-
undefined
|
|
360
|
+
undefined
|
|
361
361
|
);
|
|
362
362
|
},
|
|
363
363
|
}}
|
|
@@ -388,7 +388,7 @@ const HeaderToolkitAction: React.FC<any> = ({
|
|
|
388
388
|
[pinTool?.key],
|
|
389
389
|
() => {
|
|
390
390
|
getToolkitConfig();
|
|
391
|
-
}
|
|
391
|
+
}
|
|
392
392
|
);
|
|
393
393
|
navigator?.toolkitCallback?.(pinTool.key);
|
|
394
394
|
}}
|
package/Application/Navigator.ts
CHANGED
|
@@ -12,7 +12,7 @@ class Navigator {
|
|
|
12
12
|
toolkitConfig?: HeaderToolkitProps;
|
|
13
13
|
maxApi?: any;
|
|
14
14
|
dismissData?: any;
|
|
15
|
-
toolkitCallback?: (
|
|
15
|
+
toolkitCallback?: (key: string) => void;
|
|
16
16
|
|
|
17
17
|
constructor(navigation: any, isReady: any) {
|
|
18
18
|
this.ref = navigation;
|
|
@@ -78,7 +78,7 @@ class Navigator {
|
|
|
78
78
|
StackActions.push('Modal', {
|
|
79
79
|
...params,
|
|
80
80
|
isBottomSheet: true,
|
|
81
|
-
})
|
|
81
|
+
})
|
|
82
82
|
);
|
|
83
83
|
}
|
|
84
84
|
};
|
|
@@ -103,7 +103,7 @@ class Navigator {
|
|
|
103
103
|
CommonActions.navigate({
|
|
104
104
|
name,
|
|
105
105
|
params,
|
|
106
|
-
})
|
|
106
|
+
})
|
|
107
107
|
);
|
|
108
108
|
}
|
|
109
109
|
};
|
|
@@ -124,7 +124,7 @@ class Navigator {
|
|
|
124
124
|
params,
|
|
125
125
|
},
|
|
126
126
|
],
|
|
127
|
-
})
|
|
127
|
+
})
|
|
128
128
|
);
|
|
129
129
|
}
|
|
130
130
|
};
|
|
@@ -141,9 +141,7 @@ class Navigator {
|
|
|
141
141
|
* set callback function for toolkit
|
|
142
142
|
* @param callback
|
|
143
143
|
*/
|
|
144
|
-
setToolkitCallback = (
|
|
145
|
-
callback: (item: {key: string; action: string}) => void,
|
|
146
|
-
) => {
|
|
144
|
+
setToolkitCallback = (callback: (key: string) => void) => {
|
|
147
145
|
this.toolkitCallback = callback;
|
|
148
146
|
};
|
|
149
147
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, {useContext, useEffect, useLayoutEffect, useRef} from 'react';
|
|
2
2
|
import {useHeaderHeight} from '@react-navigation/stack';
|
|
3
|
-
import {InteractionManager, Linking, View} from 'react-native';
|
|
3
|
+
import {Alert, InteractionManager, Linking, View} from 'react-native';
|
|
4
4
|
import {ScreenParams} from './types';
|
|
5
5
|
import Navigation from './Navigation';
|
|
6
6
|
import {ApplicationContext, MiniAppContext, ScreenContext} from './index';
|
|
@@ -95,6 +95,8 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
95
95
|
const timeInteraction = useRef(0);
|
|
96
96
|
const timeoutLoad = useRef<any>();
|
|
97
97
|
const tracked = useRef<any>({
|
|
98
|
+
traceIdLoad: undefined,
|
|
99
|
+
traceIdInteraction: undefined,
|
|
98
100
|
releaseLoad: undefined,
|
|
99
101
|
releaseInteraction: undefined,
|
|
100
102
|
timeoutLoad: undefined,
|
|
@@ -125,6 +127,15 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
125
127
|
if (options) {
|
|
126
128
|
navigation.setOptions(options);
|
|
127
129
|
}
|
|
130
|
+
navigator?.maxApi?.startTraceScreenLoad?.(screenName, (data: any) => {
|
|
131
|
+
tracked.current.traceIdLoad = data?.traceId;
|
|
132
|
+
});
|
|
133
|
+
navigator?.maxApi?.startTraceScreenInteraction?.(
|
|
134
|
+
screenName,
|
|
135
|
+
(data: any) => {
|
|
136
|
+
tracked.current.traceIdInteraction = data?.traceId;
|
|
137
|
+
}
|
|
138
|
+
);
|
|
128
139
|
}, [options]);
|
|
129
140
|
|
|
130
141
|
/**
|
|
@@ -146,6 +157,8 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
146
157
|
}, 5000);
|
|
147
158
|
|
|
148
159
|
return () => {
|
|
160
|
+
clearTimeout(tracked.current.timeoutLoad);
|
|
161
|
+
clearTimeout(tracked.current.timeoutInteraction);
|
|
149
162
|
onScreenLoad();
|
|
150
163
|
onScreenInteraction();
|
|
151
164
|
};
|
|
@@ -155,8 +168,10 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
155
168
|
* tracking for screen load
|
|
156
169
|
*/
|
|
157
170
|
const onScreenLoad = () => {
|
|
158
|
-
clearTimeout(tracked.current.timeoutLoad);
|
|
159
171
|
if (!tracked.current?.releaseLoad) {
|
|
172
|
+
if (timeLoad.current === 0) {
|
|
173
|
+
timeLoad.current = endTime.current - startTime.current;
|
|
174
|
+
}
|
|
160
175
|
context.autoTracking?.({
|
|
161
176
|
appId: context.appId,
|
|
162
177
|
code: context.code,
|
|
@@ -166,10 +181,18 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
166
181
|
state: 'load',
|
|
167
182
|
duration: timeLoad.current,
|
|
168
183
|
});
|
|
184
|
+
navigator?.maxApi?.stopTrace?.(
|
|
185
|
+
tracked.current.traceIdLoad,
|
|
186
|
+
{value: timeLoad.current},
|
|
187
|
+
null
|
|
188
|
+
);
|
|
169
189
|
navigator?.maxApi?.showToastDebug?.({
|
|
170
190
|
appId: `auto - ${context.appId}`,
|
|
171
191
|
message: `${screenName} screen_load_time ${timeLoad.current}`,
|
|
172
192
|
});
|
|
193
|
+
if (timeLoad.current === 0 && context.enableAutoId) {
|
|
194
|
+
Alert.alert(screenName, "Can't get screen load time");
|
|
195
|
+
}
|
|
173
196
|
tracked.current.releaseLoad = true;
|
|
174
197
|
}
|
|
175
198
|
};
|
|
@@ -178,8 +201,17 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
178
201
|
* tracking for screen load
|
|
179
202
|
*/
|
|
180
203
|
const onScreenInteraction = () => {
|
|
181
|
-
clearTimeout(tracked.current.timeoutInteraction);
|
|
182
204
|
if (!tracked.current?.releaseInteraction) {
|
|
205
|
+
if (timeLoad.current === 0) {
|
|
206
|
+
timeLoad.current = endTime.current - startTime.current;
|
|
207
|
+
}
|
|
208
|
+
if (timeInteraction.current === 0 && context.enableAutoId) {
|
|
209
|
+
if (context.enableAutoId) {
|
|
210
|
+
Alert.alert(screenName, "Can't get screen interaction time");
|
|
211
|
+
}
|
|
212
|
+
timeInteraction.current = timeLoad.current;
|
|
213
|
+
}
|
|
214
|
+
|
|
183
215
|
context.autoTracking?.({
|
|
184
216
|
appId: context.appId,
|
|
185
217
|
code: context.code,
|
|
@@ -189,7 +221,11 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
189
221
|
state: 'interaction',
|
|
190
222
|
duration: timeInteraction.current - timeLoad.current,
|
|
191
223
|
});
|
|
192
|
-
|
|
224
|
+
navigator?.maxApi?.stopTrace?.(
|
|
225
|
+
tracked.current.traceIdInteraction,
|
|
226
|
+
{value: timeInteraction.current},
|
|
227
|
+
null
|
|
228
|
+
);
|
|
193
229
|
navigator?.maxApi?.showToastDebug?.({
|
|
194
230
|
appId: `auto - ${context.appId}`,
|
|
195
231
|
message: `${screenName} screen_interaction_time ${timeInteraction.current}`,
|
|
@@ -203,12 +239,12 @@ const StackScreen: React.FC<ScreenParams> = props => {
|
|
|
203
239
|
value={{
|
|
204
240
|
screenName,
|
|
205
241
|
onElementLoad: () => {
|
|
242
|
+
clearTimeout(timeoutLoad.current);
|
|
206
243
|
endTime.current = Date.now();
|
|
207
244
|
interaction.current?.cancel?.();
|
|
208
245
|
interaction.current = InteractionManager.runAfterInteractions(() => {
|
|
209
246
|
timeInteraction.current = Date.now() - startTime.current;
|
|
210
247
|
});
|
|
211
|
-
clearTimeout(timeoutLoad.current);
|
|
212
248
|
timeoutLoad.current = setTimeout(() => {
|
|
213
249
|
if (timeLoad.current === 0) {
|
|
214
250
|
timeLoad.current = endTime.current - startTime.current;
|
package/Input/Input.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, {
|
|
2
2
|
forwardRef,
|
|
3
|
+
ReactNode,
|
|
3
4
|
useContext,
|
|
4
5
|
useImperativeHandle,
|
|
5
6
|
useRef,
|
|
@@ -16,11 +17,15 @@ import {
|
|
|
16
17
|
import {ApplicationContext, ComponentContext} from '../Application';
|
|
17
18
|
import {Icon} from '../Icon';
|
|
18
19
|
import {Loader} from '../Loader';
|
|
20
|
+
import {Text} from '../Text';
|
|
19
21
|
import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
|
|
20
22
|
import {InputProps} from './index';
|
|
21
23
|
import styles from './styles';
|
|
22
24
|
import {checkTyping} from './utils';
|
|
23
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Input default component
|
|
28
|
+
*/
|
|
24
29
|
const Input = forwardRef(
|
|
25
30
|
(
|
|
26
31
|
{
|
|
@@ -34,16 +39,19 @@ const Input = forwardRef(
|
|
|
34
39
|
onFocus,
|
|
35
40
|
errorMessage,
|
|
36
41
|
icon,
|
|
42
|
+
iconColor,
|
|
43
|
+
onPressIcon,
|
|
44
|
+
trailing,
|
|
45
|
+
trailingColor,
|
|
46
|
+
onPressTrailing,
|
|
37
47
|
disabled = false,
|
|
38
48
|
floatingIconColor,
|
|
39
|
-
iconColor,
|
|
40
49
|
required = false,
|
|
41
50
|
errorSpacing,
|
|
42
51
|
loading = false,
|
|
43
52
|
leadingIcon,
|
|
44
53
|
leadingIconColor,
|
|
45
54
|
fontWeight = 'Regular',
|
|
46
|
-
onPressIcon,
|
|
47
55
|
secureTextEntry,
|
|
48
56
|
keyboardType,
|
|
49
57
|
style,
|
|
@@ -51,9 +59,10 @@ const Input = forwardRef(
|
|
|
51
59
|
hintText,
|
|
52
60
|
accessibilityLabel,
|
|
53
61
|
editable = true,
|
|
62
|
+
onPressFloatingIcon,
|
|
54
63
|
...props
|
|
55
64
|
}: InputProps,
|
|
56
|
-
ref
|
|
65
|
+
ref
|
|
57
66
|
) => {
|
|
58
67
|
const {theme} = useContext(ApplicationContext);
|
|
59
68
|
const [focused, setFocused] = useState(false);
|
|
@@ -90,7 +99,11 @@ const Input = forwardRef(
|
|
|
90
99
|
};
|
|
91
100
|
});
|
|
92
101
|
|
|
93
|
-
|
|
102
|
+
/**
|
|
103
|
+
* Render trailing icon or text
|
|
104
|
+
* @param color
|
|
105
|
+
*/
|
|
106
|
+
const renderTrailing = (color?: string) => {
|
|
94
107
|
if (loading) {
|
|
95
108
|
return <Loader type={'spinner'} color={color} style={styles.icon} />;
|
|
96
109
|
}
|
|
@@ -109,24 +122,46 @@ const Input = forwardRef(
|
|
|
109
122
|
</TouchableOpacity>
|
|
110
123
|
);
|
|
111
124
|
}
|
|
112
|
-
if (icon) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
125
|
+
if (icon || trailing) {
|
|
126
|
+
const renderIconTouchable = (icon: ReactNode) => {
|
|
127
|
+
return (
|
|
128
|
+
<TouchableOpacity
|
|
129
|
+
onPress={onPressTrailing ?? onPressIcon}
|
|
130
|
+
style={styles.icon}>
|
|
131
|
+
{icon}
|
|
132
|
+
</TouchableOpacity>
|
|
133
|
+
);
|
|
134
|
+
};
|
|
135
|
+
const trailingValue = icon || trailing;
|
|
136
|
+
if (trailingValue?.includes('_') || trailingValue?.includes('http')) {
|
|
137
|
+
return renderIconTouchable(
|
|
138
|
+
<Icon
|
|
139
|
+
color={color}
|
|
140
|
+
source={(icon || trailing) as string}
|
|
141
|
+
size={24}
|
|
142
|
+
/>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
return renderIconTouchable(
|
|
146
|
+
<Text
|
|
147
|
+
typography="action_xs_bold"
|
|
148
|
+
color={color ?? theme.colors.primary}
|
|
149
|
+
numberOfLines={1}>
|
|
150
|
+
{trailingValue!.substring(0, 15)}
|
|
151
|
+
</Text>
|
|
120
152
|
);
|
|
121
153
|
}
|
|
122
154
|
};
|
|
123
155
|
|
|
156
|
+
/**
|
|
157
|
+
* Render input view
|
|
158
|
+
*/
|
|
124
159
|
const renderInputView = () => {
|
|
125
160
|
const disabledColor = theme.colors.text.disable;
|
|
126
161
|
const secure = secureTextInput && secureTextEntry;
|
|
127
162
|
let textColor = theme.colors.text.default;
|
|
128
163
|
let placeholderColor = theme.colors.text.hint;
|
|
129
|
-
let iconTintColor = iconColor;
|
|
164
|
+
let iconTintColor = trailingColor ?? iconColor;
|
|
130
165
|
|
|
131
166
|
if (disabled) {
|
|
132
167
|
textColor = disabledColor;
|
|
@@ -155,6 +190,7 @@ const Input = forwardRef(
|
|
|
155
190
|
disabled={disabled}
|
|
156
191
|
required={required}
|
|
157
192
|
floatingIcon={floatingIcon}
|
|
193
|
+
onPress={onPressFloatingIcon}
|
|
158
194
|
/>
|
|
159
195
|
<View style={styles.inputView}>
|
|
160
196
|
{!!leadingIcon && (
|
|
@@ -204,21 +240,19 @@ const Input = forwardRef(
|
|
|
204
240
|
/>
|
|
205
241
|
</TouchableOpacity>
|
|
206
242
|
)}
|
|
207
|
-
{
|
|
243
|
+
{renderTrailing(iconTintColor)}
|
|
208
244
|
</View>
|
|
209
245
|
</View>
|
|
210
246
|
);
|
|
211
247
|
};
|
|
212
248
|
|
|
213
249
|
let inputState = 'active';
|
|
214
|
-
|
|
215
250
|
if (value && value?.length > 0) {
|
|
216
251
|
inputState = 'filled';
|
|
217
252
|
}
|
|
218
253
|
if (errorMessage && errorMessage?.length > 0) {
|
|
219
254
|
inputState = 'error';
|
|
220
255
|
}
|
|
221
|
-
|
|
222
256
|
if (disabled) {
|
|
223
257
|
inputState = 'disabled';
|
|
224
258
|
}
|
|
@@ -242,7 +276,7 @@ const Input = forwardRef(
|
|
|
242
276
|
</View>
|
|
243
277
|
</ComponentContext.Provider>
|
|
244
278
|
);
|
|
245
|
-
}
|
|
279
|
+
}
|
|
246
280
|
);
|
|
247
281
|
|
|
248
282
|
export default Input;
|
package/Input/InputDropDown.tsx
CHANGED
|
@@ -1,66 +1,55 @@
|
|
|
1
1
|
import React, {useContext} from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import {TouchableOpacity, View} from 'react-native';
|
|
3
3
|
import {ApplicationContext, ComponentContext} from '../Application';
|
|
4
|
-
import {Styles} from '../Consts';
|
|
5
4
|
import {Icon} from '../Icon';
|
|
6
|
-
import {Loader} from '../Loader';
|
|
7
5
|
import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
|
|
8
6
|
import {InputDropDownProps} from './index';
|
|
7
|
+
import {Text} from '../Text';
|
|
9
8
|
import styles from './styles';
|
|
9
|
+
import {Spacing} from '../Consts';
|
|
10
10
|
|
|
11
11
|
const InputDropDown = ({
|
|
12
12
|
value,
|
|
13
13
|
floatingValue,
|
|
14
14
|
floatingIcon,
|
|
15
|
+
onPressFloatingIcon,
|
|
15
16
|
size = 'small',
|
|
16
17
|
onPress,
|
|
17
18
|
placeholder,
|
|
18
19
|
errorMessage,
|
|
19
|
-
icon = 'arrow_chevron_down_small',
|
|
20
20
|
disabled = false,
|
|
21
21
|
floatingIconColor,
|
|
22
|
-
iconColor,
|
|
23
22
|
required = false,
|
|
24
23
|
errorSpacing,
|
|
25
|
-
loading = false,
|
|
26
24
|
leadingIcon,
|
|
27
25
|
leadingIconColor,
|
|
28
26
|
style,
|
|
29
27
|
params,
|
|
30
28
|
accessibilityLabel,
|
|
31
29
|
hintText,
|
|
32
|
-
|
|
30
|
+
multiline,
|
|
33
31
|
}: InputDropDownProps) => {
|
|
34
32
|
const {theme} = useContext(ApplicationContext);
|
|
35
|
-
const full = !!value || !!placeholder;
|
|
36
|
-
|
|
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
|
-
};
|
|
45
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Render the input view
|
|
36
|
+
*/
|
|
46
37
|
const renderInputView = () => {
|
|
47
38
|
const disabledColor = theme.colors.text.disable;
|
|
48
39
|
let textColor = theme.colors.text.default;
|
|
49
40
|
let placeholderColor = theme.colors.text.hint;
|
|
50
|
-
let iconTintColor = iconColor;
|
|
51
41
|
|
|
52
42
|
if (disabled) {
|
|
53
43
|
textColor = disabledColor;
|
|
54
44
|
placeholderColor = disabledColor;
|
|
55
|
-
iconTintColor = disabledColor;
|
|
56
45
|
}
|
|
57
46
|
|
|
58
47
|
return (
|
|
59
48
|
<View
|
|
60
49
|
style={[
|
|
61
|
-
styles.
|
|
50
|
+
styles.inputDropDownWrapper,
|
|
62
51
|
{backgroundColor: theme.colors.background.surface},
|
|
63
|
-
getSizeStyle(size),
|
|
52
|
+
getSizeStyle(size, multiline),
|
|
64
53
|
getBorderColor(theme, false, errorMessage, disabled),
|
|
65
54
|
]}>
|
|
66
55
|
<FloatingView
|
|
@@ -69,10 +58,18 @@ const InputDropDown = ({
|
|
|
69
58
|
disabled={disabled}
|
|
70
59
|
required={required}
|
|
71
60
|
floatingIcon={floatingIcon}
|
|
61
|
+
onPress={onPressFloatingIcon}
|
|
72
62
|
/>
|
|
73
|
-
<View style={
|
|
63
|
+
<View style={styles.inputDropDownView}>
|
|
74
64
|
{!!leadingIcon && (
|
|
75
|
-
<View
|
|
65
|
+
<View
|
|
66
|
+
style={[
|
|
67
|
+
styles.leadingIconContainerDropDown,
|
|
68
|
+
{
|
|
69
|
+
marginTop: Spacing.M,
|
|
70
|
+
marginRight: Spacing.S,
|
|
71
|
+
},
|
|
72
|
+
]}>
|
|
76
73
|
<Icon
|
|
77
74
|
color={leadingIconColor}
|
|
78
75
|
source={leadingIcon}
|
|
@@ -80,28 +77,27 @@ const InputDropDown = ({
|
|
|
80
77
|
/>
|
|
81
78
|
</View>
|
|
82
79
|
)}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
80
|
+
<View
|
|
81
|
+
accessibilityLabel={accessibilityLabel}
|
|
82
|
+
style={styles.textViewDropDown}>
|
|
83
|
+
<Text
|
|
84
|
+
numberOfLines={multiline ? undefined : 1}
|
|
85
|
+
typography={'body_default_regular'}
|
|
86
|
+
color={value ? textColor : placeholderColor}>
|
|
87
|
+
{value || placeholder}
|
|
88
|
+
</Text>
|
|
89
|
+
</View>
|
|
90
|
+
</View>
|
|
91
|
+
<View
|
|
92
|
+
style={[
|
|
93
|
+
styles.iconViewDropDown,
|
|
94
|
+
{
|
|
95
|
+
alignItems: multiline ? 'flex-start' : 'center',
|
|
96
|
+
paddingTop: multiline ? Spacing.M : 0,
|
|
97
|
+
},
|
|
98
|
+
]}>
|
|
99
|
+
<Icon source={'arrow_chevron_down_small'} />
|
|
103
100
|
</View>
|
|
104
|
-
<View style={styles.iconView}>{renderIcon(iconTintColor)}</View>
|
|
105
101
|
</View>
|
|
106
102
|
);
|
|
107
103
|
};
|
|
@@ -116,8 +112,9 @@ const InputDropDown = ({
|
|
|
116
112
|
componentId: accessibilityLabel,
|
|
117
113
|
}}>
|
|
118
114
|
<TouchableOpacity
|
|
115
|
+
activeOpacity={0.6}
|
|
119
116
|
onPress={onPress}
|
|
120
|
-
style={[style,
|
|
117
|
+
style={[style, styles.wrapper]}>
|
|
121
118
|
{renderInputView()}
|
|
122
119
|
<ErrorView
|
|
123
120
|
errorMessage={errorMessage}
|
package/Input/InputMoney.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, {
|
|
2
2
|
forwardRef,
|
|
3
|
+
ReactNode,
|
|
3
4
|
useContext,
|
|
4
5
|
useEffect,
|
|
5
6
|
useImperativeHandle,
|
|
@@ -19,6 +20,8 @@ import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
|
|
|
19
20
|
import {InputMoneyProps} from './index';
|
|
20
21
|
import styles from './styles';
|
|
21
22
|
import {formatMoneyToNumber, formatNumberToMoney} from './utils';
|
|
23
|
+
import {Text} from '../Text';
|
|
24
|
+
import {Loader} from '../Loader';
|
|
22
25
|
|
|
23
26
|
const InputMoney = forwardRef(
|
|
24
27
|
(
|
|
@@ -27,13 +30,18 @@ const InputMoney = forwardRef(
|
|
|
27
30
|
floatingValue,
|
|
28
31
|
floatingIcon,
|
|
29
32
|
size = 'small',
|
|
33
|
+
loading,
|
|
30
34
|
onBlur,
|
|
31
35
|
onFocus,
|
|
32
36
|
errorMessage,
|
|
33
37
|
icon,
|
|
38
|
+
iconColor,
|
|
39
|
+
onPressIcon,
|
|
40
|
+
trailing,
|
|
41
|
+
trailingColor,
|
|
42
|
+
onPressTrailing,
|
|
34
43
|
disabled = false,
|
|
35
44
|
floatingIconColor,
|
|
36
|
-
iconColor,
|
|
37
45
|
required = false,
|
|
38
46
|
errorSpacing,
|
|
39
47
|
style,
|
|
@@ -42,9 +50,10 @@ const InputMoney = forwardRef(
|
|
|
42
50
|
accessibilityLabel,
|
|
43
51
|
hintText,
|
|
44
52
|
value: _value,
|
|
53
|
+
onPressFloatingIcon,
|
|
45
54
|
...props
|
|
46
55
|
}: InputMoneyProps,
|
|
47
|
-
ref
|
|
56
|
+
ref
|
|
48
57
|
) => {
|
|
49
58
|
const {theme} = useContext(ApplicationContext);
|
|
50
59
|
const [focused, setFocused] = useState(false);
|
|
@@ -63,7 +72,7 @@ const InputMoney = forwardRef(
|
|
|
63
72
|
};
|
|
64
73
|
|
|
65
74
|
const [value, setValue] = useState(
|
|
66
|
-
defaultValue ? validateText(defaultValue) : ''
|
|
75
|
+
defaultValue ? validateText(defaultValue) : ''
|
|
67
76
|
);
|
|
68
77
|
|
|
69
78
|
const onClearText = () => {
|
|
@@ -99,11 +108,51 @@ const InputMoney = forwardRef(
|
|
|
99
108
|
onBlur?.(e);
|
|
100
109
|
};
|
|
101
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
|
+
|
|
102
151
|
const renderInputView = () => {
|
|
103
152
|
const disabledColor = theme.colors.text.disable;
|
|
104
153
|
let textColor = theme.colors.text.default;
|
|
105
154
|
let placeholderColor = theme.colors.text.hint;
|
|
106
|
-
let iconTintColor = iconColor;
|
|
155
|
+
let iconTintColor = trailingColor ?? iconColor;
|
|
107
156
|
|
|
108
157
|
if (disabled) {
|
|
109
158
|
textColor = disabledColor;
|
|
@@ -125,6 +174,7 @@ const InputMoney = forwardRef(
|
|
|
125
174
|
disabled={disabled}
|
|
126
175
|
required={required}
|
|
127
176
|
floatingIcon={floatingIcon}
|
|
177
|
+
onPress={onPressFloatingIcon}
|
|
128
178
|
/>
|
|
129
179
|
<View style={styles.inputView}>
|
|
130
180
|
<TextInput
|
|
@@ -160,7 +210,7 @@ const InputMoney = forwardRef(
|
|
|
160
210
|
/>
|
|
161
211
|
</TouchableOpacity>
|
|
162
212
|
)}
|
|
163
|
-
{
|
|
213
|
+
{renderTrailing(iconTintColor)}
|
|
164
214
|
</View>
|
|
165
215
|
</View>
|
|
166
216
|
);
|
|
@@ -198,7 +248,7 @@ const InputMoney = forwardRef(
|
|
|
198
248
|
</View>
|
|
199
249
|
</ComponentContext.Provider>
|
|
200
250
|
);
|
|
201
|
-
}
|
|
251
|
+
}
|
|
202
252
|
);
|
|
203
253
|
|
|
204
254
|
export default InputMoney;
|
package/Input/InputOTP.tsx
CHANGED
|
@@ -94,7 +94,10 @@ const InputOTP = forwardRef(
|
|
|
94
94
|
onChangeText: (text: string) => {
|
|
95
95
|
_onChangeText(text);
|
|
96
96
|
},
|
|
97
|
-
focus: () =>
|
|
97
|
+
focus: () => {
|
|
98
|
+
setFocused(true);
|
|
99
|
+
inputRef.current?.focus()
|
|
100
|
+
},
|
|
98
101
|
blur: () => inputRef.current?.blur(),
|
|
99
102
|
setText: (text: string) => _onChangeText(text),
|
|
100
103
|
}));
|