@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 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.xlarge,
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
- onChangeText === null || onChangeText === void 0 || onChangeText(trimmedPin);
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: maskedValueWithExtraSpace,
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.xlarge,
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
- onChangeText === null || onChangeText === void 0 || onChangeText(trimmedPin);
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: maskedValueWithExtraSpace,
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.8-alpha.1",
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
@@ -40,7 +40,6 @@ export default {
40
40
  'react-native-vector-icons',
41
41
  'react-native-linear-gradient',
42
42
  '@hero-design/react-native-month-year-picker',
43
- '@react-native-clipboard/clipboard',
44
43
  ],
45
44
  plugins: [
46
45
  replace({
@@ -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, Platform, TextInput } from 'react-native';
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
- onChangeText?.(trimmedPin);
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={maskedValueWithExtraSpace}
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.xlarge,
40
+ hiddenInputText: theme.space.xsmall,
41
41
  hiddenInputHorrizontalPadding: theme.space.small,
42
42
  };
43
43