@momo-kits/foundation 0.89.5 → 0.92.1-beta.16
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/BottomTabBar.tsx +479 -0
- package/Application/{BottomTab.tsx → BottomTab/index.tsx} +19 -9
- package/Application/Components.tsx +48 -26
- package/Application/ModalScreen.tsx +107 -131
- package/Application/NavigationContainer.tsx +64 -51
- package/Application/Navigator.ts +51 -31
- package/Application/StackScreen.tsx +83 -12
- package/Application/index.ts +0 -4
- package/Application/types.ts +17 -7
- package/Application/utils.tsx +73 -10
- package/Badge/Badge.tsx +1 -1
- package/Button/index.tsx +54 -14
- package/CheckBox/index.tsx +53 -20
- package/CheckBox/types.ts +4 -0
- package/Consts/colors+spacing+radius.ts +14 -0
- package/IconButton/index.tsx +30 -7
- package/Image/index.tsx +3 -1
- package/Input/Input.tsx +68 -5
- package/Input/InputDropDown.tsx +44 -5
- package/Input/InputMoney.tsx +53 -5
- package/Input/InputOTP.tsx +39 -7
- package/Input/InputSearch.tsx +61 -25
- package/Input/InputTextArea.tsx +23 -0
- package/Input/index.tsx +29 -2
- package/Input/styles.ts +3 -3
- package/Popup/PopupNotify.tsx +13 -2
- package/Popup/PopupPromotion.tsx +11 -4
- package/Radio/index.tsx +52 -19
- package/Radio/types.ts +5 -0
- package/Switch/index.tsx +39 -14
- package/Switch/types.ts +4 -0
- package/Text/index.tsx +24 -5
- package/Text/styles.ts +8 -8
- package/Text/types.ts +19 -1
- package/Title/index.tsx +148 -102
- package/Title/styles.ts +33 -9
- package/Title/types.ts +12 -48
- package/index.ts +2 -1
- package/package.json +3 -1
- package/verify.js +9 -6
package/CheckBox/index.tsx
CHANGED
|
@@ -5,6 +5,16 @@ import styles from './styles';
|
|
|
5
5
|
import {ApplicationContext} from '../Application';
|
|
6
6
|
import {Text} from '../Text';
|
|
7
7
|
import {Icon} from '../Icon';
|
|
8
|
+
import {
|
|
9
|
+
cleanNameForTracking,
|
|
10
|
+
formatNameLength,
|
|
11
|
+
getAccessibilityID,
|
|
12
|
+
} from '../Application/utils';
|
|
13
|
+
|
|
14
|
+
const {
|
|
15
|
+
ScreenContext,
|
|
16
|
+
MiniAppContext,
|
|
17
|
+
} = require('react-native/Libraries/Components/ScreenContext');
|
|
8
18
|
|
|
9
19
|
const CheckBox: FC<CheckBoxProps> = ({
|
|
10
20
|
value,
|
|
@@ -13,8 +23,12 @@ const CheckBox: FC<CheckBoxProps> = ({
|
|
|
13
23
|
style,
|
|
14
24
|
label,
|
|
15
25
|
indeterminate,
|
|
26
|
+
params,
|
|
27
|
+
componentId,
|
|
16
28
|
}) => {
|
|
29
|
+
const {appId, code} = useContext<any>(MiniAppContext);
|
|
17
30
|
const {theme} = useContext(ApplicationContext);
|
|
31
|
+
const screenInfo = useContext<any>(ScreenContext);
|
|
18
32
|
const haveValue = value || indeterminate;
|
|
19
33
|
const iconSource = indeterminate ? 'ic_minus' : 'ic_checked';
|
|
20
34
|
let borderColor = theme.colors.text.default;
|
|
@@ -34,27 +48,46 @@ const CheckBox: FC<CheckBoxProps> = ({
|
|
|
34
48
|
}
|
|
35
49
|
}
|
|
36
50
|
|
|
51
|
+
const accessibilityID = getAccessibilityID(
|
|
52
|
+
`${appId}/${code}/${screenInfo.screenName}/cbx_${cleanNameForTracking(
|
|
53
|
+
label,
|
|
54
|
+
)}_${indeterminate ? 'na' : value}`,
|
|
55
|
+
);
|
|
56
|
+
|
|
37
57
|
return (
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
<ScreenContext.Provider
|
|
59
|
+
value={{
|
|
60
|
+
...screenInfo,
|
|
61
|
+
componentName: 'Button',
|
|
62
|
+
params,
|
|
63
|
+
state: disabled ? 'disabled' : 'filled',
|
|
64
|
+
componentId,
|
|
65
|
+
action: 'click',
|
|
66
|
+
componentLabel: formatNameLength(label || ''),
|
|
67
|
+
componentValue: indeterminate ? 'indetermine' : value,
|
|
68
|
+
}}>
|
|
69
|
+
<TouchableOpacity
|
|
70
|
+
{...accessibilityID}
|
|
71
|
+
activeOpacity={0.8}
|
|
72
|
+
onPress={() => onChange?.(!value)}
|
|
73
|
+
disabled={disabled}
|
|
74
|
+
style={[style, styles.container]}>
|
|
75
|
+
<View
|
|
76
|
+
style={[
|
|
77
|
+
{borderColor, backgroundColor, borderWidth: 1},
|
|
78
|
+
styles.checkbox,
|
|
79
|
+
]}>
|
|
80
|
+
{haveValue && (
|
|
81
|
+
<Icon
|
|
82
|
+
color={theme.colors.background.surface}
|
|
83
|
+
size={20}
|
|
84
|
+
source={iconSource}
|
|
85
|
+
/>
|
|
86
|
+
)}
|
|
87
|
+
</View>
|
|
88
|
+
{!!label && <Text typography={'body_default_regular'}>{label}</Text>}
|
|
89
|
+
</TouchableOpacity>
|
|
90
|
+
</ScreenContext.Provider>
|
|
58
91
|
);
|
|
59
92
|
};
|
|
60
93
|
|
package/CheckBox/types.ts
CHANGED
|
@@ -213,6 +213,20 @@ const Shadow = {
|
|
|
213
213
|
elevation: 6,
|
|
214
214
|
},
|
|
215
215
|
}),
|
|
216
|
+
|
|
217
|
+
Pink: Platform.select({
|
|
218
|
+
ios: {
|
|
219
|
+
shadowColor: '#e27eb5',
|
|
220
|
+
shadowOffset: {width: 0, height: 6},
|
|
221
|
+
shadowOpacity: 0.25,
|
|
222
|
+
shadowRadius: 8,
|
|
223
|
+
},
|
|
224
|
+
android: {
|
|
225
|
+
elevation: 16,
|
|
226
|
+
shadowColor: '#e27eb5',
|
|
227
|
+
shadowOpacity: 0.25,
|
|
228
|
+
},
|
|
229
|
+
}),
|
|
216
230
|
};
|
|
217
231
|
|
|
218
232
|
export {Colors, Spacing, Radius, Shadow};
|
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
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import React, {useContext, useRef, useState} from 'react';
|
|
2
2
|
import {StyleSheet, View} from 'react-native';
|
|
3
|
-
import FastImage from 'react-native-fast-image';
|
|
3
|
+
import FastImage, {Source} from 'react-native-fast-image';
|
|
4
4
|
import styles from './styles';
|
|
5
5
|
import {ApplicationContext} from '../Application';
|
|
6
6
|
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
|
|
|
@@ -44,6 +45,7 @@ const Image: React.FC<ImageProps> = ({
|
|
|
44
45
|
return (
|
|
45
46
|
<FastImage
|
|
46
47
|
{...rest}
|
|
48
|
+
{...getAccessibilityID(`img|${(source as Source).uri}`)}
|
|
47
49
|
source={source}
|
|
48
50
|
style={[styles.container, style]}
|
|
49
51
|
onProgress={() => {
|
package/Input/Input.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, {forwardRef, useContext, useRef, useState} from 'react';
|
|
2
2
|
import {
|
|
3
3
|
NativeSyntheticEvent,
|
|
4
|
+
Platform,
|
|
4
5
|
TextInput,
|
|
5
6
|
TextInputFocusEventData,
|
|
6
7
|
TouchableOpacity,
|
|
@@ -13,6 +14,16 @@ import {InputProps} from './index';
|
|
|
13
14
|
import {Icon} from '../Icon';
|
|
14
15
|
import {checkTyping} from './utils';
|
|
15
16
|
import {Loader} from '../Loader';
|
|
17
|
+
import {
|
|
18
|
+
formatComponentName,
|
|
19
|
+
getAccessibilityID,
|
|
20
|
+
cleanNameForTracking,
|
|
21
|
+
} from '../Application/utils';
|
|
22
|
+
|
|
23
|
+
const {
|
|
24
|
+
ScreenContext,
|
|
25
|
+
MiniAppContext,
|
|
26
|
+
} = require('react-native/Libraries/Components/ScreenContext');
|
|
16
27
|
|
|
17
28
|
const Input = forwardRef(
|
|
18
29
|
(
|
|
@@ -38,16 +49,21 @@ const Input = forwardRef(
|
|
|
38
49
|
fontWeight = 'Regular',
|
|
39
50
|
onPressIcon,
|
|
40
51
|
secureTextEntry,
|
|
52
|
+
keyboardType,
|
|
41
53
|
style,
|
|
54
|
+
params,
|
|
55
|
+
componentId,
|
|
42
56
|
...props
|
|
43
57
|
}: InputProps,
|
|
44
58
|
ref,
|
|
45
59
|
) => {
|
|
46
60
|
const {theme} = useContext(ApplicationContext);
|
|
61
|
+
const {appId, code} = useContext<any>(MiniAppContext);
|
|
47
62
|
const [focused, setFocused] = useState(false);
|
|
48
63
|
const [haveValue, setHaveValue] = useState(!!value || !!props.defaultValue);
|
|
49
64
|
const [secureTextInput, setSecureTextInput] = useState(secureTextEntry);
|
|
50
65
|
const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
|
|
66
|
+
const screenInfo = useContext<any>(ScreenContext);
|
|
51
67
|
|
|
52
68
|
const onClearText = () => {
|
|
53
69
|
inputRef?.current?.clear();
|
|
@@ -106,6 +122,21 @@ const Input = forwardRef(
|
|
|
106
122
|
let textColor = theme.colors.text.default;
|
|
107
123
|
let placeholderColor = theme.colors.text.hint;
|
|
108
124
|
let iconTintColor = iconColor;
|
|
125
|
+
const accessibilityID = disabled
|
|
126
|
+
? getAccessibilityID(
|
|
127
|
+
`${appId}/${code}/${
|
|
128
|
+
screenInfo.screenName
|
|
129
|
+
}/input_${cleanNameForTracking(
|
|
130
|
+
floatingValue ?? placeholder,
|
|
131
|
+
)}_disabled`,
|
|
132
|
+
)
|
|
133
|
+
: getAccessibilityID(
|
|
134
|
+
`${appId}/${code}/${
|
|
135
|
+
screenInfo.screenName
|
|
136
|
+
}/input_${cleanNameForTracking(
|
|
137
|
+
floatingValue ?? placeholder ?? value,
|
|
138
|
+
)}`,
|
|
139
|
+
);
|
|
109
140
|
|
|
110
141
|
if (disabled) {
|
|
111
142
|
textColor = disabledColor;
|
|
@@ -113,6 +144,13 @@ const Input = forwardRef(
|
|
|
113
144
|
iconTintColor = disabledColor;
|
|
114
145
|
}
|
|
115
146
|
|
|
147
|
+
if (secureTextEntry) {
|
|
148
|
+
keyboardType = Platform.select({
|
|
149
|
+
ios: 'ascii-capable',
|
|
150
|
+
android: 'visible-password',
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
116
154
|
return (
|
|
117
155
|
<View
|
|
118
156
|
style={[
|
|
@@ -140,7 +178,8 @@ const Input = forwardRef(
|
|
|
140
178
|
)}
|
|
141
179
|
<TextInput
|
|
142
180
|
{...props}
|
|
143
|
-
|
|
181
|
+
{...accessibilityID}
|
|
182
|
+
editable={props.editable && !disabled}
|
|
144
183
|
secureTextEntry={secure}
|
|
145
184
|
textAlignVertical="center"
|
|
146
185
|
ref={inputRef}
|
|
@@ -160,6 +199,7 @@ const Input = forwardRef(
|
|
|
160
199
|
placeholder={placeholder}
|
|
161
200
|
selectionColor={theme.colors.primary}
|
|
162
201
|
placeholderTextColor={placeholderColor}
|
|
202
|
+
keyboardType={keyboardType}
|
|
163
203
|
/>
|
|
164
204
|
</View>
|
|
165
205
|
<View style={styles.iconView}>
|
|
@@ -180,11 +220,34 @@ const Input = forwardRef(
|
|
|
180
220
|
);
|
|
181
221
|
};
|
|
182
222
|
|
|
223
|
+
let inputState = 'active';
|
|
224
|
+
|
|
225
|
+
if (value && value?.length > 0) {
|
|
226
|
+
inputState = 'filled';
|
|
227
|
+
}
|
|
228
|
+
if (errorMessage && errorMessage?.length > 0) {
|
|
229
|
+
inputState = 'error';
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (disabled) {
|
|
233
|
+
inputState = 'disabled';
|
|
234
|
+
}
|
|
235
|
+
|
|
183
236
|
return (
|
|
184
|
-
<
|
|
185
|
-
{
|
|
186
|
-
|
|
187
|
-
|
|
237
|
+
<ScreenContext.Provider
|
|
238
|
+
value={{
|
|
239
|
+
...screenInfo,
|
|
240
|
+
componentName: 'Input',
|
|
241
|
+
params,
|
|
242
|
+
componentLabel: formatComponentName(floatingValue || ''),
|
|
243
|
+
state: inputState,
|
|
244
|
+
componentId,
|
|
245
|
+
}}>
|
|
246
|
+
<View style={[style, styles.wrapper]}>
|
|
247
|
+
{renderInputView()}
|
|
248
|
+
<ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
|
|
249
|
+
</View>
|
|
250
|
+
</ScreenContext.Provider>
|
|
188
251
|
);
|
|
189
252
|
},
|
|
190
253
|
);
|
package/Input/InputDropDown.tsx
CHANGED
|
@@ -7,6 +7,16 @@ import {InputDropDownProps} from './index';
|
|
|
7
7
|
import {Icon} from '../Icon';
|
|
8
8
|
import {Loader} from '../Loader';
|
|
9
9
|
import {Styles} from '../Consts';
|
|
10
|
+
import {
|
|
11
|
+
cleanNameForTracking,
|
|
12
|
+
formatComponentName,
|
|
13
|
+
getAccessibilityID,
|
|
14
|
+
} from '../Application/utils';
|
|
15
|
+
|
|
16
|
+
const {
|
|
17
|
+
ScreenContext,
|
|
18
|
+
MiniAppContext,
|
|
19
|
+
} = require('react-native/Libraries/Components/ScreenContext');
|
|
10
20
|
|
|
11
21
|
const InputDropDown = ({
|
|
12
22
|
value,
|
|
@@ -26,10 +36,14 @@ const InputDropDown = ({
|
|
|
26
36
|
leadingIcon,
|
|
27
37
|
leadingIconColor,
|
|
28
38
|
style,
|
|
39
|
+
params,
|
|
40
|
+
componentId,
|
|
29
41
|
...props
|
|
30
42
|
}: InputDropDownProps) => {
|
|
43
|
+
const {appId, code} = useContext<any>(MiniAppContext);
|
|
31
44
|
const {theme} = useContext(ApplicationContext);
|
|
32
45
|
const full = !!value || !!placeholder;
|
|
46
|
+
const screenInfo = useContext<any>(ScreenContext);
|
|
33
47
|
|
|
34
48
|
const renderIcon = (color: string | undefined) => {
|
|
35
49
|
if (loading) {
|
|
@@ -45,6 +59,19 @@ const InputDropDown = ({
|
|
|
45
59
|
let textColor = theme.colors.text.default;
|
|
46
60
|
let placeholderColor = theme.colors.text.hint;
|
|
47
61
|
let iconTintColor = iconColor;
|
|
62
|
+
const accessibilityID = disabled
|
|
63
|
+
? getAccessibilityID(
|
|
64
|
+
`${appId}/${code}/${
|
|
65
|
+
screenInfo.screenName
|
|
66
|
+
}/input_${cleanNameForTracking(
|
|
67
|
+
floatingValue ?? placeholder,
|
|
68
|
+
)}_disabled`,
|
|
69
|
+
)
|
|
70
|
+
: getAccessibilityID(
|
|
71
|
+
`${appId}/${code}/${
|
|
72
|
+
screenInfo.screenName
|
|
73
|
+
}/input_${cleanNameForTracking(floatingValue ?? placeholder)}`,
|
|
74
|
+
);
|
|
48
75
|
|
|
49
76
|
if (disabled) {
|
|
50
77
|
textColor = disabledColor;
|
|
@@ -80,9 +107,9 @@ const InputDropDown = ({
|
|
|
80
107
|
{full && (
|
|
81
108
|
<TextInput
|
|
82
109
|
{...props}
|
|
110
|
+
{...accessibilityID}
|
|
83
111
|
onPressIn={onPress}
|
|
84
112
|
editable={false}
|
|
85
|
-
textAlignVertical="top"
|
|
86
113
|
style={[
|
|
87
114
|
styles.input,
|
|
88
115
|
{
|
|
@@ -104,10 +131,22 @@ const InputDropDown = ({
|
|
|
104
131
|
};
|
|
105
132
|
|
|
106
133
|
return (
|
|
107
|
-
<
|
|
108
|
-
{
|
|
109
|
-
|
|
110
|
-
|
|
134
|
+
<ScreenContext.Provider
|
|
135
|
+
value={{
|
|
136
|
+
...screenInfo,
|
|
137
|
+
componentName: 'InputOTP',
|
|
138
|
+
params,
|
|
139
|
+
state: 'enabled',
|
|
140
|
+
componentLabel: formatComponentName(floatingValue || ''),
|
|
141
|
+
componentId,
|
|
142
|
+
}}>
|
|
143
|
+
<TouchableOpacity
|
|
144
|
+
onPress={onPress}
|
|
145
|
+
style={[style, full && styles.wrapper]}>
|
|
146
|
+
{renderInputView()}
|
|
147
|
+
<ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
|
|
148
|
+
</TouchableOpacity>
|
|
149
|
+
</ScreenContext.Provider>
|
|
111
150
|
);
|
|
112
151
|
};
|
|
113
152
|
|
package/Input/InputMoney.tsx
CHANGED
|
@@ -18,6 +18,16 @@ 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 {
|
|
22
|
+
cleanNameForTracking,
|
|
23
|
+
formatComponentName,
|
|
24
|
+
getAccessibilityID,
|
|
25
|
+
} from '../Application/utils';
|
|
26
|
+
|
|
27
|
+
const {
|
|
28
|
+
ScreenContext,
|
|
29
|
+
MiniAppContext,
|
|
30
|
+
} = require('react-native/Libraries/Components/ScreenContext');
|
|
21
31
|
|
|
22
32
|
const InputMoney = forwardRef(
|
|
23
33
|
(
|
|
@@ -36,14 +46,18 @@ const InputMoney = forwardRef(
|
|
|
36
46
|
required = false,
|
|
37
47
|
errorSpacing,
|
|
38
48
|
style,
|
|
49
|
+
params,
|
|
39
50
|
defaultValue = '',
|
|
51
|
+
componentId,
|
|
40
52
|
...props
|
|
41
53
|
}: InputMoneyProps,
|
|
42
54
|
ref,
|
|
43
55
|
) => {
|
|
44
56
|
const {theme} = useContext(ApplicationContext);
|
|
57
|
+
const {appId, code} = useContext<any>(MiniAppContext);
|
|
45
58
|
const [focused, setFocused] = useState(false);
|
|
46
59
|
const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
|
|
60
|
+
const screenInfo = useContext<any>(ScreenContext);
|
|
47
61
|
|
|
48
62
|
const validateText = (text: string) => {
|
|
49
63
|
const valueFormat = formatMoneyToNumber(text, 'đ');
|
|
@@ -89,6 +103,17 @@ const InputMoney = forwardRef(
|
|
|
89
103
|
let textColor = theme.colors.text.default;
|
|
90
104
|
let placeholderColor = theme.colors.text.hint;
|
|
91
105
|
let iconTintColor = iconColor;
|
|
106
|
+
const accessibilityID = disabled
|
|
107
|
+
? getAccessibilityID(
|
|
108
|
+
`${appId}/${code}/${
|
|
109
|
+
screenInfo.screenName
|
|
110
|
+
}/input_${cleanNameForTracking(floatingValue)}_disabled`,
|
|
111
|
+
)
|
|
112
|
+
: getAccessibilityID(
|
|
113
|
+
`${appId}/${code}/${
|
|
114
|
+
screenInfo.screenName
|
|
115
|
+
}/input_${cleanNameForTracking(floatingValue)}`,
|
|
116
|
+
);
|
|
92
117
|
|
|
93
118
|
if (disabled) {
|
|
94
119
|
textColor = disabledColor;
|
|
@@ -114,8 +139,8 @@ const InputMoney = forwardRef(
|
|
|
114
139
|
<View style={styles.inputView}>
|
|
115
140
|
<TextInput
|
|
116
141
|
{...props}
|
|
142
|
+
{...accessibilityID}
|
|
117
143
|
editable={!disabled}
|
|
118
|
-
textAlignVertical="top"
|
|
119
144
|
ref={inputRef}
|
|
120
145
|
keyboardType={'number-pad'}
|
|
121
146
|
style={[
|
|
@@ -151,11 +176,34 @@ const InputMoney = forwardRef(
|
|
|
151
176
|
);
|
|
152
177
|
};
|
|
153
178
|
|
|
179
|
+
let inputState = 'active';
|
|
180
|
+
|
|
181
|
+
if (value && value?.length > 0) {
|
|
182
|
+
inputState = 'filled';
|
|
183
|
+
}
|
|
184
|
+
if (errorMessage && errorMessage?.length > 0) {
|
|
185
|
+
inputState = 'error';
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (disabled) {
|
|
189
|
+
inputState = 'disabled';
|
|
190
|
+
}
|
|
191
|
+
|
|
154
192
|
return (
|
|
155
|
-
<
|
|
156
|
-
{
|
|
157
|
-
|
|
158
|
-
|
|
193
|
+
<ScreenContext.Provider
|
|
194
|
+
value={{
|
|
195
|
+
...screenInfo,
|
|
196
|
+
componentName: 'InputMoney',
|
|
197
|
+
params,
|
|
198
|
+
componentLabel: formatComponentName(floatingValue || ''),
|
|
199
|
+
state: inputState,
|
|
200
|
+
componentId,
|
|
201
|
+
}}>
|
|
202
|
+
<View style={[style, styles.wrapper]}>
|
|
203
|
+
{renderInputView()}
|
|
204
|
+
<ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
|
|
205
|
+
</View>
|
|
206
|
+
</ScreenContext.Provider>
|
|
159
207
|
);
|
|
160
208
|
},
|
|
161
209
|
);
|
package/Input/InputOTP.tsx
CHANGED
|
@@ -21,6 +21,16 @@ import styles from './styles';
|
|
|
21
21
|
import {ErrorView, getBorderColor} from './common';
|
|
22
22
|
import {ApplicationContext} from '../Application';
|
|
23
23
|
import {Spacing} from '../Consts';
|
|
24
|
+
import {
|
|
25
|
+
cleanNameForTracking,
|
|
26
|
+
formatComponentName,
|
|
27
|
+
getAccessibilityID,
|
|
28
|
+
} from '../Application/utils';
|
|
29
|
+
|
|
30
|
+
const {
|
|
31
|
+
ScreenContext,
|
|
32
|
+
MiniAppContext,
|
|
33
|
+
} = require('react-native/Libraries/Components/ScreenContext');
|
|
24
34
|
|
|
25
35
|
const OTPCaret: FC<CaretProps> = ({index, length}) => {
|
|
26
36
|
const DURATION = 300;
|
|
@@ -78,16 +88,21 @@ const InputOTP = forwardRef(
|
|
|
78
88
|
onFocus,
|
|
79
89
|
onBlur,
|
|
80
90
|
dataType = 'number',
|
|
91
|
+
params,
|
|
81
92
|
style,
|
|
93
|
+
componentId,
|
|
82
94
|
...props
|
|
83
95
|
}: InputOTPProps,
|
|
84
96
|
ref,
|
|
85
97
|
) => {
|
|
86
98
|
const MAX_LENGTH = 10;
|
|
99
|
+
const {appId, code} = useContext<any>(MiniAppContext);
|
|
100
|
+
|
|
87
101
|
const [value, setValue] = useState('');
|
|
88
102
|
const [focused, setFocused] = useState(false);
|
|
89
103
|
const inputRef = useRef<TextInput>(null);
|
|
90
104
|
const {theme} = useContext(ApplicationContext);
|
|
105
|
+
const screenInfo = useContext<any>(ScreenContext);
|
|
91
106
|
|
|
92
107
|
useImperativeHandle(ref, () => ({
|
|
93
108
|
onChangeText: (text: string) => {
|
|
@@ -180,6 +195,12 @@ const InputOTP = forwardRef(
|
|
|
180
195
|
);
|
|
181
196
|
};
|
|
182
197
|
|
|
198
|
+
const accessibilityID = getAccessibilityID(
|
|
199
|
+
`${appId}/${code}/${screenInfo.screenName}/input_${cleanNameForTracking(
|
|
200
|
+
floatingValue,
|
|
201
|
+
)}`,
|
|
202
|
+
);
|
|
203
|
+
|
|
183
204
|
const renderInputView = () => {
|
|
184
205
|
return (
|
|
185
206
|
<View
|
|
@@ -205,6 +226,7 @@ const InputOTP = forwardRef(
|
|
|
205
226
|
<View style={styles.inputView}>
|
|
206
227
|
<TextInput
|
|
207
228
|
{...props}
|
|
229
|
+
{...accessibilityID}
|
|
208
230
|
ref={inputRef}
|
|
209
231
|
value={value}
|
|
210
232
|
onChangeText={_onChangeText}
|
|
@@ -221,13 +243,23 @@ const InputOTP = forwardRef(
|
|
|
221
243
|
};
|
|
222
244
|
|
|
223
245
|
return (
|
|
224
|
-
<
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
246
|
+
<ScreenContext.Provider
|
|
247
|
+
value={{
|
|
248
|
+
...screenInfo,
|
|
249
|
+
componentName: 'InputOTP',
|
|
250
|
+
params,
|
|
251
|
+
componentLabel: formatComponentName(floatingValue || ''),
|
|
252
|
+
state: 'enabled',
|
|
253
|
+
componentId,
|
|
254
|
+
}}>
|
|
255
|
+
<TouchableOpacity
|
|
256
|
+
activeOpacity={1}
|
|
257
|
+
onPress={onFocusInput}
|
|
258
|
+
style={[style, styles.otpWrapper]}>
|
|
259
|
+
{renderInputView()}
|
|
260
|
+
<ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
|
|
261
|
+
</TouchableOpacity>
|
|
262
|
+
</ScreenContext.Provider>
|
|
231
263
|
);
|
|
232
264
|
},
|
|
233
265
|
);
|