@widergy/mobile-ui 1.14.6 → 1.15.1
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/CHANGELOG.md +14 -0
- package/lib/components/Button/index.js +1 -1
- package/lib/components/UTBadge/index.js +2 -2
- package/lib/components/UTBadge/theme.js +9 -6
- package/lib/components/UTBaseInputField/README.md +45 -31
- package/lib/components/UTBaseInputField/components/ActionAdornment/index.js +5 -16
- package/lib/components/UTBaseInputField/components/BadgeAdornment/index.js +13 -0
- package/lib/components/UTBaseInputField/components/IconAdornment/constants.js +2 -0
- package/lib/components/UTBaseInputField/components/IconAdornment/index.js +20 -15
- package/lib/components/UTBaseInputField/components/IconAdornment/proptypes.js +20 -0
- package/lib/components/UTBaseInputField/components/IconAdornment/utils.js +7 -2
- package/lib/components/UTBaseInputField/constants.js +18 -3
- package/lib/components/UTBaseInputField/index.js +89 -88
- package/lib/components/UTBaseInputField/proptypes.js +60 -0
- package/lib/components/UTBaseInputField/theme.js +72 -32
- package/lib/components/UTBottomSheet/README.md +53 -0
- package/lib/components/UTBottomSheet/index.js +139 -0
- package/lib/components/UTBottomSheet/styles.js +46 -0
- package/lib/components/UTButton/constants.js +5 -14
- package/lib/components/UTButton/index.js +6 -22
- package/lib/components/UTButton/proptypes.js +29 -0
- package/lib/components/UTButton/theme.js +6 -5
- package/lib/components/UTCheckBox/README.md +4 -30
- package/lib/components/UTCheckBox/constants.js +4 -1
- package/lib/components/UTCheckBox/index.js +33 -22
- package/lib/components/UTCheckBox/proptypes.js +12 -3
- package/lib/components/UTCheckBox/styles.js +7 -0
- package/lib/components/UTCheckBox/theme.js +98 -54
- package/lib/components/UTCheckList/README.MD +14 -10
- package/lib/components/UTCheckList/constants.js +6 -1
- package/lib/components/UTCheckList/index.js +44 -66
- package/lib/components/UTCheckList/proptypes.js +48 -0
- package/lib/components/UTCheckList/styles.js +10 -5
- package/lib/components/UTCheckList/utils.js +5 -0
- package/lib/components/UTFieldLabel/index.js +4 -3
- package/lib/components/UTLabel/constants.js +11 -11
- package/lib/components/UTLabel/index.js +3 -17
- package/lib/components/UTLabel/proptypes.js +19 -0
- package/lib/components/UTLabel/theme.js +2 -2
- package/lib/components/UTMenu/index.js +1 -1
- package/lib/components/UTPasswordField/versions/V0/components/PasswordValidations/styles.js +1 -0
- package/lib/components/UTPasswordField/versions/V1/index.js +3 -2
- package/lib/components/UTPhoneInput/constants.js +303 -0
- package/lib/components/UTPhoneInput/index.js +296 -0
- package/lib/components/UTPhoneInput/styles.js +18 -0
- package/lib/components/UTSearchField/README.md +42 -0
- package/lib/components/UTSearchField/index.js +59 -0
- package/lib/components/UTSearchField/proptypes.js +28 -0
- package/lib/components/UTSelect/index.js +10 -97
- package/lib/components/UTSelect/{componentes → versions/V0/componentes}/MultipleItem/index.js +1 -1
- package/lib/components/UTSelect/versions/V0/index.js +103 -0
- package/lib/components/UTSelect/versions/V1/README.md +82 -0
- package/lib/components/UTSelect/versions/V1/index.js +171 -0
- package/lib/components/UTSelect/versions/V1/proptypes.js +45 -0
- package/lib/components/UTSelect/versions/V1/styles.js +18 -0
- package/lib/components/UTTextArea/index.js +4 -2
- package/lib/components/UTTextInput/versions/V0/components/BaseInput/index.js +3 -3
- package/lib/components/UTTextInput/versions/V1/README.md +36 -35
- package/lib/components/UTTextInput/versions/V1/components/TextInputField/index.js +24 -15
- package/lib/components/UTTextInput/versions/V1/constants.js +3 -5
- package/lib/components/UTTextInput/versions/V1/index.js +25 -20
- package/lib/components/UTTextInput/versions/V1/proptypes.js +25 -7
- package/lib/constants/inputs.js +4 -0
- package/lib/index.js +47 -51
- package/package.json +2 -2
- /package/lib/components/UTSelect/{componentes → versions/V0/componentes}/MultipleItem/styles.js +0 -0
- /package/lib/components/UTSelect/{proptypes.js → versions/V0/proptypes.js} +0 -0
- /package/lib/components/UTSelect/{styles.js → versions/V0/styles.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [1.15.1](https://github.com/widergy/mobile-ui/compare/v1.15.0...v1.15.1) (2024-07-31)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* implement select with bottom sheet ([#321](https://github.com/widergy/mobile-ui/issues/321)) ([f50e3de](https://github.com/widergy/mobile-ui/commit/f50e3de1e0310e5dbb453afdb05e792d5e8d5a15))
|
|
7
|
+
|
|
8
|
+
# [1.15.0](https://github.com/widergy/mobile-ui/compare/v1.14.6...v1.15.0) (2024-07-31)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* new phone input component ([#325](https://github.com/widergy/mobile-ui/issues/325)) ([6c6d20d](https://github.com/widergy/mobile-ui/commit/6c6d20d8395e4d30a1917a5309c325c62a89e79c))
|
|
14
|
+
|
|
1
15
|
## [1.14.6](https://github.com/widergy/mobile-ui/compare/v1.14.5...v1.14.6) (2024-07-26)
|
|
2
16
|
|
|
3
17
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { string } from 'prop-types';
|
|
2
|
+
import { number, oneOfType, string } from 'prop-types';
|
|
3
3
|
import { View } from 'react-native';
|
|
4
4
|
import { ViewPropTypes } from 'deprecated-react-native-prop-types';
|
|
5
5
|
|
|
@@ -29,7 +29,7 @@ const UTBadge = ({ children, colorTheme, style }) => {
|
|
|
29
29
|
UTBadge.defaultProps = DEFAULT_PROPS;
|
|
30
30
|
|
|
31
31
|
UTBadge.propTypes = {
|
|
32
|
-
children: string,
|
|
32
|
+
children: oneOfType([string, number]),
|
|
33
33
|
colorTheme: string,
|
|
34
34
|
style: ViewPropTypes.style
|
|
35
35
|
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
|
|
1
3
|
import { COLORS_MAPPER, DEFAULT_PROPS } from './constants';
|
|
2
4
|
|
|
3
5
|
export const variantsColorTheme = (theme, colorTheme) => {
|
|
@@ -19,26 +21,27 @@ export const variantsColorTheme = (theme, colorTheme) => {
|
|
|
19
21
|
};
|
|
20
22
|
};
|
|
21
23
|
|
|
22
|
-
const baseButtonTheme = (
|
|
24
|
+
const baseButtonTheme = StyleSheet.create({
|
|
23
25
|
noChildren: {
|
|
24
26
|
height: 10,
|
|
25
27
|
width: 10
|
|
26
28
|
},
|
|
27
29
|
root: {
|
|
28
30
|
alignItems: 'center',
|
|
29
|
-
borderRadius:
|
|
31
|
+
borderRadius: 10,
|
|
30
32
|
justifyContent: 'center',
|
|
31
|
-
|
|
33
|
+
overflow: 'hidden'
|
|
32
34
|
},
|
|
33
35
|
text: {
|
|
34
|
-
alignSelf: 'flex-start',
|
|
35
36
|
height: 20,
|
|
36
|
-
|
|
37
|
+
minWidth: 20,
|
|
38
|
+
paddingHorizontal: 6,
|
|
39
|
+
textAlign: 'center'
|
|
37
40
|
}
|
|
38
41
|
});
|
|
39
42
|
|
|
40
43
|
export const retrieveStyle = ({ theme, colorTheme, children }) => {
|
|
41
|
-
const baseTheme = baseButtonTheme
|
|
44
|
+
const baseTheme = baseButtonTheme;
|
|
42
45
|
const textTheme = children ? baseTheme.text : baseTheme.noChildren;
|
|
43
46
|
const variantTheme = variantsColorTheme(theme, colorTheme);
|
|
44
47
|
|
|
@@ -1,31 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
|
10
|
-
|
|
|
11
|
-
|
|
|
12
|
-
|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
|
|
|
23
|
-
| readOnly | bool | | Whether the input field is read-only. |
|
|
24
|
-
| returnKeyType | string | | Type of return key to display on the keyboard. |
|
|
25
|
-
| rightAdornments | array | | Elements to display on the right side of the input field. |
|
|
26
|
-
| style | object | | Custom styles to apply to the component. |
|
|
27
|
-
| type | string | | Type of the input field (e.g., email, numeric, password). |
|
|
28
|
-
| value | string | | Value of the input field. |
|
|
1
|
+
| Name | Type | Default | Description |
|
|
2
|
+
| --------------------- | -------------------------------------------------------------- | --------------------------------- | --------------------------------------------------------- |
|
|
3
|
+
| alwaysShowPlaceholder | bool | false | Whether to always show the placeholder text. |
|
|
4
|
+
| disabled | bool | | Whether the input field is disabled. |
|
|
5
|
+
| error | string | | Error message to display. |
|
|
6
|
+
| id | oneOfType([number, string]) | | Unique identifier for the input field. |
|
|
7
|
+
| input | shape({ value: string.isRequired, onChange: func.isRequired }) | { value: '', onChange: () => {} } | Input object containing the value and onChange handler. |
|
|
8
|
+
| inputSize | string | 'large' | Size of the input field. One of: `small`, `large`. |
|
|
9
|
+
| leftAdornments | arrayOf(shape({ name: string, props: object })) | | Elements to display on the left side of the input field. |
|
|
10
|
+
| maxCount | number | | Maximum number of characters allowed. |
|
|
11
|
+
| maxRows | number | | Maximum number of rows for multiline input. |
|
|
12
|
+
| onBlur | func | | Callback function to handle blur event. |
|
|
13
|
+
| onFocus | func | | Callback function to handle focus event. |
|
|
14
|
+
| onSubmitEditing | func | | Callback function to handle submit editing event. |
|
|
15
|
+
| placeholder | string | | Placeholder text for the input field. |
|
|
16
|
+
| readOnly | bool | | Whether the input field is read-only. |
|
|
17
|
+
| returnKeyType | string | | Type of return key to display on the keyboard. |
|
|
18
|
+
| rightAdornments | arrayOf(shape({ name: string, props: object })) | | Elements to display on the right side of the input field. |
|
|
19
|
+
| style | shape({ container: object, input: object, root: object }) | {} | Custom styles to apply to the component. |
|
|
20
|
+
| type | string | | Type of the input field (e.g., email, numeric, password). |
|
|
21
|
+
| variant | string | 'white' | Variant of the input field. One of: `white`, `gray`. |
|
|
22
|
+
| editable | bool | true | Whether the input field is editable. |
|
|
29
23
|
|
|
30
24
|
## Input Types
|
|
31
25
|
|
|
@@ -101,18 +95,38 @@ Displays a suffix text after the input field.
|
|
|
101
95
|
|
|
102
96
|
#### IconAdornment
|
|
103
97
|
|
|
104
|
-
Displays an icon, with
|
|
98
|
+
Displays an icon, with optional changes on focus and error.
|
|
105
99
|
|
|
106
100
|
- **Props passed to IconAdornment:**
|
|
107
101
|
- `Icon` (elementType): The icon to display.
|
|
102
|
+
- `changeOnError` (bool): Whether to change the icon on error (default is false).
|
|
103
|
+
- `changeOnFocus` (bool): Whether to change the icon on focus (default is false).
|
|
104
|
+
- `colorTheme` (string): The color theme of the icon.
|
|
108
105
|
- `error` (string): The error message (received from UTBaseInputField if an error occurs).
|
|
106
|
+
- `focused` (bool): Whether the input field is focused (received from UTBaseInputField).
|
|
109
107
|
- `inputStyle` (object): The style of the input field (received from UTBaseInputField).
|
|
110
|
-
- `
|
|
108
|
+
- `shade` (string): The shade of the icon.
|
|
109
|
+
|
|
110
|
+
**Example Usage:**
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
<UTBaseInputField
|
|
114
|
+
rightAdornments={[{ name: 'Icon', props: { Icon: 'search', changeOnError: true, changeOnFocus: true } }]}
|
|
115
|
+
/>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### BadgeAdornment
|
|
119
|
+
|
|
120
|
+
Displays a badge with text.
|
|
121
|
+
|
|
122
|
+
- **Props passed to BadgeAdornment:**
|
|
123
|
+
- `text` (string): The text to display inside the badge.
|
|
124
|
+
- `colorTheme` (string): The color theme of the badge.
|
|
111
125
|
|
|
112
126
|
**Example Usage:**
|
|
113
127
|
|
|
114
128
|
```javascript
|
|
115
|
-
<UTBaseInputField rightAdornments={[{ name: '
|
|
129
|
+
<UTBaseInputField rightAdornments={[{ name: 'Badge', props: { text: 'New', colorTheme: 'red' } }]} />
|
|
116
130
|
```
|
|
117
131
|
|
|
118
132
|
#### ActionAdornment
|
|
@@ -1,34 +1,23 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { bool, shape } from 'prop-types';
|
|
3
3
|
import { ViewPropTypes } from 'deprecated-react-native-prop-types';
|
|
4
4
|
|
|
5
5
|
import UTButton from '../../../UTButton';
|
|
6
|
+
import { propTypes as utbuttonProptypes } from '../../../UTButton/proptypes';
|
|
6
7
|
|
|
7
8
|
const ActionAdornment = ({ action, disabled, actionStyle }) => {
|
|
8
9
|
if (!action) return null;
|
|
9
10
|
|
|
10
11
|
return (
|
|
11
|
-
<UTButton
|
|
12
|
-
colorTheme={action.colorTheme}
|
|
13
|
-
disabled={disabled}
|
|
14
|
-
Icon={action.icon}
|
|
15
|
-
onPress={action.onPress}
|
|
16
|
-
style={actionStyle}
|
|
17
|
-
variant="text"
|
|
18
|
-
>
|
|
12
|
+
<UTButton disabled={disabled} style={actionStyle} variant="text" {...action}>
|
|
19
13
|
{action.text}
|
|
20
14
|
</UTButton>
|
|
21
15
|
);
|
|
22
16
|
};
|
|
23
17
|
|
|
24
18
|
ActionAdornment.propTypes = {
|
|
25
|
-
action: shape(
|
|
26
|
-
|
|
27
|
-
icon: func,
|
|
28
|
-
onPress: func,
|
|
29
|
-
text: string
|
|
30
|
-
}),
|
|
31
|
-
actionStyle: ViewPropTypes.style,
|
|
19
|
+
action: shape(utbuttonProptypes),
|
|
20
|
+
actionStyle: shape({ object: ViewPropTypes.style }),
|
|
32
21
|
disabled: bool
|
|
33
22
|
};
|
|
34
23
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { number, oneOfType, string } from 'prop-types';
|
|
3
|
+
|
|
4
|
+
import UTBadge from '../../../UTBadge';
|
|
5
|
+
|
|
6
|
+
const BadgeAdornment = ({ text, colorTheme }) => <UTBadge colorTheme={colorTheme}>{text}</UTBadge>;
|
|
7
|
+
|
|
8
|
+
BadgeAdornment.propTypes = {
|
|
9
|
+
colorTheme: string,
|
|
10
|
+
text: oneOfType([string, number])
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default BadgeAdornment;
|
|
@@ -1,32 +1,37 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { shape, string, elementType, bool } from 'prop-types';
|
|
3
|
-
import { TextPropTypes } from 'deprecated-react-native-prop-types';
|
|
4
2
|
|
|
5
3
|
import { isUTIcon } from '../../../UTIcon/utils';
|
|
6
4
|
import UTIcon from '../../../UTIcon';
|
|
7
5
|
|
|
8
|
-
import { ERROR_ICON } from './constants';
|
|
6
|
+
import { ERROR_ICON, ICON_SIZE } from './constants';
|
|
9
7
|
import { getIconColorProps } from './utils';
|
|
8
|
+
import { defaultProps, propTypes } from './proptypes';
|
|
10
9
|
|
|
11
|
-
const IconAdornment = ({
|
|
10
|
+
const IconAdornment = ({
|
|
11
|
+
changeOnError,
|
|
12
|
+
changeOnFocus,
|
|
13
|
+
colorTheme,
|
|
14
|
+
error,
|
|
15
|
+
focused,
|
|
16
|
+
Icon,
|
|
17
|
+
inputStyle,
|
|
18
|
+
shade
|
|
19
|
+
}) => {
|
|
12
20
|
const IconToRender = error && changeOnError ? ERROR_ICON : Icon;
|
|
13
|
-
|
|
14
21
|
if (!IconToRender) return null;
|
|
15
22
|
|
|
16
23
|
return isUTIcon(IconToRender) ? (
|
|
17
|
-
<UTIcon
|
|
24
|
+
<UTIcon
|
|
25
|
+
name={IconToRender}
|
|
26
|
+
size={ICON_SIZE}
|
|
27
|
+
{...getIconColorProps(changeOnError, changeOnFocus, colorTheme, error, focused, shade)}
|
|
28
|
+
/>
|
|
18
29
|
) : (
|
|
19
|
-
<
|
|
30
|
+
<Icon size={ICON_SIZE} fill={inputStyle.root.color} />
|
|
20
31
|
);
|
|
21
32
|
};
|
|
22
33
|
|
|
23
|
-
IconAdornment.propTypes =
|
|
24
|
-
|
|
25
|
-
Icon: elementType,
|
|
26
|
-
inputStyle: shape({
|
|
27
|
-
root: TextPropTypes.style
|
|
28
|
-
}),
|
|
29
|
-
changeOnError: bool
|
|
30
|
-
};
|
|
34
|
+
IconAdornment.propTypes = propTypes;
|
|
35
|
+
IconAdornment.defaultProps = defaultProps;
|
|
31
36
|
|
|
32
37
|
export default IconAdornment;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { shape, string, elementType, bool, oneOfType } from 'prop-types';
|
|
2
|
+
import { TextPropTypes } from 'deprecated-react-native-prop-types';
|
|
3
|
+
|
|
4
|
+
export const propTypes = {
|
|
5
|
+
changeOnError: bool,
|
|
6
|
+
changeOnFocus: bool,
|
|
7
|
+
colorTheme: string,
|
|
8
|
+
error: oneOfType([bool, string]),
|
|
9
|
+
focused: bool,
|
|
10
|
+
Icon: elementType,
|
|
11
|
+
inputStyle: shape({
|
|
12
|
+
root: TextPropTypes.style
|
|
13
|
+
}),
|
|
14
|
+
shade: string
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const defaultProps = {
|
|
18
|
+
changeOnError: false,
|
|
19
|
+
changeOnFocus: false
|
|
20
|
+
};
|
|
@@ -1,2 +1,7 @@
|
|
|
1
|
-
export const getIconColorProps = (error,
|
|
2
|
-
changeOnError && error
|
|
1
|
+
export const getIconColorProps = (changeOnError, changeOnFocus, colorTheme, error, focused, shade) => {
|
|
2
|
+
return changeOnError && error
|
|
3
|
+
? { colorTheme: 'error', shade: '04' }
|
|
4
|
+
: changeOnFocus && focused
|
|
5
|
+
? { colorTheme: 'accent', shade: '04' }
|
|
6
|
+
: { colorTheme: colorTheme || 'gray', shade };
|
|
7
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import ActionAdornment from './components/ActionAdornment';
|
|
2
|
+
import BadgeAdornment from './components/BadgeAdornment';
|
|
2
3
|
import IconAdornment from './components/IconAdornment';
|
|
3
4
|
import PrefixAdornment from './components/PrefixAdornment';
|
|
4
5
|
import SuffixAdornment from './components/SuffixAdornment';
|
|
@@ -6,27 +7,41 @@ import TooltipAdornment from './components/TooltipAdornment';
|
|
|
6
7
|
|
|
7
8
|
export const TYPES = {
|
|
8
9
|
EMAIL: 'email',
|
|
10
|
+
NUMBER: 'number',
|
|
9
11
|
NUMERIC: 'numeric',
|
|
10
|
-
PASSWORD: 'password'
|
|
12
|
+
PASSWORD: 'password',
|
|
13
|
+
PHONE: 'phone'
|
|
11
14
|
};
|
|
12
15
|
|
|
13
16
|
export const KEYBOARD_BY_TYPE = {
|
|
14
17
|
[TYPES.EMAIL]: 'email-address',
|
|
15
|
-
[TYPES.
|
|
18
|
+
[TYPES.NUMBER]: 'number-pad',
|
|
19
|
+
[TYPES.NUMERIC]: 'numeric',
|
|
20
|
+
[TYPES.PHONE]: 'phone-pad'
|
|
16
21
|
};
|
|
17
22
|
|
|
18
23
|
export const COMPONENT_KEYS = {
|
|
19
24
|
ACTION: 'Action',
|
|
25
|
+
BADGE: 'Badge',
|
|
20
26
|
ICON: 'Icon',
|
|
21
27
|
PREFIX: 'Prefix',
|
|
22
28
|
SUFFIX: 'Suffix',
|
|
23
29
|
TOOLTIP: 'Tooltip'
|
|
24
30
|
};
|
|
25
31
|
|
|
26
|
-
export const
|
|
32
|
+
export const SIZES = {
|
|
33
|
+
SMALL: 'small',
|
|
34
|
+
LARGE: 'large'
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const VARIANT = {
|
|
38
|
+
WHITE: 'white',
|
|
39
|
+
GRAY: 'gray'
|
|
40
|
+
};
|
|
27
41
|
|
|
28
42
|
export const COMPONENTS_MAPPER = {
|
|
29
43
|
[COMPONENT_KEYS.ACTION]: ActionAdornment,
|
|
44
|
+
[COMPONENT_KEYS.BADGE]: BadgeAdornment,
|
|
30
45
|
[COMPONENT_KEYS.ICON]: IconAdornment,
|
|
31
46
|
[COMPONENT_KEYS.PREFIX]: PrefixAdornment,
|
|
32
47
|
[COMPONENT_KEYS.SUFFIX]: SuffixAdornment,
|
|
@@ -1,41 +1,54 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
|
|
1
|
+
import React, {
|
|
2
|
+
forwardRef,
|
|
3
|
+
useCallback,
|
|
4
|
+
useEffect,
|
|
5
|
+
useImperativeHandle,
|
|
6
|
+
useLayoutEffect,
|
|
7
|
+
useRef,
|
|
8
|
+
useState
|
|
9
|
+
} from 'react';
|
|
3
10
|
import { View, TextInput } from 'react-native';
|
|
4
|
-
import { ViewPropTypes } from 'deprecated-react-native-prop-types';
|
|
5
11
|
|
|
6
12
|
import { useTheme } from '../../theming';
|
|
7
13
|
import UTLabel from '../UTLabel';
|
|
8
14
|
|
|
15
|
+
import { defaultProps, propTypes } from './proptypes';
|
|
9
16
|
import { KEYBOARD_BY_TYPE, TYPES, COMPONENTS_MAPPER } from './constants';
|
|
10
|
-
import { retrieveStyle } from './theme';
|
|
17
|
+
import { LINE_HEIGHT, retrieveStyle } from './theme';
|
|
11
18
|
|
|
12
19
|
const UTBaseInputField = forwardRef(
|
|
13
20
|
(
|
|
14
21
|
{
|
|
15
22
|
alwaysShowPlaceholder,
|
|
23
|
+
blurOnSubmit,
|
|
16
24
|
disabled,
|
|
25
|
+
editable,
|
|
17
26
|
error,
|
|
27
|
+
id,
|
|
28
|
+
input,
|
|
18
29
|
inputSize,
|
|
19
30
|
leftAdornments,
|
|
20
|
-
|
|
31
|
+
maxLength,
|
|
21
32
|
maxRows,
|
|
22
33
|
onBlur,
|
|
23
|
-
onChange,
|
|
24
34
|
onFocus,
|
|
25
35
|
onSubmitEditing,
|
|
26
36
|
placeholder,
|
|
27
37
|
readOnly,
|
|
28
38
|
returnKeyType,
|
|
29
39
|
rightAdornments,
|
|
40
|
+
showCharacterCount,
|
|
30
41
|
style,
|
|
31
42
|
type,
|
|
32
|
-
|
|
43
|
+
variant
|
|
33
44
|
},
|
|
34
45
|
ref
|
|
35
46
|
) => {
|
|
47
|
+
const { value, onChange } = input;
|
|
36
48
|
const [displayValue, setDisplayValue] = useState(value);
|
|
37
49
|
const [focused, setFocused] = useState(false);
|
|
38
|
-
const
|
|
50
|
+
const inputWidthRef = useRef(null);
|
|
51
|
+
const inputRef = useRef(null);
|
|
39
52
|
|
|
40
53
|
const theme = useTheme();
|
|
41
54
|
const multiline = maxRows > 1;
|
|
@@ -49,25 +62,35 @@ const UTBaseInputField = forwardRef(
|
|
|
49
62
|
[onFocus, value, multiline]
|
|
50
63
|
);
|
|
51
64
|
|
|
52
|
-
const truncateText =
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
},
|
|
60
|
-
[inputWidth]
|
|
61
|
-
);
|
|
65
|
+
const truncateText = (text, width) => {
|
|
66
|
+
const currentWidth = width || inputWidthRef.current;
|
|
67
|
+
if (!currentWidth || !text) return text;
|
|
68
|
+
const charWidth = 8;
|
|
69
|
+
const maxCharsPerLine = Math.floor(currentWidth / charWidth);
|
|
70
|
+
return text.length > maxCharsPerLine ? `${text.substring(0, maxCharsPerLine - 3)}...` : text;
|
|
71
|
+
};
|
|
62
72
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
);
|
|
73
|
+
useLayoutEffect(() => {
|
|
74
|
+
if (inputRef.current) {
|
|
75
|
+
inputRef.current.measure((_x, _y, width) => {
|
|
76
|
+
inputWidthRef.current = width;
|
|
77
|
+
setDisplayValue(truncateText(value, width));
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}, [value]);
|
|
81
|
+
|
|
82
|
+
const handleBlur = event => {
|
|
83
|
+
setFocused(false);
|
|
84
|
+
if (!multiline) setDisplayValue(truncateText(value));
|
|
85
|
+
onBlur?.(event);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const handleSubmitEditing = event => {
|
|
89
|
+
if (blurOnSubmit && inputRef.current) {
|
|
90
|
+
handleBlur();
|
|
91
|
+
}
|
|
92
|
+
onSubmitEditing?.(event);
|
|
93
|
+
};
|
|
71
94
|
|
|
72
95
|
const { actionStyle, containerStyle, inputRowStyle, inputStyle, textLengthRowStyle } = retrieveStyle({
|
|
73
96
|
disabled,
|
|
@@ -78,58 +101,69 @@ const UTBaseInputField = forwardRef(
|
|
|
78
101
|
multiline,
|
|
79
102
|
readOnly,
|
|
80
103
|
style,
|
|
81
|
-
theme
|
|
104
|
+
theme,
|
|
105
|
+
variant
|
|
82
106
|
});
|
|
83
107
|
|
|
84
108
|
useEffect(() => {
|
|
85
109
|
setDisplayValue(value);
|
|
86
110
|
}, [value]);
|
|
87
111
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
setInputWidth(width);
|
|
92
|
-
});
|
|
112
|
+
useImperativeHandle(ref, () => ({
|
|
113
|
+
truncate: () => {
|
|
114
|
+
setDisplayValue(truncateText(value));
|
|
93
115
|
}
|
|
94
|
-
}
|
|
116
|
+
}));
|
|
95
117
|
|
|
96
118
|
const secureTextEntry = type === TYPES.PASSWORD;
|
|
97
119
|
const autoCapitalize = type === TYPES.EMAIL ? 'none' : 'sentences';
|
|
98
120
|
const keyboardType = KEYBOARD_BY_TYPE[type] || 'default';
|
|
99
121
|
|
|
100
|
-
const renderElement = useCallback(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
122
|
+
const renderElement = useCallback(
|
|
123
|
+
element => {
|
|
124
|
+
const Component = COMPONENTS_MAPPER[element.name];
|
|
125
|
+
return Component ? (
|
|
126
|
+
<Component
|
|
127
|
+
actionStyle={actionStyle}
|
|
128
|
+
disabled={disabled}
|
|
129
|
+
error={error}
|
|
130
|
+
focused={focused}
|
|
131
|
+
inputStyle={inputStyle}
|
|
132
|
+
key={element.name}
|
|
133
|
+
{...element.props}
|
|
134
|
+
/>
|
|
135
|
+
) : null;
|
|
136
|
+
},
|
|
137
|
+
[actionStyle, disabled, error, focused, inputStyle]
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
const minHeight =
|
|
141
|
+
containerStyle.borderWidth * 2 +
|
|
142
|
+
containerStyle.paddingVertical * 2 +
|
|
143
|
+
(inputStyle.lineHeight || LINE_HEIGHT) * maxRows;
|
|
113
144
|
|
|
114
145
|
return (
|
|
115
|
-
<View style={containerStyle}>
|
|
146
|
+
<View style={[containerStyle, { minHeight }]}>
|
|
116
147
|
<View style={inputRowStyle}>
|
|
117
148
|
{leftAdornments.map(renderElement)}
|
|
118
149
|
<TextInput
|
|
119
150
|
autoCapitalize={autoCapitalize}
|
|
120
151
|
autoCorrect={false}
|
|
121
|
-
editable={!disabled && !readOnly}
|
|
152
|
+
editable={!disabled && !readOnly && editable}
|
|
153
|
+
id={id ? `${id}` : undefined}
|
|
122
154
|
keyboardType={keyboardType}
|
|
123
|
-
maxLength={
|
|
155
|
+
maxLength={maxLength}
|
|
124
156
|
multiline={multiline}
|
|
125
157
|
numberOfLines={maxRows}
|
|
126
158
|
onChangeText={onChange}
|
|
127
159
|
onEndEditing={handleBlur}
|
|
160
|
+
onBlur={handleBlur}
|
|
128
161
|
onFocus={handleFocus}
|
|
129
|
-
onSubmitEditing={
|
|
162
|
+
onSubmitEditing={handleSubmitEditing}
|
|
130
163
|
placeholder={!focused && !alwaysShowPlaceholder ? '' : placeholder}
|
|
131
164
|
placeholderTextColor={inputStyle.placeholderTextColor}
|
|
132
|
-
|
|
165
|
+
pointerEvents={editable ? 'auto' : 'none'}
|
|
166
|
+
ref={inputRef}
|
|
133
167
|
returnKeyType={returnKeyType}
|
|
134
168
|
secureTextEntry={secureTextEntry}
|
|
135
169
|
selectionColor={inputStyle.selectionColor}
|
|
@@ -139,10 +173,10 @@ const UTBaseInputField = forwardRef(
|
|
|
139
173
|
/>
|
|
140
174
|
{rightAdornments.map(renderElement)}
|
|
141
175
|
</View>
|
|
142
|
-
{
|
|
176
|
+
{maxLength && showCharacterCount && (
|
|
143
177
|
<View style={textLengthRowStyle}>
|
|
144
178
|
<UTLabel colorTheme="gray" variant="small">
|
|
145
|
-
{value?.length || 0}/{
|
|
179
|
+
{value?.length || 0}/{maxLength}
|
|
146
180
|
</UTLabel>
|
|
147
181
|
</View>
|
|
148
182
|
)}
|
|
@@ -152,40 +186,7 @@ const UTBaseInputField = forwardRef(
|
|
|
152
186
|
);
|
|
153
187
|
|
|
154
188
|
UTBaseInputField.displayName = 'UTBaseInputField';
|
|
155
|
-
|
|
156
|
-
UTBaseInputField.propTypes =
|
|
157
|
-
alwaysShowPlaceholder: bool,
|
|
158
|
-
disabled: bool,
|
|
159
|
-
error: string,
|
|
160
|
-
inputSize: string,
|
|
161
|
-
leftAdornments: arrayOf(
|
|
162
|
-
shape({
|
|
163
|
-
name: string.isRequired,
|
|
164
|
-
props: shape({})
|
|
165
|
-
})
|
|
166
|
-
),
|
|
167
|
-
maxCount: number,
|
|
168
|
-
maxRows: number,
|
|
169
|
-
onBlur: func,
|
|
170
|
-
onChange: func,
|
|
171
|
-
onFocus: func,
|
|
172
|
-
onSubmitEditing: func,
|
|
173
|
-
placeholder: string,
|
|
174
|
-
readOnly: bool,
|
|
175
|
-
returnKeyType: string,
|
|
176
|
-
rightAdornments: arrayOf(
|
|
177
|
-
shape({
|
|
178
|
-
name: string.isRequired,
|
|
179
|
-
props: shape({})
|
|
180
|
-
})
|
|
181
|
-
),
|
|
182
|
-
style: shape({
|
|
183
|
-
container: ViewPropTypes.style,
|
|
184
|
-
input: ViewPropTypes.style,
|
|
185
|
-
root: ViewPropTypes.style
|
|
186
|
-
}),
|
|
187
|
-
type: string,
|
|
188
|
-
value: string
|
|
189
|
-
};
|
|
189
|
+
UTBaseInputField.defaultProps = defaultProps;
|
|
190
|
+
UTBaseInputField.propTypes = propTypes;
|
|
190
191
|
|
|
191
192
|
export default UTBaseInputField;
|