@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.
Files changed (68) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/lib/components/Button/index.js +1 -1
  3. package/lib/components/UTBadge/index.js +2 -2
  4. package/lib/components/UTBadge/theme.js +9 -6
  5. package/lib/components/UTBaseInputField/README.md +45 -31
  6. package/lib/components/UTBaseInputField/components/ActionAdornment/index.js +5 -16
  7. package/lib/components/UTBaseInputField/components/BadgeAdornment/index.js +13 -0
  8. package/lib/components/UTBaseInputField/components/IconAdornment/constants.js +2 -0
  9. package/lib/components/UTBaseInputField/components/IconAdornment/index.js +20 -15
  10. package/lib/components/UTBaseInputField/components/IconAdornment/proptypes.js +20 -0
  11. package/lib/components/UTBaseInputField/components/IconAdornment/utils.js +7 -2
  12. package/lib/components/UTBaseInputField/constants.js +18 -3
  13. package/lib/components/UTBaseInputField/index.js +89 -88
  14. package/lib/components/UTBaseInputField/proptypes.js +60 -0
  15. package/lib/components/UTBaseInputField/theme.js +72 -32
  16. package/lib/components/UTBottomSheet/README.md +53 -0
  17. package/lib/components/UTBottomSheet/index.js +139 -0
  18. package/lib/components/UTBottomSheet/styles.js +46 -0
  19. package/lib/components/UTButton/constants.js +5 -14
  20. package/lib/components/UTButton/index.js +6 -22
  21. package/lib/components/UTButton/proptypes.js +29 -0
  22. package/lib/components/UTButton/theme.js +6 -5
  23. package/lib/components/UTCheckBox/README.md +4 -30
  24. package/lib/components/UTCheckBox/constants.js +4 -1
  25. package/lib/components/UTCheckBox/index.js +33 -22
  26. package/lib/components/UTCheckBox/proptypes.js +12 -3
  27. package/lib/components/UTCheckBox/styles.js +7 -0
  28. package/lib/components/UTCheckBox/theme.js +98 -54
  29. package/lib/components/UTCheckList/README.MD +14 -10
  30. package/lib/components/UTCheckList/constants.js +6 -1
  31. package/lib/components/UTCheckList/index.js +44 -66
  32. package/lib/components/UTCheckList/proptypes.js +48 -0
  33. package/lib/components/UTCheckList/styles.js +10 -5
  34. package/lib/components/UTCheckList/utils.js +5 -0
  35. package/lib/components/UTFieldLabel/index.js +4 -3
  36. package/lib/components/UTLabel/constants.js +11 -11
  37. package/lib/components/UTLabel/index.js +3 -17
  38. package/lib/components/UTLabel/proptypes.js +19 -0
  39. package/lib/components/UTLabel/theme.js +2 -2
  40. package/lib/components/UTMenu/index.js +1 -1
  41. package/lib/components/UTPasswordField/versions/V0/components/PasswordValidations/styles.js +1 -0
  42. package/lib/components/UTPasswordField/versions/V1/index.js +3 -2
  43. package/lib/components/UTPhoneInput/constants.js +303 -0
  44. package/lib/components/UTPhoneInput/index.js +296 -0
  45. package/lib/components/UTPhoneInput/styles.js +18 -0
  46. package/lib/components/UTSearchField/README.md +42 -0
  47. package/lib/components/UTSearchField/index.js +59 -0
  48. package/lib/components/UTSearchField/proptypes.js +28 -0
  49. package/lib/components/UTSelect/index.js +10 -97
  50. package/lib/components/UTSelect/{componentes → versions/V0/componentes}/MultipleItem/index.js +1 -1
  51. package/lib/components/UTSelect/versions/V0/index.js +103 -0
  52. package/lib/components/UTSelect/versions/V1/README.md +82 -0
  53. package/lib/components/UTSelect/versions/V1/index.js +171 -0
  54. package/lib/components/UTSelect/versions/V1/proptypes.js +45 -0
  55. package/lib/components/UTSelect/versions/V1/styles.js +18 -0
  56. package/lib/components/UTTextArea/index.js +4 -2
  57. package/lib/components/UTTextInput/versions/V0/components/BaseInput/index.js +3 -3
  58. package/lib/components/UTTextInput/versions/V1/README.md +36 -35
  59. package/lib/components/UTTextInput/versions/V1/components/TextInputField/index.js +24 -15
  60. package/lib/components/UTTextInput/versions/V1/constants.js +3 -5
  61. package/lib/components/UTTextInput/versions/V1/index.js +25 -20
  62. package/lib/components/UTTextInput/versions/V1/proptypes.js +25 -7
  63. package/lib/constants/inputs.js +4 -0
  64. package/lib/index.js +47 -51
  65. package/package.json +2 -2
  66. /package/lib/components/UTSelect/{componentes → versions/V0/componentes}/MultipleItem/styles.js +0 -0
  67. /package/lib/components/UTSelect/{proptypes.js → versions/V0/proptypes.js} +0 -0
  68. /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
 
@@ -44,7 +44,7 @@ const Button = ({
44
44
  ? NO_ELEVATION
45
45
  : mode === OUTLINED
46
46
  ? NO_ELEVATION
47
- : elevation ?? themeStyles.buttonElevation
47
+ : (elevation ?? themeStyles.buttonElevation)
48
48
  }
49
49
  style={[
50
50
  styles.container,
@@ -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: 100,
31
+ borderRadius: 10,
30
32
  justifyContent: 'center',
31
- margin: 10
33
+ overflow: 'hidden'
32
34
  },
33
35
  text: {
34
- alignSelf: 'flex-start',
35
36
  height: 20,
36
- paddingHorizontal: 6
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
- # UTBaseInputField
2
-
3
- ## Description
4
-
5
- `UTBaseInputField` is a flexible and customizable input field component that supports various input types, adornments, and styles. It can be used to create text inputs with additional functionality such as icons, prefixes, suffixes, and action buttons.
6
-
7
- ## Props
8
-
9
- | Name | Type | Default | Description |
10
- | --------------------- | ------ | ------- | --------------------------------------------------------- |
11
- | alwaysShowPlaceholder | bool | | Whether to always show the placeholder text. |
12
- | disabled | bool | | Whether the input field is disabled. |
13
- | error | string | | Error message to display. |
14
- | inputSize | string | | Size of the input field. |
15
- | leftAdornments | array | | Elements to display on the left side of the input field. |
16
- | maxCount | number | | Maximum number of characters allowed. |
17
- | maxRows | number | | Maximum number of rows for multiline input. |
18
- | onBlur | func | | Callback function to handle blur event. |
19
- | onChange | func | | Callback function to handle change event. |
20
- | onFocus | func | | Callback function to handle focus event. |
21
- | onSubmitEditing | func | | Callback function to handle submit editing event. |
22
- | placeholder | string | | Placeholder text for the input field. |
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 an optional change on error.
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
- - `changeOnError` (bool): Whether to change the icon on error (default is false).
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: 'Icon', props: { Icon: 'search', changeOnError: true } }]} />
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 { string, bool, shape, func } from 'prop-types';
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
- colorTheme: string,
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 +1,3 @@
1
1
  export const ERROR_ICON = 'IconInfoCircle';
2
+
3
+ export const ICON_SIZE = 20;
@@ -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 = ({ Icon, error, inputStyle, changeOnError = false }) => {
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 name={IconToRender} {...getIconColorProps(error, changeOnError)} />
24
+ <UTIcon
25
+ name={IconToRender}
26
+ size={ICON_SIZE}
27
+ {...getIconColorProps(changeOnError, changeOnFocus, colorTheme, error, focused, shade)}
28
+ />
18
29
  ) : (
19
- <IconToRender fill={inputStyle.root.color} />
30
+ <Icon size={ICON_SIZE} fill={inputStyle.root.color} />
20
31
  );
21
32
  };
22
33
 
23
- IconAdornment.propTypes = {
24
- error: string,
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, changeOnError) =>
2
- changeOnError && error ? { colorTheme: 'error', shade: '04' } : { colorTheme: 'gray' };
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.NUMERIC]: 'numeric'
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 SMALL = 'small';
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, { forwardRef, useCallback, useEffect, useLayoutEffect, useState } from 'react';
2
- import { bool, func, number, string, arrayOf, shape } from 'prop-types';
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
- maxCount,
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
- value
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 [inputWidth, setInputWidth] = useState(null);
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 = useCallback(
53
- text => {
54
- if (!inputWidth || !text) return text;
55
- const charWidth = 8;
56
- const maxCharsPerLine = Math.floor(inputWidth / charWidth);
57
- const maxLength = maxCharsPerLine;
58
- return text.length > maxLength ? `${text.substring(0, maxLength - 3)}...` : text;
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
- const handleBlur = useCallback(
64
- event => {
65
- setFocused(false);
66
- if (!multiline) setDisplayValue(truncateText(value));
67
- onBlur?.(event);
68
- },
69
- [truncateText, value, multiline, onBlur]
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
- useLayoutEffect(() => {
89
- if (ref?.current) {
90
- ref.current.measure((_x, _y, width) => {
91
- setInputWidth(width);
92
- });
112
+ useImperativeHandle(ref, () => ({
113
+ truncate: () => {
114
+ setDisplayValue(truncateText(value));
93
115
  }
94
- }, [focused]);
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(element => {
101
- const Component = COMPONENTS_MAPPER[element.name];
102
- return Component ? (
103
- <Component
104
- actionStyle={actionStyle}
105
- disabled={disabled}
106
- error={error}
107
- inputStyle={inputStyle}
108
- key={element.name}
109
- {...element.props}
110
- />
111
- ) : null;
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={maxCount}
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={onSubmitEditing}
162
+ onSubmitEditing={handleSubmitEditing}
130
163
  placeholder={!focused && !alwaysShowPlaceholder ? '' : placeholder}
131
164
  placeholderTextColor={inputStyle.placeholderTextColor}
132
- ref={ref}
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
- {maxCount && (
176
+ {maxLength && showCharacterCount && (
143
177
  <View style={textLengthRowStyle}>
144
178
  <UTLabel colorTheme="gray" variant="small">
145
- {value?.length || 0}/{maxCount}
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;