@momo-kits/foundation 1.0.9 → 1.0.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.
package/Input/Input.tsx CHANGED
@@ -27,6 +27,7 @@ const Input: FC<InputProps> = ({
27
27
  disabled,
28
28
  floatingIconColor,
29
29
  iconColor,
30
+ required,
30
31
  ...props
31
32
  }) => {
32
33
  const {theme} = useContext(ApplicationContext);
@@ -81,6 +82,7 @@ const Input: FC<InputProps> = ({
81
82
  floatingValue={floatingValue}
82
83
  floatingIconColor={floatingIconColor}
83
84
  disabled={disabled}
85
+ required={required}
84
86
  floatingIcon={floatingIcon}
85
87
  />
86
88
  <View style={styles.inputView}>
@@ -95,6 +97,7 @@ const Input: FC<InputProps> = ({
95
97
  color: textColor,
96
98
  },
97
99
  ]}
100
+ textBreakStrategy="highQuality"
98
101
  value={value}
99
102
  onChangeText={_onChangeText}
100
103
  onFocus={_onFocus}
@@ -0,0 +1,151 @@
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 {ApplicationContext} from '../Navigation';
10
+ import styles from './styles';
11
+ import {Image} from '../Image';
12
+ import {ErrorView, FloatingView, getBorderColor} from './common';
13
+ import {MoneyInputProps} from './index';
14
+ import {Icon} from '../Icon';
15
+
16
+ const MoneyInput: FC<MoneyInputProps> = ({
17
+ onChangeText,
18
+ floatingValue,
19
+ floatingIcon,
20
+ size,
21
+ onBlur,
22
+ onFocus,
23
+ errorMessage,
24
+ icon,
25
+ disabled,
26
+ floatingIconColor,
27
+ iconColor,
28
+ required,
29
+ ...props
30
+ }) => {
31
+ const {theme} = useContext(ApplicationContext);
32
+ const [focused, setFocused] = useState(false);
33
+ const [value, setValue] = useState('');
34
+ const inputRef = useRef<any>(null);
35
+
36
+ const onClearText = () => {
37
+ inputRef?.current?.clear();
38
+ };
39
+
40
+ const formatNumberWithDots = (num: string) => {
41
+ return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.');
42
+ };
43
+ const _onChangeText = (text: string) => {
44
+ let numericValue = text.replace(/[^0-9]/g, '');
45
+ if (numericValue === '') numericValue = '0';
46
+ const formattedNumber = formatNumberWithDots(numericValue);
47
+ const formattedValue = `${formattedNumber}đ`;
48
+ onChangeText?.(formattedValue);
49
+ setValue(formattedValue);
50
+ };
51
+ const getSizeStyle = () => {
52
+ if (size === 'small') {
53
+ return styles.smallContainer;
54
+ }
55
+ return styles.container;
56
+ };
57
+
58
+ const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
59
+ setFocused(true);
60
+ onFocus?.(e);
61
+ };
62
+
63
+ const _onBlur = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
64
+ setFocused(false);
65
+ onBlur?.(e);
66
+ };
67
+
68
+ const renderInputView = () => {
69
+ const disabledColor = theme.colors.text.disable;
70
+ let textColor = theme.colors.text.default;
71
+ let placeholderColor = theme.colors.text.hint;
72
+ let iconTintColor = iconColor;
73
+
74
+ if (disabled) {
75
+ textColor = disabledColor;
76
+ placeholderColor = disabledColor;
77
+ iconTintColor = disabledColor;
78
+ }
79
+
80
+ return (
81
+ <View
82
+ style={[
83
+ getSizeStyle(),
84
+ getBorderColor(focused, errorMessage, disabled),
85
+ styles.inputWrapper,
86
+ {backgroundColor: theme.colors.background.surface},
87
+ ]}>
88
+ <FloatingView
89
+ floatingValue={floatingValue}
90
+ floatingIconColor={floatingIconColor}
91
+ disabled={disabled}
92
+ required={required}
93
+ floatingIcon={floatingIcon}
94
+ />
95
+ <View style={styles.inputView}>
96
+ <TextInput
97
+ {...props}
98
+ editable={!disabled}
99
+ textAlignVertical="top"
100
+ ref={inputRef}
101
+ keyboardType={'number-pad'}
102
+ style={[
103
+ styles.moneyInput,
104
+ {
105
+ color: textColor,
106
+ },
107
+ ]}
108
+ value={value}
109
+ onChangeText={_onChangeText}
110
+ onFocus={_onFocus}
111
+ onBlur={_onBlur}
112
+ selectionColor={theme.colors.primary}
113
+ placeholderTextColor={placeholderColor}
114
+ placeholder={'0đ'}
115
+ />
116
+ </View>
117
+ <View style={styles.iconView}>
118
+ {focused && (
119
+ <TouchableOpacity style={styles.iconWrapper} onPress={onClearText}>
120
+ <Icon
121
+ source="24_navigation_close_circle_full"
122
+ size={16}
123
+ color={theme.colors.text.hint}
124
+ />
125
+ </TouchableOpacity>
126
+ )}
127
+ {icon && (
128
+ <Image
129
+ tintColor={iconTintColor}
130
+ source={{uri: icon}}
131
+ style={styles.icon}
132
+ />
133
+ )}
134
+ </View>
135
+ </View>
136
+ );
137
+ };
138
+
139
+ return (
140
+ <View style={styles.wrapper}>
141
+ {renderInputView()}
142
+ <ErrorView errorMessage={errorMessage} />
143
+ </View>
144
+ );
145
+ };
146
+
147
+ MoneyInput.defaultProps = {
148
+ size: 'small',
149
+ };
150
+
151
+ export default MoneyInput;
@@ -35,6 +35,7 @@ const TextArea: FC<TextAreaProps> = props => {
35
35
  height,
36
36
  placeholder,
37
37
  maxLength,
38
+ required,
38
39
  } = props;
39
40
 
40
41
  const [focused, setFocused] = useState(false);
@@ -83,7 +84,7 @@ const TextArea: FC<TextAreaProps> = props => {
83
84
  <View
84
85
  style={[
85
86
  getBorderColor(focused, errorMessage, disabled),
86
- styles.textAreaWrapper,
87
+ styles.textAreaWradpper,
87
88
  {
88
89
  height: height || DEFAULT_HEIGHT,
89
90
  backgroundColor: theme.colors.background.surface,
@@ -94,6 +95,7 @@ const TextArea: FC<TextAreaProps> = props => {
94
95
  floatingIconColor={floatingIconColor}
95
96
  disabled={disabled}
96
97
  floatingIcon={floatingIcon}
98
+ required={required}
97
99
  />
98
100
  <View style={styles.rowArea}>
99
101
  <View style={styles.textAreaView}>
@@ -108,6 +110,7 @@ const TextArea: FC<TextAreaProps> = props => {
108
110
  },
109
111
  ]}
110
112
  maxLength={maxLength}
113
+ textBreakStrategy="highQuality"
111
114
  multiline={true}
112
115
  value={value}
113
116
  onChangeText={_onChangeText}
package/Input/common.tsx CHANGED
@@ -11,6 +11,7 @@ type FloatingViewProps = {
11
11
  floatingIconColor?: string;
12
12
  disabled?: boolean;
13
13
  floatingIcon?: string;
14
+ required?: boolean;
14
15
  };
15
16
 
16
17
  export const DEFAULT_HEIGHT = 112;
@@ -63,6 +64,7 @@ export const FloatingView: FC<FloatingViewProps> = ({
63
64
  floatingIconColor,
64
65
  disabled,
65
66
  floatingIcon,
67
+ required,
66
68
  }) => {
67
69
  const {theme} = useContext(ApplicationContext);
68
70
 
@@ -85,6 +87,11 @@ export const FloatingView: FC<FloatingViewProps> = ({
85
87
  ]}>
86
88
  <Text color={floatingTextColor} typography={'label_s'}>
87
89
  {floatingValue}
90
+ {required && (
91
+ <Text typography={'label_s'} color={theme.colors.error.primary}>
92
+ *
93
+ </Text>
94
+ )}
88
95
  </Text>
89
96
  {floatingIcon && (
90
97
  <Image
package/Input/index.tsx CHANGED
@@ -1,6 +1,7 @@
1
1
  import Input from './Input';
2
2
  import TextArea from './TextArea';
3
3
  import SearchInput from './SearchInput';
4
+ import MoneyInput from './MoneyInput';
4
5
  import {TextInputProps} from 'react-native';
5
6
 
6
7
  export interface InputProps extends TextInputProps {
@@ -12,20 +13,26 @@ export interface InputProps extends TextInputProps {
12
13
  disabled?: boolean;
13
14
  floatingIconColor?: string;
14
15
  iconColor?: string;
16
+ required?: boolean;
15
17
  }
16
18
 
17
- type InputPropsWithoutSize = Omit<InputProps, 'size'>;
19
+ type InputPropsWithoutSizeAndIcon = Omit<
20
+ InputProps,
21
+ 'size' | 'icon' | 'iconColor'
22
+ >;
23
+ type InputPropsWithoutRequiredAndSize = Omit<InputProps, 'required' | 'size'>;
24
+ type InputPropsWithoutPlaceholder = Omit<InputProps, 'placeholder'>;
18
25
 
19
- export interface TextAreaProps extends TextInputProps, InputPropsWithoutSize {
26
+ export interface TextAreaProps extends InputPropsWithoutSizeAndIcon {
20
27
  height?: number;
21
28
  }
22
29
 
23
- export interface SearchInputProps
24
- extends TextInputProps,
25
- InputPropsWithoutSize {
30
+ export interface SearchInputProps extends InputPropsWithoutRequiredAndSize {
26
31
  buttonText?: string;
27
32
  showButtonText?: boolean;
28
33
  showIcon?: boolean;
29
34
  }
30
35
 
31
- export {Input, TextArea, SearchInput};
36
+ export interface MoneyInputProps extends InputPropsWithoutPlaceholder {}
37
+
38
+ export {Input, TextArea, SearchInput, MoneyInput};
package/Input/styles.ts CHANGED
@@ -10,14 +10,12 @@ export default StyleSheet.create({
10
10
  container: {
11
11
  borderWidth: 1,
12
12
  borderRadius: Radius.S,
13
- marginBottom: Spacing.XS,
14
13
  height: 56,
15
14
  paddingVertical: 8,
16
15
  },
17
16
  smallContainer: {
18
17
  borderRadius: Radius.S,
19
18
  borderWidth: 1,
20
- marginBottom: Spacing.XS,
21
19
  height: 48,
22
20
  },
23
21
  floatingView: {
@@ -32,6 +30,7 @@ export default StyleSheet.create({
32
30
  errorView: {
33
31
  flexDirection: 'row',
34
32
  alignItems: 'center',
33
+ marginTop: Spacing.XS,
35
34
  },
36
35
  inputView: {
37
36
  justifyContent: 'space-between',
@@ -115,4 +114,11 @@ export default StyleSheet.create({
115
114
  width: 1,
116
115
  marginLeft: Spacing.XS,
117
116
  },
117
+ moneyInput: {
118
+ width: '100%',
119
+ paddingLeft: Spacing.M,
120
+ height: '100%',
121
+ fontSize: 20,
122
+ fontWeight: 'bold',
123
+ },
118
124
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "1.0.9",
3
+ "version": "1.0.10",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {