@momo-kits/foundation 0.75.1-beta.10

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.
Files changed (76) hide show
  1. package/Assets/header-background.png +0 -0
  2. package/Assets/icon.json +3947 -0
  3. package/Button/index.tsx +278 -0
  4. package/Button/styles.ts +41 -0
  5. package/CheckBox/index.tsx +61 -0
  6. package/CheckBox/styles.ts +15 -0
  7. package/CheckBox/types.ts +38 -0
  8. package/Consts/colors+spacing+radius.ts +214 -0
  9. package/Consts/index.ts +4 -0
  10. package/Consts/styles.ts +78 -0
  11. package/Consts/theme.ts +121 -0
  12. package/Divider/index.tsx +19 -0
  13. package/Icon/index.tsx +37 -0
  14. package/Icon/types.ts +27 -0
  15. package/IconButton/index.tsx +140 -0
  16. package/IconButton/styles.ts +19 -0
  17. package/Image/index.tsx +80 -0
  18. package/Image/styles.ts +13 -0
  19. package/Image/types.ts +3 -0
  20. package/Input/Input.tsx +136 -0
  21. package/Input/InputMoney.tsx +132 -0
  22. package/Input/InputSearch.tsx +161 -0
  23. package/Input/InputTextArea.tsx +152 -0
  24. package/Input/common.tsx +118 -0
  25. package/Input/index.tsx +96 -0
  26. package/Input/styles.ts +122 -0
  27. package/Input/utils.ts +69 -0
  28. package/Layout/Card.tsx +141 -0
  29. package/Layout/GridSystem.tsx +124 -0
  30. package/Layout/Item.tsx +60 -0
  31. package/Layout/ScreenContainer.tsx +121 -0
  32. package/Layout/Section.tsx +141 -0
  33. package/Layout/index.ts +17 -0
  34. package/Layout/types.ts +59 -0
  35. package/Layout/utils.ts +60 -0
  36. package/Navigation/BottomTab.tsx +39 -0
  37. package/Navigation/Components.tsx +365 -0
  38. package/Navigation/ModalScreen.tsx +226 -0
  39. package/Navigation/Navigation.ts +44 -0
  40. package/Navigation/NavigationButton.tsx +54 -0
  41. package/Navigation/NavigationContainer.tsx +77 -0
  42. package/Navigation/Navigator.ts +82 -0
  43. package/Navigation/StackScreen.tsx +27 -0
  44. package/Navigation/index.ts +14 -0
  45. package/Navigation/types.ts +158 -0
  46. package/Navigation/utils.tsx +138 -0
  47. package/Pagination/Dot.tsx +16 -0
  48. package/Pagination/PaginationDot.tsx +33 -0
  49. package/Pagination/PaginationNumber.tsx +23 -0
  50. package/Pagination/PaginationScroll.tsx +88 -0
  51. package/Pagination/PaginationWhiteDot.tsx +32 -0
  52. package/Pagination/index.tsx +25 -0
  53. package/Pagination/styles.ts +47 -0
  54. package/Pagination/types.ts +38 -0
  55. package/Popup/PopupNotify.tsx +215 -0
  56. package/Popup/PopupPromotion.tsx +77 -0
  57. package/Popup/index.tsx +4 -0
  58. package/Popup/types.ts +70 -0
  59. package/Radio/index.tsx +65 -0
  60. package/Radio/styles.ts +11 -0
  61. package/Radio/types.ts +38 -0
  62. package/Skeleton/index.tsx +72 -0
  63. package/Skeleton/styles.ts +5 -0
  64. package/Skeleton/types.ts +3 -0
  65. package/Switch/index.tsx +40 -0
  66. package/Switch/styles.ts +23 -0
  67. package/Switch/types.ts +26 -0
  68. package/Tag/index.tsx +79 -0
  69. package/Tag/styles.ts +24 -0
  70. package/Tag/types.ts +36 -0
  71. package/Text/index.tsx +123 -0
  72. package/Text/styles.ts +35 -0
  73. package/Text/types.ts +40 -0
  74. package/index.ts +38 -0
  75. package/package.json +41 -0
  76. package/publish.sh +26 -0
@@ -0,0 +1,78 @@
1
+ import {StyleSheet} from 'react-native';
2
+
3
+ const Styles = StyleSheet.create({
4
+ flex: {
5
+ flex: 1,
6
+ },
7
+ flexCenter: {
8
+ flex: 1,
9
+ alignItems: 'center',
10
+ justifyContent: 'center',
11
+ },
12
+ row: {
13
+ flexDirection: 'row',
14
+ alignItems: 'center',
15
+ },
16
+ rowSpace: {
17
+ flexDirection: 'row',
18
+ alignItems: 'center',
19
+ justifyContent: 'space-between',
20
+ },
21
+ rowCenter: {
22
+ flexDirection: 'row',
23
+ alignItems: 'center',
24
+ justifyContent: 'center',
25
+ },
26
+ rowWrap: {
27
+ flexDirection: 'row',
28
+ flexWrap: 'wrap',
29
+ },
30
+ columnSpace: {
31
+ flexDirection: 'column',
32
+ alignItems: 'center',
33
+ justifyContent: 'space-between',
34
+ },
35
+ columnSpaceRight: {
36
+ flexDirection: 'column',
37
+ alignItems: 'flex-end',
38
+ justifyContent: 'space-between',
39
+ },
40
+ columnCenter: {
41
+ flexDirection: 'column',
42
+ alignItems: 'center',
43
+ justifyContent: 'center',
44
+ },
45
+ columnCenterRight: {
46
+ flexDirection: 'column',
47
+ alignItems: 'flex-end',
48
+ justifyContent: 'center',
49
+ },
50
+ //paddingHorizontal
51
+ paddingHorizontal4: {
52
+ paddingHorizontal: 4,
53
+ },
54
+ paddingHorizontal8: {
55
+ paddingHorizontal: 8,
56
+ },
57
+ paddingHorizontal16: {
58
+ paddingHorizontal: 16,
59
+ },
60
+ paddingHorizontal24: {
61
+ paddingHorizontal: 24,
62
+ },
63
+ //paddingVertical
64
+ paddingVertical4: {
65
+ paddingVertical: 4,
66
+ },
67
+ paddingVertical8: {
68
+ paddingVertical: 8,
69
+ },
70
+ paddingVertical16: {
71
+ paddingVertical: 16,
72
+ },
73
+ paddingVertical24: {
74
+ paddingVertical: 24,
75
+ },
76
+ });
77
+
78
+ export {Styles};
@@ -0,0 +1,121 @@
1
+ import {Context, Theme} from '../Navigation/types';
2
+ import {Colors} from './colors+spacing+radius';
3
+
4
+ const defaultTheme: Theme = {
5
+ dark: false,
6
+ colors: {
7
+ primary: Colors.pink_03,
8
+ secondary: Colors.pink_07,
9
+ background: {
10
+ default: '#f2f2f6',
11
+ surface: Colors.black_01,
12
+ tonal: Colors.pink_09,
13
+ pressed: '#dfdfe6',
14
+ selected: Colors.pink_10,
15
+ disable: '#ebebf2',
16
+ },
17
+ text: {
18
+ default: Colors.black_17,
19
+ secondary: Colors.black_15,
20
+ hint: Colors.black_12,
21
+ disable: Colors.black_08,
22
+ },
23
+ border: {
24
+ default: Colors.black_04,
25
+ disable: Colors.black_02,
26
+ },
27
+ success: {
28
+ primary: Colors.green_03,
29
+ secondary: Colors.green_07,
30
+ container: Colors.green_08,
31
+ },
32
+ warning: {
33
+ primary: Colors.orange_03,
34
+ secondary: Colors.orange_07,
35
+ container: Colors.orange_08,
36
+ },
37
+ error: {
38
+ primary: Colors.red_03,
39
+ secondary: Colors.red_07,
40
+ container: Colors.red_08,
41
+ },
42
+ highlight: {
43
+ primary: Colors.mint_03,
44
+ secondary: Colors.mint_07,
45
+ container: Colors.mint_08,
46
+ },
47
+ interactive: {
48
+ primary: Colors.blue_03,
49
+ secondary: Colors.blue_07,
50
+ container: Colors.blue_08,
51
+ },
52
+ },
53
+ font: 'SFProText',
54
+ assets: {
55
+ headerBackground:
56
+ 'https://static.momocdn.net/app/img/app/img/header-background.png',
57
+ },
58
+ };
59
+
60
+ const defaultDarkTheme: Theme = {
61
+ dark: true,
62
+ colors: {
63
+ primary: Colors.pink_04,
64
+ secondary: Colors.pink_08,
65
+ background: {
66
+ default: '#121212', // Dark background
67
+ surface: '#1e1e1e', // Slightly lighter surface background
68
+ tonal: Colors.pink_10,
69
+ pressed: '#1a1a1a', // Pressed state background
70
+ selected: Colors.pink_11,
71
+ disable: '#303030', // Disabled state background
72
+ },
73
+ text: {
74
+ default: '#ffffff', // White text for better contrast
75
+ secondary: '#b0b0b0', // Light gray secondary text
76
+ hint: '#727272', // Hint text color
77
+ disable: '#505050', // Disabled text color
78
+ },
79
+ border: {
80
+ default: '#2a2a2a', // Darker borders
81
+ disable: '#242424', // Disabled state border color
82
+ },
83
+ success: {
84
+ primary: Colors.green_03,
85
+ secondary: Colors.green_07,
86
+ container: Colors.green_08,
87
+ },
88
+ warning: {
89
+ primary: Colors.orange_03,
90
+ secondary: Colors.orange_07,
91
+ container: Colors.orange_08,
92
+ },
93
+ error: {
94
+ primary: Colors.red_03,
95
+ secondary: Colors.red_07,
96
+ container: Colors.red_08,
97
+ },
98
+ highlight: {
99
+ primary: Colors.mint_03,
100
+ secondary: Colors.mint_07,
101
+ container: Colors.mint_08,
102
+ },
103
+ interactive: {
104
+ primary: Colors.blue_03,
105
+ secondary: Colors.blue_07,
106
+ container: Colors.blue_08,
107
+ },
108
+ },
109
+ font: 'SFProText',
110
+ assets: {
111
+ headerBackground:
112
+ 'https://static.momocdn.net/app/img/app/img/header-background.png',
113
+ },
114
+ };
115
+
116
+ const defaultContext: Context = {
117
+ theme: defaultTheme,
118
+ navigator: undefined,
119
+ };
120
+
121
+ export {defaultContext, defaultTheme, defaultDarkTheme};
@@ -0,0 +1,19 @@
1
+ import React, {useContext} from 'react';
2
+ import {View} from 'react-native';
3
+ import {ApplicationContext} from '../Navigation';
4
+
5
+ const Divider = () => {
6
+ const {theme} = useContext(ApplicationContext);
7
+
8
+ return (
9
+ <View
10
+ style={{
11
+ height: 1,
12
+ width: '100%',
13
+ backgroundColor: theme.colors.border.default,
14
+ }}
15
+ />
16
+ );
17
+ };
18
+
19
+ export {Divider};
package/Icon/index.tsx ADDED
@@ -0,0 +1,37 @@
1
+ import React, {useContext} from 'react';
2
+ import IconSources from '../Assets/icon.json';
3
+ import {IconProps} from './types';
4
+ import {ApplicationContext} from '../Navigation';
5
+ import {Image} from '../Image';
6
+
7
+ const Icon: React.FC<IconProps> = ({source, size, color, style = {}}) => {
8
+ const {theme} = useContext(ApplicationContext);
9
+
10
+ /**
11
+ * get icon source maps or remote http
12
+ */
13
+ const getIconSource = (): any => {
14
+ if (source && !source.includes('http')) {
15
+ let icon: {[key: string]: {uri: string}} = IconSources;
16
+ return icon[source] ?? icon.ic_warning;
17
+ }
18
+ return {uri: source};
19
+ };
20
+
21
+ return (
22
+ <Image
23
+ accessibilityLabel={`Icon/${getIconSource()}`}
24
+ loading={false}
25
+ source={getIconSource()}
26
+ style={[style, {width: size, height: size}]}
27
+ tintColor={color ?? theme.colors.text.default}
28
+ />
29
+ );
30
+ };
31
+
32
+ Icon.defaultProps = {
33
+ source: 'ic_back',
34
+ size: 24,
35
+ };
36
+
37
+ export {Icon, IconSources};
package/Icon/types.ts ADDED
@@ -0,0 +1,27 @@
1
+ import {ViewStyle} from 'react-native';
2
+
3
+ export type IconProps = {
4
+ /**
5
+ * Represents the identifier or the path for the icon image source.
6
+ * It is a required property.
7
+ */
8
+ source: string;
9
+
10
+ /**
11
+ * Optional. Represents the size of the icon.
12
+ * It can be used to set the width and height of the icon.
13
+ */
14
+ size?: number;
15
+
16
+ /**
17
+ * Optional. Represents the color of the icon.
18
+ * It can be any valid color in @momo-kits/foundation.
19
+ */
20
+ color?: string;
21
+
22
+ /**
23
+ * Optional. Used to apply custom styling to the Icon component.
24
+ * Accepts an object of style properties.
25
+ */
26
+ style?: ViewStyle;
27
+ };
@@ -0,0 +1,140 @@
1
+ import React, {useContext} from 'react';
2
+ import {
3
+ GestureResponderEvent,
4
+ StyleSheet,
5
+ TouchableOpacity,
6
+ TouchableOpacityProps,
7
+ } from 'react-native';
8
+ import {ApplicationContext} from '../Navigation';
9
+ import {Colors} from '../Consts';
10
+ import {Icon} from '../Icon';
11
+ import styles from './styles';
12
+
13
+ export interface IconButtonProps extends TouchableOpacityProps {
14
+ /**
15
+ * Represents the name or key of the icon to be displayed on the IconButton.
16
+ * It is a required property.
17
+ */
18
+ icon: string;
19
+
20
+ /**
21
+ * Optional. Defines the visual style of the IconButton.
22
+ */
23
+ type?: 'primary' | 'tonal' | 'secondary' | 'danger' | 'outline' | 'disabled';
24
+
25
+ /**
26
+ * Optional. Defines the size of the IconButton.
27
+ */
28
+ size?: 'large' | 'small';
29
+ }
30
+
31
+ const IconButton: React.FC<IconButtonProps> = ({
32
+ type,
33
+ icon,
34
+ size,
35
+ onPress,
36
+ ...rest
37
+ }) => {
38
+ const {theme} = useContext(ApplicationContext);
39
+
40
+ /**
41
+ * get size icon button
42
+ */
43
+ const getSizeStyle = () => {
44
+ if (size === 'small') {
45
+ return styles.small;
46
+ }
47
+ return styles.large;
48
+ };
49
+
50
+ /**
51
+ * get style for icon button by type
52
+ */
53
+ const getTypeStyle = () => {
54
+ switch (type) {
55
+ case 'disabled':
56
+ return {
57
+ backgroundColor: theme.colors.background.disable,
58
+ };
59
+ case 'primary':
60
+ return {backgroundColor: theme.colors.primary};
61
+ case 'secondary':
62
+ return {
63
+ backgroundColor: theme.colors.background.surface,
64
+ borderWidth: 1,
65
+ borderColor: theme.colors.border.default,
66
+ };
67
+ case 'outline':
68
+ return {
69
+ backgroundColor: theme.colors.background.surface,
70
+ borderWidth: 1,
71
+ borderColor: theme.colors.primary,
72
+ };
73
+ case 'tonal':
74
+ return {
75
+ backgroundColor: theme.colors.background.tonal,
76
+ };
77
+ case 'danger':
78
+ return {
79
+ backgroundColor: theme.colors.error.primary,
80
+ };
81
+ default:
82
+ return {backgroundColor: theme.colors.primary};
83
+ }
84
+ };
85
+
86
+ /**
87
+ * get color for icon
88
+ */
89
+ const getIconColor = () => {
90
+ switch (type) {
91
+ case 'disabled':
92
+ return theme.colors.text.disable;
93
+ case 'primary':
94
+ return Colors.black_01;
95
+ case 'danger':
96
+ return Colors.black_01;
97
+ case 'tonal':
98
+ return theme.colors.primary;
99
+ case 'secondary':
100
+ return theme.colors.text.default;
101
+ case 'outline':
102
+ return theme.colors.primary;
103
+ default:
104
+ return Colors.black_01;
105
+ }
106
+ };
107
+
108
+ /**
109
+ * handle press
110
+ * @param e
111
+ */
112
+ const onPressButton = (e: GestureResponderEvent) => {
113
+ if (type === 'disabled') {
114
+ return () => {};
115
+ }
116
+ onPress?.(e);
117
+ };
118
+
119
+ const activeOpacity = type === 'disabled' ? 0.75 : 0.5;
120
+ const buttonStyle = StyleSheet.flatten([getTypeStyle(), getSizeStyle()]);
121
+ const iconSize = size === 'small' ? 16 : 24;
122
+
123
+ return (
124
+ <TouchableOpacity
125
+ {...rest}
126
+ accessibilityLabel={`IconButton/${icon}`}
127
+ activeOpacity={activeOpacity}
128
+ onPress={onPressButton}
129
+ style={buttonStyle}>
130
+ <Icon size={iconSize} source={icon} color={getIconColor()} />
131
+ </TouchableOpacity>
132
+ );
133
+ };
134
+
135
+ IconButton.defaultProps = {
136
+ type: 'primary',
137
+ disabled: false,
138
+ };
139
+
140
+ export {IconButton};
@@ -0,0 +1,19 @@
1
+ import {StyleSheet} from 'react-native';
2
+ import {Radius} from '../Consts';
3
+
4
+ export default StyleSheet.create({
5
+ large: {
6
+ width: 48,
7
+ height: 48,
8
+ borderRadius: Radius.XL,
9
+ justifyContent: 'center',
10
+ alignItems: 'center',
11
+ },
12
+ small: {
13
+ width: 40,
14
+ height: 40,
15
+ borderRadius: Radius.XL,
16
+ justifyContent: 'center',
17
+ alignItems: 'center',
18
+ },
19
+ });
@@ -0,0 +1,80 @@
1
+ import React, {useContext, useState} from 'react';
2
+ import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native';
3
+ import FastImage from 'react-native-fast-image';
4
+ import styles from './styles';
5
+ import {ApplicationContext} from '../Navigation';
6
+ import {Skeleton} from '../Skeleton';
7
+ import {Icon} from '../Icon';
8
+ import {Styles} from '../Consts';
9
+ import {FastImagePropsWithoutStyle} from './types';
10
+
11
+ export interface ImageProps extends FastImagePropsWithoutStyle {
12
+ style?: StyleProp<ViewStyle>;
13
+ loading?: boolean;
14
+ accessibilityLabel?: string;
15
+ }
16
+
17
+ const Image: React.FC<ImageProps> = ({
18
+ style,
19
+ source,
20
+ accessibilityLabel,
21
+ ...rest
22
+ }) => {
23
+ const {theme} = useContext(ApplicationContext);
24
+ const [loading, setLoading] = useState(rest.loading);
25
+ const [fail, setFail] = useState(false);
26
+
27
+ /**
28
+ * render content loading | fail | rendered
29
+ * @returns {JSX.Element}
30
+ */
31
+ const renderContent = () => {
32
+ if (loading || fail) {
33
+ let content = (
34
+ <Skeleton style={[StyleSheet.absoluteFill, styles.image]} />
35
+ );
36
+ if (fail) {
37
+ content = (
38
+ <View style={Styles.flexCenter}>
39
+ <Icon source="media_fail" color={theme.colors.text.disable} />
40
+ </View>
41
+ );
42
+ }
43
+ return (
44
+ <View
45
+ style={[
46
+ StyleSheet.absoluteFill,
47
+ styles.image,
48
+ {backgroundColor: theme.colors.background.disable},
49
+ ]}>
50
+ {content}
51
+ </View>
52
+ );
53
+ }
54
+ };
55
+
56
+ return (
57
+ <View
58
+ style={[styles.container, style]}
59
+ accessibilityLabel={`Image/${accessibilityLabel ?? source}`}>
60
+ <FastImage
61
+ {...rest}
62
+ source={source}
63
+ style={styles.image}
64
+ onLoad={() => {
65
+ setFail(false);
66
+ setLoading(rest.loading);
67
+ }}
68
+ onLoadEnd={() => setLoading(false)}
69
+ onError={() => setFail(true)}
70
+ />
71
+ {renderContent()}
72
+ </View>
73
+ );
74
+ };
75
+
76
+ Image.defaultProps = {
77
+ loading: true,
78
+ };
79
+
80
+ export {Image};
@@ -0,0 +1,13 @@
1
+ import {StyleSheet} from 'react-native';
2
+
3
+ export default StyleSheet.create({
4
+ container: {
5
+ overflow: 'hidden',
6
+ alignItems: 'center',
7
+ justifyContent: 'center',
8
+ },
9
+ image: {
10
+ width: '100%',
11
+ height: '100%',
12
+ },
13
+ });
package/Image/types.ts ADDED
@@ -0,0 +1,3 @@
1
+ import {FastImageProps} from 'react-native-fast-image';
2
+
3
+ export type FastImagePropsWithoutStyle = Omit<FastImageProps, 'style'>;
@@ -0,0 +1,136 @@
1
+ import React, {FC, useContext, useEffect, useRef, useState} from 'react';
2
+ import {
3
+ NativeSyntheticEvent,
4
+ TextInput,
5
+ TextInputFocusEventData,
6
+ TouchableOpacity,
7
+ View,
8
+ } from 'react-native';
9
+ import {ApplicationContext} from '../Navigation';
10
+ import styles from './styles';
11
+ import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
12
+ import {InputProps} from './index';
13
+ import {Icon} from '../Icon';
14
+ import {checkTyping} from './utils';
15
+
16
+ const Input: FC<InputProps> = ({
17
+ value,
18
+ onChangeText,
19
+ floatingValue,
20
+ floatingIcon,
21
+ size,
22
+ placeholder,
23
+ onBlur,
24
+ onFocus,
25
+ errorMessage,
26
+ icon,
27
+ disabled,
28
+ floatingIconColor,
29
+ iconColor,
30
+ required,
31
+ ...props
32
+ }) => {
33
+ const {theme} = useContext(ApplicationContext);
34
+ const [focused, setFocused] = useState(false);
35
+ const [haveValue, setHaveValue] = useState(!!value || !!props.defaultValue);
36
+
37
+ const inputRef = useRef<any>(null);
38
+
39
+ const onClearText = () => {
40
+ inputRef?.current?.clear();
41
+ _onChangeText('');
42
+ };
43
+
44
+ const _onChangeText = (text: string) => {
45
+ checkTyping(text, haveValue, setHaveValue);
46
+ onChangeText?.(text);
47
+ };
48
+
49
+ const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
50
+ setFocused(true);
51
+ onFocus?.(e);
52
+ };
53
+
54
+ const _onBlur = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
55
+ setFocused(false);
56
+ onBlur?.(e);
57
+ };
58
+
59
+ const renderInputView = () => {
60
+ const disabledColor = theme.colors.text.disable;
61
+ let textColor = theme.colors.text.default;
62
+ let placeholderColor = theme.colors.text.hint;
63
+ let iconTintColor = iconColor;
64
+
65
+ if (disabled) {
66
+ textColor = disabledColor;
67
+ placeholderColor = disabledColor;
68
+ iconTintColor = disabledColor;
69
+ }
70
+
71
+ return (
72
+ <View
73
+ style={[
74
+ getSizeStyle(size),
75
+ getBorderColor(focused, errorMessage, disabled),
76
+ styles.inputWrapper,
77
+ {backgroundColor: theme.colors.background.surface},
78
+ ]}>
79
+ <FloatingView
80
+ floatingValue={floatingValue}
81
+ floatingIconColor={floatingIconColor}
82
+ disabled={disabled}
83
+ required={required}
84
+ floatingIcon={floatingIcon}
85
+ />
86
+ <View style={styles.inputView}>
87
+ <TextInput
88
+ {...props}
89
+ editable={!disabled}
90
+ textAlignVertical="top"
91
+ ref={inputRef}
92
+ style={[
93
+ styles.input,
94
+ {
95
+ color: textColor,
96
+ },
97
+ ]}
98
+ textBreakStrategy="highQuality"
99
+ value={value}
100
+ onChangeText={_onChangeText}
101
+ onFocus={_onFocus}
102
+ onBlur={_onBlur}
103
+ placeholder={placeholder}
104
+ selectionColor={theme.colors.primary}
105
+ placeholderTextColor={placeholderColor}
106
+ />
107
+ </View>
108
+ <View style={styles.iconView}>
109
+ {focused && haveValue && (
110
+ <TouchableOpacity style={styles.iconWrapper} onPress={onClearText}>
111
+ <Icon
112
+ source="24_navigation_close_circle_full"
113
+ size={16}
114
+ color={theme.colors.text.hint}
115
+ />
116
+ </TouchableOpacity>
117
+ )}
118
+ {!!icon && <Icon color={iconTintColor} source={icon} size={24} />}
119
+ </View>
120
+ </View>
121
+ );
122
+ };
123
+
124
+ return (
125
+ <View style={styles.wrapper} accessibilityLabel={`Input`}>
126
+ {renderInputView()}
127
+ <ErrorView errorMessage={errorMessage} />
128
+ </View>
129
+ );
130
+ };
131
+
132
+ Input.defaultProps = {
133
+ size: 'small',
134
+ };
135
+
136
+ export default Input;