@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.
@@ -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 preEdit: Edit[] = [
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
- // Caret the native input reports for the raw, unformatted text. On iOS that
200
- // event lands after onChangeText and must not override the formatted caret.
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
- rawCaretRef.current = 0;
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
- const { start, end } = e.nativeEvent.selection;
289
- const rawCaret = rawCaretRef.current;
290
- rawCaretRef.current = null;
291
- if (start === end && start === rawCaret) {
292
- return;
293
- }
294
- const display = displayRef.current;
295
- const max = display ? display.length - currency.length : 0;
296
- const clamped = { start: Math.min(start, max), end: Math.min(end, max) };
297
- selectionRef.current = clamped;
298
- if (clamped.start !== start || clamped.end !== end) {
299
- inputRef.current?.setSelection(clamped.start, clamped.end);
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>) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.167.1-beta.10",
3
+ "version": "0.167.1-beta.12",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {},