intl-tel-input 25.5.2 → 25.8.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.
@@ -1360,18 +1360,18 @@ var rawCountryData = [
1360
1360
  ]
1361
1361
  ];
1362
1362
  var allCountries = [];
1363
- for (let i = 0; i < rawCountryData.length; i++) {
1364
- const c = rawCountryData[i];
1365
- allCountries[i] = {
1363
+ for (const c of rawCountryData) {
1364
+ allCountries.push({
1366
1365
  name: "",
1367
- // this is now populated in the plugin
1366
+ // populated in the plugin
1368
1367
  iso2: c[0],
1369
1368
  dialCode: c[1],
1370
1369
  priority: c[2] || 0,
1371
1370
  areaCodes: c[3] || null,
1372
1371
  nodeById: {},
1372
+ // populated by the plugin
1373
1373
  nationalPrefix: c[4] || null
1374
- };
1374
+ });
1375
1375
  }
1376
1376
  var data_default = allCountries;
1377
1377
 
@@ -1628,6 +1628,7 @@ var interfaceTranslations = {
1628
1628
  noCountrySelected: "No country selected",
1629
1629
  countryListAriaLabel: "List of countries",
1630
1630
  searchPlaceholder: "Search",
1631
+ clearSearchAriaLabel: "Clear search",
1631
1632
  zeroSearchResults: "No results found",
1632
1633
  oneSearchResult: "1 result found",
1633
1634
  multipleSearchResults: "${count} results found",
@@ -1642,10 +1643,23 @@ var allTranslations = { ...countries_default, ...interface_default };
1642
1643
  var en_default = allTranslations;
1643
1644
 
1644
1645
  // src/js/intl-tel-input.ts
1645
- for (let i = 0; i < data_default.length; i++) {
1646
- data_default[i].name = en_default[data_default[i].iso2];
1646
+ for (const c of data_default) {
1647
+ c.name = en_default[c.iso2];
1647
1648
  }
1648
1649
  var id = 0;
1650
+ var mq = (q) => {
1651
+ return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(q).matches;
1652
+ };
1653
+ var computeDefaultUseFullscreenPopup = () => {
1654
+ if (typeof navigator !== "undefined" && typeof window !== "undefined") {
1655
+ const isMobileUserAgent = /Android.+Mobile|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
1656
+ const isNarrowViewport = mq("(max-width: 500px)");
1657
+ const isShortViewport = mq("(max-height: 600px)");
1658
+ const isCoarsePointer = mq("(pointer: coarse)");
1659
+ return isMobileUserAgent || isNarrowViewport || isCoarsePointer && isShortViewport;
1660
+ }
1661
+ return false;
1662
+ };
1649
1663
  var defaults = {
1650
1664
  //* Whether or not to allow the dropdown.
1651
1665
  allowDropdown: true,
@@ -1692,13 +1706,7 @@ var defaults = {
1692
1706
  //* Only allow certain chars e.g. a plus followed by numeric digits, and cap at max valid length.
1693
1707
  strictMode: false,
1694
1708
  //* Use full screen popup instead of dropdown for country list.
1695
- useFullscreenPopup: typeof navigator !== "undefined" && typeof window !== "undefined" ? (
1696
- //* We cannot just test screen size as some smartphones/website meta tags will report desktop resolutions.
1697
- //* Note: to target Android Mobiles (and not Tablets), we must find 'Android' and 'Mobile'
1698
- /Android.+Mobile|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
1699
- navigator.userAgent
1700
- ) || window.innerWidth <= 500
1701
- ) : false,
1709
+ useFullscreenPopup: computeDefaultUseFullscreenPopup(),
1702
1710
  //* The number type to enforce during validation.
1703
1711
  validationNumberTypes: ["MOBILE"]
1704
1712
  };
@@ -1726,7 +1734,7 @@ var normaliseString = (s = "") => s.normalize("NFD").replace(/[\u0300-\u036f]/g,
1726
1734
  var isRegionlessNanp = (number) => {
1727
1735
  const numeric = getNumeric(number);
1728
1736
  if (numeric.charAt(0) === "1") {
1729
- const areaCode = numeric.substr(1, 3);
1737
+ const areaCode = numeric.substring(1, 4);
1730
1738
  return regionlessNanpNumbers.includes(areaCode);
1731
1739
  }
1732
1740
  return false;
@@ -1749,8 +1757,8 @@ var translateCursorPosition = (relevantChars, formattedValue, prevCaretPos, isDe
1749
1757
  }
1750
1758
  return formattedValue.length;
1751
1759
  };
1752
- var createEl = (name, attrs, container) => {
1753
- const el = document.createElement(name);
1760
+ var createEl = (tagName, attrs, container) => {
1761
+ const el = document.createElement(tagName);
1754
1762
  if (attrs) {
1755
1763
  Object.entries(attrs).forEach(([key, value]) => el.setAttribute(key, value));
1756
1764
  }
@@ -1763,7 +1771,14 @@ var forEachInstance = (method, ...args) => {
1763
1771
  const { instances } = intlTelInput;
1764
1772
  Object.values(instances).forEach((instance) => instance[method](...args));
1765
1773
  };
1766
- var Iti = class {
1774
+ var Iti = class _Iti {
1775
+ /**
1776
+ * Build a space-delimited class string from an object map of className -> truthy/falsey.
1777
+ * Only keys with truthy values are included.
1778
+ */
1779
+ static _buildClassNames(flags) {
1780
+ return Object.keys(flags).filter((k) => Boolean(flags[k])).join(" ");
1781
+ }
1767
1782
  constructor(input, customOptions = {}) {
1768
1783
  this.id = id++;
1769
1784
  this.telInput = input;
@@ -1826,6 +1841,16 @@ var Iti = class {
1826
1841
  this._processDialCodes();
1827
1842
  this._translateCountryNames();
1828
1843
  this._sortCountries();
1844
+ this.countryByIso2 = new Map(this.countries.map((c) => [c.iso2, c]));
1845
+ this._cacheSearchTokens();
1846
+ }
1847
+ //* Precompute and cache country search tokens to speed up filtering
1848
+ _cacheSearchTokens() {
1849
+ for (const c of this.countries) {
1850
+ c.normalisedName = normaliseString(c.name);
1851
+ c.initials = c.name.split(/[^a-zA-ZÀ-ÿа-яА-Я]/).map((word) => word[0]).join("").toLowerCase();
1852
+ c.dialCodePlus = `+${c.dialCode}`;
1853
+ }
1829
1854
  }
1830
1855
  //* Sort countries by countryOrder option (if present), then name.
1831
1856
  _sortCountries() {
@@ -1857,13 +1882,12 @@ var Iti = class {
1857
1882
  if (!this.dialCodeToIso2Map.hasOwnProperty(dialCode)) {
1858
1883
  this.dialCodeToIso2Map[dialCode] = [];
1859
1884
  }
1860
- for (let i = 0; i < this.dialCodeToIso2Map[dialCode].length; i++) {
1861
- if (this.dialCodeToIso2Map[dialCode][i] === iso2) {
1862
- return;
1863
- }
1885
+ const iso2List = this.dialCodeToIso2Map[dialCode];
1886
+ if (iso2List.includes(iso2)) {
1887
+ return;
1864
1888
  }
1865
- const index = priority !== void 0 ? priority : this.dialCodeToIso2Map[dialCode].length;
1866
- this.dialCodeToIso2Map[dialCode][index] = iso2;
1889
+ const index = priority !== void 0 ? priority : iso2List.length;
1890
+ iso2List[index] = iso2;
1867
1891
  }
1868
1892
  //* Process onlyCountries or excludeCountries array if present.
1869
1893
  _processAllCountries() {
@@ -1888,33 +1912,30 @@ var Iti = class {
1888
1912
  }
1889
1913
  //* Translate Countries by object literal provided on config.
1890
1914
  _translateCountryNames() {
1891
- for (let i = 0; i < this.countries.length; i++) {
1892
- const iso2 = this.countries[i].iso2.toLowerCase();
1915
+ for (const c of this.countries) {
1916
+ const iso2 = c.iso2.toLowerCase();
1893
1917
  if (this.options.i18n.hasOwnProperty(iso2)) {
1894
- this.countries[i].name = this.options.i18n[iso2];
1918
+ c.name = this.options.i18n[iso2];
1895
1919
  }
1896
1920
  }
1897
1921
  }
1898
1922
  //* Generate this.dialCodes and this.dialCodeToIso2Map.
1899
1923
  _processDialCodes() {
1900
- this.dialCodes = {};
1924
+ this.dialCodes = /* @__PURE__ */ new Set();
1901
1925
  this.dialCodeMaxLen = 0;
1902
1926
  this.dialCodeToIso2Map = {};
1903
- for (let i = 0; i < this.countries.length; i++) {
1904
- const c = this.countries[i];
1905
- if (!this.dialCodes[c.dialCode]) {
1906
- this.dialCodes[c.dialCode] = true;
1927
+ for (const c of this.countries) {
1928
+ if (!this.dialCodes.has(c.dialCode)) {
1929
+ this.dialCodes.add(c.dialCode);
1907
1930
  }
1908
1931
  this._addToDialCodeMap(c.iso2, c.dialCode, c.priority);
1909
1932
  }
1910
- for (let i = 0; i < this.countries.length; i++) {
1911
- const c = this.countries[i];
1933
+ for (const c of this.countries) {
1912
1934
  if (c.areaCodes) {
1913
1935
  const rootIso2Code = this.dialCodeToIso2Map[c.dialCode][0];
1914
- for (let j = 0; j < c.areaCodes.length; j++) {
1915
- const areaCode = c.areaCodes[j];
1936
+ for (const areaCode of c.areaCodes) {
1916
1937
  for (let k = 1; k < areaCode.length; k++) {
1917
- const partialAreaCode = areaCode.substr(0, k);
1938
+ const partialAreaCode = areaCode.substring(0, k);
1918
1939
  const partialDialCode = c.dialCode + partialAreaCode;
1919
1940
  this._addToDialCodeMap(rootIso2Code, partialDialCode);
1920
1941
  this._addToDialCodeMap(c.iso2, partialDialCode);
@@ -1942,20 +1963,14 @@ var Iti = class {
1942
1963
  countrySearch,
1943
1964
  i18n
1944
1965
  } = this.options;
1945
- let parentClass = "iti";
1946
- if (allowDropdown) {
1947
- parentClass += " iti--allow-dropdown";
1948
- }
1949
- if (showFlags) {
1950
- parentClass += " iti--show-flags";
1951
- }
1952
- if (containerClass) {
1953
- parentClass += ` ${containerClass}`;
1954
- }
1955
- if (!useFullscreenPopup) {
1956
- parentClass += " iti--inline-dropdown";
1957
- }
1958
- const wrapper = createEl("div", { class: parentClass });
1966
+ const parentClasses = _Iti._buildClassNames({
1967
+ "iti": true,
1968
+ "iti--allow-dropdown": allowDropdown,
1969
+ "iti--show-flags": showFlags,
1970
+ "iti--inline-dropdown": !useFullscreenPopup,
1971
+ [containerClass]: Boolean(containerClass)
1972
+ });
1973
+ const wrapper = createEl("div", { class: parentClasses });
1959
1974
  this.telInput.parentNode?.insertBefore(wrapper, this.telInput);
1960
1975
  if (allowDropdown || showFlags || separateDialCode) {
1961
1976
  this.countryContainer = createEl(
@@ -1976,9 +1991,8 @@ var Iti = class {
1976
1991
  class: "iti__selected-country",
1977
1992
  "aria-expanded": "false",
1978
1993
  "aria-label": this.options.i18n.selectedCountryAriaLabel,
1979
- "aria-haspopup": "true",
1980
- "aria-controls": `iti-${this.id}__dropdown-content`,
1981
- "role": "combobox"
1994
+ "aria-haspopup": "dialog",
1995
+ "aria-controls": `iti-${this.id}__dropdown-content`
1982
1996
  },
1983
1997
  this.countryContainer
1984
1998
  );
@@ -2017,15 +2031,38 @@ var Iti = class {
2017
2031
  const extraClasses = fixDropdownWidth ? "" : "iti--flexible-dropdown-width";
2018
2032
  this.dropdownContent = createEl("div", {
2019
2033
  id: `iti-${this.id}__dropdown-content`,
2020
- class: `iti__dropdown-content iti__hide ${extraClasses}`
2034
+ class: `iti__dropdown-content iti__hide ${extraClasses}`,
2035
+ role: "dialog",
2036
+ "aria-modal": "true"
2021
2037
  });
2022
2038
  if (countrySearch) {
2039
+ const searchWrapper = createEl(
2040
+ "div",
2041
+ { class: "iti__search-input-wrapper" },
2042
+ this.dropdownContent
2043
+ );
2044
+ this.searchIcon = createEl(
2045
+ "span",
2046
+ {
2047
+ class: "iti__search-icon",
2048
+ "aria-hidden": "true"
2049
+ },
2050
+ searchWrapper
2051
+ );
2052
+ this.searchIcon.innerHTML = `
2053
+ <svg class="iti__search-icon-svg" width="14" height="14" viewBox="0 0 24 24" focusable="false" aria-hidden="true">
2054
+ <circle cx="11" cy="11" r="7" />
2055
+ <line x1="21" y1="21" x2="16.65" y2="16.65" />
2056
+ </svg>`;
2023
2057
  this.searchInput = createEl(
2024
2058
  "input",
2025
2059
  {
2026
- type: "text",
2060
+ id: `iti-${this.id}__search-input`,
2061
+ // Chrome says inputs need either a name or an id
2062
+ type: "search",
2027
2063
  class: "iti__search-input",
2028
2064
  placeholder: i18n.searchPlaceholder,
2065
+ // role=combobox + aria-autocomplete=list + aria-activedescendant allows maintaining focus on the search input while allowing users to navigate search results with up/down keyboard keys
2029
2066
  role: "combobox",
2030
2067
  "aria-expanded": "true",
2031
2068
  "aria-label": i18n.searchPlaceholder,
@@ -2033,13 +2070,42 @@ var Iti = class {
2033
2070
  "aria-autocomplete": "list",
2034
2071
  "autocomplete": "off"
2035
2072
  },
2036
- this.dropdownContent
2073
+ searchWrapper
2074
+ );
2075
+ this.searchClearButton = createEl(
2076
+ "button",
2077
+ {
2078
+ type: "button",
2079
+ class: "iti__search-clear iti__hide",
2080
+ "aria-label": i18n.clearSearchAriaLabel,
2081
+ tabindex: "-1"
2082
+ },
2083
+ searchWrapper
2037
2084
  );
2085
+ const maskId = `iti-${this.id}-clear-mask`;
2086
+ this.searchClearButton.innerHTML = `
2087
+ <svg class="iti__search-clear-svg" width="12" height="12" viewBox="0 0 16 16" aria-hidden="true" focusable="false">
2088
+ <mask id="${maskId}" maskUnits="userSpaceOnUse">
2089
+ <rect width="16" height="16" fill="white" />
2090
+ <path d="M5.2 5.2 L10.8 10.8 M10.8 5.2 L5.2 10.8" stroke="black" stroke-linecap="round" class="iti__search-clear-x" />
2091
+ </mask>
2092
+ <circle cx="8" cy="8" r="8" class="iti__search-clear-bg" mask="url(#${maskId})" />
2093
+ </svg>`;
2038
2094
  this.searchResultsA11yText = createEl(
2039
2095
  "span",
2040
2096
  { class: "iti__a11y-text" },
2041
2097
  this.dropdownContent
2042
2098
  );
2099
+ this.searchNoResults = createEl(
2100
+ "div",
2101
+ {
2102
+ class: "iti__no-results iti__hide",
2103
+ "aria-hidden": "true"
2104
+ // all a11y messaging happens in this.searchResultsA11yText
2105
+ },
2106
+ this.dropdownContent
2107
+ );
2108
+ this.searchNoResults.textContent = i18n.zeroSearchResults;
2043
2109
  }
2044
2110
  this.countryList = createEl(
2045
2111
  "ul",
@@ -2053,18 +2119,16 @@ var Iti = class {
2053
2119
  );
2054
2120
  this._appendListItems();
2055
2121
  if (countrySearch) {
2056
- this._updateSearchResultsText();
2122
+ this._updateSearchResultsA11yText();
2057
2123
  }
2058
2124
  if (dropdownContainer) {
2059
- let dropdownClasses = "iti iti--container";
2060
- if (containerClass) {
2061
- dropdownClasses += ` ${containerClass}`;
2062
- }
2063
- if (useFullscreenPopup) {
2064
- dropdownClasses += " iti--fullscreen-popup";
2065
- } else {
2066
- dropdownClasses += " iti--inline-dropdown";
2067
- }
2125
+ const dropdownClasses = _Iti._buildClassNames({
2126
+ "iti": true,
2127
+ "iti--container": true,
2128
+ "iti--fullscreen-popup": useFullscreenPopup,
2129
+ "iti--inline-dropdown": !useFullscreenPopup,
2130
+ [containerClass]: Boolean(containerClass)
2131
+ });
2068
2132
  this.dropdown = createEl("div", { class: dropdownClasses });
2069
2133
  this.dropdown.appendChild(this.dropdownContent);
2070
2134
  } else {
@@ -2349,7 +2413,7 @@ var Iti = class {
2349
2413
  //* Adhere to the input's maxlength attr.
2350
2414
  _cap(number) {
2351
2415
  const max = parseInt(this.telInput.getAttribute("maxlength") || "", 10);
2352
- return max && number.length > max ? number.substr(0, max) : number;
2416
+ return max && number.length > max ? number.substring(0, max) : number;
2353
2417
  }
2354
2418
  //* Trigger a custom event on the input.
2355
2419
  _trigger(name, detailProps = {}) {
@@ -2462,6 +2526,11 @@ var Iti = class {
2462
2526
  } else {
2463
2527
  this._filterCountries("", true);
2464
2528
  }
2529
+ if (this.searchInput.value) {
2530
+ this.searchClearButton.classList.remove("iti__hide");
2531
+ } else {
2532
+ this.searchClearButton.classList.add("iti__hide");
2533
+ }
2465
2534
  };
2466
2535
  let keyupTimer = null;
2467
2536
  this._handleSearchChange = () => {
@@ -2474,14 +2543,20 @@ var Iti = class {
2474
2543
  }, 100);
2475
2544
  };
2476
2545
  this.searchInput.addEventListener("input", this._handleSearchChange);
2546
+ this._handleSearchClear = (e) => {
2547
+ e.stopPropagation();
2548
+ this.searchInput.value = "";
2549
+ this.searchInput.focus();
2550
+ doFilter();
2551
+ };
2552
+ this.searchClearButton.addEventListener("click", this._handleSearchClear);
2477
2553
  this.searchInput.addEventListener("click", (e) => e.stopPropagation());
2478
2554
  }
2479
2555
  }
2480
2556
  //* Hidden search (countrySearch disabled): Find the first list item whose name starts with the query string.
2481
2557
  _searchForCountry(query) {
2482
- for (let i = 0; i < this.countries.length; i++) {
2483
- const c = this.countries[i];
2484
- const startsWith = c.name.substr(0, query.length).toLowerCase() === query;
2558
+ for (const c of this.countries) {
2559
+ const startsWith = c.name.substring(0, query.length).toLowerCase() === query;
2485
2560
  if (startsWith) {
2486
2561
  const listItem = c.nodeById[this.id];
2487
2562
  this._highlightListItem(listItem, false);
@@ -2502,23 +2577,20 @@ var Iti = class {
2502
2577
  const dialCodeMatches = [];
2503
2578
  const dialCodeContains = [];
2504
2579
  const initialsMatches = [];
2505
- for (let i = 0; i < this.countries.length; i++) {
2506
- const c = this.countries[i];
2507
- const normalisedCountryName = normaliseString(c.name);
2508
- const countryInitials = c.name.split(/[^a-zA-ZÀ-ÿа-яА-Я]/).map((word) => word[0]).join("").toLowerCase();
2580
+ for (const c of this.countries) {
2509
2581
  if (isReset || queryLength === 0) {
2510
2582
  nameContains.push(c);
2511
- } else if (c.iso2.toLowerCase() === normalisedQuery) {
2583
+ } else if (c.iso2 === normalisedQuery) {
2512
2584
  iso2Matches.push(c);
2513
- } else if (normalisedCountryName.startsWith(normalisedQuery)) {
2585
+ } else if (c.normalisedName.startsWith(normalisedQuery)) {
2514
2586
  nameStartWith.push(c);
2515
- } else if (normalisedCountryName.includes(normalisedQuery)) {
2587
+ } else if (c.normalisedName.includes(normalisedQuery)) {
2516
2588
  nameContains.push(c);
2517
- } else if (normalisedQuery === c.dialCode || normalisedQuery === `+${c.dialCode}`) {
2589
+ } else if (normalisedQuery === c.dialCode || normalisedQuery === c.dialCodePlus) {
2518
2590
  dialCodeMatches.push(c);
2519
- } else if (`+${c.dialCode}`.includes(normalisedQuery)) {
2591
+ } else if (c.dialCodePlus.includes(normalisedQuery)) {
2520
2592
  dialCodeContains.push(c);
2521
- } else if (countryInitials.includes(normalisedQuery)) {
2593
+ } else if (c.initials.includes(normalisedQuery)) {
2522
2594
  initialsMatches.push(c);
2523
2595
  }
2524
2596
  }
@@ -2542,12 +2614,17 @@ var Iti = class {
2542
2614
  }
2543
2615
  if (noCountriesAddedYet) {
2544
2616
  this._highlightListItem(null, false);
2617
+ if (this.searchNoResults) {
2618
+ this.searchNoResults.classList.remove("iti__hide");
2619
+ }
2620
+ } else if (this.searchNoResults) {
2621
+ this.searchNoResults.classList.add("iti__hide");
2545
2622
  }
2546
2623
  this.countryList.scrollTop = 0;
2547
- this._updateSearchResultsText();
2624
+ this._updateSearchResultsA11yText();
2548
2625
  }
2549
2626
  //* Update search results text (for a11y).
2550
- _updateSearchResultsText() {
2627
+ _updateSearchResultsA11yText() {
2551
2628
  const { i18n } = this.options;
2552
2629
  const count = this.countryList.childElementCount;
2553
2630
  let searchText;
@@ -2638,9 +2715,9 @@ var Iti = class {
2638
2715
  const alreadySelected = selectedIso2 && iso2Codes.includes(selectedIso2) && !hasAreaCodesButNoneMatched;
2639
2716
  const isRegionlessNanpNumber = selectedDialCode === "1" && isRegionlessNanp(numeric);
2640
2717
  if (!isRegionlessNanpNumber && !alreadySelected) {
2641
- for (let j = 0; j < iso2Codes.length; j++) {
2642
- if (iso2Codes[j]) {
2643
- return iso2Codes[j];
2718
+ for (const iso2 of iso2Codes) {
2719
+ if (iso2) {
2720
+ return iso2;
2644
2721
  }
2645
2722
  }
2646
2723
  }
@@ -2662,9 +2739,8 @@ var Iti = class {
2662
2739
  if (this.highlightedItem) {
2663
2740
  this.highlightedItem.classList.add("iti__highlight");
2664
2741
  this.highlightedItem.setAttribute("aria-selected", "true");
2665
- const activeDescendant = this.highlightedItem.getAttribute("id") || "";
2666
- this.selectedCountry.setAttribute("aria-activedescendant", activeDescendant);
2667
2742
  if (this.options.countrySearch) {
2743
+ const activeDescendant = this.highlightedItem.getAttribute("id") || "";
2668
2744
  this.searchInput.setAttribute("aria-activedescendant", activeDescendant);
2669
2745
  }
2670
2746
  }
@@ -2673,12 +2749,11 @@ var Iti = class {
2673
2749
  }
2674
2750
  }
2675
2751
  //* Find the country data for the given iso2 code
2676
- //* the ignoreOnlyCountriesOption is only used during init() while parsing the onlyCountries array
2752
+ //* the allowFail option is only used during init() for the initialCountry option, and for the iso2 returned from geoIpLookup - in these 2 cases we don't want to error out
2677
2753
  _getCountryData(iso2, allowFail) {
2678
- for (let i = 0; i < this.countries.length; i++) {
2679
- if (this.countries[i].iso2 === iso2) {
2680
- return this.countries[i];
2681
- }
2754
+ const country = this.countryByIso2.get(iso2);
2755
+ if (country) {
2756
+ return country;
2682
2757
  }
2683
2758
  if (allowFail) {
2684
2759
  return null;
@@ -2829,7 +2904,6 @@ var Iti = class {
2829
2904
  _closeDropdown() {
2830
2905
  this.dropdownContent.classList.add("iti__hide");
2831
2906
  this.selectedCountry.setAttribute("aria-expanded", "false");
2832
- this.selectedCountry.removeAttribute("aria-activedescendant");
2833
2907
  if (this.highlightedItem) {
2834
2908
  this.highlightedItem.setAttribute("aria-selected", "false");
2835
2909
  }
@@ -2837,9 +2911,9 @@ var Iti = class {
2837
2911
  this.searchInput.removeAttribute("aria-activedescendant");
2838
2912
  }
2839
2913
  this.dropdownArrow.classList.remove("iti__arrow--up");
2840
- document.removeEventListener("keydown", this._handleKeydownOnDropdown);
2841
2914
  if (this.options.countrySearch) {
2842
2915
  this.searchInput.removeEventListener("input", this._handleSearchChange);
2916
+ this.searchClearButton.removeEventListener("click", this._handleSearchClear);
2843
2917
  }
2844
2918
  document.documentElement.removeEventListener(
2845
2919
  "click",
@@ -2909,11 +2983,11 @@ var Iti = class {
2909
2983
  numericChars += c;
2910
2984
  if (includeAreaCode) {
2911
2985
  if (this.dialCodeToIso2Map[numericChars]) {
2912
- dialCode = number.substr(0, i + 1);
2986
+ dialCode = number.substring(0, i + 1);
2913
2987
  }
2914
2988
  } else {
2915
- if (this.dialCodes[numericChars]) {
2916
- dialCode = number.substr(0, i + 1);
2989
+ if (this.dialCodes.has(numericChars)) {
2990
+ dialCode = number.substring(0, i + 1);
2917
2991
  break;
2918
2992
  }
2919
2993
  }
@@ -2946,7 +3020,7 @@ var Iti = class {
2946
3020
  if (dialCode) {
2947
3021
  dialCode = `+${this.selectedCountryData.dialCode}`;
2948
3022
  const start = number[dialCode.length] === " " || number[dialCode.length] === "-" ? dialCode.length + 1 : dialCode.length;
2949
- number = number.substr(start);
3023
+ number = number.substring(start);
2950
3024
  }
2951
3025
  }
2952
3026
  return this._cap(number);
@@ -3080,38 +3154,32 @@ var Iti = class {
3080
3154
  }
3081
3155
  return -99;
3082
3156
  }
3083
- //* Validate the input val
3157
+ //* Validate the input val (with precise=false)
3084
3158
  isValidNumber() {
3085
- if (!this.selectedCountryData.iso2) {
3086
- return false;
3087
- }
3088
- const val = this._getFullNumber();
3089
- const alphaCharPosition = val.search(/\p{L}/u);
3090
- if (alphaCharPosition > -1) {
3091
- const beforeAlphaChar = val.substring(0, alphaCharPosition);
3092
- const beforeAlphaIsValid = this._utilsIsPossibleNumber(beforeAlphaChar);
3093
- const isValid = this._utilsIsPossibleNumber(val);
3094
- return beforeAlphaIsValid && isValid;
3095
- }
3096
- return this._utilsIsPossibleNumber(val);
3159
+ return this._validateNumber(false);
3160
+ }
3161
+ //* Validate the input val (with precise=true)
3162
+ isValidNumberPrecise() {
3163
+ return this._validateNumber(true);
3097
3164
  }
3098
3165
  _utilsIsPossibleNumber(val) {
3099
3166
  return intlTelInput.utils ? intlTelInput.utils.isPossibleNumber(val, this.selectedCountryData.iso2, this.options.validationNumberTypes) : null;
3100
3167
  }
3101
- //* Validate the input val (precise)
3102
- isValidNumberPrecise() {
3168
+ //* Shared internal validation logic to handle alpha character extension rules.
3169
+ _validateNumber(precise) {
3103
3170
  if (!this.selectedCountryData.iso2) {
3104
3171
  return false;
3105
3172
  }
3106
3173
  const val = this._getFullNumber();
3107
3174
  const alphaCharPosition = val.search(/\p{L}/u);
3175
+ const testValidity = (s) => precise ? this._utilsIsValidNumber(s) : this._utilsIsPossibleNumber(s);
3108
3176
  if (alphaCharPosition > -1) {
3109
3177
  const beforeAlphaChar = val.substring(0, alphaCharPosition);
3110
- const beforeAlphaIsValid = this._utilsIsValidNumber(beforeAlphaChar);
3111
- const isValid = this._utilsIsValidNumber(val);
3178
+ const beforeAlphaIsValid = testValidity(beforeAlphaChar);
3179
+ const isValid = testValidity(val);
3112
3180
  return beforeAlphaIsValid && isValid;
3113
3181
  }
3114
- return this._utilsIsValidNumber(val);
3182
+ return testValidity(val);
3115
3183
  }
3116
3184
  _utilsIsValidNumber(val) {
3117
3185
  return intlTelInput.utils ? intlTelInput.utils.isValidNumber(val, this.selectedCountryData.iso2, this.options.validationNumberTypes) : null;
@@ -3203,7 +3271,7 @@ var intlTelInput = Object.assign(
3203
3271
  attachUtils,
3204
3272
  startedLoadingUtilsScript: false,
3205
3273
  startedLoadingAutoCountry: false,
3206
- version: "25.5.2"
3274
+ version: "25.8.0"
3207
3275
  }
3208
3276
  );
3209
3277
  var intl_tel_input_default = intlTelInput;
@@ -1,12 +1,17 @@
1
1
  declare module "intl-tel-input/data" {
2
2
  export type Country = {
3
- name: string;
4
3
  iso2: string;
5
4
  dialCode: string;
6
5
  priority: number;
7
6
  areaCodes: string[] | null;
8
- nodeById: object;
9
7
  nationalPrefix: string | null;
8
+ name: string;
9
+ nodeById: {
10
+ [instanceId: number]: HTMLElement;
11
+ };
12
+ normalisedName?: string;
13
+ initials?: string;
14
+ dialCodePlus?: string;
10
15
  };
11
16
  const allCountries: Country[];
12
17
  export default allCountries;
@@ -259,6 +264,7 @@ declare module "intl-tel-input/i18n/types" {
259
264
  ax?: string;
260
265
  selectedCountryAriaLabel?: string;
261
266
  searchPlaceholder?: string;
267
+ clearSearchAriaLabel?: string;
262
268
  countryListAriaLabel?: string;
263
269
  oneSearchResult?: string;
264
270
  multipleSearchResults?: string;
@@ -383,6 +389,7 @@ declare module "intl-tel-input" {
383
389
  private dialCodeMaxLen;
384
390
  private dialCodeToIso2Map;
385
391
  private dialCodes;
392
+ private countryByIso2;
386
393
  private countryContainer;
387
394
  private selectedCountry;
388
395
  private selectedCountryInner;
@@ -391,6 +398,9 @@ declare module "intl-tel-input" {
391
398
  private dropdownArrow;
392
399
  private dropdownContent;
393
400
  private searchInput;
401
+ private searchIcon;
402
+ private searchClearButton;
403
+ private searchNoResults;
394
404
  private searchResultsA11yText;
395
405
  private countryList;
396
406
  private dropdown;
@@ -412,14 +422,21 @@ declare module "intl-tel-input" {
412
422
  private _handleClickOffToClose;
413
423
  private _handleKeydownOnDropdown;
414
424
  private _handleSearchChange;
425
+ private _handleSearchClear;
415
426
  private _handlePageLoad;
416
427
  private resolveAutoCountryPromise;
417
428
  private rejectAutoCountryPromise;
418
429
  private resolveUtilsScriptPromise;
419
430
  private rejectUtilsScriptPromise;
431
+ /**
432
+ * Build a space-delimited class string from an object map of className -> truthy/falsey.
433
+ * Only keys with truthy values are included.
434
+ */
435
+ private static _buildClassNames;
420
436
  constructor(input: HTMLInputElement, customOptions?: SomeOptions);
421
437
  _init(): void;
422
438
  private _processCountryData;
439
+ private _cacheSearchTokens;
423
440
  private _sortCountries;
424
441
  private _addToDialCodeMap;
425
442
  private _processAllCountries;
@@ -442,7 +459,7 @@ declare module "intl-tel-input" {
442
459
  private _bindDropdownListeners;
443
460
  private _searchForCountry;
444
461
  private _filterCountries;
445
- private _updateSearchResultsText;
462
+ private _updateSearchResultsA11yText;
446
463
  private _handleUpDownKey;
447
464
  private _handleEnterKey;
448
465
  private _updateValFromNumber;
@@ -475,8 +492,9 @@ declare module "intl-tel-input" {
475
492
  getSelectedCountryData(): SelectedCountryData;
476
493
  getValidationError(): number;
477
494
  isValidNumber(): boolean | null;
478
- private _utilsIsPossibleNumber;
479
495
  isValidNumberPrecise(): boolean | null;
496
+ private _utilsIsPossibleNumber;
497
+ private _validateNumber;
480
498
  private _utilsIsValidNumber;
481
499
  setCountry(iso2: string): void;
482
500
  setNumber(number: string): void;