@momo-kits/foundation 0.89.6 → 0.92.1-tracking.12
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/BottomTab.tsx +6 -1
- package/Application/Components.tsx +17 -6
- package/Application/ModalScreen.tsx +131 -107
- package/Application/NavigationContainer.tsx +51 -47
- package/Application/StackScreen.tsx +65 -7
- package/Application/types.ts +5 -3
- package/Application/utils.tsx +59 -2
- package/Button/index.tsx +49 -16
- package/CheckBox/index.tsx +44 -21
- package/CheckBox/types.ts +4 -0
- package/IconButton/index.tsx +30 -7
- package/Image/index.tsx +3 -0
- package/Input/Input.tsx +40 -5
- package/Input/InputDropDown.tsx +30 -5
- package/Input/InputMoney.tsx +41 -5
- package/Input/InputOTP.tsx +31 -8
- package/Input/InputSearch.tsx +60 -26
- package/Input/InputTextArea.tsx +12 -2
- package/Input/index.tsx +27 -2
- package/Popup/PopupNotify.tsx +12 -0
- package/Popup/PopupPromotion.tsx +8 -2
- package/Radio/index.tsx +43 -20
- package/Radio/types.ts +5 -0
- package/Switch/index.tsx +36 -14
- package/Switch/types.ts +4 -0
- package/Text/index.tsx +1 -0
- package/Text/styles.ts +2 -2
- package/index.ts +2 -1
- package/package.json +2 -2
package/Application/utils.tsx
CHANGED
|
@@ -12,7 +12,8 @@ import {
|
|
|
12
12
|
} from './Components';
|
|
13
13
|
import {NavigationOptions, Theme} from './types';
|
|
14
14
|
import {Colors} from '../Consts';
|
|
15
|
-
|
|
15
|
+
import {Platform} from 'react-native';
|
|
16
|
+
const isIOS = Platform.OS === 'ios';
|
|
16
17
|
/**
|
|
17
18
|
* default options for stack screen
|
|
18
19
|
*/
|
|
@@ -141,4 +142,60 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
|
|
|
141
142
|
};
|
|
142
143
|
};
|
|
143
144
|
|
|
144
|
-
|
|
145
|
+
const getAccessibilityID = (key = '') => {
|
|
146
|
+
if (isIOS) {
|
|
147
|
+
return {
|
|
148
|
+
accessible: true,
|
|
149
|
+
testID: key,
|
|
150
|
+
};
|
|
151
|
+
} else {
|
|
152
|
+
return {
|
|
153
|
+
accessibilityLabel: key,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const formatComponentName = (word = '') => {
|
|
159
|
+
const accentsMap = {
|
|
160
|
+
a: 'á|à|ả|ã|ạ|â|ấ|ầ|ẩ|ẫ|ậ|ă|ắ|ằ|ẳ|ẵ|ặ',
|
|
161
|
+
A: 'Á|À|Ả|Ã|Ạ|Â|Ấ|Ầ|Ẩ|Ẫ|Ậ|Ă|Ắ|Ằ|Ẳ|Ẵ|Ặ',
|
|
162
|
+
e: 'é|è|ẻ|ẽ|ẹ|ê|ế|ề|ể|ễ|ệ',
|
|
163
|
+
E: 'É|È|Ẻ|Ẽ|Ẹ|Ê|Ế|Ề|Ể|Ễ|Ệ',
|
|
164
|
+
i: 'í|ì|ỉ|ĩ|ị',
|
|
165
|
+
I: 'Í|Ì|Ỉ|Ĩ|Ị',
|
|
166
|
+
o: 'ó|ò|ỏ|õ|ọ|ô|ố|ồ|ổ|ỗ|ộ|ơ|ớ|ờ|ở|ỡ|ợ',
|
|
167
|
+
O: 'Ó|Ò|Ỏ|Õ|Ọ|Ô|Ố|Ồ|Ổ|Ỗ|Ộ|Ơ|Ớ|Ờ|Ở|Ỡ|Ợ',
|
|
168
|
+
u: 'ú|ù|ủ|ũ|ụ|ư|ứ|ừ|ử|ữ|ự',
|
|
169
|
+
U: 'Ú|Ù|Ủ|Ũ|Ụ|Ư|Ứ|Ừ|Ử|Ữ|Ự',
|
|
170
|
+
y: 'ý|ỳ|ỷ|ỹ|ỵ',
|
|
171
|
+
Y: 'Ý|Ỳ|Ỷ|Ỹ|Ỵ',
|
|
172
|
+
d: 'đ',
|
|
173
|
+
D: 'Đ',
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
for (const [nonAccent, accentGroup] of Object.entries(accentsMap)) {
|
|
177
|
+
const accents = new RegExp(accentGroup, 'g');
|
|
178
|
+
word = word.replace(accents, nonAccent);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
word = word.replace(/\s+/g, '_').toLowerCase();
|
|
182
|
+
|
|
183
|
+
return word;
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const formatNameLength = (name = '') => {
|
|
187
|
+
let formattedName = name;
|
|
188
|
+
if (formattedName.length > 100) {
|
|
189
|
+
formattedName = formattedName.substring(0, 100);
|
|
190
|
+
}
|
|
191
|
+
return formattedName;
|
|
192
|
+
};
|
|
193
|
+
export {
|
|
194
|
+
getStackOptions,
|
|
195
|
+
getDialogOptions,
|
|
196
|
+
getModalOptions,
|
|
197
|
+
getOptions,
|
|
198
|
+
formatComponentName,
|
|
199
|
+
formatNameLength,
|
|
200
|
+
getAccessibilityID,
|
|
201
|
+
};
|
package/Button/index.tsx
CHANGED
|
@@ -6,15 +6,19 @@ import {
|
|
|
6
6
|
TouchableOpacityProps,
|
|
7
7
|
View,
|
|
8
8
|
} from 'react-native';
|
|
9
|
-
|
|
10
9
|
import LinearGradient from 'react-native-linear-gradient';
|
|
11
|
-
import {ApplicationContext} from '../Application';
|
|
10
|
+
import {ApplicationContext, MiniAppContext} from '../Application';
|
|
12
11
|
import {Text} from '../Text';
|
|
13
12
|
import {Typography} from '../Text/types';
|
|
14
13
|
import {Colors, Spacing} from '../Consts';
|
|
15
14
|
import styles from './styles';
|
|
16
15
|
import {Icon} from '../Icon';
|
|
17
16
|
import {Loader} from '../Loader';
|
|
17
|
+
import {formatComponentName, getAccessibilityID} from '../Application/utils';
|
|
18
|
+
|
|
19
|
+
const {
|
|
20
|
+
ScreenContext,
|
|
21
|
+
} = require('react-native/Libraries/Components/ScreenContext');
|
|
18
22
|
|
|
19
23
|
const AnimationLinear = Animated.createAnimatedComponent(LinearGradient);
|
|
20
24
|
|
|
@@ -70,6 +74,12 @@ export interface ButtonProps extends TouchableOpacityProps {
|
|
|
70
74
|
* A callback function that is called when the button is pressed.
|
|
71
75
|
*/
|
|
72
76
|
onPress: () => void;
|
|
77
|
+
|
|
78
|
+
params?: any;
|
|
79
|
+
|
|
80
|
+
componentId?: string;
|
|
81
|
+
|
|
82
|
+
accessibilityID?: object
|
|
73
83
|
}
|
|
74
84
|
|
|
75
85
|
const Button: FC<ButtonProps> = ({
|
|
@@ -82,9 +92,14 @@ const Button: FC<ButtonProps> = ({
|
|
|
82
92
|
loading = false,
|
|
83
93
|
title = 'Button',
|
|
84
94
|
onPress,
|
|
95
|
+
params,
|
|
96
|
+
componentId,
|
|
97
|
+
accessibilityLabel,
|
|
98
|
+
accessibilityID,
|
|
85
99
|
...rest
|
|
86
100
|
}) => {
|
|
87
101
|
const {theme, config} = useContext(ApplicationContext);
|
|
102
|
+
const {appId, code} = useContext(MiniAppContext)
|
|
88
103
|
const {gradient, color} = config?.navigationBar?.buttonColors ?? {};
|
|
89
104
|
let gradientPros;
|
|
90
105
|
if (gradient?.length > 0 && type == 'primary') {
|
|
@@ -94,6 +109,8 @@ const Button: FC<ButtonProps> = ({
|
|
|
94
109
|
end: {x: 0, y: 0.5},
|
|
95
110
|
};
|
|
96
111
|
}
|
|
112
|
+
|
|
113
|
+
const screenInfo = useContext<any>(ScreenContext);
|
|
97
114
|
const getSizeStyle = () => {
|
|
98
115
|
const styleSheet: {[key: string]: any} = styles;
|
|
99
116
|
return styleSheet[size ?? 'small'];
|
|
@@ -289,21 +306,37 @@ const Button: FC<ButtonProps> = ({
|
|
|
289
306
|
};
|
|
290
307
|
|
|
291
308
|
const activeOpacity = type === 'disabled' ? 0.75 : 0.5;
|
|
292
|
-
|
|
309
|
+
const selfAccessibilityID = accessibilityID ? accessibilityID : getAccessibilityID?.(`${appId}/${code}/${screenInfo.screenName}/btn_${title}`)
|
|
293
310
|
return (
|
|
294
|
-
<
|
|
295
|
-
{
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
311
|
+
<ScreenContext.Provider
|
|
312
|
+
value={{
|
|
313
|
+
...screenInfo,
|
|
314
|
+
componentName: 'Button',
|
|
315
|
+
params,
|
|
316
|
+
state: loading
|
|
317
|
+
? 'loading'
|
|
318
|
+
: type === 'disabled'
|
|
319
|
+
? 'disabled'
|
|
320
|
+
: 'enabled',
|
|
321
|
+
componentId,
|
|
322
|
+
componentValue: formatComponentName(title),
|
|
323
|
+
action: 'click',
|
|
324
|
+
}}>
|
|
325
|
+
<TouchableOpacity
|
|
326
|
+
{...rest}
|
|
327
|
+
{...selfAccessibilityID}
|
|
328
|
+
activeOpacity={activeOpacity}
|
|
329
|
+
onPress={onPressButton}
|
|
330
|
+
style={buttonStyle}>
|
|
331
|
+
{renderLeading()}
|
|
332
|
+
{renderTitle()}
|
|
333
|
+
{renderTrailing()}
|
|
334
|
+
{gradientPros && (
|
|
335
|
+
<AnimationLinear {...gradientPros} style={styles.gradientView} />
|
|
336
|
+
)}
|
|
337
|
+
{gradientPros && <View style={styles.strokeView} />}
|
|
338
|
+
</TouchableOpacity>
|
|
339
|
+
</ScreenContext.Provider>
|
|
307
340
|
);
|
|
308
341
|
};
|
|
309
342
|
|
package/CheckBox/index.tsx
CHANGED
|
@@ -2,9 +2,14 @@ import React, {FC, useContext} from 'react';
|
|
|
2
2
|
import {TouchableOpacity, View} from 'react-native';
|
|
3
3
|
import {CheckBoxProps} from './types';
|
|
4
4
|
import styles from './styles';
|
|
5
|
-
import {ApplicationContext} from '../Application';
|
|
5
|
+
import {ApplicationContext, MiniAppContext} from '../Application';
|
|
6
6
|
import {Text} from '../Text';
|
|
7
7
|
import {Icon} from '../Icon';
|
|
8
|
+
import {formatNameLength, getAccessibilityID} from '../Application/utils';
|
|
9
|
+
|
|
10
|
+
const {
|
|
11
|
+
ScreenContext,
|
|
12
|
+
} = require('react-native/Libraries/Components/ScreenContext');
|
|
8
13
|
|
|
9
14
|
const CheckBox: FC<CheckBoxProps> = ({
|
|
10
15
|
value,
|
|
@@ -13,8 +18,12 @@ const CheckBox: FC<CheckBoxProps> = ({
|
|
|
13
18
|
style,
|
|
14
19
|
label,
|
|
15
20
|
indeterminate,
|
|
21
|
+
params,
|
|
22
|
+
componentId,
|
|
16
23
|
}) => {
|
|
24
|
+
const {appId} = useContext(MiniAppContext)
|
|
17
25
|
const {theme} = useContext(ApplicationContext);
|
|
26
|
+
const screenInfo = useContext<any>(ScreenContext);
|
|
18
27
|
const haveValue = value || indeterminate;
|
|
19
28
|
const iconSource = indeterminate ? 'ic_minus' : 'ic_checked';
|
|
20
29
|
let borderColor = theme.colors.text.default;
|
|
@@ -33,28 +42,42 @@ const CheckBox: FC<CheckBoxProps> = ({
|
|
|
33
42
|
backgroundColor = theme.colors.background.tonal;
|
|
34
43
|
}
|
|
35
44
|
}
|
|
45
|
+
const accessibilityID = getAccessibilityID?.(`${appId}/${screenInfo.screenName}/cbx_${label}_${value}`)
|
|
36
46
|
|
|
37
47
|
return (
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
48
|
+
<ScreenContext.Provider
|
|
49
|
+
value={{
|
|
50
|
+
...screenInfo,
|
|
51
|
+
componentName: 'Button',
|
|
52
|
+
params,
|
|
53
|
+
state: disabled ? 'disabled' : 'filled',
|
|
54
|
+
componentId,
|
|
55
|
+
action: 'click',
|
|
56
|
+
componentLabel: formatNameLength(label || ''),
|
|
57
|
+
componentValue: indeterminate ? 'indetermine' : value,
|
|
58
|
+
}}>
|
|
59
|
+
<TouchableOpacity
|
|
60
|
+
{...accessibilityID}
|
|
61
|
+
activeOpacity={0.8}
|
|
62
|
+
onPress={() => onChange?.(!value)}
|
|
63
|
+
disabled={disabled}
|
|
64
|
+
style={[style, styles.container]}>
|
|
65
|
+
<View
|
|
66
|
+
style={[
|
|
67
|
+
{borderColor, backgroundColor, borderWidth: 1},
|
|
68
|
+
styles.checkbox,
|
|
69
|
+
]}>
|
|
70
|
+
{haveValue && (
|
|
71
|
+
<Icon
|
|
72
|
+
color={theme.colors.background.surface}
|
|
73
|
+
size={20}
|
|
74
|
+
source={iconSource}
|
|
75
|
+
/>
|
|
76
|
+
)}
|
|
77
|
+
</View>
|
|
78
|
+
{!!label && <Text typography={'body_default_regular'}>{label}</Text>}
|
|
79
|
+
</TouchableOpacity>
|
|
80
|
+
</ScreenContext.Provider>
|
|
58
81
|
);
|
|
59
82
|
};
|
|
60
83
|
|
package/CheckBox/types.ts
CHANGED
package/IconButton/index.tsx
CHANGED
|
@@ -9,6 +9,11 @@ import {ApplicationContext} from '../Application';
|
|
|
9
9
|
import {Colors} from '../Consts';
|
|
10
10
|
import {Icon} from '../Icon';
|
|
11
11
|
import styles from './styles';
|
|
12
|
+
import {formatComponentName} from '../Application/utils';
|
|
13
|
+
|
|
14
|
+
const {
|
|
15
|
+
ScreenContext,
|
|
16
|
+
} = require('react-native/Libraries/Components/ScreenContext');
|
|
12
17
|
|
|
13
18
|
export interface IconButtonProps extends TouchableOpacityProps {
|
|
14
19
|
/**
|
|
@@ -26,6 +31,10 @@ export interface IconButtonProps extends TouchableOpacityProps {
|
|
|
26
31
|
* Optional. Defines the size of the IconButton.
|
|
27
32
|
*/
|
|
28
33
|
size?: 'large' | 'small';
|
|
34
|
+
|
|
35
|
+
params?: any;
|
|
36
|
+
|
|
37
|
+
componentId?: string;
|
|
29
38
|
}
|
|
30
39
|
|
|
31
40
|
const IconButton: React.FC<IconButtonProps> = ({
|
|
@@ -33,9 +42,12 @@ const IconButton: React.FC<IconButtonProps> = ({
|
|
|
33
42
|
icon,
|
|
34
43
|
size,
|
|
35
44
|
onPress,
|
|
45
|
+
params,
|
|
46
|
+
componentId,
|
|
36
47
|
...rest
|
|
37
48
|
}) => {
|
|
38
49
|
const {theme} = useContext(ApplicationContext);
|
|
50
|
+
const screenInfo = useContext<any>(ScreenContext);
|
|
39
51
|
|
|
40
52
|
/**
|
|
41
53
|
* get size icon button
|
|
@@ -121,13 +133,24 @@ const IconButton: React.FC<IconButtonProps> = ({
|
|
|
121
133
|
const iconSize = size === 'small' ? 16 : 24;
|
|
122
134
|
|
|
123
135
|
return (
|
|
124
|
-
<
|
|
125
|
-
{
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
136
|
+
<ScreenContext.Provider
|
|
137
|
+
value={{
|
|
138
|
+
...screenInfo,
|
|
139
|
+
componentName: 'IconButton',
|
|
140
|
+
params,
|
|
141
|
+
state: type === 'disabled' ? 'disabled' : 'enabled',
|
|
142
|
+
componentId,
|
|
143
|
+
componentValue: formatComponentName(icon),
|
|
144
|
+
action: 'click',
|
|
145
|
+
}}>
|
|
146
|
+
<TouchableOpacity
|
|
147
|
+
{...rest}
|
|
148
|
+
activeOpacity={activeOpacity}
|
|
149
|
+
onPress={onPressButton}
|
|
150
|
+
style={buttonStyle}>
|
|
151
|
+
<Icon size={iconSize} source={icon} color={getIconColor()} />
|
|
152
|
+
</TouchableOpacity>
|
|
153
|
+
</ScreenContext.Provider>
|
|
131
154
|
);
|
|
132
155
|
};
|
|
133
156
|
|
package/Image/index.tsx
CHANGED
|
@@ -7,6 +7,7 @@ import {Skeleton} from '../Skeleton';
|
|
|
7
7
|
import {Icon} from '../Icon';
|
|
8
8
|
import {Styles} from '../Consts';
|
|
9
9
|
import {ImageProps} from './types';
|
|
10
|
+
import {getAccessibilityID} from "../Application/utils";
|
|
10
11
|
|
|
11
12
|
type Status = 'success' | 'loading' | 'error';
|
|
12
13
|
|
|
@@ -41,9 +42,11 @@ const Image: React.FC<ImageProps> = ({
|
|
|
41
42
|
return children;
|
|
42
43
|
};
|
|
43
44
|
|
|
45
|
+
const accessibilityID = getAccessibilityID?.(`img|${source}`)
|
|
44
46
|
return (
|
|
45
47
|
<FastImage
|
|
46
48
|
{...rest}
|
|
49
|
+
{...accessibilityID}
|
|
47
50
|
source={source}
|
|
48
51
|
style={[styles.container, style]}
|
|
49
52
|
onProgress={() => {
|
package/Input/Input.tsx
CHANGED
|
@@ -6,13 +6,18 @@ import {
|
|
|
6
6
|
TouchableOpacity,
|
|
7
7
|
View,
|
|
8
8
|
} from 'react-native';
|
|
9
|
-
import {ApplicationContext} from '../Application';
|
|
9
|
+
import {ApplicationContext, MiniAppContext} from '../Application';
|
|
10
10
|
import styles from './styles';
|
|
11
11
|
import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
|
|
12
12
|
import {InputProps} from './index';
|
|
13
13
|
import {Icon} from '../Icon';
|
|
14
14
|
import {checkTyping} from './utils';
|
|
15
15
|
import {Loader} from '../Loader';
|
|
16
|
+
import {formatComponentName, getAccessibilityID} from '../Application/utils';
|
|
17
|
+
|
|
18
|
+
const {
|
|
19
|
+
ScreenContext,
|
|
20
|
+
} = require('react-native/Libraries/Components/ScreenContext');
|
|
16
21
|
|
|
17
22
|
const Input = forwardRef(
|
|
18
23
|
(
|
|
@@ -39,15 +44,19 @@ const Input = forwardRef(
|
|
|
39
44
|
onPressIcon,
|
|
40
45
|
secureTextEntry,
|
|
41
46
|
style,
|
|
47
|
+
params,
|
|
48
|
+
componentId,
|
|
42
49
|
...props
|
|
43
50
|
}: InputProps,
|
|
44
51
|
ref,
|
|
45
52
|
) => {
|
|
46
53
|
const {theme} = useContext(ApplicationContext);
|
|
54
|
+
const {appId} = useContext(MiniAppContext)
|
|
47
55
|
const [focused, setFocused] = useState(false);
|
|
48
56
|
const [haveValue, setHaveValue] = useState(!!value || !!props.defaultValue);
|
|
49
57
|
const [secureTextInput, setSecureTextInput] = useState(secureTextEntry);
|
|
50
58
|
const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
|
|
59
|
+
const screenInfo = useContext<any>(ScreenContext);
|
|
51
60
|
|
|
52
61
|
const onClearText = () => {
|
|
53
62
|
inputRef?.current?.clear();
|
|
@@ -112,6 +121,7 @@ const Input = forwardRef(
|
|
|
112
121
|
placeholderColor = disabledColor;
|
|
113
122
|
iconTintColor = disabledColor;
|
|
114
123
|
}
|
|
124
|
+
const accessibilityID = getAccessibilityID?.(`${appId}/${screenInfo.screenName}/input_${floatingValue}${disabled && "_disabled" }`)
|
|
115
125
|
|
|
116
126
|
return (
|
|
117
127
|
<View
|
|
@@ -140,6 +150,7 @@ const Input = forwardRef(
|
|
|
140
150
|
)}
|
|
141
151
|
<TextInput
|
|
142
152
|
{...props}
|
|
153
|
+
{...accessibilityID}
|
|
143
154
|
editable={!disabled}
|
|
144
155
|
secureTextEntry={secure}
|
|
145
156
|
textAlignVertical="center"
|
|
@@ -180,11 +191,35 @@ const Input = forwardRef(
|
|
|
180
191
|
);
|
|
181
192
|
};
|
|
182
193
|
|
|
194
|
+
let inputState = 'active';
|
|
195
|
+
|
|
196
|
+
if (value && value?.length > 0) {
|
|
197
|
+
inputState = 'filled';
|
|
198
|
+
}
|
|
199
|
+
if (errorMessage && errorMessage?.length > 0) {
|
|
200
|
+
inputState = 'error';
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (disabled) {
|
|
204
|
+
inputState = 'disabled';
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
|
|
183
208
|
return (
|
|
184
|
-
<
|
|
185
|
-
{
|
|
186
|
-
|
|
187
|
-
|
|
209
|
+
<ScreenContext.Provider
|
|
210
|
+
value={{
|
|
211
|
+
...screenInfo,
|
|
212
|
+
componentName: 'Input',
|
|
213
|
+
params,
|
|
214
|
+
componentLabel: formatComponentName(floatingValue || ''),
|
|
215
|
+
state: inputState,
|
|
216
|
+
componentId,
|
|
217
|
+
}}>
|
|
218
|
+
<View style={[style, styles.wrapper]}>
|
|
219
|
+
{renderInputView()}
|
|
220
|
+
<ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
|
|
221
|
+
</View>
|
|
222
|
+
</ScreenContext.Provider>
|
|
188
223
|
);
|
|
189
224
|
},
|
|
190
225
|
);
|
package/Input/InputDropDown.tsx
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import React, {useContext} from 'react';
|
|
2
2
|
import {TextInput, TouchableOpacity, View} from 'react-native';
|
|
3
|
-
import {ApplicationContext} from '../Application';
|
|
3
|
+
import {ApplicationContext, MiniAppContext} from '../Application';
|
|
4
4
|
import styles from './styles';
|
|
5
5
|
import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
|
|
6
6
|
import {InputDropDownProps} from './index';
|
|
7
7
|
import {Icon} from '../Icon';
|
|
8
8
|
import {Loader} from '../Loader';
|
|
9
9
|
import {Styles} from '../Consts';
|
|
10
|
+
import {formatComponentName, getAccessibilityID} from '../Application/utils';
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
ScreenContext,
|
|
14
|
+
} = require('react-native/Libraries/Components/ScreenContext');
|
|
10
15
|
|
|
11
16
|
const InputDropDown = ({
|
|
12
17
|
value,
|
|
@@ -26,10 +31,14 @@ const InputDropDown = ({
|
|
|
26
31
|
leadingIcon,
|
|
27
32
|
leadingIconColor,
|
|
28
33
|
style,
|
|
34
|
+
params,
|
|
35
|
+
componentId,
|
|
29
36
|
...props
|
|
30
37
|
}: InputDropDownProps) => {
|
|
38
|
+
const {appId} = useContext(MiniAppContext)
|
|
31
39
|
const {theme} = useContext(ApplicationContext);
|
|
32
40
|
const full = !!value || !!placeholder;
|
|
41
|
+
const screenInfo = useContext<any>(ScreenContext);
|
|
33
42
|
|
|
34
43
|
const renderIcon = (color: string | undefined) => {
|
|
35
44
|
if (loading) {
|
|
@@ -51,6 +60,7 @@ const InputDropDown = ({
|
|
|
51
60
|
placeholderColor = disabledColor;
|
|
52
61
|
iconTintColor = disabledColor;
|
|
53
62
|
}
|
|
63
|
+
const accessibilityID = getAccessibilityID?.(`${appId}/${screenInfo.screenName}/input_${floatingValue}${disabled && "_disabled" }`)
|
|
54
64
|
|
|
55
65
|
return (
|
|
56
66
|
<View
|
|
@@ -80,6 +90,7 @@ const InputDropDown = ({
|
|
|
80
90
|
{full && (
|
|
81
91
|
<TextInput
|
|
82
92
|
{...props}
|
|
93
|
+
{...accessibilityID}
|
|
83
94
|
onPressIn={onPress}
|
|
84
95
|
editable={false}
|
|
85
96
|
textAlignVertical="top"
|
|
@@ -103,11 +114,25 @@ const InputDropDown = ({
|
|
|
103
114
|
);
|
|
104
115
|
};
|
|
105
116
|
|
|
117
|
+
|
|
118
|
+
|
|
106
119
|
return (
|
|
107
|
-
<
|
|
108
|
-
{
|
|
109
|
-
|
|
110
|
-
|
|
120
|
+
<ScreenContext.Provider
|
|
121
|
+
value={{
|
|
122
|
+
...screenInfo,
|
|
123
|
+
componentName: 'InputOTP',
|
|
124
|
+
params,
|
|
125
|
+
state: 'enabled',
|
|
126
|
+
componentLabel: formatComponentName(floatingValue || ''),
|
|
127
|
+
componentId,
|
|
128
|
+
}}>
|
|
129
|
+
<TouchableOpacity
|
|
130
|
+
onPress={onPress}
|
|
131
|
+
style={[style, full && styles.wrapper]}>
|
|
132
|
+
{renderInputView()}
|
|
133
|
+
<ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
|
|
134
|
+
</TouchableOpacity>
|
|
135
|
+
</ScreenContext.Provider>
|
|
111
136
|
);
|
|
112
137
|
};
|
|
113
138
|
|
package/Input/InputMoney.tsx
CHANGED
|
@@ -12,12 +12,17 @@ import {
|
|
|
12
12
|
TouchableOpacity,
|
|
13
13
|
View,
|
|
14
14
|
} from 'react-native';
|
|
15
|
-
import {ApplicationContext} from '../Application';
|
|
15
|
+
import {ApplicationContext, MiniAppContext} from '../Application';
|
|
16
16
|
import styles from './styles';
|
|
17
17
|
import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
|
|
18
18
|
import {InputMoneyProps} from './index';
|
|
19
19
|
import {Icon} from '../Icon';
|
|
20
20
|
import {formatMoneyToNumber, formatNumberToMoney} from './utils';
|
|
21
|
+
import {formatComponentName, getAccessibilityID} from '../Application/utils';
|
|
22
|
+
|
|
23
|
+
const {
|
|
24
|
+
ScreenContext,
|
|
25
|
+
} = require('react-native/Libraries/Components/ScreenContext');
|
|
21
26
|
|
|
22
27
|
const InputMoney = forwardRef(
|
|
23
28
|
(
|
|
@@ -36,14 +41,18 @@ const InputMoney = forwardRef(
|
|
|
36
41
|
required = false,
|
|
37
42
|
errorSpacing,
|
|
38
43
|
style,
|
|
44
|
+
params,
|
|
39
45
|
defaultValue = '',
|
|
46
|
+
componentId,
|
|
40
47
|
...props
|
|
41
48
|
}: InputMoneyProps,
|
|
42
49
|
ref,
|
|
43
50
|
) => {
|
|
44
51
|
const {theme} = useContext(ApplicationContext);
|
|
52
|
+
const {appId} = useContext(MiniAppContext)
|
|
45
53
|
const [focused, setFocused] = useState(false);
|
|
46
54
|
const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
|
|
55
|
+
const screenInfo = useContext<any>(ScreenContext);
|
|
47
56
|
|
|
48
57
|
const validateText = (text: string) => {
|
|
49
58
|
const valueFormat = formatMoneyToNumber(text, 'đ');
|
|
@@ -95,6 +104,7 @@ const InputMoney = forwardRef(
|
|
|
95
104
|
placeholderColor = disabledColor;
|
|
96
105
|
iconTintColor = disabledColor;
|
|
97
106
|
}
|
|
107
|
+
const accessibilityID = getAccessibilityID?.(`${appId}/${screenInfo.screenName}/input_${floatingValue}${disabled && "_disabled" }`)
|
|
98
108
|
|
|
99
109
|
return (
|
|
100
110
|
<View
|
|
@@ -114,6 +124,7 @@ const InputMoney = forwardRef(
|
|
|
114
124
|
<View style={styles.inputView}>
|
|
115
125
|
<TextInput
|
|
116
126
|
{...props}
|
|
127
|
+
{...accessibilityID}
|
|
117
128
|
editable={!disabled}
|
|
118
129
|
textAlignVertical="top"
|
|
119
130
|
ref={inputRef}
|
|
@@ -151,11 +162,36 @@ const InputMoney = forwardRef(
|
|
|
151
162
|
);
|
|
152
163
|
};
|
|
153
164
|
|
|
165
|
+
let inputState = 'active';
|
|
166
|
+
|
|
167
|
+
if (value && value?.length > 0) {
|
|
168
|
+
inputState = 'filled';
|
|
169
|
+
}
|
|
170
|
+
if (errorMessage && errorMessage?.length > 0) {
|
|
171
|
+
inputState = 'error';
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (disabled) {
|
|
175
|
+
inputState = 'disabled';
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
|
|
154
179
|
return (
|
|
155
|
-
<
|
|
156
|
-
{
|
|
157
|
-
|
|
158
|
-
|
|
180
|
+
<ScreenContext.Provider
|
|
181
|
+
value={{
|
|
182
|
+
...screenInfo,
|
|
183
|
+
componentName: 'InputMoney',
|
|
184
|
+
params,
|
|
185
|
+
componentLabel: formatComponentName(floatingValue || ''),
|
|
186
|
+
state: inputState,
|
|
187
|
+
componentId,
|
|
188
|
+
}}>
|
|
189
|
+
<View
|
|
190
|
+
style={[style, styles.wrapper]}>
|
|
191
|
+
{renderInputView()}
|
|
192
|
+
<ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
|
|
193
|
+
</View>
|
|
194
|
+
</ScreenContext.Provider>
|
|
159
195
|
);
|
|
160
196
|
},
|
|
161
197
|
);
|