@momo-kits/foundation 0.89.5 → 0.89.6-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Application/BottomSheet.tsx +216 -0
- package/Application/BottomTab/BottomTabBar.tsx +278 -0
- package/Application/{BottomTab.tsx → BottomTab/index.tsx} +42 -18
- package/Application/Components.tsx +350 -86
- package/Application/Localize.ts +44 -0
- package/Application/ModalScreen.tsx +14 -185
- package/Application/Navigation.ts +5 -19
- package/Application/NavigationContainer.tsx +62 -72
- package/Application/Navigator.ts +53 -35
- package/Application/StackScreen.tsx +289 -32
- package/Application/index.ts +13 -15
- package/Application/types.ts +64 -35
- package/Application/utils.tsx +76 -30
- package/Assets/icon_bank.json +1 -1
- package/Badge/Badge.tsx +1 -1
- package/Badge/BadgeDotAnimation.tsx +95 -0
- package/Badge/index.tsx +2 -1
- package/Badge/styles.ts +50 -6
- package/Button/index.tsx +44 -26
- package/CheckBox/index.tsx +37 -26
- package/CheckBox/types.ts +5 -3
- package/Consts/colors+spacing+radius.ts +14 -0
- package/Icon/index.tsx +9 -8
- package/Icon/types.ts +2 -2
- package/IconButton/index.tsx +24 -14
- package/Image/index.tsx +23 -8
- package/Image/types.ts +2 -0
- package/Input/Input.tsx +116 -26
- package/Input/InputDropDown.tsx +66 -51
- package/Input/InputMoney.tsx +106 -15
- package/Input/InputOTP.tsx +49 -26
- package/Input/InputSearch.tsx +252 -99
- package/Input/InputTextArea.tsx +26 -6
- package/Input/TextTyping.tsx +113 -0
- package/Input/common.tsx +48 -22
- package/Input/index.tsx +112 -77
- package/Input/styles.ts +48 -11
- package/Input/utils.ts +1 -1
- package/Layout/Card.tsx +4 -3
- package/Layout/FloatingButton.tsx +168 -0
- package/Layout/GridSystem.tsx +1 -1
- package/Layout/ItemList.tsx +3 -2
- package/Layout/Screen.tsx +242 -121
- package/Layout/Section.tsx +4 -3
- package/Layout/styles.ts +11 -13
- package/Layout/types.ts +1 -1
- package/Layout/utils.ts +4 -4
- package/Loader/index.tsx +2 -0
- package/Pagination/PaginationScroll.tsx +2 -2
- package/Pagination/styles.ts +1 -1
- package/Popup/PopupNotify.tsx +56 -45
- package/Popup/PopupPromotion.tsx +5 -7
- package/Popup/types.ts +1 -7
- package/Radio/index.tsx +35 -20
- package/Radio/types.ts +5 -3
- package/Switch/index.tsx +32 -18
- package/Switch/types.ts +5 -3
- package/Tag/index.tsx +9 -2
- package/Tag/styles.ts +3 -2
- package/Tag/types.ts +12 -0
- package/Text/index.tsx +24 -5
- package/Text/styles.ts +8 -8
- package/Text/types.ts +19 -1
- package/Title/index.tsx +170 -103
- package/Title/styles.ts +36 -9
- package/Title/types.ts +16 -48
- package/code-scanner.js +125 -16
- package/index.ts +7 -0
- package/migrate_typo.js +56 -0
- package/package.json +11 -10
- package/publish.sh +16 -21
- package/tsconfig.json +1 -1
- package/verify.js +37 -40
package/Icon/index.tsx
CHANGED
|
@@ -5,7 +5,12 @@ import {IconProps} from './types';
|
|
|
5
5
|
import {ApplicationContext} from '../Application';
|
|
6
6
|
import {Image} from '../Image';
|
|
7
7
|
|
|
8
|
-
const Icon: React.FC<IconProps> = ({
|
|
8
|
+
const Icon: React.FC<IconProps> = ({
|
|
9
|
+
source = 'ic_back',
|
|
10
|
+
size = 24,
|
|
11
|
+
color,
|
|
12
|
+
style = {},
|
|
13
|
+
}) => {
|
|
9
14
|
const {theme} = useContext(ApplicationContext);
|
|
10
15
|
|
|
11
16
|
/**
|
|
@@ -20,22 +25,18 @@ const Icon: React.FC<IconProps> = ({source, size, color, style = {}}) => {
|
|
|
20
25
|
};
|
|
21
26
|
|
|
22
27
|
const tintColorProps = color !== null && {
|
|
23
|
-
tintColor: color ?? theme.colors.text.default
|
|
24
|
-
}
|
|
28
|
+
tintColor: color ?? theme.colors.text.default,
|
|
29
|
+
};
|
|
25
30
|
|
|
26
31
|
return (
|
|
27
32
|
<Image
|
|
28
33
|
loading={false}
|
|
29
34
|
source={getIconSource()}
|
|
30
35
|
style={[style, {width: size, height: size}]}
|
|
36
|
+
resizeMode="contain"
|
|
31
37
|
{...tintColorProps}
|
|
32
38
|
/>
|
|
33
39
|
);
|
|
34
40
|
};
|
|
35
41
|
|
|
36
|
-
Icon.defaultProps = {
|
|
37
|
-
source: 'ic_back',
|
|
38
|
-
size: 24,
|
|
39
|
-
};
|
|
40
|
-
|
|
41
42
|
export {Icon, IconSources, IconBankSources};
|
package/Icon/types.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {ImageStyle} from 'react-native-fast-image';
|
|
2
|
+
import {StyleProp} from 'react-native';
|
|
2
3
|
|
|
3
4
|
export type IconProps = {
|
|
4
5
|
/**
|
|
@@ -15,7 +16,6 @@ export type IconProps = {
|
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Optional. Represents the color of the icon.
|
|
18
|
-
* It can be any valid color in @momo-kits/foundation.
|
|
19
19
|
*/
|
|
20
20
|
color?: string | null;
|
|
21
21
|
|
|
@@ -23,5 +23,5 @@ export type IconProps = {
|
|
|
23
23
|
* Optional. Used to apply custom styling to the Icon component.
|
|
24
24
|
* Accepts an object of style properties.
|
|
25
25
|
*/
|
|
26
|
-
style?: ImageStyle
|
|
26
|
+
style?: StyleProp<ImageStyle>;
|
|
27
27
|
};
|
package/IconButton/index.tsx
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
TouchableOpacity,
|
|
6
6
|
TouchableOpacityProps,
|
|
7
7
|
} from 'react-native';
|
|
8
|
-
import {ApplicationContext} from '../Application';
|
|
8
|
+
import {ApplicationContext, ComponentContext} from '../Application';
|
|
9
9
|
import {Colors} from '../Consts';
|
|
10
10
|
import {Icon} from '../Icon';
|
|
11
11
|
import styles from './styles';
|
|
@@ -26,13 +26,17 @@ export interface IconButtonProps extends TouchableOpacityProps {
|
|
|
26
26
|
* Optional. Defines the size of the IconButton.
|
|
27
27
|
*/
|
|
28
28
|
size?: 'large' | 'small';
|
|
29
|
+
|
|
30
|
+
params?: any;
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
const IconButton: React.FC<IconButtonProps> = ({
|
|
32
|
-
type,
|
|
34
|
+
type = 'primary',
|
|
33
35
|
icon,
|
|
34
36
|
size,
|
|
35
37
|
onPress,
|
|
38
|
+
params,
|
|
39
|
+
accessibilityLabel,
|
|
36
40
|
...rest
|
|
37
41
|
}) => {
|
|
38
42
|
const {theme} = useContext(ApplicationContext);
|
|
@@ -121,19 +125,25 @@ const IconButton: React.FC<IconButtonProps> = ({
|
|
|
121
125
|
const iconSize = size === 'small' ? 16 : 24;
|
|
122
126
|
|
|
123
127
|
return (
|
|
124
|
-
<
|
|
125
|
-
{
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
<ComponentContext.Provider
|
|
129
|
+
value={{
|
|
130
|
+
componentName: 'IconButton',
|
|
131
|
+
params,
|
|
132
|
+
state: type === 'disabled' ? 'disabled' : 'enabled',
|
|
133
|
+
componentId: accessibilityLabel,
|
|
134
|
+
componentValue: icon,
|
|
135
|
+
action: 'click',
|
|
136
|
+
}}>
|
|
137
|
+
<TouchableOpacity
|
|
138
|
+
{...rest}
|
|
139
|
+
accessibilityLabel={accessibilityLabel}
|
|
140
|
+
activeOpacity={activeOpacity}
|
|
141
|
+
onPress={onPressButton}
|
|
142
|
+
style={buttonStyle}>
|
|
143
|
+
<Icon size={iconSize} source={icon} color={getIconColor()} />
|
|
144
|
+
</TouchableOpacity>
|
|
145
|
+
</ComponentContext.Provider>
|
|
131
146
|
);
|
|
132
147
|
};
|
|
133
148
|
|
|
134
|
-
IconButton.defaultProps = {
|
|
135
|
-
type: 'primary',
|
|
136
|
-
disabled: false,
|
|
137
|
-
};
|
|
138
|
-
|
|
139
149
|
export {IconButton};
|
package/Image/index.tsx
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import React, {useContext, useRef, useState} from 'react';
|
|
1
|
+
import React, {useContext, useEffect, 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
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
ApplicationContext,
|
|
7
|
+
ComponentContext,
|
|
8
|
+
MiniAppContext,
|
|
9
|
+
} from '../Application';
|
|
6
10
|
import {Skeleton} from '../Skeleton';
|
|
7
11
|
import {Icon} from '../Icon';
|
|
8
12
|
import {Styles} from '../Consts';
|
|
@@ -13,14 +17,28 @@ type Status = 'success' | 'loading' | 'error';
|
|
|
13
17
|
const Image: React.FC<ImageProps> = ({
|
|
14
18
|
style,
|
|
15
19
|
source,
|
|
16
|
-
loading,
|
|
20
|
+
loading = true,
|
|
17
21
|
children,
|
|
22
|
+
accessibilityLabel,
|
|
18
23
|
...rest
|
|
19
24
|
}) => {
|
|
20
25
|
const {theme} = useContext(ApplicationContext);
|
|
26
|
+
const app = useContext<any>(MiniAppContext);
|
|
27
|
+
const component = useContext<any>(ComponentContext);
|
|
21
28
|
const error = useRef(false);
|
|
22
29
|
const [status, setStatus] = useState<Status>('success');
|
|
23
30
|
|
|
31
|
+
const test: any = {
|
|
32
|
+
accessibilityLabel: accessibilityLabel || `img|${(source as Source).uri}`,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
if (app.enableAutoId) {
|
|
37
|
+
component?.addChildren?.(test.accessibilityLabel, 'add');
|
|
38
|
+
return () => component?.addChildren?.(test.accessibilityLabel, 'remove');
|
|
39
|
+
}
|
|
40
|
+
}, []);
|
|
41
|
+
|
|
24
42
|
/**
|
|
25
43
|
* render content loading | fail | rendered
|
|
26
44
|
*/
|
|
@@ -44,6 +62,7 @@ const Image: React.FC<ImageProps> = ({
|
|
|
44
62
|
return (
|
|
45
63
|
<FastImage
|
|
46
64
|
{...rest}
|
|
65
|
+
{...test}
|
|
47
66
|
source={source}
|
|
48
67
|
style={[styles.container, style]}
|
|
49
68
|
onProgress={() => {
|
|
@@ -75,8 +94,4 @@ const Image: React.FC<ImageProps> = ({
|
|
|
75
94
|
);
|
|
76
95
|
};
|
|
77
96
|
|
|
78
|
-
Image.defaultProps = {
|
|
79
|
-
loading: true,
|
|
80
|
-
};
|
|
81
|
-
|
|
82
97
|
export {Image};
|
package/Image/types.ts
CHANGED
package/Input/Input.tsx
CHANGED
|
@@ -1,19 +1,31 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
forwardRef,
|
|
3
|
+
ReactNode,
|
|
4
|
+
useContext,
|
|
5
|
+
useImperativeHandle,
|
|
6
|
+
useRef,
|
|
7
|
+
useState,
|
|
8
|
+
} from 'react';
|
|
2
9
|
import {
|
|
3
10
|
NativeSyntheticEvent,
|
|
11
|
+
Platform,
|
|
4
12
|
TextInput,
|
|
5
13
|
TextInputFocusEventData,
|
|
6
14
|
TouchableOpacity,
|
|
7
15
|
View,
|
|
8
16
|
} from 'react-native';
|
|
9
|
-
import {ApplicationContext} from '../Application';
|
|
10
|
-
import
|
|
17
|
+
import {ApplicationContext, ComponentContext} from '../Application';
|
|
18
|
+
import {Icon} from '../Icon';
|
|
19
|
+
import {Loader} from '../Loader';
|
|
20
|
+
import {Text} from '../Text';
|
|
11
21
|
import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
|
|
12
22
|
import {InputProps} from './index';
|
|
13
|
-
import
|
|
23
|
+
import styles from './styles';
|
|
14
24
|
import {checkTyping} from './utils';
|
|
15
|
-
import {Loader} from '../Loader';
|
|
16
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Input default component
|
|
28
|
+
*/
|
|
17
29
|
const Input = forwardRef(
|
|
18
30
|
(
|
|
19
31
|
{
|
|
@@ -27,27 +39,36 @@ const Input = forwardRef(
|
|
|
27
39
|
onFocus,
|
|
28
40
|
errorMessage,
|
|
29
41
|
icon,
|
|
42
|
+
iconColor,
|
|
43
|
+
onPressIcon,
|
|
44
|
+
trailing,
|
|
45
|
+
trailingColor,
|
|
46
|
+
onPressTrailing,
|
|
30
47
|
disabled = false,
|
|
31
48
|
floatingIconColor,
|
|
32
|
-
iconColor,
|
|
33
49
|
required = false,
|
|
34
50
|
errorSpacing,
|
|
35
51
|
loading = false,
|
|
36
52
|
leadingIcon,
|
|
37
53
|
leadingIconColor,
|
|
38
54
|
fontWeight = 'Regular',
|
|
39
|
-
onPressIcon,
|
|
40
55
|
secureTextEntry,
|
|
56
|
+
keyboardType,
|
|
41
57
|
style,
|
|
58
|
+
params,
|
|
59
|
+
hintText,
|
|
60
|
+
accessibilityLabel,
|
|
61
|
+
editable = true,
|
|
62
|
+
onPressFloatingIcon,
|
|
42
63
|
...props
|
|
43
64
|
}: InputProps,
|
|
44
|
-
ref
|
|
65
|
+
ref
|
|
45
66
|
) => {
|
|
46
67
|
const {theme} = useContext(ApplicationContext);
|
|
47
68
|
const [focused, setFocused] = useState(false);
|
|
48
69
|
const [haveValue, setHaveValue] = useState(!!value || !!props.defaultValue);
|
|
49
70
|
const [secureTextInput, setSecureTextInput] = useState(secureTextEntry);
|
|
50
|
-
const inputRef =
|
|
71
|
+
const inputRef = useRef<TextInput | null>(null);
|
|
51
72
|
|
|
52
73
|
const onClearText = () => {
|
|
53
74
|
inputRef?.current?.clear();
|
|
@@ -69,7 +90,20 @@ const Input = forwardRef(
|
|
|
69
90
|
onBlur?.(e);
|
|
70
91
|
};
|
|
71
92
|
|
|
72
|
-
|
|
93
|
+
useImperativeHandle(ref, () => {
|
|
94
|
+
return {
|
|
95
|
+
clear: onClearText,
|
|
96
|
+
focus: () => inputRef.current?.focus(),
|
|
97
|
+
blur: () => inputRef.current?.blur(),
|
|
98
|
+
setText: (text: string) => _onChangeText(text),
|
|
99
|
+
};
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Render trailing icon or text
|
|
104
|
+
* @param color
|
|
105
|
+
*/
|
|
106
|
+
const renderTrailing = (color?: string) => {
|
|
73
107
|
if (loading) {
|
|
74
108
|
return <Loader type={'spinner'} color={color} style={styles.icon} />;
|
|
75
109
|
}
|
|
@@ -88,24 +122,46 @@ const Input = forwardRef(
|
|
|
88
122
|
</TouchableOpacity>
|
|
89
123
|
);
|
|
90
124
|
}
|
|
91
|
-
if (icon) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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>
|
|
99
152
|
);
|
|
100
153
|
}
|
|
101
154
|
};
|
|
102
155
|
|
|
156
|
+
/**
|
|
157
|
+
* Render input view
|
|
158
|
+
*/
|
|
103
159
|
const renderInputView = () => {
|
|
104
160
|
const disabledColor = theme.colors.text.disable;
|
|
105
161
|
const secure = secureTextInput && secureTextEntry;
|
|
106
162
|
let textColor = theme.colors.text.default;
|
|
107
163
|
let placeholderColor = theme.colors.text.hint;
|
|
108
|
-
let iconTintColor = iconColor;
|
|
164
|
+
let iconTintColor = trailingColor ?? iconColor;
|
|
109
165
|
|
|
110
166
|
if (disabled) {
|
|
111
167
|
textColor = disabledColor;
|
|
@@ -113,6 +169,13 @@ const Input = forwardRef(
|
|
|
113
169
|
iconTintColor = disabledColor;
|
|
114
170
|
}
|
|
115
171
|
|
|
172
|
+
if (secureTextEntry) {
|
|
173
|
+
keyboardType = Platform.select({
|
|
174
|
+
ios: 'ascii-capable',
|
|
175
|
+
android: 'visible-password',
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
116
179
|
return (
|
|
117
180
|
<View
|
|
118
181
|
style={[
|
|
@@ -127,6 +190,7 @@ const Input = forwardRef(
|
|
|
127
190
|
disabled={disabled}
|
|
128
191
|
required={required}
|
|
129
192
|
floatingIcon={floatingIcon}
|
|
193
|
+
onPress={onPressFloatingIcon}
|
|
130
194
|
/>
|
|
131
195
|
<View style={styles.inputView}>
|
|
132
196
|
{!!leadingIcon && (
|
|
@@ -140,7 +204,8 @@ const Input = forwardRef(
|
|
|
140
204
|
)}
|
|
141
205
|
<TextInput
|
|
142
206
|
{...props}
|
|
143
|
-
|
|
207
|
+
accessibilityLabel={accessibilityLabel}
|
|
208
|
+
editable={editable && !disabled}
|
|
144
209
|
secureTextEntry={secure}
|
|
145
210
|
textAlignVertical="center"
|
|
146
211
|
ref={inputRef}
|
|
@@ -160,6 +225,7 @@ const Input = forwardRef(
|
|
|
160
225
|
placeholder={placeholder}
|
|
161
226
|
selectionColor={theme.colors.primary}
|
|
162
227
|
placeholderTextColor={placeholderColor}
|
|
228
|
+
keyboardType={keyboardType}
|
|
163
229
|
/>
|
|
164
230
|
</View>
|
|
165
231
|
<View style={styles.iconView}>
|
|
@@ -174,19 +240,43 @@ const Input = forwardRef(
|
|
|
174
240
|
/>
|
|
175
241
|
</TouchableOpacity>
|
|
176
242
|
)}
|
|
177
|
-
{
|
|
243
|
+
{renderTrailing(iconTintColor)}
|
|
178
244
|
</View>
|
|
179
245
|
</View>
|
|
180
246
|
);
|
|
181
247
|
};
|
|
182
248
|
|
|
249
|
+
let inputState = 'active';
|
|
250
|
+
if (value && value?.length > 0) {
|
|
251
|
+
inputState = 'filled';
|
|
252
|
+
}
|
|
253
|
+
if (errorMessage && errorMessage?.length > 0) {
|
|
254
|
+
inputState = 'error';
|
|
255
|
+
}
|
|
256
|
+
if (disabled) {
|
|
257
|
+
inputState = 'disabled';
|
|
258
|
+
}
|
|
259
|
+
|
|
183
260
|
return (
|
|
184
|
-
<
|
|
185
|
-
{
|
|
186
|
-
|
|
187
|
-
|
|
261
|
+
<ComponentContext.Provider
|
|
262
|
+
value={{
|
|
263
|
+
componentName: 'Input',
|
|
264
|
+
params,
|
|
265
|
+
componentLabel: floatingValue,
|
|
266
|
+
state: inputState,
|
|
267
|
+
componentId: accessibilityLabel,
|
|
268
|
+
}}>
|
|
269
|
+
<View style={[style, styles.wrapper]}>
|
|
270
|
+
{renderInputView()}
|
|
271
|
+
<ErrorView
|
|
272
|
+
errorMessage={errorMessage}
|
|
273
|
+
errorSpacing={errorSpacing}
|
|
274
|
+
hintText={hintText}
|
|
275
|
+
/>
|
|
276
|
+
</View>
|
|
277
|
+
</ComponentContext.Provider>
|
|
188
278
|
);
|
|
189
|
-
}
|
|
279
|
+
}
|
|
190
280
|
);
|
|
191
281
|
|
|
192
282
|
export default Input;
|
package/Input/InputDropDown.tsx
CHANGED
|
@@ -1,63 +1,55 @@
|
|
|
1
1
|
import React, {useContext} from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import {ApplicationContext} from '../Application';
|
|
4
|
-
import
|
|
2
|
+
import {TouchableOpacity, View} from 'react-native';
|
|
3
|
+
import {ApplicationContext, ComponentContext} from '../Application';
|
|
4
|
+
import {Icon} from '../Icon';
|
|
5
5
|
import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
|
|
6
6
|
import {InputDropDownProps} from './index';
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
7
|
+
import {Text} from '../Text';
|
|
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,
|
|
28
|
+
accessibilityLabel,
|
|
29
|
+
hintText,
|
|
30
|
+
multiline,
|
|
30
31
|
}: InputDropDownProps) => {
|
|
31
32
|
const {theme} = useContext(ApplicationContext);
|
|
32
|
-
const full = !!value || !!placeholder;
|
|
33
|
-
|
|
34
|
-
const renderIcon = (color: string | undefined) => {
|
|
35
|
-
if (loading) {
|
|
36
|
-
return <Loader type={'spinner'} color={color} />;
|
|
37
|
-
}
|
|
38
|
-
if (icon) {
|
|
39
|
-
return <Icon color={color} source={icon} size={24} />;
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Render the input view
|
|
36
|
+
*/
|
|
43
37
|
const renderInputView = () => {
|
|
44
38
|
const disabledColor = theme.colors.text.disable;
|
|
45
39
|
let textColor = theme.colors.text.default;
|
|
46
40
|
let placeholderColor = theme.colors.text.hint;
|
|
47
|
-
let iconTintColor = iconColor;
|
|
48
41
|
|
|
49
42
|
if (disabled) {
|
|
50
43
|
textColor = disabledColor;
|
|
51
44
|
placeholderColor = disabledColor;
|
|
52
|
-
iconTintColor = disabledColor;
|
|
53
45
|
}
|
|
54
46
|
|
|
55
47
|
return (
|
|
56
48
|
<View
|
|
57
49
|
style={[
|
|
58
|
-
styles.
|
|
50
|
+
styles.inputDropDownWrapper,
|
|
59
51
|
{backgroundColor: theme.colors.background.surface},
|
|
60
|
-
getSizeStyle(size),
|
|
52
|
+
getSizeStyle(size, multiline),
|
|
61
53
|
getBorderColor(theme, false, errorMessage, disabled),
|
|
62
54
|
]}>
|
|
63
55
|
<FloatingView
|
|
@@ -66,10 +58,18 @@ const InputDropDown = ({
|
|
|
66
58
|
disabled={disabled}
|
|
67
59
|
required={required}
|
|
68
60
|
floatingIcon={floatingIcon}
|
|
61
|
+
onPress={onPressFloatingIcon}
|
|
69
62
|
/>
|
|
70
|
-
<View style={
|
|
63
|
+
<View style={styles.inputDropDownView}>
|
|
71
64
|
{!!leadingIcon && (
|
|
72
|
-
<View
|
|
65
|
+
<View
|
|
66
|
+
style={[
|
|
67
|
+
styles.leadingIconContainerDropDown,
|
|
68
|
+
{
|
|
69
|
+
marginTop: Spacing.M,
|
|
70
|
+
marginRight: Spacing.S,
|
|
71
|
+
},
|
|
72
|
+
]}>
|
|
73
73
|
<Icon
|
|
74
74
|
color={leadingIconColor}
|
|
75
75
|
source={leadingIcon}
|
|
@@ -77,37 +77,52 @@ const InputDropDown = ({
|
|
|
77
77
|
/>
|
|
78
78
|
</View>
|
|
79
79
|
)}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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'} />
|
|
100
100
|
</View>
|
|
101
|
-
<View style={styles.iconView}>{renderIcon(iconTintColor)}</View>
|
|
102
101
|
</View>
|
|
103
102
|
);
|
|
104
103
|
};
|
|
105
104
|
|
|
106
105
|
return (
|
|
107
|
-
<
|
|
108
|
-
{
|
|
109
|
-
|
|
110
|
-
|
|
106
|
+
<ComponentContext.Provider
|
|
107
|
+
value={{
|
|
108
|
+
componentName: 'InputDropDown',
|
|
109
|
+
params,
|
|
110
|
+
state: 'enabled',
|
|
111
|
+
componentLabel: floatingValue,
|
|
112
|
+
componentId: accessibilityLabel,
|
|
113
|
+
}}>
|
|
114
|
+
<TouchableOpacity
|
|
115
|
+
activeOpacity={0.6}
|
|
116
|
+
onPress={onPress}
|
|
117
|
+
style={[style, styles.wrapper]}>
|
|
118
|
+
{renderInputView()}
|
|
119
|
+
<ErrorView
|
|
120
|
+
errorMessage={errorMessage}
|
|
121
|
+
errorSpacing={errorSpacing}
|
|
122
|
+
hintText={hintText}
|
|
123
|
+
/>
|
|
124
|
+
</TouchableOpacity>
|
|
125
|
+
</ComponentContext.Provider>
|
|
111
126
|
);
|
|
112
127
|
};
|
|
113
128
|
|