@momo-kits/foundation 0.167.1-beta.10 → 0.167.1-beta.12
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 +26 -43
- package/package.json +1 -1
package/Input/InputMoney.tsx
CHANGED
|
@@ -10,7 +10,6 @@ import React, {
|
|
|
10
10
|
} from 'react';
|
|
11
11
|
import {
|
|
12
12
|
NativeSyntheticEvent,
|
|
13
|
-
Platform,
|
|
14
13
|
TextInput,
|
|
15
14
|
TextInputFocusEventData,
|
|
16
15
|
TextInputSelectionChangeEventData,
|
|
@@ -57,13 +56,10 @@ const caretFromDigitIndex = (display: string, digitIndex: number) => {
|
|
|
57
56
|
return 0;
|
|
58
57
|
};
|
|
59
58
|
|
|
60
|
-
// Finds which range of `old` was replaced to produce `next`. `selection` is
|
|
61
|
-
// the pre-edit selection on iOS and already the post-edit caret on Android,
|
|
62
|
-
// where onSelectionChange fires before onChangeText.
|
|
63
59
|
const detectEdit = (old: string, next: string, selection: Selection): Edit => {
|
|
64
60
|
const { start, end } = selection;
|
|
65
61
|
const removed = old.length - next.length;
|
|
66
|
-
const
|
|
62
|
+
const candidates: Edit[] = [
|
|
67
63
|
{
|
|
68
64
|
start,
|
|
69
65
|
end,
|
|
@@ -72,26 +68,6 @@ const detectEdit = (old: string, next: string, selection: Selection): Edit => {
|
|
|
72
68
|
{ start: start - removed, end: start, inserted: '' },
|
|
73
69
|
{ start, end: start + removed, inserted: '' },
|
|
74
70
|
];
|
|
75
|
-
const postEdit: Edit[] = [];
|
|
76
|
-
const tail = next.length - start;
|
|
77
|
-
if (start === end && tail <= old.length) {
|
|
78
|
-
let prefix = 0;
|
|
79
|
-
while (
|
|
80
|
-
prefix < Math.min(start, old.length - tail) &&
|
|
81
|
-
old[prefix] === next[prefix]
|
|
82
|
-
) {
|
|
83
|
-
prefix += 1;
|
|
84
|
-
}
|
|
85
|
-
postEdit.push({
|
|
86
|
-
start: prefix,
|
|
87
|
-
end: old.length - tail,
|
|
88
|
-
inserted: next.slice(prefix, start),
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
const candidates =
|
|
92
|
-
Platform.OS === 'android'
|
|
93
|
-
? [...postEdit, ...preEdit]
|
|
94
|
-
: [...preEdit, ...postEdit];
|
|
95
71
|
const match = candidates.find(
|
|
96
72
|
e =>
|
|
97
73
|
e.start >= 0 &&
|
|
@@ -196,9 +172,8 @@ const InputMoney = forwardRef(
|
|
|
196
172
|
const selectionRef = useRef<Selection>({ start: 0, end: 0 });
|
|
197
173
|
// Caret to push to native once the committed text is rendered.
|
|
198
174
|
const pendingCaretRef = useRef<number | null>(null);
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const rawCaretRef = useRef<number | null>(null);
|
|
175
|
+
const pendingSelectionRef = useRef<Selection | null>(null);
|
|
176
|
+
const editingRef = useRef(false);
|
|
202
177
|
const inputRef = useRef<TextInput>(null);
|
|
203
178
|
const componentName = 'InputMoney';
|
|
204
179
|
|
|
@@ -265,10 +240,13 @@ const InputMoney = forwardRef(
|
|
|
265
240
|
const _onChangeText = (text: string) => {
|
|
266
241
|
let digits = '';
|
|
267
242
|
let caretDigit = 0;
|
|
268
|
-
|
|
243
|
+
pendingSelectionRef.current = null;
|
|
244
|
+
editingRef.current = true;
|
|
245
|
+
setTimeout(() => {
|
|
246
|
+
editingRef.current = false;
|
|
247
|
+
});
|
|
269
248
|
if (text) {
|
|
270
249
|
const edit = detectEdit(displayRef.current, text, selectionRef.current);
|
|
271
|
-
rawCaretRef.current = edit.start + edit.inserted.length;
|
|
272
250
|
({ digits, caretDigit } = applyEdit(
|
|
273
251
|
displayRef.current,
|
|
274
252
|
edit,
|
|
@@ -285,19 +263,24 @@ const InputMoney = forwardRef(
|
|
|
285
263
|
e: NativeSyntheticEvent<TextInputSelectionChangeEventData>,
|
|
286
264
|
) => {
|
|
287
265
|
props.onSelectionChange?.(e);
|
|
288
|
-
|
|
289
|
-
const
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
return;
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
266
|
+
if (editingRef.current) return;
|
|
267
|
+
const selection = e.nativeEvent.selection;
|
|
268
|
+
pendingSelectionRef.current = selection;
|
|
269
|
+
setTimeout(() => {
|
|
270
|
+
if (pendingSelectionRef.current !== selection) return;
|
|
271
|
+
pendingSelectionRef.current = null;
|
|
272
|
+
const { start, end } = selection;
|
|
273
|
+
const display = displayRef.current;
|
|
274
|
+
const max = display ? display.length - currency.length : 0;
|
|
275
|
+
const clamped = {
|
|
276
|
+
start: Math.min(start, max),
|
|
277
|
+
end: Math.min(end, max),
|
|
278
|
+
};
|
|
279
|
+
selectionRef.current = clamped;
|
|
280
|
+
if (clamped.start !== start || clamped.end !== end) {
|
|
281
|
+
inputRef.current?.setSelection(clamped.start, clamped.end);
|
|
282
|
+
}
|
|
283
|
+
});
|
|
301
284
|
};
|
|
302
285
|
|
|
303
286
|
const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
|