@widergy/mobile-ui 1.23.0 → 1.23.2

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 CHANGED
@@ -1,3 +1,17 @@
1
+ ## [1.23.2](https://github.com/widergy/mobile-ui/compare/v1.23.1...v1.23.2) (2024-09-12)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * fix input bug ([#355](https://github.com/widergy/mobile-ui/issues/355)) ([82869dd](https://github.com/widergy/mobile-ui/commit/82869ddabb526824d2fd2c6da0f86bf0c8fca92d))
7
+
8
+ ## [1.23.1](https://github.com/widergy/mobile-ui/compare/v1.23.0...v1.23.1) (2024-09-04)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * instance validation added ([#352](https://github.com/widergy/mobile-ui/issues/352)) ([6f2d5da](https://github.com/widergy/mobile-ui/commit/6f2d5da7771e61736eb602f9de080acffb48a63b))
14
+
1
15
  # [1.23.0](https://github.com/widergy/mobile-ui/compare/v1.22.0...v1.23.0) (2024-09-04)
2
16
 
3
17
 
@@ -5,6 +5,12 @@ import PrefixAdornment from './components/PrefixAdornment';
5
5
  import SuffixAdornment from './components/SuffixAdornment';
6
6
  import TooltipAdornment from './components/TooltipAdornment';
7
7
 
8
+ export const DEBOUNCE_DELAY = 150;
9
+ export const DEBOUNCE_CONFIG = {
10
+ leading: false,
11
+ trailing: true
12
+ };
13
+
8
14
  export const TYPES = {
9
15
  EMAIL: 'email',
10
16
  NUMBER: 'number',
@@ -4,16 +4,19 @@ import React, {
4
4
  useEffect,
5
5
  useImperativeHandle,
6
6
  useLayoutEffect,
7
+ useMemo,
7
8
  useRef,
8
9
  useState
9
10
  } from 'react';
10
11
  import { View, TextInput } from 'react-native';
12
+ import debounce from 'lodash/debounce';
11
13
 
12
14
  import { useTheme } from '../../theming';
13
15
  import UTLabel from '../UTLabel';
14
16
 
17
+ import { COMPONENTS_MAPPER, DEBOUNCE_CONFIG, DEBOUNCE_DELAY } from './constants';
15
18
  import { defaultProps, propTypes } from './proptypes';
16
- import { KEYBOARD_BY_TYPE, TYPES, COMPONENTS_MAPPER } from './constants';
19
+ import { getPropsByType } from './utils';
17
20
  import { LINE_HEIGHT, retrieveStyle } from './theme';
18
21
 
19
22
  const UTBaseInputField = forwardRef(
@@ -45,7 +48,6 @@ const UTBaseInputField = forwardRef(
45
48
  },
46
49
  ref
47
50
  ) => {
48
- const [displayValue, setDisplayValue] = useState(value);
49
51
  const [focused, setFocused] = useState(false);
50
52
  const inputWidthRef = useRef(null);
51
53
  const inputRef = useRef(null);
@@ -53,35 +55,55 @@ const UTBaseInputField = forwardRef(
53
55
  const theme = useTheme();
54
56
  const multiline = maxRows > 1;
55
57
 
58
+ const { secureTextEntry, autoCapitalize, keyboardType } = getPropsByType(type);
59
+
60
+ const setNativeText = useMemo(
61
+ () => debounce(text => inputRef.current?.setNativeProps({ text }), DEBOUNCE_DELAY, DEBOUNCE_CONFIG),
62
+ []
63
+ );
64
+
56
65
  const handleFocus = useCallback(
57
66
  event => {
58
67
  setFocused(true);
59
- if (!multiline) setDisplayValue(value);
68
+ setNativeText(value);
60
69
  onFocus?.(event);
61
70
  },
62
- [onFocus, value, multiline]
71
+ [onFocus, value, setNativeText]
63
72
  );
64
73
 
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
- };
74
+ const truncateText = useCallback(
75
+ (text, width) => {
76
+ if (multiline) return text;
77
+ const currentWidth = width || inputWidthRef.current;
78
+ if (!currentWidth || !text) return text;
79
+ const charWidth = 8;
80
+ const maxCharsPerLine = Math.floor(currentWidth / charWidth);
81
+ return text.length > maxCharsPerLine ? `${text.substring(0, maxCharsPerLine - 3)}...` : text;
82
+ },
83
+ [multiline, inputWidthRef]
84
+ );
85
+
86
+ useEffect(() => {
87
+ if (!focused && !multiline) {
88
+ const truncated = truncateText(value, inputWidthRef.current);
89
+ setNativeText(truncated);
90
+ } else {
91
+ setNativeText(value);
92
+ }
93
+ }, [value, focused, multiline, setNativeText, truncateText]);
72
94
 
73
95
  useLayoutEffect(() => {
74
96
  if (inputRef.current) {
75
97
  inputRef.current.measure((_x, _y, width) => {
76
98
  inputWidthRef.current = width;
77
- setDisplayValue(truncateText(value, width));
78
99
  });
79
100
  }
80
- }, [value]);
101
+ }, [value, focused]);
81
102
 
82
103
  const handleBlur = event => {
83
104
  setFocused(false);
84
- if (!multiline) setDisplayValue(truncateText(value));
105
+ const truncated = truncateText(value, inputWidthRef.current);
106
+ setNativeText(truncated);
85
107
  onBlur?.(event);
86
108
  };
87
109
 
@@ -92,26 +114,27 @@ const UTBaseInputField = forwardRef(
92
114
  onSubmitEditing?.(event);
93
115
  };
94
116
 
95
- const { actionStyle, containerStyle, inputRowStyle, inputStyle, textLengthRowStyle } = retrieveStyle({
96
- disabled: disabled && !readOnly,
97
- error,
98
- focused,
99
- inputSize,
100
- maxRows,
101
- multiline,
102
- readOnly,
103
- style,
104
- theme,
105
- variant
106
- });
107
-
108
- useEffect(() => {
109
- setDisplayValue(value);
110
- }, [value]);
117
+ const { actionStyle, containerStyle, inputRowStyle, inputStyle, textLengthRowStyle } = useMemo(
118
+ () =>
119
+ retrieveStyle({
120
+ disabled: disabled && !readOnly,
121
+ error,
122
+ focused,
123
+ inputSize,
124
+ maxRows,
125
+ multiline,
126
+ readOnly,
127
+ style,
128
+ theme,
129
+ variant
130
+ }),
131
+ [disabled, readOnly, error, focused, inputSize, maxRows, multiline, style, theme, variant]
132
+ );
111
133
 
112
134
  useImperativeHandle(ref, () => ({
113
135
  truncate: () => {
114
- setDisplayValue(truncateText(value));
136
+ const truncated = truncateText(value, inputWidthRef.current);
137
+ setNativeText(truncated);
115
138
  },
116
139
  focus: () => {
117
140
  if (inputRef.current) {
@@ -126,10 +149,6 @@ const UTBaseInputField = forwardRef(
126
149
  ...inputRef.current
127
150
  }));
128
151
 
129
- const secureTextEntry = [TYPES.PASSWORD, TYPES.PASSWORD_NUMERIC].includes(type);
130
- const autoCapitalize = type === TYPES.EMAIL ? 'none' : 'sentences';
131
- const keyboardType = KEYBOARD_BY_TYPE[type] || 'default';
132
-
133
152
  const renderElement = useCallback(
134
153
  element => {
135
154
  const Component = COMPONENTS_MAPPER[element.name];
@@ -160,15 +179,16 @@ const UTBaseInputField = forwardRef(
160
179
  <TextInput
161
180
  autoCapitalize={autoCapitalize}
162
181
  autoCorrect={false}
182
+ defaultValue={value}
163
183
  editable={!disabled && !readOnly && editable}
164
184
  id={id ? `${id}` : undefined}
165
185
  keyboardType={keyboardType}
166
186
  maxLength={maxLength}
167
187
  multiline={multiline}
168
188
  numberOfLines={maxRows}
169
- onChangeText={onChange}
170
- onEndEditing={handleBlur}
171
189
  onBlur={handleBlur}
190
+ onChangeText={text => setNativeText(value) || onChange(text)}
191
+ onEndEditing={handleBlur}
172
192
  onFocus={handleFocus}
173
193
  onSubmitEditing={handleSubmitEditing}
174
194
  placeholder={!focused && !alwaysShowPlaceholder ? '' : placeholder}
@@ -180,7 +200,6 @@ const UTBaseInputField = forwardRef(
180
200
  selectionColor={inputStyle.selectionColor}
181
201
  style={inputStyle.root}
182
202
  type={type}
183
- value={focused || multiline ? value : displayValue}
184
203
  />
185
204
  {rightAdornments.map(renderElement)}
186
205
  </View>
@@ -0,0 +1,13 @@
1
+ import { KEYBOARD_BY_TYPE, TYPES } from './constants';
2
+
3
+ export const getPropsByType = type => {
4
+ const autoCapitalize = type === TYPES.EMAIL ? 'none' : 'sentences';
5
+ const keyboardType = KEYBOARD_BY_TYPE[type] || 'default';
6
+ const secureTextEntry = [TYPES.PASSWORD, TYPES.PASSWORD_NUMERIC].includes(type);
7
+
8
+ return {
9
+ autoCapitalize,
10
+ keyboardType,
11
+ secureTextEntry
12
+ };
13
+ };
@@ -131,13 +131,13 @@ export const singleEventMultitracking = (trackers, eventDefinitions) => (name, e
131
131
  });
132
132
  };
133
133
 
134
- export const intercomSingleEvent = trackEventFunction => eventData => {
134
+ export const intercomSingleEvent = intercomInstance => eventData => {
135
135
  const { name, ...eventMetadata } = eventData;
136
- if (trackEventFunction) trackEventFunction(name, eventMetadata);
136
+ if (intercomInstance) intercomInstance.logEvent(name, eventMetadata);
137
137
  };
138
138
 
139
- export const intercomUpdateUser = updaterFunction => userProperties => {
140
- updaterFunction(userProperties);
139
+ export const intercomUpdateUser = intercomInstance => userProperties => {
140
+ if (intercomInstance) intercomInstance.updateUser(userProperties);
141
141
  };
142
142
 
143
143
  export default {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@widergy/mobile-ui",
3
3
  "description": "Widergy Mobile Components",
4
4
  "author": "widergy",
5
- "version": "1.23.0",
5
+ "version": "1.23.2",
6
6
  "repository": "https://github.com/widergy/mobile-ui.git",
7
7
  "main": "lib/index.js",
8
8
  "files": [