@momo-kits/foundation 0.168.1-beta.3 → 0.168.1-beta.4

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.
@@ -8,6 +8,7 @@ import React, {
8
8
  useState,
9
9
  } from 'react';
10
10
  import {
11
+ Platform,
11
12
  TextInput,
12
13
  TextInputFocusEvent,
13
14
  TouchableOpacity,
@@ -74,6 +75,7 @@ const InputMoney = forwardRef(
74
75
  const [numericValue, setNumericValue] = useState('');
75
76
  const [lastDisplayValue, setLastDisplayValue] = useState('');
76
77
  const inputRef = useRef<TextInput>(null);
78
+ const caretDigitsAfter = useRef<number | undefined>(undefined);
77
79
  const componentName = 'InputMoney';
78
80
 
79
81
  const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
@@ -91,14 +93,28 @@ const InputMoney = forwardRef(
91
93
  if (value !== undefined && typeof value === 'string') {
92
94
  const cleanValue = value.replace(/\D/g, '').replace(/^0+(?=\d)/, '');
93
95
  if (cleanValue !== numericValue) {
96
+ caretDigitsAfter.current = undefined;
94
97
  setNumericValue(cleanValue);
95
98
  updateDisplayValue(cleanValue);
96
99
  }
97
100
  }
98
101
  }, [value]);
99
102
 
103
+ // Android moves the caret proportionally when the text is replaced, so it
104
+ // lands before the typed digit once a separator is added. Put it back after
105
+ // the same digit.
100
106
  useEffect(() => {
101
107
  setLastDisplayValue(displayValue);
108
+ const digitsAfter = caretDigitsAfter.current;
109
+ caretDigitsAfter.current = undefined;
110
+ if (Platform.OS !== 'android' || digitsAfter === undefined) return;
111
+ let before = parseInputText(displayValue).length - digitsAfter;
112
+ let caret = 0;
113
+ while (before > 0 && caret < displayValue.length) {
114
+ if (/\d/.test(displayValue[caret])) before -= 1;
115
+ caret += 1;
116
+ }
117
+ inputRef.current?.setSelection(caret, caret);
102
118
  }, [displayValue]);
103
119
 
104
120
  const updateDisplayValue = (numeric: string) => {
@@ -142,19 +158,22 @@ const InputMoney = forwardRef(
142
158
  onChangeText?.('');
143
159
  return;
144
160
  }
145
- if (text.length < lastDisplayValue.length) {
146
- const old = lastDisplayValue;
147
- let start = 0;
148
- while (start < text.length && old[start] === text[start]) {
149
- start += 1;
150
- }
151
- let suffix = 0;
152
- while (
153
- suffix < text.length - start &&
154
- old[old.length - 1 - suffix] === text[text.length - 1 - suffix]
155
- ) {
156
- suffix += 1;
157
- }
161
+ const old = lastDisplayValue;
162
+ let start = 0;
163
+ while (start < text.length && old[start] === text[start]) {
164
+ start += 1;
165
+ }
166
+ let suffix = 0;
167
+ while (
168
+ suffix < Math.min(text.length, old.length) - start &&
169
+ old[old.length - 1 - suffix] === text[text.length - 1 - suffix]
170
+ ) {
171
+ suffix += 1;
172
+ }
173
+ caretDigitsAfter.current = text
174
+ .slice(text.length - suffix)
175
+ .replace(/\D/g, '').length;
176
+ if (text.length < old.length) {
158
177
  const removed = old.slice(start, old.length - suffix);
159
178
  if (!/\d/.test(removed)) {
160
179
  const index = removed.includes('.')
@@ -183,6 +202,7 @@ const InputMoney = forwardRef(
183
202
  };
184
203
 
185
204
  const _setText = (text: string) => {
205
+ caretDigitsAfter.current = undefined;
186
206
  if (!text) {
187
207
  setDisplayValue('');
188
208
  setNumericValue('');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.168.1-beta.3",
3
+ "version": "0.168.1-beta.4",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {},