intl-tel-input 28.0.8 → 28.0.9

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.
@@ -3629,6 +3629,7 @@ var Iti = class _Iti {
3629
3629
  #numerals;
3630
3630
  //* Tracks whether the user has typed/pasted their own formatting chars, so AYT-formatting should back off.
3631
3631
  #userOverrideFormatting = false;
3632
+ #strictPasteSnapshot = null;
3632
3633
  #autoCountryDeferred;
3633
3634
  #utilsDeferred;
3634
3635
  constructor(input, customOptions = {}) {
@@ -3910,21 +3911,30 @@ var Iti = class _Iti {
3910
3911
  if (detail?.["isCountryChange"]) {
3911
3912
  return;
3912
3913
  }
3913
- const inputValue = this.#getTelInputValue();
3914
- if (this.#isAndroid && e?.data === "+" && separateDialCode && allowDropdown && countrySearch) {
3914
+ let inputValue = this.#getTelInputValue();
3915
+ const isPaste = e?.inputType === INPUT_TYPES.PASTE;
3916
+ const isStrictPaste = strictMode && isPaste;
3917
+ if (this.#isAndroid && !isPaste && e?.data === "+" && separateDialCode && allowDropdown && countrySearch) {
3915
3918
  this.#handleAndroidPlusKey(inputValue);
3916
3919
  return;
3917
3920
  }
3918
- if (this.#isAndroid && strictMode && (e?.data === " " || e?.data === "-" || e?.data === ".")) {
3921
+ if (this.#isAndroid && !isPaste && strictMode && (e?.data === " " || e?.data === "-" || e?.data === ".")) {
3919
3922
  this.#handleAndroidStrictReject(inputValue, e.data);
3920
3923
  return;
3921
3924
  }
3925
+ if (isStrictPaste) {
3926
+ const didRejectPaste = this.#handleStrictPasteInputEvent();
3927
+ if (didRejectPaste) {
3928
+ return;
3929
+ }
3930
+ inputValue = this.#getTelInputValue();
3931
+ }
3922
3932
  if (this.#updateCountryFromNumber(inputValue)) {
3923
3933
  this.#dispatchCountryChangeEvent();
3924
3934
  }
3925
- const isFormattingChar = e?.data && REGEX.NON_PLUS_NUMERIC.test(e.data);
3926
- const isPaste = e?.inputType === INPUT_TYPES.PASTE && inputValue;
3927
- if (isFormattingChar || isPaste && !strictMode) {
3935
+ const isFormattingChar = !isStrictPaste && e?.data && REGEX.NON_PLUS_NUMERIC.test(e.data);
3936
+ const isNonStrictPaste = isPaste && inputValue && !strictMode;
3937
+ if (isFormattingChar || isNonStrictPaste) {
3928
3938
  this.#userOverrideFormatting = true;
3929
3939
  } else if (!REGEX.NON_PLUS_NUMERIC.test(inputValue)) {
3930
3940
  this.#userOverrideFormatting = false;
@@ -4004,20 +4014,37 @@ var Iti = class _Iti {
4004
4014
  signal: this.#abortController.signal
4005
4015
  });
4006
4016
  }
4007
- // Handle paste events when strictMode is enabled by sanitising the pasted content before it's inserted into the input, and rejecting it entirely if it would result in an invalid number
4017
+ // In strict mode, remember paste details before the browser inserts the pasted text.
4018
+ // The actual sanitisation runs on the following input event so native paste stays enabled.
4008
4019
  #handleStrictPasteEvent = (e) => {
4009
- e.preventDefault();
4010
4020
  const input = this.#ui.telInputEl;
4011
- const selStart = input.selectionStart;
4012
- const selEnd = input.selectionEnd;
4013
4021
  const inputValue = this.#getTelInputValue();
4014
- const before = inputValue.slice(0, selStart ?? void 0);
4015
- const after = inputValue.slice(selEnd ?? void 0);
4022
+ this.#strictPasteSnapshot = {
4023
+ pastedRaw: e.clipboardData?.getData("text") ?? "",
4024
+ value: inputValue,
4025
+ selectionStart: input.selectionStart ?? inputValue.length,
4026
+ selectionEnd: input.selectionEnd ?? inputValue.length
4027
+ };
4028
+ };
4029
+ // Handle paste input events when strictMode is enabled by sanitising the pasted content after
4030
+ // the browser inserts it, and rejecting it entirely if it would result in an invalid number.
4031
+ #handleStrictPasteInputEvent() {
4032
+ const input = this.#ui.telInputEl;
4033
+ const pasteSnapshot = this.#strictPasteSnapshot;
4034
+ this.#strictPasteSnapshot = null;
4035
+ if (!pasteSnapshot) {
4036
+ return false;
4037
+ }
4038
+ const pastedRaw = pasteSnapshot.pastedRaw;
4039
+ const originalValue = pasteSnapshot.value;
4040
+ const selStart = pasteSnapshot.selectionStart;
4041
+ const selEnd = pasteSnapshot.selectionEnd;
4042
+ const before = originalValue.slice(0, selStart);
4043
+ const after = originalValue.slice(selEnd);
4016
4044
  const iso2 = this.#selectedCountry?.iso2;
4017
- const pastedRaw = e.clipboardData.getData("text");
4018
4045
  const pasted = this.#numerals.normalise(pastedRaw);
4019
4046
  const initialCharSelected = selStart === 0 && selEnd > 0;
4020
- const allowLeadingPlus = !inputValue.startsWith("+") || initialCharSelected;
4047
+ const allowLeadingPlus = !originalValue.startsWith("+") || initialCharSelected;
4021
4048
  const allowedChars = pasted.replace(REGEX.NON_PLUS_NUMERIC_GLOBAL, "");
4022
4049
  const hasLeadingPlus = allowedChars.startsWith("+");
4023
4050
  const numerics = allowedChars.replace(/\+/g, "");
@@ -4031,7 +4058,8 @@ var Iti = class _Iti {
4031
4058
  rejectedInput: pastedRaw,
4032
4059
  reason: "max-length"
4033
4060
  });
4034
- return;
4061
+ this.#restoreValueBeforeStrictPaste(pasteSnapshot);
4062
+ return true;
4035
4063
  }
4036
4064
  if (newValue.length > 5 && intlTelInput.utils) {
4037
4065
  let coreNumber = intlTelInput.utils.getCoreNumber(newValue, iso2);
@@ -4046,10 +4074,11 @@ var Iti = class _Iti {
4046
4074
  rejectedInput: pastedRaw,
4047
4075
  reason: "max-length"
4048
4076
  });
4049
- return;
4077
+ this.#restoreValueBeforeStrictPaste(pasteSnapshot);
4078
+ return true;
4050
4079
  }
4051
4080
  if (this.#maxCoreNumberLength && coreNumber.length > this.#maxCoreNumberLength) {
4052
- if (input.selectionEnd === inputValue.length) {
4081
+ if (selEnd === originalValue.length) {
4053
4082
  const trimLength = coreNumber.length - this.#maxCoreNumberLength;
4054
4083
  newValue = newValue.slice(0, newValue.length - trimLength);
4055
4084
  rejectReason = "max-length";
@@ -4060,14 +4089,14 @@ var Iti = class _Iti {
4060
4089
  rejectedInput: pastedRaw,
4061
4090
  reason: "max-length"
4062
4091
  });
4063
- return;
4092
+ this.#restoreValueBeforeStrictPaste(pasteSnapshot);
4093
+ return true;
4064
4094
  }
4065
4095
  }
4066
4096
  }
4067
4097
  this.#setTelInputValue(newValue);
4068
4098
  const caretPos = selStart + sanitised.length;
4069
4099
  input.setSelectionRange(caretPos, caretPos);
4070
- input.dispatchEvent(new InputEvent("input", { bubbles: true }));
4071
4100
  if (rejectReason) {
4072
4101
  if (pasted.length > 0 && sanitised.length === 0) {
4073
4102
  this.#playStrictRejectAnimation();
@@ -4078,7 +4107,15 @@ var Iti = class _Iti {
4078
4107
  reason: rejectReason
4079
4108
  });
4080
4109
  }
4081
- };
4110
+ return false;
4111
+ }
4112
+ #restoreValueBeforeStrictPaste(pasteSnapshot) {
4113
+ this.#setTelInputValue(pasteSnapshot.value);
4114
+ this.#ui.telInputEl.setSelectionRange(
4115
+ pasteSnapshot.selectionStart,
4116
+ pasteSnapshot.selectionEnd
4117
+ );
4118
+ }
4082
4119
  //* Adhere to the input's maxlength attr.
4083
4120
  #truncateToMaxLength(number) {
4084
4121
  const max = Number(this.#ui.telInputEl.getAttribute("maxlength"));
@@ -4718,7 +4755,7 @@ var intlTelInput = Object.assign(
4718
4755
  attachUtils,
4719
4756
  startedLoadingUtils: false,
4720
4757
  startedLoadingAutoCountry: false,
4721
- version: "28.0.8",
4758
+ version: "28.0.9",
4722
4759
  NUMBER_FORMAT,
4723
4760
  NUMBER_TYPE,
4724
4761
  VALIDATION_ERROR
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "intl-tel-input",
3
- "version": "28.0.8",
3
+ "version": "28.0.9",
4
4
  "description": "A JavaScript library for entering, formatting, and validating international telephone numbers",
5
5
  "type": "module",
6
6
  "license": "MIT",