intl-tel-input 23.3.2 → 23.4.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.
@@ -1397,6 +1397,8 @@ var defaults = {
1397
1397
  containerClass: "",
1398
1398
  //* The order of the countries in the dropdown. Defaults to alphabetical.
1399
1399
  countryOrder: null,
1400
+ //* Add a country search input at the top of the dropdown.
1401
+ countrySearch: true,
1400
1402
  //* Modify the auto placeholder.
1401
1403
  customPlaceholder: null,
1402
1404
  //* Append menu to specified element.
@@ -1519,6 +1521,7 @@ var Iti = class {
1519
1521
  if (this.options.separateDialCode) {
1520
1522
  this.options.allowDropdown = true;
1521
1523
  this.options.nationalMode = false;
1524
+ this.options.countrySearch = true;
1522
1525
  }
1523
1526
  if (!this.options.showFlags && !this.options.separateDialCode) {
1524
1527
  this.options.nationalMode = false;
@@ -1671,6 +1674,7 @@ var Iti = class {
1671
1674
  dropdownContainer,
1672
1675
  fixDropdownWidth,
1673
1676
  useFullscreenPopup,
1677
+ countrySearch,
1674
1678
  i18n
1675
1679
  } = this.options;
1676
1680
  let parentClass = "iti";
@@ -1747,26 +1751,28 @@ var Iti = class {
1747
1751
  id: `iti-${this.id}__dropdown-content`,
1748
1752
  class: `iti__dropdown-content iti__hide ${extraClasses}`
1749
1753
  });
1750
- this.searchInput = createEl(
1751
- "input",
1752
- {
1753
- type: "text",
1754
- class: "iti__search-input",
1755
- placeholder: i18n.searchPlaceholder,
1756
- role: "combobox",
1757
- "aria-expanded": "true",
1758
- "aria-label": i18n.searchPlaceholder,
1759
- "aria-controls": `iti-${this.id}__country-listbox`,
1760
- "aria-autocomplete": "list",
1761
- "autocomplete": "off"
1762
- },
1763
- this.dropdownContent
1764
- );
1765
- this.searchResultsA11yText = createEl(
1766
- "span",
1767
- { class: "iti__a11y-text" },
1768
- this.dropdownContent
1769
- );
1754
+ if (countrySearch) {
1755
+ this.searchInput = createEl(
1756
+ "input",
1757
+ {
1758
+ type: "text",
1759
+ class: "iti__search-input",
1760
+ placeholder: i18n.searchPlaceholder,
1761
+ role: "combobox",
1762
+ "aria-expanded": "true",
1763
+ "aria-label": i18n.searchPlaceholder,
1764
+ "aria-controls": `iti-${this.id}__country-listbox`,
1765
+ "aria-autocomplete": "list",
1766
+ "autocomplete": "off"
1767
+ },
1768
+ this.dropdownContent
1769
+ );
1770
+ this.searchResultsA11yText = createEl(
1771
+ "span",
1772
+ { class: "iti__a11y-text" },
1773
+ this.dropdownContent
1774
+ );
1775
+ }
1770
1776
  this.countryList = createEl(
1771
1777
  "ul",
1772
1778
  {
@@ -1777,8 +1783,10 @@ var Iti = class {
1777
1783
  },
1778
1784
  this.dropdownContent
1779
1785
  );
1780
- this._appendListItems(this.countries, "iti__standard");
1781
- this._updateSearchResultsText();
1786
+ this._appendListItems();
1787
+ if (countrySearch) {
1788
+ this._updateSearchResultsText();
1789
+ }
1782
1790
  if (dropdownContainer) {
1783
1791
  let dropdownClasses = "iti iti--container";
1784
1792
  if (useFullscreenPopup) {
@@ -1813,15 +1821,16 @@ var Iti = class {
1813
1821
  }
1814
1822
  }
1815
1823
  }
1816
- //* For each of the passed countries: add a country <li> to the countryList <ul> container.
1817
- _appendListItems(countries, className) {
1818
- for (let i = 0; i < countries.length; i++) {
1819
- const c = countries[i];
1824
+ //* For each country: add a country list item <li> to the countryList <ul> container.
1825
+ _appendListItems() {
1826
+ for (let i = 0; i < this.countries.length; i++) {
1827
+ const c = this.countries[i];
1828
+ const extraClass = i === 0 ? "iti__highlight" : "";
1820
1829
  const listItem = createEl(
1821
1830
  "li",
1822
1831
  {
1823
1832
  id: `iti-${this.id}__item-${c.iso2}`,
1824
- class: `iti__country ${className}`,
1833
+ class: `iti__country ${extraClass}`,
1825
1834
  tabindex: "-1",
1826
1835
  role: "option",
1827
1836
  "data-dial-code": c.dialCode,
@@ -2062,24 +2071,26 @@ var Iti = class {
2062
2071
  }
2063
2072
  //* Open the dropdown.
2064
2073
  _openDropdown() {
2065
- const { fixDropdownWidth } = this.options;
2074
+ const { fixDropdownWidth, countrySearch } = this.options;
2066
2075
  if (fixDropdownWidth) {
2067
2076
  this.dropdownContent.style.width = `${this.telInput.offsetWidth}px`;
2068
2077
  }
2069
2078
  this.dropdownContent.classList.remove("iti__hide");
2070
2079
  this.selectedCountry.setAttribute("aria-expanded", "true");
2071
2080
  this._setDropdownPosition();
2072
- const firstCountryItem = this.countryList.firstElementChild;
2073
- if (firstCountryItem) {
2074
- this._highlightListItem(firstCountryItem, false);
2075
- this.countryList.scrollTop = 0;
2081
+ if (countrySearch) {
2082
+ const firstCountryItem = this.countryList.firstElementChild;
2083
+ if (firstCountryItem) {
2084
+ this._highlightListItem(firstCountryItem, false);
2085
+ this.countryList.scrollTop = 0;
2086
+ }
2087
+ this.searchInput.focus();
2076
2088
  }
2077
- this.searchInput.focus();
2078
2089
  this._bindDropdownListeners();
2079
2090
  this.dropdownArrow.classList.add("iti__arrow--up");
2080
2091
  this._trigger("open:countrydropdown");
2081
2092
  }
2082
- //* Decide if should position dropdown above or below input (depends on position within viewport, and scroll).
2093
+ //* Set the dropdown position
2083
2094
  _setDropdownPosition() {
2084
2095
  if (this.options.dropdownContainer) {
2085
2096
  this.options.dropdownContainer.appendChild(this.dropdown);
@@ -2125,6 +2136,8 @@ var Iti = class {
2125
2136
  "click",
2126
2137
  this._handleClickOffToClose
2127
2138
  );
2139
+ let query = "";
2140
+ let queryTimer = null;
2128
2141
  this._handleKeydownOnDropdown = (e) => {
2129
2142
  if (["ArrowUp", "ArrowDown", "Enter", "Escape"].includes(e.key)) {
2130
2143
  e.preventDefault();
@@ -2137,29 +2150,56 @@ var Iti = class {
2137
2150
  this._closeDropdown();
2138
2151
  }
2139
2152
  }
2140
- };
2141
- document.addEventListener("keydown", this._handleKeydownOnDropdown);
2142
- const doFilter = () => {
2143
- const inputQuery = this.searchInput.value.trim();
2144
- if (inputQuery) {
2145
- this._filterCountries(inputQuery);
2146
- } else {
2147
- this._filterCountries("", true);
2153
+ if (!this.options.countrySearch && /^[a-zA-ZÀ-ÿа-яА-Я ]$/.test(e.key)) {
2154
+ e.stopPropagation();
2155
+ if (queryTimer) {
2156
+ clearTimeout(queryTimer);
2157
+ }
2158
+ query += e.key.toLowerCase();
2159
+ this._searchForCountry(query);
2160
+ queryTimer = setTimeout(() => {
2161
+ query = "";
2162
+ }, 1e3);
2148
2163
  }
2149
2164
  };
2150
- let keyupTimer = null;
2151
- this._handleSearchChange = () => {
2152
- if (keyupTimer) {
2153
- clearTimeout(keyupTimer);
2165
+ document.addEventListener("keydown", this._handleKeydownOnDropdown);
2166
+ if (this.options.countrySearch) {
2167
+ const doFilter = () => {
2168
+ const inputQuery = this.searchInput.value.trim();
2169
+ if (inputQuery) {
2170
+ this._filterCountries(inputQuery);
2171
+ } else {
2172
+ this._filterCountries("", true);
2173
+ }
2174
+ };
2175
+ let keyupTimer = null;
2176
+ this._handleSearchChange = () => {
2177
+ if (keyupTimer) {
2178
+ clearTimeout(keyupTimer);
2179
+ }
2180
+ keyupTimer = setTimeout(() => {
2181
+ doFilter();
2182
+ keyupTimer = null;
2183
+ }, 100);
2184
+ };
2185
+ this.searchInput.addEventListener("input", this._handleSearchChange);
2186
+ this.searchInput.addEventListener("click", (e) => e.stopPropagation());
2187
+ }
2188
+ }
2189
+ //* Hidden search (countrySearch disabled): Find the first list item whose name starts with the query string.
2190
+ _searchForCountry(query) {
2191
+ for (let i = 0; i < this.countries.length; i++) {
2192
+ const c = this.countries[i];
2193
+ const startsWith = c.name.substr(0, query.length).toLowerCase() === query;
2194
+ if (startsWith) {
2195
+ const listItem = c.nodeById[this.id];
2196
+ this._highlightListItem(listItem, false);
2197
+ this._scrollTo(listItem);
2198
+ break;
2154
2199
  }
2155
- keyupTimer = setTimeout(() => {
2156
- doFilter();
2157
- keyupTimer = null;
2158
- }, 100);
2159
- };
2160
- this.searchInput.addEventListener("input", this._handleSearchChange);
2161
- this.searchInput.addEventListener("click", (e) => e.stopPropagation());
2200
+ }
2162
2201
  }
2202
+ //* Country search enabled: Filter the countries according to the search query.
2163
2203
  _filterCountries(query, isReset = false) {
2164
2204
  let noCountriesAddedYet = true;
2165
2205
  this.countryList.innerHTML = "";
@@ -2287,7 +2327,9 @@ var Iti = class {
2287
2327
  this.highlightedItem.setAttribute("aria-selected", "true");
2288
2328
  const activeDescendant = this.highlightedItem.getAttribute("id") || "";
2289
2329
  this.selectedCountry.setAttribute("aria-activedescendant", activeDescendant);
2290
- this.searchInput.setAttribute("aria-activedescendant", activeDescendant);
2330
+ if (this.options.countrySearch) {
2331
+ this.searchInput.setAttribute("aria-activedescendant", activeDescendant);
2332
+ }
2291
2333
  }
2292
2334
  if (shouldFocus) {
2293
2335
  this.highlightedItem.focus();
@@ -2444,10 +2486,14 @@ var Iti = class {
2444
2486
  if (this.highlightedItem) {
2445
2487
  this.highlightedItem.setAttribute("aria-selected", "false");
2446
2488
  }
2447
- this.searchInput.removeAttribute("aria-activedescendant");
2489
+ if (this.options.countrySearch) {
2490
+ this.searchInput.removeAttribute("aria-activedescendant");
2491
+ }
2448
2492
  this.dropdownArrow.classList.remove("iti__arrow--up");
2449
2493
  document.removeEventListener("keydown", this._handleKeydownOnDropdown);
2450
- this.searchInput.removeEventListener("input", this._handleSearchChange);
2494
+ if (this.options.countrySearch) {
2495
+ this.searchInput.removeEventListener("input", this._handleSearchChange);
2496
+ }
2451
2497
  document.documentElement.removeEventListener(
2452
2498
  "click",
2453
2499
  this._handleClickOffToClose
@@ -2758,7 +2804,7 @@ var intlTelInput = Object.assign(
2758
2804
  //* A map from instance ID to instance object.
2759
2805
  instances: {},
2760
2806
  loadUtils,
2761
- version: "23.3.2"
2807
+ version: "23.4.0"
2762
2808
  }
2763
2809
  );
2764
2810
  var intl_tel_input_default = intlTelInput;
@@ -1361,6 +1361,8 @@ var defaults = {
1361
1361
  containerClass: "",
1362
1362
  //* The order of the countries in the dropdown. Defaults to alphabetical.
1363
1363
  countryOrder: null,
1364
+ //* Add a country search input at the top of the dropdown.
1365
+ countrySearch: true,
1364
1366
  //* Modify the auto placeholder.
1365
1367
  customPlaceholder: null,
1366
1368
  //* Append menu to specified element.
@@ -1483,6 +1485,7 @@ var Iti = class {
1483
1485
  if (this.options.separateDialCode) {
1484
1486
  this.options.allowDropdown = true;
1485
1487
  this.options.nationalMode = false;
1488
+ this.options.countrySearch = true;
1486
1489
  }
1487
1490
  if (!this.options.showFlags && !this.options.separateDialCode) {
1488
1491
  this.options.nationalMode = false;
@@ -1635,6 +1638,7 @@ var Iti = class {
1635
1638
  dropdownContainer,
1636
1639
  fixDropdownWidth,
1637
1640
  useFullscreenPopup,
1641
+ countrySearch,
1638
1642
  i18n
1639
1643
  } = this.options;
1640
1644
  let parentClass = "iti";
@@ -1711,26 +1715,28 @@ var Iti = class {
1711
1715
  id: `iti-${this.id}__dropdown-content`,
1712
1716
  class: `iti__dropdown-content iti__hide ${extraClasses}`
1713
1717
  });
1714
- this.searchInput = createEl(
1715
- "input",
1716
- {
1717
- type: "text",
1718
- class: "iti__search-input",
1719
- placeholder: i18n.searchPlaceholder,
1720
- role: "combobox",
1721
- "aria-expanded": "true",
1722
- "aria-label": i18n.searchPlaceholder,
1723
- "aria-controls": `iti-${this.id}__country-listbox`,
1724
- "aria-autocomplete": "list",
1725
- "autocomplete": "off"
1726
- },
1727
- this.dropdownContent
1728
- );
1729
- this.searchResultsA11yText = createEl(
1730
- "span",
1731
- { class: "iti__a11y-text" },
1732
- this.dropdownContent
1733
- );
1718
+ if (countrySearch) {
1719
+ this.searchInput = createEl(
1720
+ "input",
1721
+ {
1722
+ type: "text",
1723
+ class: "iti__search-input",
1724
+ placeholder: i18n.searchPlaceholder,
1725
+ role: "combobox",
1726
+ "aria-expanded": "true",
1727
+ "aria-label": i18n.searchPlaceholder,
1728
+ "aria-controls": `iti-${this.id}__country-listbox`,
1729
+ "aria-autocomplete": "list",
1730
+ "autocomplete": "off"
1731
+ },
1732
+ this.dropdownContent
1733
+ );
1734
+ this.searchResultsA11yText = createEl(
1735
+ "span",
1736
+ { class: "iti__a11y-text" },
1737
+ this.dropdownContent
1738
+ );
1739
+ }
1734
1740
  this.countryList = createEl(
1735
1741
  "ul",
1736
1742
  {
@@ -1741,8 +1747,10 @@ var Iti = class {
1741
1747
  },
1742
1748
  this.dropdownContent
1743
1749
  );
1744
- this._appendListItems(this.countries, "iti__standard");
1745
- this._updateSearchResultsText();
1750
+ this._appendListItems();
1751
+ if (countrySearch) {
1752
+ this._updateSearchResultsText();
1753
+ }
1746
1754
  if (dropdownContainer) {
1747
1755
  let dropdownClasses = "iti iti--container";
1748
1756
  if (useFullscreenPopup) {
@@ -1777,15 +1785,16 @@ var Iti = class {
1777
1785
  }
1778
1786
  }
1779
1787
  }
1780
- //* For each of the passed countries: add a country <li> to the countryList <ul> container.
1781
- _appendListItems(countries, className) {
1782
- for (let i = 0; i < countries.length; i++) {
1783
- const c = countries[i];
1788
+ //* For each country: add a country list item <li> to the countryList <ul> container.
1789
+ _appendListItems() {
1790
+ for (let i = 0; i < this.countries.length; i++) {
1791
+ const c = this.countries[i];
1792
+ const extraClass = i === 0 ? "iti__highlight" : "";
1784
1793
  const listItem = createEl(
1785
1794
  "li",
1786
1795
  {
1787
1796
  id: `iti-${this.id}__item-${c.iso2}`,
1788
- class: `iti__country ${className}`,
1797
+ class: `iti__country ${extraClass}`,
1789
1798
  tabindex: "-1",
1790
1799
  role: "option",
1791
1800
  "data-dial-code": c.dialCode,
@@ -2026,24 +2035,26 @@ var Iti = class {
2026
2035
  }
2027
2036
  //* Open the dropdown.
2028
2037
  _openDropdown() {
2029
- const { fixDropdownWidth } = this.options;
2038
+ const { fixDropdownWidth, countrySearch } = this.options;
2030
2039
  if (fixDropdownWidth) {
2031
2040
  this.dropdownContent.style.width = `${this.telInput.offsetWidth}px`;
2032
2041
  }
2033
2042
  this.dropdownContent.classList.remove("iti__hide");
2034
2043
  this.selectedCountry.setAttribute("aria-expanded", "true");
2035
2044
  this._setDropdownPosition();
2036
- const firstCountryItem = this.countryList.firstElementChild;
2037
- if (firstCountryItem) {
2038
- this._highlightListItem(firstCountryItem, false);
2039
- this.countryList.scrollTop = 0;
2045
+ if (countrySearch) {
2046
+ const firstCountryItem = this.countryList.firstElementChild;
2047
+ if (firstCountryItem) {
2048
+ this._highlightListItem(firstCountryItem, false);
2049
+ this.countryList.scrollTop = 0;
2050
+ }
2051
+ this.searchInput.focus();
2040
2052
  }
2041
- this.searchInput.focus();
2042
2053
  this._bindDropdownListeners();
2043
2054
  this.dropdownArrow.classList.add("iti__arrow--up");
2044
2055
  this._trigger("open:countrydropdown");
2045
2056
  }
2046
- //* Decide if should position dropdown above or below input (depends on position within viewport, and scroll).
2057
+ //* Set the dropdown position
2047
2058
  _setDropdownPosition() {
2048
2059
  if (this.options.dropdownContainer) {
2049
2060
  this.options.dropdownContainer.appendChild(this.dropdown);
@@ -2089,6 +2100,8 @@ var Iti = class {
2089
2100
  "click",
2090
2101
  this._handleClickOffToClose
2091
2102
  );
2103
+ let query = "";
2104
+ let queryTimer = null;
2092
2105
  this._handleKeydownOnDropdown = (e) => {
2093
2106
  if (["ArrowUp", "ArrowDown", "Enter", "Escape"].includes(e.key)) {
2094
2107
  e.preventDefault();
@@ -2101,29 +2114,56 @@ var Iti = class {
2101
2114
  this._closeDropdown();
2102
2115
  }
2103
2116
  }
2104
- };
2105
- document.addEventListener("keydown", this._handleKeydownOnDropdown);
2106
- const doFilter = () => {
2107
- const inputQuery = this.searchInput.value.trim();
2108
- if (inputQuery) {
2109
- this._filterCountries(inputQuery);
2110
- } else {
2111
- this._filterCountries("", true);
2117
+ if (!this.options.countrySearch && /^[a-zA-ZÀ-ÿа-яА-Я ]$/.test(e.key)) {
2118
+ e.stopPropagation();
2119
+ if (queryTimer) {
2120
+ clearTimeout(queryTimer);
2121
+ }
2122
+ query += e.key.toLowerCase();
2123
+ this._searchForCountry(query);
2124
+ queryTimer = setTimeout(() => {
2125
+ query = "";
2126
+ }, 1e3);
2112
2127
  }
2113
2128
  };
2114
- let keyupTimer = null;
2115
- this._handleSearchChange = () => {
2116
- if (keyupTimer) {
2117
- clearTimeout(keyupTimer);
2129
+ document.addEventListener("keydown", this._handleKeydownOnDropdown);
2130
+ if (this.options.countrySearch) {
2131
+ const doFilter = () => {
2132
+ const inputQuery = this.searchInput.value.trim();
2133
+ if (inputQuery) {
2134
+ this._filterCountries(inputQuery);
2135
+ } else {
2136
+ this._filterCountries("", true);
2137
+ }
2138
+ };
2139
+ let keyupTimer = null;
2140
+ this._handleSearchChange = () => {
2141
+ if (keyupTimer) {
2142
+ clearTimeout(keyupTimer);
2143
+ }
2144
+ keyupTimer = setTimeout(() => {
2145
+ doFilter();
2146
+ keyupTimer = null;
2147
+ }, 100);
2148
+ };
2149
+ this.searchInput.addEventListener("input", this._handleSearchChange);
2150
+ this.searchInput.addEventListener("click", (e) => e.stopPropagation());
2151
+ }
2152
+ }
2153
+ //* Hidden search (countrySearch disabled): Find the first list item whose name starts with the query string.
2154
+ _searchForCountry(query) {
2155
+ for (let i = 0; i < this.countries.length; i++) {
2156
+ const c = this.countries[i];
2157
+ const startsWith = c.name.substr(0, query.length).toLowerCase() === query;
2158
+ if (startsWith) {
2159
+ const listItem = c.nodeById[this.id];
2160
+ this._highlightListItem(listItem, false);
2161
+ this._scrollTo(listItem);
2162
+ break;
2118
2163
  }
2119
- keyupTimer = setTimeout(() => {
2120
- doFilter();
2121
- keyupTimer = null;
2122
- }, 100);
2123
- };
2124
- this.searchInput.addEventListener("input", this._handleSearchChange);
2125
- this.searchInput.addEventListener("click", (e) => e.stopPropagation());
2164
+ }
2126
2165
  }
2166
+ //* Country search enabled: Filter the countries according to the search query.
2127
2167
  _filterCountries(query, isReset = false) {
2128
2168
  let noCountriesAddedYet = true;
2129
2169
  this.countryList.innerHTML = "";
@@ -2251,7 +2291,9 @@ var Iti = class {
2251
2291
  this.highlightedItem.setAttribute("aria-selected", "true");
2252
2292
  const activeDescendant = this.highlightedItem.getAttribute("id") || "";
2253
2293
  this.selectedCountry.setAttribute("aria-activedescendant", activeDescendant);
2254
- this.searchInput.setAttribute("aria-activedescendant", activeDescendant);
2294
+ if (this.options.countrySearch) {
2295
+ this.searchInput.setAttribute("aria-activedescendant", activeDescendant);
2296
+ }
2255
2297
  }
2256
2298
  if (shouldFocus) {
2257
2299
  this.highlightedItem.focus();
@@ -2408,10 +2450,14 @@ var Iti = class {
2408
2450
  if (this.highlightedItem) {
2409
2451
  this.highlightedItem.setAttribute("aria-selected", "false");
2410
2452
  }
2411
- this.searchInput.removeAttribute("aria-activedescendant");
2453
+ if (this.options.countrySearch) {
2454
+ this.searchInput.removeAttribute("aria-activedescendant");
2455
+ }
2412
2456
  this.dropdownArrow.classList.remove("iti__arrow--up");
2413
2457
  document.removeEventListener("keydown", this._handleKeydownOnDropdown);
2414
- this.searchInput.removeEventListener("input", this._handleSearchChange);
2458
+ if (this.options.countrySearch) {
2459
+ this.searchInput.removeEventListener("input", this._handleSearchChange);
2460
+ }
2415
2461
  document.documentElement.removeEventListener(
2416
2462
  "click",
2417
2463
  this._handleClickOffToClose
@@ -2722,7 +2768,7 @@ var intlTelInput = Object.assign(
2722
2768
  //* A map from instance ID to instance object.
2723
2769
  instances: {},
2724
2770
  loadUtils,
2725
- version: "23.3.2"
2771
+ version: "23.4.0"
2726
2772
  }
2727
2773
  );
2728
2774
  var intl_tel_input_default = intlTelInput;