@momo-kits/foundation 0.168.1-beta.1 → 0.168.1-beta.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/Input/InputMoney.tsx +17 -36
- package/package.json +1 -1
package/Input/InputMoney.tsx
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable react-hooks/exhaustive-deps */
|
|
2
1
|
import React, {
|
|
3
2
|
forwardRef,
|
|
4
3
|
useContext,
|
|
@@ -43,7 +42,6 @@ const countDigits = (text: string) => text.replace(/\D/g, '').length;
|
|
|
43
42
|
const groupDigits = (digits: string) =>
|
|
44
43
|
digits.replace(/\B(?=(\d{3})+(?!\d))/g, '.');
|
|
45
44
|
|
|
46
|
-
// Caret position right after the `digitIndex`-th digit of `display`.
|
|
47
45
|
const caretFromDigitIndex = (display: string, digitIndex: number) => {
|
|
48
46
|
let count = 0;
|
|
49
47
|
for (let i = 0; i < display.length && count < digitIndex; i++) {
|
|
@@ -97,9 +95,6 @@ const detectEdit = (old: string, next: string, selection: Selection): Edit => {
|
|
|
97
95
|
};
|
|
98
96
|
};
|
|
99
97
|
|
|
100
|
-
// Applies `edit` to the digits of `display`. Separators and currency are never
|
|
101
|
-
// deleted: removing a separator deletes the digit before it instead, removing
|
|
102
|
-
// only the currency leaves the digits untouched.
|
|
103
98
|
const applyEdit = (display: string, edit: Edit, digitLimit: number) => {
|
|
104
99
|
const digits = display.replace(/\D/g, '');
|
|
105
100
|
let left = countDigits(display.slice(0, edit.start));
|
|
@@ -165,11 +160,10 @@ const InputMoney = forwardRef(
|
|
|
165
160
|
const inputFontFamily = exportFontFamily('bold');
|
|
166
161
|
const [focused, setFocused] = useState(false);
|
|
167
162
|
const [displayValue, setDisplayValue] = useState('');
|
|
168
|
-
const [numericValue, setNumericValue] = useState('');
|
|
169
163
|
const [commitCount, setCommitCount] = useState(0);
|
|
170
164
|
const displayRef = useRef('');
|
|
165
|
+
const digitsRef = useRef('');
|
|
171
166
|
const selectionRef = useRef<Selection>({ start: 0, end: 0 });
|
|
172
|
-
// Caret to push to native once the committed text is rendered.
|
|
173
167
|
const pendingCaretRef = useRef<number | null>(null);
|
|
174
168
|
const pendingSelectionRef = useRef<Selection | null>(null);
|
|
175
169
|
const editingRef = useRef(false);
|
|
@@ -183,54 +177,39 @@ const InputMoney = forwardRef(
|
|
|
183
177
|
props.accessibilityLabel,
|
|
184
178
|
);
|
|
185
179
|
|
|
186
|
-
const
|
|
187
|
-
const hasMaxLength = typeof maxLength === 'number';
|
|
188
|
-
const digitLimit = hasMaxLength ? maxLength : Number.POSITIVE_INFINITY;
|
|
180
|
+
const digitLimit = props.maxLength ?? Number.POSITIVE_INFINITY;
|
|
189
181
|
|
|
190
182
|
useEffect(() => {
|
|
191
183
|
if (value !== undefined && typeof value === 'string') {
|
|
192
184
|
const cleanValue = value.replace(/\D/g, '').replace(/^0+(?=\d)/, '');
|
|
193
|
-
if (cleanValue !==
|
|
185
|
+
if (cleanValue !== digitsRef.current) {
|
|
194
186
|
commit(cleanValue, cleanValue.length);
|
|
195
187
|
}
|
|
196
188
|
}
|
|
189
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
197
190
|
}, [value]);
|
|
198
191
|
|
|
199
|
-
// Always set the caret imperatively: a controlled `selection` prop is only
|
|
200
|
-
// sent to native when it differs from the last native selection, so it is
|
|
201
|
-
// skipped whenever a stale selection event already reported the same value.
|
|
202
192
|
useLayoutEffect(() => {
|
|
203
193
|
const caret = pendingCaretRef.current;
|
|
204
|
-
if (caret === null) return;
|
|
194
|
+
if (caret === null || !inputRef.current?.isFocused()) return;
|
|
205
195
|
pendingCaretRef.current = null;
|
|
206
|
-
|
|
207
|
-
inputRef.current.setSelection(caret, caret);
|
|
208
|
-
}
|
|
196
|
+
inputRef.current.setSelection(caret, caret);
|
|
209
197
|
}, [commitCount]);
|
|
210
198
|
|
|
211
199
|
const commit = (digits: string, caretDigit: number) => {
|
|
212
200
|
const display = digits ? `${groupDigits(digits)}${currency}` : '';
|
|
213
201
|
const caret = caretFromDigitIndex(display, caretDigit);
|
|
214
|
-
const changed = digits !==
|
|
202
|
+
const changed = digits !== digitsRef.current;
|
|
215
203
|
displayRef.current = display;
|
|
204
|
+
digitsRef.current = digits;
|
|
216
205
|
selectionRef.current = { start: caret, end: caret };
|
|
217
206
|
pendingCaretRef.current = caret;
|
|
218
207
|
setCommitCount(count => count + 1);
|
|
219
208
|
setDisplayValue(display);
|
|
220
|
-
setNumericValue(digits);
|
|
221
209
|
return changed;
|
|
222
210
|
};
|
|
223
211
|
|
|
224
|
-
const parseInputText = (text: string): string => {
|
|
225
|
-
if (!text) return '';
|
|
226
|
-
const currencyRegex = new RegExp(` ?${currency}$`, 'g');
|
|
227
|
-
const textWithoutCurrency = text.replace(currencyRegex, '').trim();
|
|
228
|
-
return textWithoutCurrency.replace(/[^\d]/g, '');
|
|
229
|
-
};
|
|
230
|
-
|
|
231
212
|
const onClearText = () => {
|
|
232
|
-
inputRef?.current?.clear();
|
|
233
|
-
inputRef.current?.setNativeProps({ text: '' });
|
|
234
213
|
commit('', 0);
|
|
235
214
|
onChangeText?.('');
|
|
236
215
|
};
|
|
@@ -256,7 +235,6 @@ const InputMoney = forwardRef(
|
|
|
256
235
|
}
|
|
257
236
|
};
|
|
258
237
|
|
|
259
|
-
// Keeps the caret out of the currency suffix.
|
|
260
238
|
const _onSelectionChange = (e: TextInputSelectionChangeEvent) => {
|
|
261
239
|
props.onSelectionChange?.(e);
|
|
262
240
|
if (editingRef.current) return;
|
|
@@ -281,6 +259,12 @@ const InputMoney = forwardRef(
|
|
|
281
259
|
|
|
282
260
|
const _onFocus = (e: TextInputFocusEvent) => {
|
|
283
261
|
setFocused(true);
|
|
262
|
+
const caret = pendingCaretRef.current;
|
|
263
|
+
pendingCaretRef.current = null;
|
|
264
|
+
if (caret !== null && !props.selectTextOnFocus) {
|
|
265
|
+
selectionRef.current = { start: caret, end: caret };
|
|
266
|
+
inputRef.current?.setSelection(caret, caret);
|
|
267
|
+
}
|
|
284
268
|
onFocus?.(e);
|
|
285
269
|
};
|
|
286
270
|
|
|
@@ -290,12 +274,8 @@ const InputMoney = forwardRef(
|
|
|
290
274
|
};
|
|
291
275
|
|
|
292
276
|
const _setText = (text: string) => {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
onChangeText?.('');
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
298
|
-
const digits = parseInputText(text)
|
|
277
|
+
const digits = text
|
|
278
|
+
.replace(/\D/g, '')
|
|
299
279
|
.replace(/^0+(?=\d)/, '')
|
|
300
280
|
.slice(0, digitLimit);
|
|
301
281
|
if (commit(digits, digits.length)) {
|
|
@@ -346,6 +326,7 @@ const InputMoney = forwardRef(
|
|
|
346
326
|
accessibilityLabel={`${componentId}`}
|
|
347
327
|
textAlignVertical="center"
|
|
348
328
|
ref={inputRef}
|
|
329
|
+
editable={props.editable !== false && !disabled}
|
|
349
330
|
accessibilityState={{
|
|
350
331
|
disabled: disabled,
|
|
351
332
|
...props.accessibilityState,
|