@momo-kits/foundation 0.92.7-rc.21 → 0.92.7-rc.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Application/BottomSheet.tsx +216 -0
- package/Application/BottomTab/BottomTabBar.tsx +62 -223
- package/Application/BottomTab/index.tsx +15 -11
- package/Application/Components.tsx +291 -45
- package/Application/Localize.ts +44 -0
- package/Application/ModalScreen.tsx +11 -181
- package/Application/Navigation.ts +4 -18
- package/Application/NavigationContainer.tsx +10 -28
- package/Application/Navigator.ts +14 -16
- package/Application/StackScreen.tsx +222 -42
- package/Application/index.ts +5 -3
- package/Application/types.ts +47 -29
- package/Application/utils.tsx +61 -19
- package/Assets/icon_bank.json +1 -1
- package/Badge/BadgeDotAnimation.tsx +95 -0
- package/Badge/index.tsx +2 -1
- package/Badge/styles.ts +50 -6
- package/Button/index.tsx +7 -8
- package/Icon/index.tsx +1 -1
- package/Icon/types.ts +1 -2
- package/Image/index.tsx +0 -1
- package/Input/Input.tsx +51 -17
- package/Input/InputDropDown.tsx +42 -45
- package/Input/InputMoney.tsx +65 -6
- package/Input/InputOTP.tsx +14 -13
- package/Input/InputSearch.tsx +259 -146
- package/Input/InputTextArea.tsx +0 -1
- package/Input/TextTyping.tsx +113 -0
- package/Input/common.tsx +29 -10
- package/Input/index.tsx +84 -89
- package/Input/styles.ts +44 -7
- package/Input/utils.ts +1 -1
- package/Layout/Card.tsx +4 -3
- package/Layout/FloatingButton.tsx +3 -3
- package/Layout/GridSystem.tsx +1 -1
- package/Layout/ItemList.tsx +3 -2
- package/Layout/Screen.tsx +188 -102
- package/Layout/Section.tsx +4 -3
- package/Layout/styles.ts +0 -6
- package/Layout/types.ts +1 -1
- package/Layout/utils.ts +2 -2
- package/Loader/index.tsx +2 -0
- package/Pagination/PaginationScroll.tsx +2 -2
- package/Pagination/styles.ts +1 -1
- package/Popup/PopupNotify.tsx +7 -7
- package/Popup/PopupPromotion.tsx +1 -1
- package/Popup/types.ts +1 -1
- package/Tag/index.tsx +9 -2
- package/Tag/styles.ts +3 -2
- package/Tag/types.ts +12 -0
- package/Title/index.tsx +20 -7
- package/Title/styles.ts +4 -4
- package/code-scanner.js +141 -124
- package/index.ts +7 -0
- package/package.json +5 -4
- package/publish.sh +16 -21
- package/tsconfig.json +1 -1
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import React, {useEffect, useRef} from 'react';
|
|
2
|
+
import {Animated, View} from 'react-native';
|
|
3
|
+
import {BadgeDotProps} from './types';
|
|
4
|
+
import styles from './styles';
|
|
5
|
+
|
|
6
|
+
const DURATION = 500;
|
|
7
|
+
|
|
8
|
+
const BadgeDotAnimation = ({size, style}: BadgeDotProps) => {
|
|
9
|
+
// Refs for animated values
|
|
10
|
+
const scaleAnim = useRef(new Animated.Value(1)).current;
|
|
11
|
+
const waveScaleAnim = useRef(new Animated.Value(1)).current;
|
|
12
|
+
const waveOpacityAnim = useRef(new Animated.Value(0)).current;
|
|
13
|
+
|
|
14
|
+
const dotStyle =
|
|
15
|
+
size === 'small' ? styles.dotAnimationSmall : styles.dotAnimation;
|
|
16
|
+
const waveStyle = size === 'small' ? styles.waveSmall : styles.wave;
|
|
17
|
+
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
// Infinite loop animation for the scale and wave effect
|
|
20
|
+
const animation = Animated.loop(
|
|
21
|
+
Animated.parallel([
|
|
22
|
+
// Dot pulse animation
|
|
23
|
+
Animated.sequence([
|
|
24
|
+
Animated.spring(scaleAnim, {
|
|
25
|
+
toValue: 1, // Scale up slightly
|
|
26
|
+
friction: 5, // Controls the "bounciness" of the spring
|
|
27
|
+
tension: 30, // Controls the "stiffness" of the spring
|
|
28
|
+
useNativeDriver: true,
|
|
29
|
+
}),
|
|
30
|
+
Animated.spring(scaleAnim, {
|
|
31
|
+
toValue: 1.1,
|
|
32
|
+
friction: 5,
|
|
33
|
+
tension: 30,
|
|
34
|
+
useNativeDriver: true,
|
|
35
|
+
}),
|
|
36
|
+
]), // Wave animation
|
|
37
|
+
Animated.sequence([
|
|
38
|
+
Animated.timing(waveScaleAnim, {
|
|
39
|
+
toValue: 2.5,
|
|
40
|
+
duration: DURATION * 3,
|
|
41
|
+
useNativeDriver: true,
|
|
42
|
+
}),
|
|
43
|
+
Animated.timing(waveScaleAnim, {
|
|
44
|
+
toValue: 1, // Reset wave size
|
|
45
|
+
duration: 0,
|
|
46
|
+
useNativeDriver: true,
|
|
47
|
+
}),
|
|
48
|
+
]), // Wave opacity animation
|
|
49
|
+
Animated.sequence([
|
|
50
|
+
Animated.timing(waveOpacityAnim, {
|
|
51
|
+
toValue: 0.3, // Wave becomes visible
|
|
52
|
+
duration: DURATION * 2,
|
|
53
|
+
useNativeDriver: true,
|
|
54
|
+
}),
|
|
55
|
+
Animated.timing(waveOpacityAnim, {
|
|
56
|
+
toValue: 0, // Wave fades out
|
|
57
|
+
duration: DURATION,
|
|
58
|
+
useNativeDriver: true,
|
|
59
|
+
}),
|
|
60
|
+
]),
|
|
61
|
+
])
|
|
62
|
+
);
|
|
63
|
+
animation.start();
|
|
64
|
+
|
|
65
|
+
return () => {
|
|
66
|
+
animation.stop();
|
|
67
|
+
};
|
|
68
|
+
}, []);
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<View style={[styles.dotAnimationContainer, style]}>
|
|
72
|
+
{/* Wave Animation */}
|
|
73
|
+
<Animated.View
|
|
74
|
+
style={[
|
|
75
|
+
waveStyle,
|
|
76
|
+
{
|
|
77
|
+
transform: [{scale: waveScaleAnim}],
|
|
78
|
+
opacity: waveOpacityAnim,
|
|
79
|
+
},
|
|
80
|
+
]}
|
|
81
|
+
/>
|
|
82
|
+
{/* Dot Animation */}
|
|
83
|
+
<Animated.View
|
|
84
|
+
style={[
|
|
85
|
+
dotStyle,
|
|
86
|
+
{
|
|
87
|
+
transform: [{scale: scaleAnim}],
|
|
88
|
+
},
|
|
89
|
+
]}
|
|
90
|
+
/>
|
|
91
|
+
</View>
|
|
92
|
+
);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export default BadgeDotAnimation;
|
package/Badge/index.tsx
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import Badge from './Badge';
|
|
2
2
|
import BadgeDot from './BadgeDot';
|
|
3
3
|
import BadgeRibbon from './BadgeRibbon';
|
|
4
|
+
import BadgeDotAnimation from './BadgeDotAnimation';
|
|
4
5
|
import {BadgeProps, BadgeDotProps, BadgeRibbonProps} from './types';
|
|
5
6
|
|
|
6
|
-
export {Badge, BadgeRibbon, BadgeDot};
|
|
7
|
+
export {Badge, BadgeRibbon, BadgeDot, BadgeDotAnimation};
|
|
7
8
|
export type {BadgeProps, BadgeDotProps, BadgeRibbonProps};
|
package/Badge/styles.ts
CHANGED
|
@@ -2,6 +2,10 @@ import {StyleSheet} from 'react-native';
|
|
|
2
2
|
import {Colors, Radius, Spacing} from '../Consts';
|
|
3
3
|
import {scaleSize} from '../Text';
|
|
4
4
|
|
|
5
|
+
const DOT_SIZE = 16;
|
|
6
|
+
|
|
7
|
+
const DOT_SMALL_SIZE = 10;
|
|
8
|
+
|
|
5
9
|
export default StyleSheet.create({
|
|
6
10
|
badge: {
|
|
7
11
|
paddingHorizontal: Spacing.XS,
|
|
@@ -15,21 +19,61 @@ export default StyleSheet.create({
|
|
|
15
19
|
borderColor: Colors.black_01,
|
|
16
20
|
alignSelf: 'baseline',
|
|
17
21
|
},
|
|
22
|
+
dotAnimationContainer: {
|
|
23
|
+
position: 'relative',
|
|
24
|
+
alignItems: 'center',
|
|
25
|
+
justifyContent: 'center',
|
|
26
|
+
},
|
|
18
27
|
dot: {
|
|
19
|
-
width:
|
|
20
|
-
height:
|
|
28
|
+
width: DOT_SIZE,
|
|
29
|
+
height: DOT_SIZE,
|
|
21
30
|
borderWidth: 2,
|
|
22
31
|
borderColor: Colors.black_01,
|
|
23
32
|
backgroundColor: Colors.red_03,
|
|
24
|
-
borderRadius:
|
|
33
|
+
borderRadius: DOT_SIZE / 2,
|
|
25
34
|
},
|
|
26
35
|
dotSmall: {
|
|
27
|
-
width:
|
|
28
|
-
height:
|
|
36
|
+
width: DOT_SMALL_SIZE,
|
|
37
|
+
height: DOT_SMALL_SIZE,
|
|
29
38
|
borderWidth: 1,
|
|
30
39
|
borderColor: Colors.black_01,
|
|
31
40
|
backgroundColor: Colors.red_03,
|
|
32
|
-
borderRadius:
|
|
41
|
+
borderRadius: DOT_SMALL_SIZE / 2,
|
|
42
|
+
},
|
|
43
|
+
dotAnimation: {
|
|
44
|
+
width: DOT_SIZE,
|
|
45
|
+
height: DOT_SIZE,
|
|
46
|
+
borderColor: Colors.black_01,
|
|
47
|
+
backgroundColor: Colors.red_03,
|
|
48
|
+
borderRadius: DOT_SIZE / 2,
|
|
49
|
+
borderWidth: 0,
|
|
50
|
+
},
|
|
51
|
+
dotAnimationSmall: {
|
|
52
|
+
width: DOT_SMALL_SIZE,
|
|
53
|
+
height: DOT_SMALL_SIZE,
|
|
54
|
+
borderColor: Colors.black_01,
|
|
55
|
+
backgroundColor: Colors.red_03,
|
|
56
|
+
borderRadius: DOT_SMALL_SIZE / 2,
|
|
57
|
+
borderWidth: 0,
|
|
58
|
+
},
|
|
59
|
+
wave: {
|
|
60
|
+
width: DOT_SIZE,
|
|
61
|
+
height: DOT_SIZE,
|
|
62
|
+
borderColor: Colors.black_01,
|
|
63
|
+
backgroundColor: Colors.red_03,
|
|
64
|
+
borderRadius: DOT_SIZE / 2,
|
|
65
|
+
opacity: 0,
|
|
66
|
+
position: 'absolute',
|
|
67
|
+
borderWidth: 0,
|
|
68
|
+
},
|
|
69
|
+
waveSmall: {
|
|
70
|
+
width: DOT_SMALL_SIZE,
|
|
71
|
+
height: DOT_SMALL_SIZE,
|
|
72
|
+
borderColor: Colors.black_01,
|
|
73
|
+
backgroundColor: Colors.red_03,
|
|
74
|
+
borderRadius: DOT_SMALL_SIZE / 2,
|
|
75
|
+
borderWidth: 0,
|
|
76
|
+
position: 'absolute',
|
|
33
77
|
},
|
|
34
78
|
ribbon: {
|
|
35
79
|
alignSelf: 'baseline',
|
package/Button/index.tsx
CHANGED
|
@@ -94,7 +94,7 @@ const Button: FC<ButtonProps> = ({
|
|
|
94
94
|
if (loading) {
|
|
95
95
|
state = 'loading';
|
|
96
96
|
}
|
|
97
|
-
if (gradient?.length > 0 && type
|
|
97
|
+
if (gradient?.length > 0 && type === 'primary') {
|
|
98
98
|
gradientPros = {
|
|
99
99
|
colors: gradient,
|
|
100
100
|
start: {x: 1, y: 0.5},
|
|
@@ -217,9 +217,9 @@ const Button: FC<ButtonProps> = ({
|
|
|
217
217
|
*/
|
|
218
218
|
const renderTitle = () => {
|
|
219
219
|
const typography = getTypography();
|
|
220
|
-
const
|
|
220
|
+
const textColor = getTextColor();
|
|
221
221
|
return (
|
|
222
|
-
<Text typography={typography} color={
|
|
222
|
+
<Text typography={typography} color={textColor} numberOfLines={1}>
|
|
223
223
|
{title}
|
|
224
224
|
</Text>
|
|
225
225
|
);
|
|
@@ -231,7 +231,7 @@ const Button: FC<ButtonProps> = ({
|
|
|
231
231
|
const renderLeading = () => {
|
|
232
232
|
const iconSize = getIconSize();
|
|
233
233
|
const marginRight = getIconSpace();
|
|
234
|
-
const
|
|
234
|
+
const textColor = tintColor ?? getTextColor();
|
|
235
235
|
|
|
236
236
|
if (loading) {
|
|
237
237
|
return (
|
|
@@ -256,7 +256,7 @@ const Button: FC<ButtonProps> = ({
|
|
|
256
256
|
styles.leading,
|
|
257
257
|
{width: iconSize, height: iconSize, marginRight},
|
|
258
258
|
]}>
|
|
259
|
-
<Icon color={
|
|
259
|
+
<Icon color={textColor} source={iconLeft} size={iconSize} />
|
|
260
260
|
</View>
|
|
261
261
|
);
|
|
262
262
|
}
|
|
@@ -266,7 +266,7 @@ const Button: FC<ButtonProps> = ({
|
|
|
266
266
|
* render trailing
|
|
267
267
|
*/
|
|
268
268
|
const renderTrailing = () => {
|
|
269
|
-
const
|
|
269
|
+
const textColor = tintColor ?? getTextColor();
|
|
270
270
|
const marginLeft = getIconSpace();
|
|
271
271
|
|
|
272
272
|
if (iconRight) {
|
|
@@ -277,7 +277,7 @@ const Button: FC<ButtonProps> = ({
|
|
|
277
277
|
styles.trailing,
|
|
278
278
|
{width: iconSize, height: iconSize, marginLeft},
|
|
279
279
|
]}>
|
|
280
|
-
<Icon color={
|
|
280
|
+
<Icon color={textColor} source={iconRight} size={iconSize} />
|
|
281
281
|
</View>
|
|
282
282
|
);
|
|
283
283
|
}
|
|
@@ -297,7 +297,6 @@ const Button: FC<ButtonProps> = ({
|
|
|
297
297
|
};
|
|
298
298
|
|
|
299
299
|
const activeOpacity = type === 'disabled' ? 0.75 : 0.5;
|
|
300
|
-
|
|
301
300
|
return (
|
|
302
301
|
<ComponentContext.Provider
|
|
303
302
|
value={{
|
package/Icon/index.tsx
CHANGED
package/Icon/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {ImageStyle} from 'react-native-fast-image';
|
|
2
|
-
import {StyleProp} from
|
|
2
|
+
import {StyleProp} from 'react-native';
|
|
3
3
|
|
|
4
4
|
export type IconProps = {
|
|
5
5
|
/**
|
|
@@ -16,7 +16,6 @@ export type IconProps = {
|
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Optional. Represents the color of the icon.
|
|
19
|
-
* It can be any valid color in @momo-kits/foundation.
|
|
20
19
|
*/
|
|
21
20
|
color?: string | null;
|
|
22
21
|
|
package/Image/index.tsx
CHANGED
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}
|