@momo-kits/foundation 1.0.3 → 1.0.5
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/Button/index.tsx +0 -1
- package/CheckBox/index.tsx +3 -5
- package/CheckBox/styles.ts +4 -2
- package/ContentLoader/index.tsx +1 -1
- package/Icon/icon.json +3 -0
- package/Icon/index.tsx +6 -4
- package/Icon/types.ts +4 -1
- package/Image/index.tsx +8 -9
- package/Image/types.ts +1 -3
- package/Input/Input.tsx +18 -38
- package/Input/SearchInput.tsx +153 -0
- package/Input/TextArea.tsx +19 -33
- package/Input/common.tsx +37 -7
- package/Input/index.tsx +14 -9
- package/Input/styles.ts +32 -6
- package/Layout/ScreenContainer.tsx +2 -22
- package/Navigation/Components.tsx +54 -16
- package/Navigation/ModalScreen.tsx +10 -12
- package/Navigation/Navigation.ts +7 -6
- package/Navigation/NavigationContainer.tsx +22 -17
- package/Navigation/StackScreen.tsx +12 -7
- package/Navigation/types.ts +4 -8
- package/Navigation/utils.tsx +51 -27
- package/Playground/index.tsx +142 -5
- package/Playground/types.ts +3 -2
- package/Popup/PopupPromotion.tsx +1 -5
- package/Popup/types.ts +0 -1
- package/Radio/index.tsx +16 -8
- package/Radio/styles.ts +0 -1
- package/Radio/types.ts +4 -1
- package/Switch/index.tsx +6 -2
- package/Switch/types.ts +4 -1
- package/package.json +3 -2
package/Button/index.tsx
CHANGED
package/CheckBox/index.tsx
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import React, {FC, useContext} from 'react';
|
|
2
2
|
import {TouchableOpacity, View} from 'react-native';
|
|
3
|
-
|
|
4
3
|
import {CheckBoxProps} from './types';
|
|
5
|
-
import {Text} from '@momo-kits/foundation';
|
|
6
4
|
import styles from './styles';
|
|
7
5
|
import Image from 'react-native-fast-image';
|
|
8
6
|
import {ApplicationContext} from '../Navigation';
|
|
9
|
-
import {
|
|
7
|
+
import {Text} from '../Text';
|
|
10
8
|
|
|
11
9
|
const IC_INDETERMINATED = 'https://img.mservice.com.vn/app/img/kits/minus.png';
|
|
12
10
|
const IC_CHECKED_DEFAULT =
|
|
@@ -31,10 +29,10 @@ const CheckBox: FC<CheckBoxProps> = props => {
|
|
|
31
29
|
|
|
32
30
|
if (disabled) {
|
|
33
31
|
borderColor = haveValue
|
|
34
|
-
? theme.colors.background.
|
|
32
|
+
? theme.colors.background.tonal
|
|
35
33
|
: theme.colors.border.disable;
|
|
36
34
|
backgroundColor = haveValue
|
|
37
|
-
? theme.colors.background.
|
|
35
|
+
? theme.colors.background.tonal
|
|
38
36
|
: theme.colors.background.surface;
|
|
39
37
|
}
|
|
40
38
|
const checkboxStyle = {borderColor, backgroundColor, borderWidth: 1};
|
package/CheckBox/styles.ts
CHANGED
|
@@ -3,11 +3,13 @@ import {Radius, Spacing} from '../Consts';
|
|
|
3
3
|
|
|
4
4
|
export default StyleSheet.create({
|
|
5
5
|
checkbox: {
|
|
6
|
-
width:
|
|
7
|
-
height:
|
|
6
|
+
width: 20,
|
|
7
|
+
height: 20,
|
|
8
8
|
borderRadius: Radius.XS,
|
|
9
9
|
borderWidth: 2,
|
|
10
10
|
marginRight: Spacing.S,
|
|
11
|
+
justifyContent: 'center',
|
|
12
|
+
alignItems: 'center',
|
|
11
13
|
},
|
|
12
14
|
container: {flexDirection: 'row'},
|
|
13
15
|
icon: {width: 20, height: 20},
|
package/ContentLoader/index.tsx
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React, {useContext, useEffect, useMemo, useRef} from 'react';
|
|
2
2
|
import {Animated, Platform, useWindowDimensions, View} from 'react-native';
|
|
3
|
+
import LinearGradient from 'react-native-linear-gradient';
|
|
3
4
|
import {ContentLoaderTypes} from './types';
|
|
4
5
|
import {ApplicationContext} from '../Navigation';
|
|
5
|
-
import LinearGradient from 'react-native-linear-gradient';
|
|
6
6
|
import {Styles} from '../Consts';
|
|
7
7
|
import styles from './styles';
|
|
8
8
|
const ContentLoader: React.FC<ContentLoaderTypes> = ({style}) => {
|
package/Icon/icon.json
CHANGED
package/Icon/index.tsx
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import React, {useContext} from 'react';
|
|
2
|
-
import {IconProps, Image, ApplicationContext} from '../index';
|
|
3
2
|
import IconSources from './icon.json';
|
|
3
|
+
import {IconProps} from './types';
|
|
4
|
+
import {ApplicationContext} from '../Navigation';
|
|
5
|
+
import {Image} from '../Image';
|
|
4
6
|
|
|
5
|
-
const Icon: React.FC<IconProps> = ({source, size, color}) => {
|
|
7
|
+
const Icon: React.FC<IconProps> = ({source, size, color, style = {}}) => {
|
|
6
8
|
const {theme} = useContext(ApplicationContext);
|
|
7
9
|
|
|
8
10
|
/**
|
|
@@ -10,7 +12,7 @@ const Icon: React.FC<IconProps> = ({source, size, color}) => {
|
|
|
10
12
|
*/
|
|
11
13
|
const getIconSource = (): any => {
|
|
12
14
|
if (source && !source.includes('http')) {
|
|
13
|
-
let icon: {[key: string]:
|
|
15
|
+
let icon: {[key: string]: {uri: string}} = IconSources;
|
|
14
16
|
return icon[source] ?? icon.ic_warning;
|
|
15
17
|
}
|
|
16
18
|
return {uri: source};
|
|
@@ -19,7 +21,7 @@ const Icon: React.FC<IconProps> = ({source, size, color}) => {
|
|
|
19
21
|
return (
|
|
20
22
|
<Image
|
|
21
23
|
source={getIconSource()}
|
|
22
|
-
style={{width: size, height: size}}
|
|
24
|
+
style={[style, {width: size, height: size}]}
|
|
23
25
|
tintColor={color ?? theme.colors.text.default}
|
|
24
26
|
/>
|
|
25
27
|
);
|
package/Icon/types.ts
CHANGED
package/Image/index.tsx
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import React, {useContext, useState} from 'react';
|
|
2
|
-
import {StyleSheet, View} from 'react-native';
|
|
2
|
+
import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native';
|
|
3
3
|
import FastImage from 'react-native-fast-image';
|
|
4
|
-
|
|
5
4
|
import styles from './styles';
|
|
6
|
-
import {ImageProps} from './types';
|
|
7
5
|
import {ApplicationContext} from '../Navigation';
|
|
8
6
|
import {ContentLoader} from '../ContentLoader';
|
|
9
7
|
import {Icon} from '../Icon';
|
|
10
8
|
import {Styles} from '../Consts';
|
|
9
|
+
import {FastImagePropsWithoutStyle} from './types';
|
|
10
|
+
|
|
11
|
+
export interface ImageProps extends FastImagePropsWithoutStyle {
|
|
12
|
+
style?: StyleProp<ViewStyle>;
|
|
13
|
+
}
|
|
11
14
|
|
|
12
|
-
const Image: React.FC<ImageProps> = ({style,
|
|
15
|
+
const Image: React.FC<ImageProps> = ({style, source, ...rest}) => {
|
|
13
16
|
const {theme} = useContext(ApplicationContext);
|
|
14
17
|
const [loading, setLoading] = useState(typeof source === 'object');
|
|
15
18
|
const [fail, setFail] = useState(false);
|
|
@@ -20,7 +23,7 @@ const Image: React.FC<ImageProps> = ({style, placeholder, source, ...rest}) => {
|
|
|
20
23
|
*/
|
|
21
24
|
const renderContent = () => {
|
|
22
25
|
if (loading || fail) {
|
|
23
|
-
let content =
|
|
26
|
+
let content = (
|
|
24
27
|
<ContentLoader style={[StyleSheet.absoluteFill, styles.image]} />
|
|
25
28
|
);
|
|
26
29
|
if (fail) {
|
|
@@ -61,8 +64,4 @@ const Image: React.FC<ImageProps> = ({style, placeholder, source, ...rest}) => {
|
|
|
61
64
|
);
|
|
62
65
|
};
|
|
63
66
|
|
|
64
|
-
Image.defaultProps = {
|
|
65
|
-
style: {},
|
|
66
|
-
};
|
|
67
|
-
|
|
68
67
|
export {Image};
|
package/Image/types.ts
CHANGED
package/Input/Input.tsx
CHANGED
|
@@ -3,22 +3,15 @@ import {
|
|
|
3
3
|
NativeSyntheticEvent,
|
|
4
4
|
TextInput,
|
|
5
5
|
TextInputFocusEventData,
|
|
6
|
-
TextInputProps,
|
|
7
6
|
TouchableOpacity,
|
|
8
7
|
View,
|
|
9
8
|
} from 'react-native';
|
|
10
9
|
import {ApplicationContext} from '../Navigation';
|
|
11
10
|
import styles from './styles';
|
|
12
|
-
import {Text} from '../Text';
|
|
13
11
|
import {Image} from '../Image';
|
|
14
|
-
import {
|
|
12
|
+
import {ErrorView, FloatingView, getBorderColor} from './common';
|
|
15
13
|
import {InputProps} from './index';
|
|
16
|
-
|
|
17
|
-
const errorMessageIcon =
|
|
18
|
-
'https://img.mservice.com.vn/app/img/kits/error_mess_icon.png';
|
|
19
|
-
const ic_clear =
|
|
20
|
-
'https://img.mservice.io/momo_app_v2/new_version/img/appx_icon/24_navigation_close_circle_full.png';
|
|
21
|
-
const MAX_LENGTH = 100;
|
|
14
|
+
import {Icon} from '../Icon';
|
|
22
15
|
|
|
23
16
|
const Input: FC<InputProps> = ({
|
|
24
17
|
value,
|
|
@@ -34,11 +27,11 @@ const Input: FC<InputProps> = ({
|
|
|
34
27
|
disabled,
|
|
35
28
|
floatingIconColor,
|
|
36
29
|
iconColor,
|
|
30
|
+
...props
|
|
37
31
|
}) => {
|
|
38
32
|
const {theme} = useContext(ApplicationContext);
|
|
39
|
-
|
|
40
33
|
const [focused, setFocused] = useState(false);
|
|
41
|
-
const inputRef = useRef(null);
|
|
34
|
+
const inputRef = useRef<any>(null);
|
|
42
35
|
|
|
43
36
|
const onClearText = () => {
|
|
44
37
|
inputRef?.current?.clear();
|
|
@@ -82,15 +75,17 @@ const Input: FC<InputProps> = ({
|
|
|
82
75
|
getSizeStyle(),
|
|
83
76
|
getBorderColor(focused, errorMessage, disabled),
|
|
84
77
|
styles.inputWrapper,
|
|
78
|
+
{backgroundColor: theme.colors.background.surface},
|
|
85
79
|
]}>
|
|
86
|
-
|
|
87
|
-
floatingValue
|
|
88
|
-
floatingIconColor
|
|
89
|
-
disabled
|
|
90
|
-
floatingIcon
|
|
91
|
-
|
|
80
|
+
<FloatingView
|
|
81
|
+
floatingValue={floatingValue}
|
|
82
|
+
floatingIconColor={floatingIconColor}
|
|
83
|
+
disabled={disabled}
|
|
84
|
+
floatingIcon={floatingIcon}
|
|
85
|
+
/>
|
|
92
86
|
<View style={styles.inputView}>
|
|
93
87
|
<TextInput
|
|
88
|
+
{...props}
|
|
94
89
|
editable={!disabled}
|
|
95
90
|
textAlignVertical="top"
|
|
96
91
|
ref={inputRef}
|
|
@@ -112,10 +107,10 @@ const Input: FC<InputProps> = ({
|
|
|
112
107
|
<View style={styles.iconView}>
|
|
113
108
|
{focused && (
|
|
114
109
|
<TouchableOpacity style={styles.iconWrapper} onPress={onClearText}>
|
|
115
|
-
<
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
110
|
+
<Icon
|
|
111
|
+
source="24_navigation_close_circle_full"
|
|
112
|
+
size={16}
|
|
113
|
+
color={theme.colors.text.hint}
|
|
119
114
|
/>
|
|
120
115
|
</TouchableOpacity>
|
|
121
116
|
)}
|
|
@@ -131,31 +126,16 @@ const Input: FC<InputProps> = ({
|
|
|
131
126
|
);
|
|
132
127
|
};
|
|
133
128
|
|
|
134
|
-
const renderErrorView = () => {
|
|
135
|
-
if (errorMessage) {
|
|
136
|
-
return (
|
|
137
|
-
<View style={styles.errorView}>
|
|
138
|
-
<Image style={styles.errorIcon} source={{uri: errorMessageIcon}} />
|
|
139
|
-
<Text color={theme.colors.error.primary} typography={'description_s'}>
|
|
140
|
-
{errorMessage}
|
|
141
|
-
</Text>
|
|
142
|
-
</View>
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
|
|
147
129
|
return (
|
|
148
130
|
<View style={styles.wrapper}>
|
|
149
131
|
{renderInputView()}
|
|
150
|
-
{
|
|
132
|
+
<ErrorView errorMessage={errorMessage} />
|
|
151
133
|
</View>
|
|
152
134
|
);
|
|
153
135
|
};
|
|
154
136
|
|
|
155
137
|
Input.defaultProps = {
|
|
156
|
-
size: '
|
|
157
|
-
maxLength: MAX_LENGTH,
|
|
158
|
-
disabled: false,
|
|
138
|
+
size: 'small',
|
|
159
139
|
};
|
|
160
140
|
|
|
161
141
|
export default Input;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import React, {FC, useContext, useRef, useState} from 'react';
|
|
2
|
+
import {
|
|
3
|
+
NativeSyntheticEvent,
|
|
4
|
+
TextInput,
|
|
5
|
+
TextInputFocusEventData,
|
|
6
|
+
TouchableOpacity,
|
|
7
|
+
View,
|
|
8
|
+
} from 'react-native';
|
|
9
|
+
import {SearchInputProps} from './index';
|
|
10
|
+
import {getBorderColor} from './common';
|
|
11
|
+
import {ApplicationContext} from '../Navigation';
|
|
12
|
+
import styles from './styles';
|
|
13
|
+
import {Icon} from '../Icon';
|
|
14
|
+
import {Image} from '../Image';
|
|
15
|
+
import {Text} from '../Text';
|
|
16
|
+
|
|
17
|
+
const SearchInput: FC<SearchInputProps> = ({
|
|
18
|
+
errorMessage,
|
|
19
|
+
disabled,
|
|
20
|
+
placeholder,
|
|
21
|
+
onFocus,
|
|
22
|
+
onBlur,
|
|
23
|
+
iconColor,
|
|
24
|
+
value,
|
|
25
|
+
onChangeText,
|
|
26
|
+
icon,
|
|
27
|
+
buttonText = 'Hủy',
|
|
28
|
+
showButtonText,
|
|
29
|
+
showIcon = true,
|
|
30
|
+
...props
|
|
31
|
+
}) => {
|
|
32
|
+
const {theme} = useContext(ApplicationContext);
|
|
33
|
+
const [focused, setFocused] = useState(false);
|
|
34
|
+
const inputRef = useRef<any>(null);
|
|
35
|
+
let iconTintColor = iconColor;
|
|
36
|
+
|
|
37
|
+
const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
|
|
38
|
+
setFocused(true);
|
|
39
|
+
onFocus?.(e);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const _onBlur = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
|
|
43
|
+
setFocused(false);
|
|
44
|
+
onBlur?.(e);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const onClearText = () => {
|
|
48
|
+
inputRef?.current?.clear();
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const _onChangeText = (text: string) => {
|
|
52
|
+
onChangeText?.(text);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const renderInputView = () => {
|
|
56
|
+
const disabledColor = theme.colors.text.disable;
|
|
57
|
+
let textColor = theme.colors.text.default;
|
|
58
|
+
let placeholderColor = theme.colors.text.hint;
|
|
59
|
+
|
|
60
|
+
if (disabled) {
|
|
61
|
+
textColor = disabledColor;
|
|
62
|
+
placeholderColor = disabledColor;
|
|
63
|
+
iconTintColor = disabledColor;
|
|
64
|
+
}
|
|
65
|
+
return (
|
|
66
|
+
<View style={styles.searchInputView}>
|
|
67
|
+
<Icon
|
|
68
|
+
source={'navigation_search'}
|
|
69
|
+
size={24}
|
|
70
|
+
color={theme.colors.text.hint}
|
|
71
|
+
/>
|
|
72
|
+
<TextInput
|
|
73
|
+
{...props}
|
|
74
|
+
editable={!disabled}
|
|
75
|
+
textAlignVertical="top"
|
|
76
|
+
ref={inputRef}
|
|
77
|
+
style={[
|
|
78
|
+
styles.searchInput,
|
|
79
|
+
{
|
|
80
|
+
color: textColor,
|
|
81
|
+
},
|
|
82
|
+
]}
|
|
83
|
+
value={value}
|
|
84
|
+
onChangeText={_onChangeText}
|
|
85
|
+
onFocus={_onFocus}
|
|
86
|
+
onBlur={_onBlur}
|
|
87
|
+
placeholder={placeholder}
|
|
88
|
+
selectionColor={theme.colors.primary}
|
|
89
|
+
placeholderTextColor={placeholderColor}
|
|
90
|
+
/>
|
|
91
|
+
</View>
|
|
92
|
+
);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const renderIconView = () => {
|
|
96
|
+
return (
|
|
97
|
+
<View
|
|
98
|
+
style={{
|
|
99
|
+
flexDirection: 'row',
|
|
100
|
+
}}>
|
|
101
|
+
{focused && (
|
|
102
|
+
<TouchableOpacity style={styles.iconWrapper} onPress={onClearText}>
|
|
103
|
+
<Icon
|
|
104
|
+
source="24_navigation_close_circle_full"
|
|
105
|
+
size={16}
|
|
106
|
+
color={theme.colors.text.hint}
|
|
107
|
+
/>
|
|
108
|
+
</TouchableOpacity>
|
|
109
|
+
)}
|
|
110
|
+
{showIcon && icon && (
|
|
111
|
+
<View>
|
|
112
|
+
<View
|
|
113
|
+
style={[
|
|
114
|
+
styles.divider,
|
|
115
|
+
{
|
|
116
|
+
backgroundColor: theme.colors.primary,
|
|
117
|
+
},
|
|
118
|
+
]}
|
|
119
|
+
/>
|
|
120
|
+
|
|
121
|
+
<Image
|
|
122
|
+
tintColor={iconTintColor}
|
|
123
|
+
source={{uri: icon}}
|
|
124
|
+
style={styles.iconSearchInput}
|
|
125
|
+
/>
|
|
126
|
+
</View>
|
|
127
|
+
)}
|
|
128
|
+
</View>
|
|
129
|
+
);
|
|
130
|
+
};
|
|
131
|
+
return (
|
|
132
|
+
<View style={styles.searchInputContainer}>
|
|
133
|
+
<View
|
|
134
|
+
style={[
|
|
135
|
+
getBorderColor(focused, errorMessage, disabled),
|
|
136
|
+
styles.searchInputWrapper,
|
|
137
|
+
{backgroundColor: theme.colors.background.surface},
|
|
138
|
+
]}>
|
|
139
|
+
{renderInputView()}
|
|
140
|
+
{renderIconView()}
|
|
141
|
+
</View>
|
|
142
|
+
{showButtonText && (
|
|
143
|
+
<TouchableOpacity>
|
|
144
|
+
<Text typography={'action_default'} style={styles.textButton}>
|
|
145
|
+
{buttonText}
|
|
146
|
+
</Text>
|
|
147
|
+
</TouchableOpacity>
|
|
148
|
+
)}
|
|
149
|
+
</View>
|
|
150
|
+
);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
export default SearchInput;
|
package/Input/TextArea.tsx
CHANGED
|
@@ -3,23 +3,21 @@ import {
|
|
|
3
3
|
NativeSyntheticEvent,
|
|
4
4
|
TextInput,
|
|
5
5
|
TextInputFocusEventData,
|
|
6
|
-
TextInputProps,
|
|
7
6
|
TouchableOpacity,
|
|
8
7
|
View,
|
|
9
8
|
} from 'react-native';
|
|
10
9
|
import styles from './styles';
|
|
11
|
-
import {Image} from '../Image';
|
|
12
10
|
import {Text} from '../Text';
|
|
13
11
|
import {ApplicationContext} from '../Navigation';
|
|
14
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
DEFAULT_HEIGHT,
|
|
14
|
+
ErrorView,
|
|
15
|
+
FloatingView,
|
|
16
|
+
getBorderColor,
|
|
17
|
+
MAX_LENGTH,
|
|
18
|
+
} from './common';
|
|
15
19
|
import {TextAreaProps} from './index';
|
|
16
|
-
|
|
17
|
-
const errorMessageIcon =
|
|
18
|
-
'https://img.mservice.com.vn/app/img/kits/error_mess_icon.png';
|
|
19
|
-
const ic_clear =
|
|
20
|
-
'https://img.mservice.io/momo_app_v2/new_version/img/appx_icon/24_navigation_close_circle_full.png';
|
|
21
|
-
const DEFAULT_HEIGHT = 112;
|
|
22
|
-
const MAX_LENGTH = 300;
|
|
20
|
+
import {Icon} from '../Icon';
|
|
23
21
|
|
|
24
22
|
const TextArea: FC<TextAreaProps> = props => {
|
|
25
23
|
const {theme} = useContext(ApplicationContext);
|
|
@@ -91,12 +89,12 @@ const TextArea: FC<TextAreaProps> = props => {
|
|
|
91
89
|
backgroundColor: theme.colors.background.surface,
|
|
92
90
|
},
|
|
93
91
|
]}>
|
|
94
|
-
|
|
95
|
-
floatingValue
|
|
96
|
-
floatingIconColor
|
|
97
|
-
disabled
|
|
98
|
-
floatingIcon
|
|
99
|
-
|
|
92
|
+
<FloatingView
|
|
93
|
+
floatingValue={floatingValue}
|
|
94
|
+
floatingIconColor={floatingIconColor}
|
|
95
|
+
disabled={disabled}
|
|
96
|
+
floatingIcon={floatingIcon}
|
|
97
|
+
/>
|
|
100
98
|
<View style={styles.rowArea}>
|
|
101
99
|
<View style={styles.textAreaView}>
|
|
102
100
|
<TextInput
|
|
@@ -122,10 +120,10 @@ const TextArea: FC<TextAreaProps> = props => {
|
|
|
122
120
|
</View>
|
|
123
121
|
{focused && (
|
|
124
122
|
<TouchableOpacity style={styles.iconWrapper} onPress={onClearText}>
|
|
125
|
-
<
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
123
|
+
<Icon
|
|
124
|
+
source="24_navigation_close_circle_full"
|
|
125
|
+
size={16}
|
|
126
|
+
color={theme.colors.text.hint}
|
|
129
127
|
/>
|
|
130
128
|
</TouchableOpacity>
|
|
131
129
|
)}
|
|
@@ -135,22 +133,10 @@ const TextArea: FC<TextAreaProps> = props => {
|
|
|
135
133
|
);
|
|
136
134
|
};
|
|
137
135
|
|
|
138
|
-
const renderErrorView = () => {
|
|
139
|
-
if (errorMessage) {
|
|
140
|
-
return (
|
|
141
|
-
<View style={styles.errorView}>
|
|
142
|
-
<Image style={styles.errorIcon} source={{uri: errorMessageIcon}} />
|
|
143
|
-
<Text color={theme.colors.error.primary} typography={'description_s'}>
|
|
144
|
-
{errorMessage}
|
|
145
|
-
</Text>
|
|
146
|
-
</View>
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
136
|
return (
|
|
151
137
|
<View style={styles.wrapper}>
|
|
152
138
|
{renderInputView()}
|
|
153
|
-
{
|
|
139
|
+
<ErrorView errorMessage={errorMessage} />
|
|
154
140
|
</View>
|
|
155
141
|
);
|
|
156
142
|
};
|
package/Input/common.tsx
CHANGED
|
@@ -2,8 +2,19 @@ import {View} from 'react-native';
|
|
|
2
2
|
import styles from './styles';
|
|
3
3
|
import {Text} from '../Text';
|
|
4
4
|
import {Image} from '../Image';
|
|
5
|
-
import React, {useContext} from 'react';
|
|
5
|
+
import React, {FC, useContext} from 'react';
|
|
6
6
|
import {ApplicationContext} from '../Navigation';
|
|
7
|
+
import {Icon} from '../Icon';
|
|
8
|
+
|
|
9
|
+
type FloatingViewProps = {
|
|
10
|
+
floatingValue?: string;
|
|
11
|
+
floatingIconColor?: string;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
floatingIcon?: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const DEFAULT_HEIGHT = 112;
|
|
17
|
+
export const MAX_LENGTH = 300;
|
|
7
18
|
|
|
8
19
|
export const getBorderColor = (
|
|
9
20
|
focused: boolean,
|
|
@@ -29,12 +40,30 @@ export const getBorderColor = (
|
|
|
29
40
|
return {borderColor};
|
|
30
41
|
};
|
|
31
42
|
|
|
32
|
-
export const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
43
|
+
export const ErrorView: FC<{errorMessage?: string}> = ({errorMessage}) => {
|
|
44
|
+
const {theme} = useContext(ApplicationContext);
|
|
45
|
+
const errorColor = theme.colors.error.primary;
|
|
46
|
+
if (errorMessage) {
|
|
47
|
+
return (
|
|
48
|
+
<View style={styles.errorView}>
|
|
49
|
+
<View style={styles.errorIcon}>
|
|
50
|
+
<Icon color={errorColor} source="ic_error" size={16} />
|
|
51
|
+
</View>
|
|
52
|
+
<Text color={errorColor} typography={'description_s'}>
|
|
53
|
+
{errorMessage}
|
|
54
|
+
</Text>
|
|
55
|
+
</View>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const FloatingView: FC<FloatingViewProps> = ({
|
|
62
|
+
floatingValue,
|
|
63
|
+
floatingIconColor,
|
|
64
|
+
disabled,
|
|
65
|
+
floatingIcon,
|
|
66
|
+
}) => {
|
|
38
67
|
const {theme} = useContext(ApplicationContext);
|
|
39
68
|
|
|
40
69
|
if (floatingValue) {
|
|
@@ -67,4 +96,5 @@ export const renderFloatingView = (
|
|
|
67
96
|
</View>
|
|
68
97
|
);
|
|
69
98
|
}
|
|
99
|
+
return null;
|
|
70
100
|
};
|
package/Input/index.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Input from './Input';
|
|
2
2
|
import TextArea from './TextArea';
|
|
3
|
+
import SearchInput from './SearchInput';
|
|
3
4
|
import {TextInputProps} from 'react-native';
|
|
4
5
|
|
|
5
6
|
export interface InputProps extends TextInputProps {
|
|
@@ -13,14 +14,18 @@ export interface InputProps extends TextInputProps {
|
|
|
13
14
|
iconColor?: string;
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
type InputPropsWithoutSize = Omit<InputProps, 'size'>;
|
|
18
|
+
|
|
19
|
+
export interface TextAreaProps extends TextInputProps, InputPropsWithoutSize {
|
|
20
|
+
height?: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface SearchInputProps
|
|
24
|
+
extends TextInputProps,
|
|
25
|
+
InputPropsWithoutSize {
|
|
26
|
+
buttonText?: string;
|
|
27
|
+
showButtonText?: boolean;
|
|
28
|
+
showIcon?: boolean;
|
|
24
29
|
}
|
|
25
30
|
|
|
26
|
-
export {Input, TextArea};
|
|
31
|
+
export {Input, TextArea, SearchInput};
|
package/Input/styles.ts
CHANGED
|
@@ -5,7 +5,6 @@ export default StyleSheet.create({
|
|
|
5
5
|
//input style
|
|
6
6
|
input: {width: '100%', paddingLeft: Spacing.M, height: '100%'},
|
|
7
7
|
wrapper: {
|
|
8
|
-
marginVertical: Spacing.M,
|
|
9
8
|
width: '100%',
|
|
10
9
|
},
|
|
11
10
|
container: {
|
|
@@ -29,7 +28,7 @@ export default StyleSheet.create({
|
|
|
29
28
|
flexDirection: 'row',
|
|
30
29
|
},
|
|
31
30
|
floatingIcon: {width: 16, height: 16, marginLeft: Spacing.XS},
|
|
32
|
-
errorIcon: {
|
|
31
|
+
errorIcon: {marginRight: Spacing.XS},
|
|
33
32
|
errorView: {
|
|
34
33
|
flexDirection: 'row',
|
|
35
34
|
alignItems: 'center',
|
|
@@ -38,10 +37,6 @@ export default StyleSheet.create({
|
|
|
38
37
|
justifyContent: 'space-between',
|
|
39
38
|
flex: 1,
|
|
40
39
|
},
|
|
41
|
-
iconClose: {
|
|
42
|
-
width: 16,
|
|
43
|
-
height: 16,
|
|
44
|
-
},
|
|
45
40
|
iconView: {
|
|
46
41
|
flexDirection: 'row',
|
|
47
42
|
alignItems: 'center',
|
|
@@ -89,4 +84,35 @@ export default StyleSheet.create({
|
|
|
89
84
|
flex: 1,
|
|
90
85
|
marginBottom: Spacing.XS,
|
|
91
86
|
},
|
|
87
|
+
|
|
88
|
+
//searchInput
|
|
89
|
+
searchInputWrapper: {
|
|
90
|
+
flexDirection: 'row',
|
|
91
|
+
borderRadius: Radius.XL,
|
|
92
|
+
borderWidth: 1,
|
|
93
|
+
paddingHorizontal: Spacing.S,
|
|
94
|
+
alignItems: 'center',
|
|
95
|
+
flex: 1,
|
|
96
|
+
},
|
|
97
|
+
searchInput: {
|
|
98
|
+
width: '100%',
|
|
99
|
+
height: 36,
|
|
100
|
+
marginLeft: Spacing.S,
|
|
101
|
+
},
|
|
102
|
+
searchInputView: {
|
|
103
|
+
flex: 1,
|
|
104
|
+
flexDirection: 'row',
|
|
105
|
+
alignItems: 'center',
|
|
106
|
+
},
|
|
107
|
+
iconSearchInput: {
|
|
108
|
+
width: 24,
|
|
109
|
+
height: 24,
|
|
110
|
+
marginLeft: Spacing.S,
|
|
111
|
+
},
|
|
112
|
+
searchInputContainer: {flexDirection: 'row', alignItems: 'center'},
|
|
113
|
+
textButton: {marginLeft: Spacing.L},
|
|
114
|
+
divider: {
|
|
115
|
+
width: 1,
|
|
116
|
+
marginLeft: Spacing.XS,
|
|
117
|
+
},
|
|
92
118
|
});
|