@hero-design/rn 8.64.8-alpha.1 → 8.64.9-alpha.0
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 +6 -0
- package/es/index.js +18 -67
- package/lib/index.js +18 -68
- package/package.json +1 -3
- package/rollup.config.js +0 -1
- package/src/components/PinInput/StyledPinInput.tsx +1 -0
- package/src/components/PinInput/index.tsx +20 -32
- package/src/theme/components/pinInput.ts +1 -1
- package/stats/8.64.8/rn-stats.html +4844 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @hero-design/rn
|
|
2
2
|
|
|
3
|
+
## 8.64.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#3341](https://github.com/Thinkei/hero-design/pull/3341) [`64499bbbdc8c3ee3de9ed61fd1e2d15f95eea7e9`](https://github.com/Thinkei/hero-design/commit/64499bbbdc8c3ee3de9ed61fd1e2d15f95eea7e9) Thanks [@vinhphan-eh](https://github.com/vinhphan-eh)! - [PinInput] Update validation logic
|
|
8
|
+
|
|
3
9
|
## 8.64.7
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/es/index.js
CHANGED
|
@@ -6,7 +6,6 @@ import { createIconSet } from 'react-native-vector-icons';
|
|
|
6
6
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
7
7
|
import { MonthYearPickerViewIOS, MonthYearPickerDialogueAndroid } from '@hero-design/react-native-month-year-picker';
|
|
8
8
|
import DateTimePicker from '@react-native-community/datetimepicker';
|
|
9
|
-
import Clipboard from '@react-native-clipboard/clipboard';
|
|
10
9
|
import RnSlider from '@react-native-community/slider';
|
|
11
10
|
import { RectButton, GestureHandlerRootView, Swipeable as Swipeable$1 } from 'react-native-gesture-handler';
|
|
12
11
|
import LinearGradient from 'react-native-linear-gradient';
|
|
@@ -372,36 +371,6 @@ function _typeof(o) {
|
|
|
372
371
|
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
373
372
|
}, _typeof(o);
|
|
374
373
|
}
|
|
375
|
-
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
376
|
-
try {
|
|
377
|
-
var info = gen[key](arg);
|
|
378
|
-
var value = info.value;
|
|
379
|
-
} catch (error) {
|
|
380
|
-
reject(error);
|
|
381
|
-
return;
|
|
382
|
-
}
|
|
383
|
-
if (info.done) {
|
|
384
|
-
resolve(value);
|
|
385
|
-
} else {
|
|
386
|
-
Promise.resolve(value).then(_next, _throw);
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
function _asyncToGenerator(fn) {
|
|
390
|
-
return function () {
|
|
391
|
-
var self = this,
|
|
392
|
-
args = arguments;
|
|
393
|
-
return new Promise(function (resolve, reject) {
|
|
394
|
-
var gen = fn.apply(self, args);
|
|
395
|
-
function _next(value) {
|
|
396
|
-
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
397
|
-
}
|
|
398
|
-
function _throw(err) {
|
|
399
|
-
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
400
|
-
}
|
|
401
|
-
_next(undefined);
|
|
402
|
-
});
|
|
403
|
-
};
|
|
404
|
-
}
|
|
405
374
|
function _classCallCheck(instance, Constructor) {
|
|
406
375
|
if (!(instance instanceof Constructor)) {
|
|
407
376
|
throw new TypeError("Cannot call a class as a function");
|
|
@@ -2916,7 +2885,7 @@ var getPinInputTheme = function getPinInputTheme(theme) {
|
|
|
2916
2885
|
var space = {
|
|
2917
2886
|
spacer: theme.space.medium,
|
|
2918
2887
|
errorMessagePadding: theme.space.xsmall,
|
|
2919
|
-
hiddenInputText: theme.space.
|
|
2888
|
+
hiddenInputText: theme.space.xsmall,
|
|
2920
2889
|
hiddenInputHorrizontalPadding: theme.space.small
|
|
2921
2890
|
};
|
|
2922
2891
|
var radii = {
|
|
@@ -15557,6 +15526,7 @@ var StyledHiddenInput = index$9(TextInput$1)(function (_ref6) {
|
|
|
15557
15526
|
top: 0,
|
|
15558
15527
|
right: 0,
|
|
15559
15528
|
width: themePinLength * cellWidth + (themePinLength - 1) * spacerWidth,
|
|
15529
|
+
overflow: 'hidden',
|
|
15560
15530
|
height: '100%',
|
|
15561
15531
|
fontSize: theme.__hd__.pinInput.fontSizes.hiddenInputText,
|
|
15562
15532
|
letterSpacing: theme.__hd__.pinInput.space.hiddenInputText,
|
|
@@ -15646,7 +15616,6 @@ var PinInput = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
15646
15616
|
error: error
|
|
15647
15617
|
});
|
|
15648
15618
|
var trimmedValue = normalizeValue(value, length);
|
|
15649
|
-
var maskedValueWithExtraSpace = Platform.OS === 'android' && !trimmedValue ? '*' : trimmedValue;
|
|
15650
15619
|
var focus = useCallback(function () {
|
|
15651
15620
|
if (inputRef !== null && inputRef !== void 0 && inputRef.current) {
|
|
15652
15621
|
inputRef.current.focus();
|
|
@@ -15660,13 +15629,20 @@ var PinInput = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
15660
15629
|
}
|
|
15661
15630
|
}, []);
|
|
15662
15631
|
var changeText = useCallback(function (text) {
|
|
15663
|
-
// Prevent user from entering more than the length
|
|
15664
15632
|
var trimmedPin = normalizeValue(text, length);
|
|
15665
|
-
|
|
15633
|
+
// If current value is already the length, replace it with the new text, starting from the length
|
|
15634
|
+
if (trimmedValue.length === length && trimmedValue.length <= text.length) {
|
|
15635
|
+
// Slice the text, starting from the length position
|
|
15636
|
+
var slicedText = text.slice(length);
|
|
15637
|
+
onChangeText === null || onChangeText === void 0 || onChangeText(normalizeValue(slicedText, length));
|
|
15638
|
+
} else {
|
|
15639
|
+
// Prevent user from entering more than the length
|
|
15640
|
+
onChangeText === null || onChangeText === void 0 || onChangeText(trimmedPin);
|
|
15641
|
+
}
|
|
15666
15642
|
if (trimmedPin.length === length) {
|
|
15667
15643
|
onFulfill === null || onFulfill === void 0 || onFulfill(trimmedPin);
|
|
15668
15644
|
}
|
|
15669
|
-
}, [length, onChangeText, onFulfill]);
|
|
15645
|
+
}, [length, onChangeText, onFulfill, trimmedValue.length]);
|
|
15670
15646
|
useEffect(function () {
|
|
15671
15647
|
// Must run after animations for keyboard to automatically open
|
|
15672
15648
|
if (autoFocus) {
|
|
@@ -15679,35 +15655,6 @@ var PinInput = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
15679
15655
|
blur: blur
|
|
15680
15656
|
};
|
|
15681
15657
|
});
|
|
15682
|
-
useEffect(function () {
|
|
15683
|
-
var autoFillInterval = setInterval( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
15684
|
-
var clipboardContent, canAutoFill, isValidClipboardContent;
|
|
15685
|
-
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
15686
|
-
while (1) switch (_context.prev = _context.next) {
|
|
15687
|
-
case 0:
|
|
15688
|
-
if (!(Platform.OS === 'android')) {
|
|
15689
|
-
_context.next = 7;
|
|
15690
|
-
break;
|
|
15691
|
-
}
|
|
15692
|
-
_context.next = 3;
|
|
15693
|
-
return Clipboard.getString();
|
|
15694
|
-
case 3:
|
|
15695
|
-
clipboardContent = _context.sent;
|
|
15696
|
-
canAutoFill = autoComplete === 'one-time-code' || textContentType === 'oneTimeCode';
|
|
15697
|
-
isValidClipboardContent = clipboardContent && clipboardContent.match(/^\d+$/) || normalizeValue(clipboardContent, length) !== trimmedValue;
|
|
15698
|
-
if (canAutoFill && isValidClipboardContent) {
|
|
15699
|
-
onChangeText === null || onChangeText === void 0 || onChangeText(clipboardContent);
|
|
15700
|
-
}
|
|
15701
|
-
case 7:
|
|
15702
|
-
case "end":
|
|
15703
|
-
return _context.stop();
|
|
15704
|
-
}
|
|
15705
|
-
}, _callee);
|
|
15706
|
-
})), 1000);
|
|
15707
|
-
return function () {
|
|
15708
|
-
clearInterval(autoFillInterval);
|
|
15709
|
-
};
|
|
15710
|
-
}, [autoComplete, textContentType, onChangeText, trimmedValue, length]);
|
|
15711
15658
|
return /*#__PURE__*/React__default.createElement(StyledWrapper$5, {
|
|
15712
15659
|
style: style,
|
|
15713
15660
|
testID: testID
|
|
@@ -15728,7 +15675,7 @@ var PinInput = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
15728
15675
|
}), /*#__PURE__*/React__default.createElement(StyledErrorMessage, null, error)), /*#__PURE__*/React__default.createElement(StyledHiddenInput, {
|
|
15729
15676
|
themePinLength: length,
|
|
15730
15677
|
ref: inputRef,
|
|
15731
|
-
value:
|
|
15678
|
+
value: trimmedValue,
|
|
15732
15679
|
onChangeText: changeText,
|
|
15733
15680
|
secureTextEntry: secure,
|
|
15734
15681
|
editable: !disabled,
|
|
@@ -15740,7 +15687,11 @@ var PinInput = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
15740
15687
|
testID: "pin-hidden-input",
|
|
15741
15688
|
textContentType: textContentType,
|
|
15742
15689
|
autoComplete: autoComplete,
|
|
15743
|
-
selectTextOnFocus: false
|
|
15690
|
+
selectTextOnFocus: false,
|
|
15691
|
+
selection: {
|
|
15692
|
+
start: trimmedValue.length,
|
|
15693
|
+
end: trimmedValue.length + 1
|
|
15694
|
+
}
|
|
15744
15695
|
}));
|
|
15745
15696
|
});
|
|
15746
15697
|
PinInput.displayName = 'PinInput';
|
package/lib/index.js
CHANGED
|
@@ -8,7 +8,6 @@ var reactNativeVectorIcons = require('react-native-vector-icons');
|
|
|
8
8
|
var reactNativeSafeAreaContext = require('react-native-safe-area-context');
|
|
9
9
|
var reactNativeMonthYearPicker = require('@hero-design/react-native-month-year-picker');
|
|
10
10
|
var DateTimePicker = require('@react-native-community/datetimepicker');
|
|
11
|
-
var Clipboard = require('@react-native-clipboard/clipboard');
|
|
12
11
|
var RnSlider = require('@react-native-community/slider');
|
|
13
12
|
var reactNativeGestureHandler = require('react-native-gesture-handler');
|
|
14
13
|
var LinearGradient = require('react-native-linear-gradient');
|
|
@@ -40,7 +39,6 @@ var reactNative__namespace = /*#__PURE__*/_interopNamespace(reactNative);
|
|
|
40
39
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
41
40
|
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
42
41
|
var DateTimePicker__default = /*#__PURE__*/_interopDefaultLegacy(DateTimePicker);
|
|
43
|
-
var Clipboard__default = /*#__PURE__*/_interopDefaultLegacy(Clipboard);
|
|
44
42
|
var RnSlider__default = /*#__PURE__*/_interopDefaultLegacy(RnSlider);
|
|
45
43
|
var LinearGradient__default = /*#__PURE__*/_interopDefaultLegacy(LinearGradient);
|
|
46
44
|
var PagerView__default = /*#__PURE__*/_interopDefaultLegacy(PagerView);
|
|
@@ -403,36 +401,6 @@ function _typeof(o) {
|
|
|
403
401
|
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
404
402
|
}, _typeof(o);
|
|
405
403
|
}
|
|
406
|
-
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
407
|
-
try {
|
|
408
|
-
var info = gen[key](arg);
|
|
409
|
-
var value = info.value;
|
|
410
|
-
} catch (error) {
|
|
411
|
-
reject(error);
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
414
|
-
if (info.done) {
|
|
415
|
-
resolve(value);
|
|
416
|
-
} else {
|
|
417
|
-
Promise.resolve(value).then(_next, _throw);
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
function _asyncToGenerator(fn) {
|
|
421
|
-
return function () {
|
|
422
|
-
var self = this,
|
|
423
|
-
args = arguments;
|
|
424
|
-
return new Promise(function (resolve, reject) {
|
|
425
|
-
var gen = fn.apply(self, args);
|
|
426
|
-
function _next(value) {
|
|
427
|
-
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
428
|
-
}
|
|
429
|
-
function _throw(err) {
|
|
430
|
-
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
431
|
-
}
|
|
432
|
-
_next(undefined);
|
|
433
|
-
});
|
|
434
|
-
};
|
|
435
|
-
}
|
|
436
404
|
function _classCallCheck(instance, Constructor) {
|
|
437
405
|
if (!(instance instanceof Constructor)) {
|
|
438
406
|
throw new TypeError("Cannot call a class as a function");
|
|
@@ -2947,7 +2915,7 @@ var getPinInputTheme = function getPinInputTheme(theme) {
|
|
|
2947
2915
|
var space = {
|
|
2948
2916
|
spacer: theme.space.medium,
|
|
2949
2917
|
errorMessagePadding: theme.space.xsmall,
|
|
2950
|
-
hiddenInputText: theme.space.
|
|
2918
|
+
hiddenInputText: theme.space.xsmall,
|
|
2951
2919
|
hiddenInputHorrizontalPadding: theme.space.small
|
|
2952
2920
|
};
|
|
2953
2921
|
var radii = {
|
|
@@ -15588,6 +15556,7 @@ var StyledHiddenInput = index$9(reactNative.TextInput)(function (_ref6) {
|
|
|
15588
15556
|
top: 0,
|
|
15589
15557
|
right: 0,
|
|
15590
15558
|
width: themePinLength * cellWidth + (themePinLength - 1) * spacerWidth,
|
|
15559
|
+
overflow: 'hidden',
|
|
15591
15560
|
height: '100%',
|
|
15592
15561
|
fontSize: theme.__hd__.pinInput.fontSizes.hiddenInputText,
|
|
15593
15562
|
letterSpacing: theme.__hd__.pinInput.space.hiddenInputText,
|
|
@@ -15677,7 +15646,6 @@ var PinInput = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
|
|
|
15677
15646
|
error: error
|
|
15678
15647
|
});
|
|
15679
15648
|
var trimmedValue = normalizeValue(value, length);
|
|
15680
|
-
var maskedValueWithExtraSpace = reactNative.Platform.OS === 'android' && !trimmedValue ? '*' : trimmedValue;
|
|
15681
15649
|
var focus = React.useCallback(function () {
|
|
15682
15650
|
if (inputRef !== null && inputRef !== void 0 && inputRef.current) {
|
|
15683
15651
|
inputRef.current.focus();
|
|
@@ -15691,13 +15659,20 @@ var PinInput = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
|
|
|
15691
15659
|
}
|
|
15692
15660
|
}, []);
|
|
15693
15661
|
var changeText = React.useCallback(function (text) {
|
|
15694
|
-
// Prevent user from entering more than the length
|
|
15695
15662
|
var trimmedPin = normalizeValue(text, length);
|
|
15696
|
-
|
|
15663
|
+
// If current value is already the length, replace it with the new text, starting from the length
|
|
15664
|
+
if (trimmedValue.length === length && trimmedValue.length <= text.length) {
|
|
15665
|
+
// Slice the text, starting from the length position
|
|
15666
|
+
var slicedText = text.slice(length);
|
|
15667
|
+
onChangeText === null || onChangeText === void 0 || onChangeText(normalizeValue(slicedText, length));
|
|
15668
|
+
} else {
|
|
15669
|
+
// Prevent user from entering more than the length
|
|
15670
|
+
onChangeText === null || onChangeText === void 0 || onChangeText(trimmedPin);
|
|
15671
|
+
}
|
|
15697
15672
|
if (trimmedPin.length === length) {
|
|
15698
15673
|
onFulfill === null || onFulfill === void 0 || onFulfill(trimmedPin);
|
|
15699
15674
|
}
|
|
15700
|
-
}, [length, onChangeText, onFulfill]);
|
|
15675
|
+
}, [length, onChangeText, onFulfill, trimmedValue.length]);
|
|
15701
15676
|
React.useEffect(function () {
|
|
15702
15677
|
// Must run after animations for keyboard to automatically open
|
|
15703
15678
|
if (autoFocus) {
|
|
@@ -15710,35 +15685,6 @@ var PinInput = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
|
|
|
15710
15685
|
blur: blur
|
|
15711
15686
|
};
|
|
15712
15687
|
});
|
|
15713
|
-
React.useEffect(function () {
|
|
15714
|
-
var autoFillInterval = setInterval( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
15715
|
-
var clipboardContent, canAutoFill, isValidClipboardContent;
|
|
15716
|
-
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
15717
|
-
while (1) switch (_context.prev = _context.next) {
|
|
15718
|
-
case 0:
|
|
15719
|
-
if (!(reactNative.Platform.OS === 'android')) {
|
|
15720
|
-
_context.next = 7;
|
|
15721
|
-
break;
|
|
15722
|
-
}
|
|
15723
|
-
_context.next = 3;
|
|
15724
|
-
return Clipboard__default["default"].getString();
|
|
15725
|
-
case 3:
|
|
15726
|
-
clipboardContent = _context.sent;
|
|
15727
|
-
canAutoFill = autoComplete === 'one-time-code' || textContentType === 'oneTimeCode';
|
|
15728
|
-
isValidClipboardContent = clipboardContent && clipboardContent.match(/^\d+$/) || normalizeValue(clipboardContent, length) !== trimmedValue;
|
|
15729
|
-
if (canAutoFill && isValidClipboardContent) {
|
|
15730
|
-
onChangeText === null || onChangeText === void 0 || onChangeText(clipboardContent);
|
|
15731
|
-
}
|
|
15732
|
-
case 7:
|
|
15733
|
-
case "end":
|
|
15734
|
-
return _context.stop();
|
|
15735
|
-
}
|
|
15736
|
-
}, _callee);
|
|
15737
|
-
})), 1000);
|
|
15738
|
-
return function () {
|
|
15739
|
-
clearInterval(autoFillInterval);
|
|
15740
|
-
};
|
|
15741
|
-
}, [autoComplete, textContentType, onChangeText, trimmedValue, length]);
|
|
15742
15688
|
return /*#__PURE__*/React__default["default"].createElement(StyledWrapper$5, {
|
|
15743
15689
|
style: style,
|
|
15744
15690
|
testID: testID
|
|
@@ -15759,7 +15705,7 @@ var PinInput = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
|
|
|
15759
15705
|
}), /*#__PURE__*/React__default["default"].createElement(StyledErrorMessage, null, error)), /*#__PURE__*/React__default["default"].createElement(StyledHiddenInput, {
|
|
15760
15706
|
themePinLength: length,
|
|
15761
15707
|
ref: inputRef,
|
|
15762
|
-
value:
|
|
15708
|
+
value: trimmedValue,
|
|
15763
15709
|
onChangeText: changeText,
|
|
15764
15710
|
secureTextEntry: secure,
|
|
15765
15711
|
editable: !disabled,
|
|
@@ -15771,7 +15717,11 @@ var PinInput = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
|
|
|
15771
15717
|
testID: "pin-hidden-input",
|
|
15772
15718
|
textContentType: textContentType,
|
|
15773
15719
|
autoComplete: autoComplete,
|
|
15774
|
-
selectTextOnFocus: false
|
|
15720
|
+
selectTextOnFocus: false,
|
|
15721
|
+
selection: {
|
|
15722
|
+
start: trimmedValue.length,
|
|
15723
|
+
end: trimmedValue.length + 1
|
|
15724
|
+
}
|
|
15775
15725
|
}));
|
|
15776
15726
|
});
|
|
15777
15727
|
PinInput.displayName = 'PinInput';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hero-design/rn",
|
|
3
|
-
"version": "8.64.
|
|
3
|
+
"version": "8.64.9-alpha.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "es/index.js",
|
|
@@ -29,7 +29,6 @@
|
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"@hero-design/react-native-month-year-picker": "^8.42.10",
|
|
32
|
-
"@react-native-clipboard/clipboard": "^1.13.2",
|
|
33
32
|
"@react-native-community/datetimepicker": "^3.5.2 || ^7.6.1",
|
|
34
33
|
"@react-native-community/slider": "^4.5.1",
|
|
35
34
|
"react": "18.2.0",
|
|
@@ -53,7 +52,6 @@
|
|
|
53
52
|
"@eslint/js": "^9.8.0",
|
|
54
53
|
"@hero-design/eslint-plugin": "9.2.0",
|
|
55
54
|
"@hero-design/react-native-month-year-picker": "^8.42.10",
|
|
56
|
-
"@react-native-clipboard/clipboard": "^1.14.2",
|
|
57
55
|
"@react-native-community/datetimepicker": "7.6.1",
|
|
58
56
|
"@react-native-community/slider": "^4.5.1",
|
|
59
57
|
"@rollup/plugin-babel": "^5.3.1",
|
package/rollup.config.js
CHANGED
|
@@ -70,6 +70,7 @@ export const StyledHiddenInput = styled(TextInput)<{ themePinLength: number }>(
|
|
|
70
70
|
top: 0,
|
|
71
71
|
right: 0,
|
|
72
72
|
width: themePinLength * cellWidth + (themePinLength - 1) * spacerWidth,
|
|
73
|
+
overflow: 'hidden',
|
|
73
74
|
height: '100%',
|
|
74
75
|
fontSize: theme.__hd__.pinInput.fontSizes.hiddenInputText,
|
|
75
76
|
letterSpacing: theme.__hd__.pinInput.space.hiddenInputText,
|
|
@@ -7,9 +7,8 @@ import React, {
|
|
|
7
7
|
useRef,
|
|
8
8
|
useState,
|
|
9
9
|
} from 'react';
|
|
10
|
-
import { InteractionManager,
|
|
10
|
+
import { InteractionManager, TextInput } from 'react-native';
|
|
11
11
|
import type { StyleProp, ViewStyle } from 'react-native';
|
|
12
|
-
import Clipboard from '@react-native-clipboard/clipboard';
|
|
13
12
|
import Icon from '../Icon';
|
|
14
13
|
import PinCell from './PinCell';
|
|
15
14
|
import {
|
|
@@ -128,9 +127,6 @@ const PinInput = forwardRef<PinInputHandler, PinInputProps>(
|
|
|
128
127
|
const state = getState({ disabled, error });
|
|
129
128
|
const trimmedValue = normalizeValue(value, length);
|
|
130
129
|
|
|
131
|
-
const maskedValueWithExtraSpace =
|
|
132
|
-
Platform.OS === 'android' && !trimmedValue ? '*' : trimmedValue;
|
|
133
|
-
|
|
134
130
|
const focus = useCallback(() => {
|
|
135
131
|
if (inputRef?.current) {
|
|
136
132
|
inputRef.current.focus();
|
|
@@ -144,19 +140,29 @@ const PinInput = forwardRef<PinInputHandler, PinInputProps>(
|
|
|
144
140
|
setFocused(false);
|
|
145
141
|
}
|
|
146
142
|
}, []);
|
|
147
|
-
|
|
148
143
|
const changeText = useCallback(
|
|
149
144
|
(text: string) => {
|
|
150
|
-
// Prevent user from entering more than the length
|
|
151
145
|
const trimmedPin = normalizeValue(text, length);
|
|
152
146
|
|
|
153
|
-
|
|
147
|
+
// If current value is already the length, replace it with the new text, starting from the length
|
|
148
|
+
if (
|
|
149
|
+
trimmedValue.length === length &&
|
|
150
|
+
trimmedValue.length <= text.length
|
|
151
|
+
) {
|
|
152
|
+
// Slice the text, starting from the length position
|
|
153
|
+
const slicedText = text.slice(length);
|
|
154
|
+
|
|
155
|
+
onChangeText?.(normalizeValue(slicedText, length));
|
|
156
|
+
} else {
|
|
157
|
+
// Prevent user from entering more than the length
|
|
158
|
+
onChangeText?.(trimmedPin);
|
|
159
|
+
}
|
|
154
160
|
|
|
155
161
|
if (trimmedPin.length === length) {
|
|
156
162
|
onFulfill?.(trimmedPin);
|
|
157
163
|
}
|
|
158
164
|
},
|
|
159
|
-
[length, onChangeText, onFulfill]
|
|
165
|
+
[length, onChangeText, onFulfill, trimmedValue.length]
|
|
160
166
|
);
|
|
161
167
|
|
|
162
168
|
useEffect(() => {
|
|
@@ -171,28 +177,6 @@ const PinInput = forwardRef<PinInputHandler, PinInputProps>(
|
|
|
171
177
|
blur,
|
|
172
178
|
}));
|
|
173
179
|
|
|
174
|
-
useEffect(() => {
|
|
175
|
-
const autoFillInterval = setInterval(async () => {
|
|
176
|
-
if (Platform.OS === 'android') {
|
|
177
|
-
const clipboardContent = await Clipboard.getString();
|
|
178
|
-
const canAutoFill =
|
|
179
|
-
autoComplete === 'one-time-code' ||
|
|
180
|
-
textContentType === 'oneTimeCode';
|
|
181
|
-
const isValidClipboardContent =
|
|
182
|
-
(clipboardContent && clipboardContent.match(/^\d+$/)) ||
|
|
183
|
-
normalizeValue(clipboardContent, length) !== trimmedValue;
|
|
184
|
-
|
|
185
|
-
if (canAutoFill && isValidClipboardContent) {
|
|
186
|
-
onChangeText?.(clipboardContent);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}, 1000);
|
|
190
|
-
|
|
191
|
-
return () => {
|
|
192
|
-
clearInterval(autoFillInterval);
|
|
193
|
-
};
|
|
194
|
-
}, [autoComplete, textContentType, onChangeText, trimmedValue, length]);
|
|
195
|
-
|
|
196
180
|
return (
|
|
197
181
|
<StyledWrapper style={style} testID={testID}>
|
|
198
182
|
<StyledPinWrapper>
|
|
@@ -222,7 +206,7 @@ const PinInput = forwardRef<PinInputHandler, PinInputProps>(
|
|
|
222
206
|
<StyledHiddenInput
|
|
223
207
|
themePinLength={length}
|
|
224
208
|
ref={inputRef}
|
|
225
|
-
value={
|
|
209
|
+
value={trimmedValue}
|
|
226
210
|
onChangeText={changeText}
|
|
227
211
|
secureTextEntry={secure}
|
|
228
212
|
editable={!disabled}
|
|
@@ -235,6 +219,10 @@ const PinInput = forwardRef<PinInputHandler, PinInputProps>(
|
|
|
235
219
|
textContentType={textContentType}
|
|
236
220
|
autoComplete={autoComplete}
|
|
237
221
|
selectTextOnFocus={false}
|
|
222
|
+
selection={{
|
|
223
|
+
start: trimmedValue.length,
|
|
224
|
+
end: trimmedValue.length + 1,
|
|
225
|
+
}}
|
|
238
226
|
/>
|
|
239
227
|
</StyledWrapper>
|
|
240
228
|
);
|
|
@@ -37,7 +37,7 @@ const getPinInputTheme = (theme: GlobalTheme) => {
|
|
|
37
37
|
const space = {
|
|
38
38
|
spacer: theme.space.medium,
|
|
39
39
|
errorMessagePadding: theme.space.xsmall,
|
|
40
|
-
hiddenInputText: theme.space.
|
|
40
|
+
hiddenInputText: theme.space.xsmall,
|
|
41
41
|
hiddenInputHorrizontalPadding: theme.space.small,
|
|
42
42
|
};
|
|
43
43
|
|