intl-tel-input 27.3.0 → 27.3.1

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.
@@ -1,5 +1,5 @@
1
1
  /*
2
- * International Telephone Input v27.3.0
2
+ * International Telephone Input v27.3.1
3
3
  * git+https://github.com/jackocnr/intl-tel-input.git
4
4
  * Licensed under the MIT license
5
5
  */
@@ -1774,13 +1774,7 @@ var _factory = (() => {
1774
1774
  dialCode: c[1],
1775
1775
  priority: c[2] || 0,
1776
1776
  areaCodes: c[3] || null,
1777
- nationalPrefix: c[4] || null,
1778
- normalisedName: "",
1779
- // populated in the plugin
1780
- initials: "",
1781
- // populated in the plugin
1782
- dialCodePlus: ""
1783
- // populated in the plugin
1777
+ nationalPrefix: c[4] || null
1784
1778
  });
1785
1779
  }
1786
1780
  var iso2Set = new Set(allCountries.map((c) => c.iso2));
@@ -2293,7 +2287,20 @@ var _factory = (() => {
2293
2287
  </svg>`;
2294
2288
 
2295
2289
  // src/js/core/countrySearch.ts
2296
- var getMatchedCountries = (countries, query) => {
2290
+ var buildSearchTokens = (countries) => {
2291
+ const tokens = /* @__PURE__ */ new Map();
2292
+ for (const c of countries) {
2293
+ const normalisedName = normaliseString(c.name);
2294
+ const initials = normalisedName.split(/[^a-z]/).map((word) => word[0]).join("");
2295
+ tokens.set(c.iso2, {
2296
+ normalisedName,
2297
+ initials,
2298
+ dialCodePlus: `+${c.dialCode}`
2299
+ });
2300
+ }
2301
+ return tokens;
2302
+ };
2303
+ var getMatchedCountries = (countries, searchTokens, query) => {
2297
2304
  const normalisedQuery = normaliseString(query);
2298
2305
  const iso2Matches = [];
2299
2306
  const nameStartsWith = [];
@@ -2302,17 +2309,18 @@ var _factory = (() => {
2302
2309
  const dialCodeContains = [];
2303
2310
  const initialsMatches = [];
2304
2311
  for (const c of countries) {
2312
+ const t = searchTokens.get(c.iso2);
2305
2313
  if (c.iso2 === normalisedQuery) {
2306
2314
  iso2Matches.push(c);
2307
- } else if (c.normalisedName.startsWith(normalisedQuery)) {
2315
+ } else if (t.normalisedName.startsWith(normalisedQuery)) {
2308
2316
  nameStartsWith.push(c);
2309
- } else if (c.normalisedName.includes(normalisedQuery)) {
2317
+ } else if (t.normalisedName.includes(normalisedQuery)) {
2310
2318
  nameContains.push(c);
2311
- } else if (normalisedQuery === c.dialCode || normalisedQuery === c.dialCodePlus) {
2319
+ } else if (normalisedQuery === c.dialCode || normalisedQuery === t.dialCodePlus) {
2312
2320
  dialCodeMatches.push(c);
2313
- } else if (c.dialCodePlus.includes(normalisedQuery)) {
2321
+ } else if (t.dialCodePlus.includes(normalisedQuery)) {
2314
2322
  dialCodeContains.push(c);
2315
- } else if (c.initials.includes(normalisedQuery)) {
2323
+ } else if (t.initials.includes(normalisedQuery)) {
2316
2324
  initialsMatches.push(c);
2317
2325
  }
2318
2326
  }
@@ -2327,16 +2335,75 @@ var _factory = (() => {
2327
2335
  ...initialsMatches
2328
2336
  ];
2329
2337
  };
2330
- var findFirstCountryStartingWith = (countries, query) => {
2338
+ var findFirstCountryStartingWith = (countries, searchTokens, query) => {
2331
2339
  const normalisedQuery = normaliseString(query);
2332
2340
  for (const c of countries) {
2333
- if (c.normalisedName.startsWith(normalisedQuery)) {
2341
+ const { normalisedName } = searchTokens.get(c.iso2);
2342
+ if (normalisedName.startsWith(normalisedQuery)) {
2334
2343
  return c;
2335
2344
  }
2336
2345
  }
2337
2346
  return null;
2338
2347
  };
2339
2348
 
2349
+ // src/js/core/numerals.ts
2350
+ var Numerals = class _Numerals {
2351
+ #userNumeralSet;
2352
+ //* Stateless conversion of any Arabic-Indic / Persian digits to ASCII 0-9.
2353
+ //* Use this when you need to normalise digits without affecting any instance's tracked numeral set (e.g. for the country-search query).
2354
+ static toAscii(str) {
2355
+ if (!str) {
2356
+ return "";
2357
+ }
2358
+ return str.replace(
2359
+ /[٠-٩]/g,
2360
+ (ch) => String.fromCharCode(48 + (ch.charCodeAt(0) - 1632))
2361
+ ).replace(
2362
+ /[۰-۹]/g,
2363
+ (ch) => String.fromCharCode(48 + (ch.charCodeAt(0) - 1776))
2364
+ );
2365
+ }
2366
+ constructor(initialValue) {
2367
+ if (initialValue) {
2368
+ this.#updateNumeralSet(initialValue);
2369
+ }
2370
+ }
2371
+ // If any Arabic-Indic digits, then label it as that set. Same for Persian. Otherwise assume ASCII.
2372
+ #updateNumeralSet(str) {
2373
+ if (/[٠-٩]/.test(str)) {
2374
+ this.#userNumeralSet = "arabic-indic";
2375
+ } else if (/[۰-۹]/.test(str)) {
2376
+ this.#userNumeralSet = "persian";
2377
+ } else {
2378
+ this.#userNumeralSet = "ascii";
2379
+ }
2380
+ }
2381
+ // Denormalise ASCII 0-9 to the user's numeral set. If not yet known, return as-is.
2382
+ // NOTE: normalise is always called before this, so it should be impossible for the numeral set to be unknown at this point.
2383
+ denormalise(str) {
2384
+ if (!this.#userNumeralSet || this.#userNumeralSet === "ascii") {
2385
+ return str;
2386
+ }
2387
+ const base = this.#userNumeralSet === "arabic-indic" ? 1632 : 1776;
2388
+ return str.replace(/[0-9]/g, (d) => String.fromCharCode(base + Number(d)));
2389
+ }
2390
+ // Normalize Eastern Arabic (U+0660-0669) and Persian/Extended Arabic-Indic (U+06F0-06F9) numerals to ASCII 0-9.
2391
+ // Tracks the user's numeral set as a side effect so denormalise can mirror it back.
2392
+ normalise(str) {
2393
+ if (!str) {
2394
+ return "";
2395
+ }
2396
+ this.#updateNumeralSet(str);
2397
+ if (this.#userNumeralSet === "ascii") {
2398
+ return str;
2399
+ }
2400
+ return _Numerals.toAscii(str);
2401
+ }
2402
+ isAscii() {
2403
+ return !this.#userNumeralSet || this.#userNumeralSet === "ascii";
2404
+ }
2405
+ };
2406
+
2340
2407
  // src/js/core/ui.ts
2341
2408
  var UI = class _UI {
2342
2409
  // private
@@ -2345,6 +2412,7 @@ var _factory = (() => {
2345
2412
  #isRTL;
2346
2413
  #originalPaddingLeft = "";
2347
2414
  #countries;
2415
+ #searchTokens;
2348
2416
  #searchDebounceTimer = null;
2349
2417
  #inlineDropdownHeight;
2350
2418
  #countryContainerEl;
@@ -2390,8 +2458,9 @@ var _factory = (() => {
2390
2458
  }
2391
2459
  }
2392
2460
  //* Generate all of the markup for the plugin: the selected country overlay, and the dropdown.
2393
- buildMarkup(countries) {
2461
+ buildMarkup(countries, searchTokens) {
2394
2462
  this.#countries = countries;
2463
+ this.#searchTokens = searchTokens;
2395
2464
  this.telInputEl.classList.add("iti__tel-input");
2396
2465
  if (!this.telInputEl.hasAttribute("type")) {
2397
2466
  this.telInputEl.setAttribute("type", "tel");
@@ -2759,7 +2828,12 @@ var _factory = (() => {
2759
2828
  if (query === "") {
2760
2829
  matchedCountries = this.#countries;
2761
2830
  } else {
2762
- matchedCountries = getMatchedCountries(this.#countries, query);
2831
+ const normalisedQuery = Numerals.toAscii(query);
2832
+ matchedCountries = getMatchedCountries(
2833
+ this.#countries,
2834
+ this.#searchTokens,
2835
+ normalisedQuery
2836
+ );
2763
2837
  }
2764
2838
  this.#showFilteredCountries(matchedCountries);
2765
2839
  }
@@ -3054,7 +3128,11 @@ var _factory = (() => {
3054
3128
  }
3055
3129
  //* Hidden search (countrySearch disabled): jump to the first list item whose name starts with the query.
3056
3130
  #searchForCountry(query) {
3057
- const match = findFirstCountryStartingWith(this.#countries, query);
3131
+ const match = findFirstCountryStartingWith(
3132
+ this.#countries,
3133
+ this.#searchTokens,
3134
+ query
3135
+ );
3058
3136
  if (match) {
3059
3137
  const listItem = this.#listItemByIso2.get(match.iso2);
3060
3138
  this.#highlightListItem(listItem);
@@ -3366,13 +3444,6 @@ var _factory = (() => {
3366
3444
  return a.name.localeCompare(b.name);
3367
3445
  });
3368
3446
  };
3369
- var cacheSearchTokens = (countries) => {
3370
- for (const c of countries) {
3371
- c.normalisedName = normaliseString(c.name);
3372
- c.initials = c.normalisedName.split(/[^a-z]/).map((word) => word[0]).join("");
3373
- c.dialCodePlus = `+${c.dialCode}`;
3374
- }
3375
- };
3376
3447
 
3377
3448
  // src/js/data/intl-regionless.ts
3378
3449
  var regionlessDialCodes = /* @__PURE__ */ new Set([
@@ -3458,54 +3529,6 @@ var _factory = (() => {
3458
3529
  return false;
3459
3530
  };
3460
3531
 
3461
- // src/js/core/numerals.ts
3462
- var Numerals = class {
3463
- #userNumeralSet;
3464
- constructor(initialValue) {
3465
- if (initialValue) {
3466
- this.#updateNumeralSet(initialValue);
3467
- }
3468
- }
3469
- // If any Arabic-Indic digits, then label it as that set. Same for Persian. Otherwise assume ASCII.
3470
- #updateNumeralSet(str) {
3471
- if (/[\u0660-\u0669]/.test(str)) {
3472
- this.#userNumeralSet = "arabic-indic";
3473
- } else if (/[\u06F0-\u06F9]/.test(str)) {
3474
- this.#userNumeralSet = "persian";
3475
- } else {
3476
- this.#userNumeralSet = "ascii";
3477
- }
3478
- }
3479
- // Denormalise ASCII 0-9 to the user's numeral set. If not yet known, return as-is.
3480
- // NOTE: normalise is always called before this, so it should be impossible for the numeral set to be unknown at this point.
3481
- denormalise(str) {
3482
- if (!this.#userNumeralSet || this.#userNumeralSet === "ascii") {
3483
- return str;
3484
- }
3485
- const base = this.#userNumeralSet === "arabic-indic" ? 1632 : 1776;
3486
- return str.replace(/[0-9]/g, (d) => String.fromCharCode(base + Number(d)));
3487
- }
3488
- // Normalize Eastern Arabic (U+0660-0669) and Persian/Extended Arabic-Indic (U+06F0-06F9) numerals to ASCII 0-9
3489
- normalise(str) {
3490
- if (!str) {
3491
- return "";
3492
- }
3493
- this.#updateNumeralSet(str);
3494
- if (this.#userNumeralSet === "ascii") {
3495
- return str;
3496
- }
3497
- const base = this.#userNumeralSet === "arabic-indic" ? 1632 : 1776;
3498
- const regex = this.#userNumeralSet === "arabic-indic" ? /[\u0660-\u0669]/g : /[\u06F0-\u06F9]/g;
3499
- return str.replace(
3500
- regex,
3501
- (ch) => String.fromCharCode(48 + (ch.charCodeAt(0) - base))
3502
- );
3503
- }
3504
- isAscii() {
3505
- return !this.#userNumeralSet || this.#userNumeralSet === "ascii";
3506
- }
3507
- };
3508
-
3509
3532
  // src/js/intlTelInput.ts
3510
3533
  var nextId = 0;
3511
3534
  var ensureUtils = (methodName) => {
@@ -3540,6 +3563,7 @@ var _factory = (() => {
3540
3563
  #dialCodeToIso2Map;
3541
3564
  #dialCodes;
3542
3565
  #countryByIso2;
3566
+ #searchTokens;
3543
3567
  #selectedCountry = null;
3544
3568
  #maxCoreNumberLength = null;
3545
3569
  #fallbackCountryIso2;
@@ -3596,7 +3620,7 @@ var _factory = (() => {
3596
3620
  #init() {
3597
3621
  this.#abortController = new AbortController();
3598
3622
  this.#processCountryData();
3599
- this.#ui.buildMarkup(this.#countries);
3623
+ this.#ui.buildMarkup(this.#countries, this.#searchTokens);
3600
3624
  this.#setInitialState();
3601
3625
  this.#initListeners();
3602
3626
  this.#startAsyncLoads();
@@ -3611,7 +3635,7 @@ var _factory = (() => {
3611
3635
  #processCountryData() {
3612
3636
  generateCountryNames(this.#countries, this.#options);
3613
3637
  sortCountries(this.#countries, this.#options);
3614
- cacheSearchTokens(this.#countries);
3638
+ this.#searchTokens = buildSearchTokens(this.#countries);
3615
3639
  }
3616
3640
  //* Set the initial state of the input value and the selected country by:
3617
3641
  //* 1. Extracting a dial code from the given number
@@ -3734,7 +3758,7 @@ var _factory = (() => {
3734
3758
  #bindAllTelInputListeners() {
3735
3759
  this.#bindInputListener();
3736
3760
  this.#bindKeydownListener();
3737
- this.#bindPasteListener();
3761
+ this.#bindStrictPasteListener();
3738
3762
  }
3739
3763
  //* Android workaround for handling plus when separateDialCode enabled (as impossible to handle with keydown/keyup, for which e.key always returns "Unidentified", see https://stackoverflow.com/q/59584061/217866)
3740
3764
  #handleAndroidPlusKey(inputValue) {
@@ -3902,15 +3926,16 @@ var _factory = (() => {
3902
3926
  e.preventDefault();
3903
3927
  }
3904
3928
  };
3905
- #bindPasteListener() {
3929
+ #bindStrictPasteListener() {
3906
3930
  if (!this.#options.strictMode) {
3907
3931
  return;
3908
3932
  }
3909
- this.#ui.telInputEl.addEventListener("paste", this.#handlePasteEvent, {
3933
+ this.#ui.telInputEl.addEventListener("paste", this.#handleStrictPasteEvent, {
3910
3934
  signal: this.#abortController.signal
3911
3935
  });
3912
3936
  }
3913
- #handlePasteEvent = (e) => {
3937
+ // 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
3938
+ #handleStrictPasteEvent = (e) => {
3914
3939
  e.preventDefault();
3915
3940
  const input = this.#ui.telInputEl;
3916
3941
  const selStart = input.selectionStart;
@@ -3929,6 +3954,15 @@ var _factory = (() => {
3929
3954
  const sanitised = hasLeadingPlus && allowLeadingPlus ? `+${numerics}` : numerics;
3930
3955
  let newValue = before + sanitised + after;
3931
3956
  let rejectReason = sanitised !== pasted ? "invalid" : null;
3957
+ if (newValue.length > 30) {
3958
+ this.#playStrictRejectAnimation();
3959
+ this.#dispatchEvent(EVENTS.STRICT_REJECT, {
3960
+ source: "paste",
3961
+ rejectedInput: pastedRaw,
3962
+ reason: "max-length"
3963
+ });
3964
+ return;
3965
+ }
3932
3966
  if (newValue.length > 5 && intlTelInput.utils) {
3933
3967
  let coreNumber = intlTelInput.utils.getCoreNumber(newValue, iso2);
3934
3968
  while (coreNumber.length === 0 && newValue.length > 0) {
@@ -4631,7 +4665,7 @@ var _factory = (() => {
4631
4665
  attachUtils,
4632
4666
  startedLoadingUtils: false,
4633
4667
  startedLoadingAutoCountry: false,
4634
- version: "27.3.0"
4668
+ version: "27.3.1"
4635
4669
  }
4636
4670
  );
4637
4671
  var intlTelInput_default = intlTelInput;