intl-tel-input 25.10.12 → 25.11.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.
Files changed (35) hide show
  1. package/README.md +62 -59
  2. package/angular/README.md +1 -1
  3. package/angular/build/IntlTelInput.js +887 -688
  4. package/angular/build/IntlTelInputWithUtils.js +891 -692
  5. package/angular/build/types/intl-tel-input/data.d.ts +3 -3
  6. package/angular/build/types/intl-tel-input.d.ts +22 -70
  7. package/angular/build/types/modules/constants.d.ts +84 -0
  8. package/angular/build/types/modules/core/countrySearch.d.ts +17 -0
  9. package/angular/build/types/modules/core/icons.d.ts +7 -0
  10. package/angular/build/types/modules/core/options.d.ts +2 -1
  11. package/angular/build/types/modules/core/ui.d.ts +44 -0
  12. package/angular/build/types/modules/data/country-data.d.ts +5 -5
  13. package/angular/build/types/modules/format/caret.d.ts +1 -1
  14. package/angular/build/types/modules/format/formatting.d.ts +3 -3
  15. package/angular/build/types/modules/types/events.d.ts +9 -0
  16. package/angular/build/types/modules/types/public-api.d.ts +3 -0
  17. package/angular/build/types/modules/utils/dom.d.ts +5 -0
  18. package/build/js/data.js +8 -2
  19. package/build/js/data.min.js +2 -2
  20. package/build/js/intlTelInput.d.ts +214 -83
  21. package/build/js/intlTelInput.js +1034 -770
  22. package/build/js/intlTelInput.min.js +13 -13
  23. package/build/js/intlTelInputWithUtils.js +1038 -774
  24. package/build/js/intlTelInputWithUtils.min.js +13 -13
  25. package/build/js/utils.js +4 -4
  26. package/package.json +3 -1
  27. package/react/README.md +1 -1
  28. package/react/build/IntlTelInput.cjs +1033 -769
  29. package/react/build/IntlTelInput.d.ts +214 -83
  30. package/react/build/IntlTelInput.js +1033 -769
  31. package/react/build/IntlTelInputWithUtils.cjs +1037 -773
  32. package/react/build/IntlTelInputWithUtils.js +1037 -773
  33. package/vue/README.md +1 -1
  34. package/vue/build/IntlTelInput.mjs +967 -739
  35. package/vue/build/IntlTelInputWithUtils.mjs +1279 -1051
@@ -1,5 +1,5 @@
1
1
  /*
2
- * International Telephone Input v25.10.12
2
+ * International Telephone Input v25.11.1
3
3
  * https://github.com/jackocnr/intl-tel-input.git
4
4
  * Licensed under the MIT license
5
5
  */
@@ -1728,7 +1728,13 @@ var factoryOutput = (() => {
1728
1728
  areaCodes: c[3] || null,
1729
1729
  nodeById: {},
1730
1730
  // populated by the plugin
1731
- nationalPrefix: c[4] || null
1731
+ nationalPrefix: c[4] || null,
1732
+ normalisedName: "",
1733
+ // populated in the plugin
1734
+ initials: "",
1735
+ // populated in the plugin
1736
+ dialCodePlus: ""
1737
+ // populated in the plugin
1732
1738
  });
1733
1739
  }
1734
1740
  var data_default = allCountries;
@@ -2000,13 +2006,111 @@ var factoryOutput = (() => {
2000
2006
  var allTranslations = { ...countries_default, ...interface_default };
2001
2007
  var en_default = allTranslations;
2002
2008
 
2003
- // src/js/modules/core/options.ts
2004
- var mq = (q) => {
2005
- return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(q).matches;
2009
+ // src/js/modules/constants.ts
2010
+ var EVENTS = {
2011
+ OPEN_COUNTRY_DROPDOWN: "open:countrydropdown",
2012
+ CLOSE_COUNTRY_DROPDOWN: "close:countrydropdown",
2013
+ COUNTRY_CHANGE: "countrychange",
2014
+ INPUT: "input"
2015
+ // used for synthetic input trigger
2016
+ };
2017
+ var CLASSES = {
2018
+ HIDE: "iti__hide",
2019
+ V_HIDE: "iti__v-hide",
2020
+ ARROW_UP: "iti__arrow--up",
2021
+ GLOBE: "iti__globe",
2022
+ FLAG: "iti__flag",
2023
+ COUNTRY_ITEM: "iti__country",
2024
+ HIGHLIGHT: "iti__highlight"
2025
+ };
2026
+ var KEYS = {
2027
+ ARROW_UP: "ArrowUp",
2028
+ ARROW_DOWN: "ArrowDown",
2029
+ SPACE: " ",
2030
+ ENTER: "Enter",
2031
+ ESC: "Escape",
2032
+ TAB: "Tab"
2033
+ };
2034
+ var INPUT_TYPES = {
2035
+ PASTE: "insertFromPaste",
2036
+ DELETE_FWD: "deleteContentForward"
2037
+ };
2038
+ var REGEX = {
2039
+ ALPHA_UNICODE: /\p{L}/u,
2040
+ // any kind of letter from any language
2041
+ NON_PLUS_NUMERIC: /[^+0-9]/,
2042
+ // chars that are NOT + or digit
2043
+ NON_PLUS_NUMERIC_GLOBAL: /[^+0-9]/g,
2044
+ // chars that are NOT + or digit (global)
2045
+ HIDDEN_SEARCH_CHAR: /^[a-zA-ZÀ-ÿа-яА-Я ]$/
2046
+ // single acceptable hidden-search char
2047
+ };
2048
+ var TIMINGS = {
2049
+ SEARCH_DEBOUNCE_MS: 100,
2050
+ HIDDEN_SEARCH_RESET_MS: 1e3,
2051
+ NEXT_TICK: 0
2052
+ };
2053
+ var SENTINELS = {
2054
+ UNKNOWN_NUMBER_TYPE: -99,
2055
+ UNKNOWN_VALIDATION_ERROR: -99
2056
+ };
2057
+ var LAYOUT = {
2058
+ SANE_SELECTED_WITH_DIAL_WIDTH: 78,
2059
+ // px width fallback when separateDialCode enabled
2060
+ SANE_SELECTED_NO_DIAL_WIDTH: 42,
2061
+ // px width fallback when no separate dial code
2062
+ INPUT_PADDING_EXTRA_LEFT: 6
2063
+ // px gap between selected country container and input text
2064
+ };
2065
+ var DIAL = {
2066
+ PLUS: "+",
2067
+ NANP: "1"
2068
+ // North American Numbering Plan
2069
+ };
2070
+ var UK = {
2071
+ ISO2: "gb",
2072
+ DIAL_CODE: "44",
2073
+ // +44 United Kingdom
2074
+ MOBILE_PREFIX: "7",
2075
+ // UK mobile numbers start with 7 after national trunk (0) or core section
2076
+ MOBILE_CORE_LENGTH: 10
2077
+ // core number length (excluding dial code / national prefix) for mobiles
2078
+ };
2079
+ var US = {
2080
+ ISO2: "us",
2081
+ DIAL_CODE: "1"
2082
+ // +1 United States
2083
+ };
2084
+ var PLACEHOLDER_MODES = {
2085
+ AGGRESSIVE: "aggressive",
2086
+ POLITE: "polite"
2087
+ };
2088
+ var INITIAL_COUNTRY = {
2089
+ AUTO: "auto"
2006
2090
  };
2091
+ var DATA_KEYS = {
2092
+ COUNTRY_CODE: "countryCode",
2093
+ DIAL_CODE: "dialCode"
2094
+ };
2095
+ var ARIA = {
2096
+ EXPANDED: "aria-expanded",
2097
+ LABEL: "aria-label",
2098
+ SELECTED: "aria-selected",
2099
+ ACTIVE_DESCENDANT: "aria-activedescendant",
2100
+ HASPOPUP: "aria-haspopup",
2101
+ CONTROLS: "aria-controls",
2102
+ HIDDEN: "aria-hidden",
2103
+ AUTOCOMPLETE: "aria-autocomplete",
2104
+ MODAL: "aria-modal"
2105
+ };
2106
+
2107
+ // src/js/modules/core/options.ts
2108
+ var mq = (q) => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(q).matches;
2007
2109
  var computeDefaultUseFullscreenPopup = () => {
2008
2110
  if (typeof navigator !== "undefined" && typeof window !== "undefined") {
2009
- const isMobileUserAgent = /Android.+Mobile|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
2111
+ const isMobileUserAgent = /Android.+Mobile|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
2112
+ navigator.userAgent
2113
+ );
2010
2114
  const isNarrowViewport = mq("(max-width: 500px)");
2011
2115
  const isShortViewport = mq("(max-height: 600px)");
2012
2116
  const isCoarsePointer = mq("(pointer: coarse)");
@@ -2020,7 +2124,7 @@ var factoryOutput = (() => {
2020
2124
  //* Whether or not to allow the dropdown.
2021
2125
  allowDropdown: true,
2022
2126
  //* Add a placeholder in the input with an example number for the selected country.
2023
- autoPlaceholder: "polite",
2127
+ autoPlaceholder: PLACEHOLDER_MODES.POLITE,
2024
2128
  //* Modify the parentClass.
2025
2129
  containerClass: "",
2026
2130
  //* The order of the countries in the dropdown. Defaults to alphabetical.
@@ -2066,7 +2170,7 @@ var factoryOutput = (() => {
2066
2170
  //* The number type to enforce during validation.
2067
2171
  validationNumberTypes: ["MOBILE"]
2068
2172
  };
2069
- function applyOptionSideEffects(o) {
2173
+ var applyOptionSideEffects = (o, defaultEnglishStrings) => {
2070
2174
  if (o.useFullscreenPopup) {
2071
2175
  o.fixDropdownWidth = false;
2072
2176
  }
@@ -2082,18 +2186,66 @@ var factoryOutput = (() => {
2082
2186
  if (o.useFullscreenPopup && !o.dropdownContainer) {
2083
2187
  o.dropdownContainer = document.body;
2084
2188
  }
2085
- o.i18n = { ...en_default, ...o.i18n };
2086
- }
2189
+ o.i18n = { ...defaultEnglishStrings, ...o.i18n };
2190
+ };
2087
2191
 
2088
2192
  // src/js/modules/utils/string.ts
2089
2193
  var getNumeric = (s) => s.replace(/\D/g, "");
2090
2194
  var normaliseString = (s = "") => s.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase();
2091
2195
 
2196
+ // src/js/modules/core/countrySearch.ts
2197
+ var getMatchedCountries = (countries, query) => {
2198
+ const normalisedQuery = normaliseString(query);
2199
+ const iso2Matches = [];
2200
+ const nameStartWith = [];
2201
+ const nameContains = [];
2202
+ const dialCodeMatches = [];
2203
+ const dialCodeContains = [];
2204
+ const initialsMatches = [];
2205
+ for (const c of countries) {
2206
+ if (c.iso2 === normalisedQuery) {
2207
+ iso2Matches.push(c);
2208
+ } else if (c.normalisedName.startsWith(normalisedQuery)) {
2209
+ nameStartWith.push(c);
2210
+ } else if (c.normalisedName.includes(normalisedQuery)) {
2211
+ nameContains.push(c);
2212
+ } else if (normalisedQuery === c.dialCode || normalisedQuery === c.dialCodePlus) {
2213
+ dialCodeMatches.push(c);
2214
+ } else if (c.dialCodePlus.includes(normalisedQuery)) {
2215
+ dialCodeContains.push(c);
2216
+ } else if (c.initials.includes(normalisedQuery)) {
2217
+ initialsMatches.push(c);
2218
+ }
2219
+ }
2220
+ const sortByPriority = (a, b) => a.priority - b.priority;
2221
+ return [
2222
+ ...iso2Matches.sort(sortByPriority),
2223
+ ...nameStartWith.sort(sortByPriority),
2224
+ ...nameContains.sort(sortByPriority),
2225
+ ...dialCodeMatches.sort(sortByPriority),
2226
+ ...dialCodeContains.sort(sortByPriority),
2227
+ ...initialsMatches.sort(sortByPriority)
2228
+ ];
2229
+ };
2230
+ var findFirstCountryStartingWith = (countries, query) => {
2231
+ const lowerQuery = query.toLowerCase();
2232
+ for (const c of countries) {
2233
+ const lowerName = c.name.toLowerCase();
2234
+ if (lowerName.startsWith(lowerQuery)) {
2235
+ return c;
2236
+ }
2237
+ }
2238
+ return null;
2239
+ };
2240
+
2092
2241
  // src/js/modules/utils/dom.ts
2242
+ var buildClassNames = (flags) => Object.keys(flags).filter((k) => Boolean(flags[k])).join(" ");
2093
2243
  var createEl = (tagName, attrs, container) => {
2094
2244
  const el = document.createElement(tagName);
2095
2245
  if (attrs) {
2096
- Object.entries(attrs).forEach(([key, value]) => el.setAttribute(key, value));
2246
+ Object.entries(attrs).forEach(
2247
+ ([key, value]) => el.setAttribute(key, value)
2248
+ );
2097
2249
  }
2098
2250
  if (container) {
2099
2251
  container.appendChild(el);
@@ -2101,251 +2253,41 @@ var factoryOutput = (() => {
2101
2253
  return el;
2102
2254
  };
2103
2255
 
2104
- // src/js/modules/data/country-data.ts
2105
- function processAllCountries(options) {
2106
- const { onlyCountries, excludeCountries } = options;
2107
- if (onlyCountries.length) {
2108
- const lowerCaseOnlyCountries = onlyCountries.map((country) => country.toLowerCase());
2109
- return data_default.filter((country) => lowerCaseOnlyCountries.includes(country.iso2));
2110
- } else if (excludeCountries.length) {
2111
- const lowerCaseExcludeCountries = excludeCountries.map((country) => country.toLowerCase());
2112
- return data_default.filter((country) => !lowerCaseExcludeCountries.includes(country.iso2));
2113
- }
2114
- return data_default;
2115
- }
2116
- function translateCountryNames(countries, options) {
2117
- for (const c of countries) {
2118
- const iso2 = c.iso2.toLowerCase();
2119
- if (options.i18n[iso2]) {
2120
- c.name = options.i18n[iso2];
2121
- }
2122
- }
2123
- }
2124
- function processDialCodes(countries, options) {
2125
- const dialCodes = /* @__PURE__ */ new Set();
2126
- let dialCodeMaxLen = 0;
2127
- const dialCodeToIso2Map = {};
2128
- const _addToDialCodeMap = (iso2, dialCode, priority) => {
2129
- if (!iso2 || !dialCode) {
2130
- return;
2131
- }
2132
- if (dialCode.length > dialCodeMaxLen) {
2133
- dialCodeMaxLen = dialCode.length;
2134
- }
2135
- if (!dialCodeToIso2Map.hasOwnProperty(dialCode)) {
2136
- dialCodeToIso2Map[dialCode] = [];
2137
- }
2138
- const iso2List = dialCodeToIso2Map[dialCode];
2139
- if (iso2List.includes(iso2)) {
2140
- return;
2141
- }
2142
- const index = priority !== void 0 ? priority : iso2List.length;
2143
- iso2List[index] = iso2;
2144
- };
2145
- for (const c of countries) {
2146
- if (!dialCodes.has(c.dialCode)) {
2147
- dialCodes.add(c.dialCode);
2148
- }
2149
- for (let k = 1; k < c.dialCode.length; k++) {
2150
- const partialDialCode = c.dialCode.substring(0, k);
2151
- _addToDialCodeMap(c.iso2, partialDialCode);
2152
- }
2153
- _addToDialCodeMap(c.iso2, c.dialCode, c.priority);
2154
- }
2155
- if (options.onlyCountries.length || options.excludeCountries.length) {
2156
- dialCodes.forEach((dialCode) => {
2157
- dialCodeToIso2Map[dialCode] = dialCodeToIso2Map[dialCode].filter(Boolean);
2158
- });
2159
- }
2160
- for (const c of countries) {
2161
- if (c.areaCodes) {
2162
- const rootIso2Code = dialCodeToIso2Map[c.dialCode][0];
2163
- for (const areaCode of c.areaCodes) {
2164
- for (let k = 1; k < areaCode.length; k++) {
2165
- const partialAreaCode = areaCode.substring(0, k);
2166
- const partialDialCode = c.dialCode + partialAreaCode;
2167
- _addToDialCodeMap(rootIso2Code, partialDialCode);
2168
- _addToDialCodeMap(c.iso2, partialDialCode);
2169
- }
2170
- _addToDialCodeMap(c.iso2, c.dialCode + areaCode);
2171
- }
2172
- }
2173
- }
2174
- return { dialCodes, dialCodeMaxLen, dialCodeToIso2Map };
2175
- }
2176
- function sortCountries(countries, options) {
2177
- if (options.countryOrder) {
2178
- options.countryOrder = options.countryOrder.map((iso2) => iso2.toLowerCase());
2179
- }
2180
- countries.sort((a, b) => {
2181
- const { countryOrder } = options;
2182
- if (countryOrder) {
2183
- const aIndex = countryOrder.indexOf(a.iso2);
2184
- const bIndex = countryOrder.indexOf(b.iso2);
2185
- const aIndexExists = aIndex > -1;
2186
- const bIndexExists = bIndex > -1;
2187
- if (aIndexExists || bIndexExists) {
2188
- if (aIndexExists && bIndexExists) {
2189
- return aIndex - bIndex;
2190
- }
2191
- return aIndexExists ? -1 : 1;
2192
- }
2193
- }
2194
- return a.name.localeCompare(b.name);
2195
- });
2196
- }
2197
- function cacheSearchTokens(countries) {
2198
- for (const c of countries) {
2199
- c.normalisedName = normaliseString(c.name);
2200
- c.initials = c.name.split(/[^a-zA-ZÀ-ÿа-яА-Я]/).map((word) => word[0]).join("").toLowerCase();
2201
- c.dialCodePlus = `+${c.dialCode}`;
2202
- }
2203
- }
2204
-
2205
- // src/js/modules/format/formatting.ts
2206
- function beforeSetNumber(fullNumber, dialCode, separateDialCode, selectedCountryData) {
2207
- let number = fullNumber;
2208
- if (separateDialCode) {
2209
- if (dialCode) {
2210
- dialCode = `+${selectedCountryData.dialCode}`;
2211
- const start = number[dialCode.length] === " " || number[dialCode.length] === "-" ? dialCode.length + 1 : dialCode.length;
2212
- number = number.substring(start);
2213
- }
2214
- }
2215
- return number;
2216
- }
2217
- function formatNumberAsYouType(fullNumber, telInputValue, utils2, selectedCountryData, separateDialCode) {
2218
- const result = utils2 ? utils2.formatNumberAsYouType(fullNumber, selectedCountryData.iso2) : fullNumber;
2219
- const { dialCode } = selectedCountryData;
2220
- if (separateDialCode && telInputValue.charAt(0) !== "+" && result.includes(`+${dialCode}`)) {
2221
- const afterDialCode = result.split(`+${dialCode}`)[1] || "";
2222
- return afterDialCode.trim();
2223
- }
2224
- return result;
2225
- }
2226
-
2227
- // src/js/modules/format/caret.ts
2228
- function translateCursorPosition(relevantChars, formattedValue, prevCaretPos, isDeleteForwards) {
2229
- if (prevCaretPos === 0 && !isDeleteForwards) {
2230
- return 0;
2231
- }
2232
- let relevantCharCount = 0;
2233
- for (let i = 0; i < formattedValue.length; i++) {
2234
- if (/[+0-9]/.test(formattedValue[i])) {
2235
- relevantCharCount++;
2236
- }
2237
- if (relevantCharCount === relevantChars && !isDeleteForwards) {
2238
- return i + 1;
2239
- }
2240
- if (isDeleteForwards && relevantCharCount === relevantChars + 1) {
2241
- return i;
2242
- }
2243
- }
2244
- return formattedValue.length;
2245
- }
2246
-
2247
- // src/js/modules/data/nanp-regionless.ts
2248
- var regionlessNanpNumbers = [
2249
- "800",
2250
- "822",
2251
- "833",
2252
- "844",
2253
- "855",
2254
- "866",
2255
- "877",
2256
- "880",
2257
- "881",
2258
- "882",
2259
- "883",
2260
- "884",
2261
- "885",
2262
- "886",
2263
- "887",
2264
- "888",
2265
- "889"
2266
- ];
2267
- var isRegionlessNanp = (number) => {
2268
- const numeric = getNumeric(number);
2269
- if (numeric.charAt(0) === "1") {
2270
- const areaCode = numeric.substring(1, 4);
2271
- return regionlessNanpNumbers.includes(areaCode);
2272
- }
2273
- return false;
2256
+ // src/js/modules/core/icons.ts
2257
+ var buildSearchIcon = () => `
2258
+ <svg class="iti__search-icon-svg" width="14" height="14" viewBox="0 0 24 24" focusable="false" ${ARIA.HIDDEN}="true">
2259
+ <circle cx="11" cy="11" r="7" />
2260
+ <line x1="21" y1="21" x2="16.65" y2="16.65" />
2261
+ </svg>`;
2262
+ var buildClearIcon = (id2) => {
2263
+ const maskId = `iti-${id2}-clear-mask`;
2264
+ return `
2265
+ <svg class="iti__search-clear-svg" width="12" height="12" viewBox="0 0 16 16" ${ARIA.HIDDEN}="true" focusable="false">
2266
+ <mask id="${maskId}" maskUnits="userSpaceOnUse">
2267
+ <rect width="16" height="16" fill="white" />
2268
+ <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" />
2269
+ </mask>
2270
+ <circle cx="8" cy="8" r="8" class="iti__search-clear-bg" mask="url(#${maskId})" />
2271
+ </svg>`;
2274
2272
  };
2275
2273
 
2276
- // src/js/intl-tel-input.ts
2277
- for (const c of data_default) {
2278
- c.name = en_default[c.iso2];
2279
- }
2280
- var id = 0;
2281
- var iso2Set = new Set(data_default.map((c) => c.iso2));
2282
- var isIso2 = (val) => iso2Set.has(val);
2283
- var forEachInstance = (method, ...args) => {
2284
- const { instances } = intlTelInput;
2285
- Object.values(instances).forEach((instance) => instance[method](...args));
2286
- };
2287
- var Iti = class _Iti {
2288
- /**
2289
- * Build a space-delimited class string from an object map of className -> truthy/falsey.
2290
- * Only keys with truthy values are included.
2291
- */
2292
- static _buildClassNames(flags) {
2293
- return Object.keys(flags).filter((k) => Boolean(flags[k])).join(" ");
2294
- }
2295
- constructor(input, customOptions = {}) {
2296
- this.id = id++;
2297
- this.telInput = input;
2274
+ // src/js/modules/core/ui.ts
2275
+ var UI = class {
2276
+ constructor(input, options, id2) {
2298
2277
  this.highlightedItem = null;
2299
- this.options = Object.assign({}, defaults, customOptions);
2278
+ input.dataset.intlTelInputId = id2.toString();
2279
+ this.telInput = input;
2280
+ this.options = options;
2281
+ this.id = id2;
2300
2282
  this.hadInitialPlaceholder = Boolean(input.getAttribute("placeholder"));
2301
- }
2302
- _detectEnvironmentAndLayout() {
2303
- this.isAndroid = typeof navigator !== "undefined" ? /Android/i.test(navigator.userAgent) : false;
2304
2283
  this.isRTL = !!this.telInput.closest("[dir=rtl]");
2305
2284
  if (this.options.separateDialCode) {
2306
2285
  this.originalPaddingLeft = this.telInput.style.paddingLeft;
2307
2286
  }
2308
2287
  }
2309
- _createInitPromises() {
2310
- const autoCountryPromise = new Promise((resolve, reject) => {
2311
- this.resolveAutoCountryPromise = resolve;
2312
- this.rejectAutoCountryPromise = reject;
2313
- });
2314
- const utilsScriptPromise = new Promise((resolve, reject) => {
2315
- this.resolveUtilsScriptPromise = resolve;
2316
- this.rejectUtilsScriptPromise = reject;
2317
- });
2318
- this.promise = Promise.all([autoCountryPromise, utilsScriptPromise]);
2319
- }
2320
- //* Can't be private as it's called from intlTelInput convenience wrapper.
2321
- _init() {
2322
- applyOptionSideEffects(this.options);
2323
- this._detectEnvironmentAndLayout();
2324
- this._createInitPromises();
2325
- this.selectedCountryData = {};
2326
- this._processCountryData();
2327
- this._generateMarkup();
2328
- this._setInitialState();
2329
- this._initListeners();
2330
- this._initRequests();
2331
- }
2332
- //********************
2333
- //* PRIVATE METHODS
2334
- //********************
2335
- //* Prepare all of the country data, including onlyCountries, excludeCountries, countryOrder options.
2336
- _processCountryData() {
2337
- this.countries = processAllCountries(this.options);
2338
- const dialRes = processDialCodes(this.countries, this.options);
2339
- this.dialCodes = dialRes.dialCodes;
2340
- this.dialCodeMaxLen = dialRes.dialCodeMaxLen;
2341
- this.dialCodeToIso2Map = dialRes.dialCodeToIso2Map;
2342
- translateCountryNames(this.countries, this.options);
2343
- sortCountries(this.countries, this.options);
2344
- this.countryByIso2 = new Map(this.countries.map((c) => [c.iso2, c]));
2345
- cacheSearchTokens(this.countries);
2346
- }
2347
2288
  //* Generate all of the markup for the plugin: the selected country overlay, and the dropdown.
2348
- _generateMarkup() {
2289
+ generateMarkup(countries) {
2290
+ this.countries = countries;
2349
2291
  this._prepareTelInput();
2350
2292
  const wrapper = this._createWrapperAndInsert();
2351
2293
  this._maybeBuildCountryContainer(wrapper);
@@ -2355,19 +2297,14 @@ var factoryOutput = (() => {
2355
2297
  }
2356
2298
  _prepareTelInput() {
2357
2299
  this.telInput.classList.add("iti__tel-input");
2358
- if (!this.telInput.hasAttribute("autocomplete") && !(this.telInput.form && this.telInput.form.hasAttribute("autocomplete"))) {
2300
+ if (!this.telInput.hasAttribute("autocomplete") && !this.telInput.form?.hasAttribute("autocomplete")) {
2359
2301
  this.telInput.setAttribute("autocomplete", "off");
2360
2302
  }
2361
2303
  }
2362
2304
  _createWrapperAndInsert() {
2363
- const {
2364
- allowDropdown,
2365
- showFlags,
2366
- containerClass,
2367
- useFullscreenPopup
2368
- } = this.options;
2369
- const parentClasses = _Iti._buildClassNames({
2370
- "iti": true,
2305
+ const { allowDropdown, showFlags, containerClass, useFullscreenPopup } = this.options;
2306
+ const parentClasses = buildClassNames({
2307
+ iti: true,
2371
2308
  "iti--allow-dropdown": allowDropdown,
2372
2309
  "iti--show-flags": showFlags,
2373
2310
  "iti--inline-dropdown": !useFullscreenPopup,
@@ -2377,20 +2314,16 @@ var factoryOutput = (() => {
2377
2314
  if (this.isRTL) {
2378
2315
  wrapper.setAttribute("dir", "ltr");
2379
2316
  }
2380
- this.telInput.parentNode?.insertBefore(wrapper, this.telInput);
2317
+ this.telInput.before(wrapper);
2381
2318
  return wrapper;
2382
2319
  }
2383
2320
  _maybeBuildCountryContainer(wrapper) {
2384
- const {
2385
- allowDropdown,
2386
- separateDialCode,
2387
- showFlags
2388
- } = this.options;
2321
+ const { allowDropdown, separateDialCode, showFlags } = this.options;
2389
2322
  if (allowDropdown || showFlags || separateDialCode) {
2390
2323
  this.countryContainer = createEl(
2391
2324
  "div",
2392
2325
  // visibly hidden until we measure it's width to set the input padding correctly
2393
- { class: "iti__country-container iti__v-hide" },
2326
+ { class: `iti__country-container ${CLASSES.V_HIDE}` },
2394
2327
  wrapper
2395
2328
  );
2396
2329
  if (allowDropdown) {
@@ -2399,10 +2332,10 @@ var factoryOutput = (() => {
2399
2332
  {
2400
2333
  type: "button",
2401
2334
  class: "iti__selected-country",
2402
- "aria-expanded": "false",
2403
- "aria-label": this.options.i18n.noCountrySelected,
2404
- "aria-haspopup": "dialog",
2405
- "aria-controls": `iti-${this.id}__dropdown-content`
2335
+ [ARIA.EXPANDED]: "false",
2336
+ [ARIA.LABEL]: this.options.i18n.noCountrySelected,
2337
+ [ARIA.HASPOPUP]: "dialog",
2338
+ [ARIA.CONTROLS]: `iti-${this.id}__dropdown-content`
2406
2339
  },
2407
2340
  this.countryContainer
2408
2341
  );
@@ -2423,13 +2356,13 @@ var factoryOutput = (() => {
2423
2356
  );
2424
2357
  this.selectedCountryInner = createEl(
2425
2358
  "div",
2426
- { class: "iti__flag" },
2359
+ { class: CLASSES.FLAG },
2427
2360
  selectedCountryPrimary
2428
2361
  );
2429
2362
  if (allowDropdown) {
2430
2363
  this.dropdownArrow = createEl(
2431
2364
  "div",
2432
- { class: "iti__arrow", "aria-hidden": "true" },
2365
+ { class: "iti__arrow", [ARIA.HIDDEN]: "true" },
2433
2366
  selectedCountryPrimary
2434
2367
  );
2435
2368
  }
@@ -2457,9 +2390,9 @@ var factoryOutput = (() => {
2457
2390
  const extraClasses = fixDropdownWidth ? "" : "iti--flexible-dropdown-width";
2458
2391
  this.dropdownContent = createEl("div", {
2459
2392
  id: `iti-${this.id}__dropdown-content`,
2460
- class: `iti__dropdown-content iti__hide ${extraClasses}`,
2393
+ class: `iti__dropdown-content ${CLASSES.HIDE} ${extraClasses}`,
2461
2394
  role: "dialog",
2462
- "aria-modal": "true"
2395
+ [ARIA.MODAL]: "true"
2463
2396
  });
2464
2397
  if (this.isRTL) {
2465
2398
  this.dropdownContent.setAttribute("dir", "rtl");
@@ -2473,17 +2406,17 @@ var factoryOutput = (() => {
2473
2406
  class: "iti__country-list",
2474
2407
  id: `iti-${this.id}__country-listbox`,
2475
2408
  role: "listbox",
2476
- "aria-label": i18n.countryListAriaLabel
2409
+ [ARIA.LABEL]: i18n.countryListAriaLabel
2477
2410
  },
2478
2411
  this.dropdownContent
2479
2412
  );
2480
2413
  this._appendListItems();
2481
2414
  if (countrySearch) {
2482
- this._updateSearchResultsA11yText();
2415
+ this.updateSearchResultsA11yText();
2483
2416
  }
2484
2417
  if (dropdownContainer) {
2485
- const dropdownClasses = _Iti._buildClassNames({
2486
- "iti": true,
2418
+ const dropdownClasses = buildClassNames({
2419
+ iti: true,
2487
2420
  "iti--container": true,
2488
2421
  "iti--fullscreen-popup": useFullscreenPopup,
2489
2422
  "iti--inline-dropdown": !useFullscreenPopup,
@@ -2506,15 +2439,11 @@ var factoryOutput = (() => {
2506
2439
  "span",
2507
2440
  {
2508
2441
  class: "iti__search-icon",
2509
- "aria-hidden": "true"
2442
+ [ARIA.HIDDEN]: "true"
2510
2443
  },
2511
2444
  searchWrapper
2512
2445
  );
2513
- this.searchIcon.innerHTML = `
2514
- <svg class="iti__search-icon-svg" width="14" height="14" viewBox="0 0 24 24" focusable="false" aria-hidden="true">
2515
- <circle cx="11" cy="11" r="7" />
2516
- <line x1="21" y1="21" x2="16.65" y2="16.65" />
2517
- </svg>`;
2446
+ this.searchIcon.innerHTML = buildSearchIcon();
2518
2447
  this.searchInput = createEl(
2519
2448
  "input",
2520
2449
  {
@@ -2525,11 +2454,11 @@ var factoryOutput = (() => {
2525
2454
  placeholder: i18n.searchPlaceholder,
2526
2455
  // 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
2527
2456
  role: "combobox",
2528
- "aria-expanded": "true",
2529
- "aria-label": i18n.searchPlaceholder,
2530
- "aria-controls": `iti-${this.id}__country-listbox`,
2531
- "aria-autocomplete": "list",
2532
- "autocomplete": "off"
2457
+ [ARIA.EXPANDED]: "true",
2458
+ [ARIA.LABEL]: i18n.searchPlaceholder,
2459
+ [ARIA.CONTROLS]: `iti-${this.id}__country-listbox`,
2460
+ [ARIA.AUTOCOMPLETE]: "list",
2461
+ autocomplete: "off"
2533
2462
  },
2534
2463
  searchWrapper
2535
2464
  );
@@ -2537,21 +2466,13 @@ var factoryOutput = (() => {
2537
2466
  "button",
2538
2467
  {
2539
2468
  type: "button",
2540
- class: "iti__search-clear iti__hide",
2541
- "aria-label": i18n.clearSearchAriaLabel,
2469
+ class: `iti__search-clear ${CLASSES.HIDE}`,
2470
+ [ARIA.LABEL]: i18n.clearSearchAriaLabel,
2542
2471
  tabindex: "-1"
2543
2472
  },
2544
2473
  searchWrapper
2545
2474
  );
2546
- const maskId = `iti-${this.id}-clear-mask`;
2547
- this.searchClearButton.innerHTML = `
2548
- <svg class="iti__search-clear-svg" width="12" height="12" viewBox="0 0 16 16" aria-hidden="true" focusable="false">
2549
- <mask id="${maskId}" maskUnits="userSpaceOnUse">
2550
- <rect width="16" height="16" fill="white" />
2551
- <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" />
2552
- </mask>
2553
- <circle cx="8" cy="8" r="8" class="iti__search-clear-bg" mask="url(#${maskId})" />
2554
- </svg>`;
2475
+ this.searchClearButton.innerHTML = buildClearIcon(this.id);
2555
2476
  this.searchResultsA11yText = createEl(
2556
2477
  "span",
2557
2478
  { class: "iti__a11y-text" },
@@ -2560,91 +2481,496 @@ var factoryOutput = (() => {
2560
2481
  this.searchNoResults = createEl(
2561
2482
  "div",
2562
2483
  {
2563
- class: "iti__no-results iti__hide",
2564
- "aria-hidden": "true"
2484
+ class: `iti__no-results ${CLASSES.HIDE}`,
2485
+ [ARIA.HIDDEN]: "true"
2565
2486
  // all a11y messaging happens in this.searchResultsA11yText
2566
2487
  },
2567
2488
  this.dropdownContent
2568
2489
  );
2569
- this.searchNoResults.textContent = i18n.zeroSearchResults;
2490
+ this.searchNoResults.textContent = i18n.zeroSearchResults;
2491
+ }
2492
+ _maybeUpdateInputPaddingAndReveal() {
2493
+ if (this.countryContainer) {
2494
+ this.updateInputPadding();
2495
+ this.countryContainer.classList.remove(CLASSES.V_HIDE);
2496
+ }
2497
+ }
2498
+ _maybeBuildHiddenInputs(wrapper) {
2499
+ const { hiddenInput } = this.options;
2500
+ if (hiddenInput) {
2501
+ const telInputName = this.telInput.getAttribute("name") || "";
2502
+ const names = hiddenInput(telInputName);
2503
+ if (names.phone) {
2504
+ const existingInput = this.telInput.form?.querySelector(
2505
+ `input[name="${names.phone}"]`
2506
+ );
2507
+ if (existingInput) {
2508
+ this.hiddenInput = existingInput;
2509
+ } else {
2510
+ this.hiddenInput = createEl("input", {
2511
+ type: "hidden",
2512
+ name: names.phone
2513
+ });
2514
+ wrapper.appendChild(this.hiddenInput);
2515
+ }
2516
+ }
2517
+ if (names.country) {
2518
+ const existingInput = this.telInput.form?.querySelector(
2519
+ `input[name="${names.country}"]`
2520
+ );
2521
+ if (existingInput) {
2522
+ this.hiddenInputCountry = existingInput;
2523
+ } else {
2524
+ this.hiddenInputCountry = createEl("input", {
2525
+ type: "hidden",
2526
+ name: names.country
2527
+ });
2528
+ wrapper.appendChild(this.hiddenInputCountry);
2529
+ }
2530
+ }
2531
+ }
2532
+ }
2533
+ //* For each country: add a country list item <li> to the countryList <ul> container.
2534
+ _appendListItems() {
2535
+ const frag = document.createDocumentFragment();
2536
+ for (let i = 0; i < this.countries.length; i++) {
2537
+ const c = this.countries[i];
2538
+ const liClass = buildClassNames({
2539
+ [CLASSES.COUNTRY_ITEM]: true,
2540
+ [CLASSES.HIGHLIGHT]: i === 0
2541
+ });
2542
+ const listItem = createEl("li", {
2543
+ id: `iti-${this.id}__item-${c.iso2}`,
2544
+ class: liClass,
2545
+ tabindex: "-1",
2546
+ role: "option",
2547
+ [ARIA.SELECTED]: "false"
2548
+ });
2549
+ listItem.dataset.dialCode = c.dialCode;
2550
+ listItem.dataset.countryCode = c.iso2;
2551
+ c.nodeById[this.id] = listItem;
2552
+ if (this.options.showFlags) {
2553
+ createEl("div", { class: `${CLASSES.FLAG} iti__${c.iso2}` }, listItem);
2554
+ }
2555
+ const nameEl = createEl("span", { class: "iti__country-name" }, listItem);
2556
+ nameEl.textContent = c.name;
2557
+ const dialEl = createEl("span", { class: "iti__dial-code" }, listItem);
2558
+ if (this.isRTL) {
2559
+ dialEl.setAttribute("dir", "ltr");
2560
+ }
2561
+ dialEl.textContent = `+${c.dialCode}`;
2562
+ frag.appendChild(listItem);
2563
+ }
2564
+ this.countryList.appendChild(frag);
2565
+ }
2566
+ //* Update the input padding to make space for the selected country/dial code.
2567
+ updateInputPadding() {
2568
+ if (this.selectedCountry) {
2569
+ const fallbackWidth = this.options.separateDialCode ? LAYOUT.SANE_SELECTED_WITH_DIAL_WIDTH : LAYOUT.SANE_SELECTED_NO_DIAL_WIDTH;
2570
+ const selectedCountryWidth = this.selectedCountry.offsetWidth || this._getHiddenSelectedCountryWidth() || fallbackWidth;
2571
+ const inputPadding = selectedCountryWidth + LAYOUT.INPUT_PADDING_EXTRA_LEFT;
2572
+ this.telInput.style.paddingLeft = `${inputPadding}px`;
2573
+ }
2574
+ }
2575
+ //* When input is in a hidden container during init, we cannot calculate the selected country width.
2576
+ //* Fix: clone the markup, make it invisible, add it to the end of the DOM, and then measure it's width.
2577
+ //* To get the right styling to apply, all we need is a shallow clone of the container,
2578
+ //* and then to inject a deep clone of the selectedCountry element.
2579
+ _getHiddenSelectedCountryWidth() {
2580
+ if (this.telInput.parentNode) {
2581
+ let body;
2582
+ try {
2583
+ body = window.top.document.body;
2584
+ } catch (e) {
2585
+ body = document.body;
2586
+ }
2587
+ const containerClone = this.telInput.parentNode.cloneNode(
2588
+ false
2589
+ );
2590
+ containerClone.style.visibility = "hidden";
2591
+ body.appendChild(containerClone);
2592
+ const countryContainerClone = this.countryContainer.cloneNode();
2593
+ containerClone.appendChild(countryContainerClone);
2594
+ const selectedCountryClone = this.selectedCountry.cloneNode(
2595
+ true
2596
+ );
2597
+ countryContainerClone.appendChild(selectedCountryClone);
2598
+ const width = selectedCountryClone.offsetWidth;
2599
+ body.removeChild(containerClone);
2600
+ return width;
2601
+ }
2602
+ return 0;
2603
+ }
2604
+ //* Update search results text (for a11y).
2605
+ updateSearchResultsA11yText() {
2606
+ const { i18n } = this.options;
2607
+ const count = this.countryList.childElementCount;
2608
+ let searchText;
2609
+ if (count === 0) {
2610
+ searchText = i18n.zeroSearchResults;
2611
+ } else {
2612
+ if (i18n.searchResultsText) {
2613
+ searchText = i18n.searchResultsText(count);
2614
+ } else if (count === 1) {
2615
+ searchText = i18n.oneSearchResult;
2616
+ } else {
2617
+ searchText = i18n.multipleSearchResults.replace(
2618
+ "${count}",
2619
+ count.toString()
2620
+ );
2621
+ }
2622
+ }
2623
+ this.searchResultsA11yText.textContent = searchText;
2624
+ }
2625
+ //* Check if an element is visible within it's container, else scroll until it is.
2626
+ scrollTo(element) {
2627
+ const container = this.countryList;
2628
+ const scrollTop = document.documentElement.scrollTop;
2629
+ const containerHeight = container.offsetHeight;
2630
+ const containerTop = container.getBoundingClientRect().top + scrollTop;
2631
+ const containerBottom = containerTop + containerHeight;
2632
+ const elementHeight = element.offsetHeight;
2633
+ const elementTop = element.getBoundingClientRect().top + scrollTop;
2634
+ const elementBottom = elementTop + elementHeight;
2635
+ const newScrollTop = elementTop - containerTop + container.scrollTop;
2636
+ if (elementTop < containerTop) {
2637
+ container.scrollTop = newScrollTop;
2638
+ } else if (elementBottom > containerBottom) {
2639
+ const heightDifference = containerHeight - elementHeight;
2640
+ container.scrollTop = newScrollTop - heightDifference;
2641
+ }
2642
+ }
2643
+ //* Remove highlighting from other list items and highlight the given item.
2644
+ highlightListItem(listItem, shouldFocus) {
2645
+ const prevItem = this.highlightedItem;
2646
+ if (prevItem) {
2647
+ prevItem.classList.remove(CLASSES.HIGHLIGHT);
2648
+ prevItem.setAttribute(ARIA.SELECTED, "false");
2649
+ }
2650
+ this.highlightedItem = listItem;
2651
+ if (this.highlightedItem) {
2652
+ this.highlightedItem.classList.add(CLASSES.HIGHLIGHT);
2653
+ this.highlightedItem.setAttribute(ARIA.SELECTED, "true");
2654
+ if (this.options.countrySearch) {
2655
+ const activeDescendant = this.highlightedItem.getAttribute("id") || "";
2656
+ this.searchInput.setAttribute(ARIA.ACTIVE_DESCENDANT, activeDescendant);
2657
+ }
2658
+ }
2659
+ if (shouldFocus) {
2660
+ this.highlightedItem.focus();
2661
+ }
2662
+ }
2663
+ //* Country search: Filter the country list to the given array of countries.
2664
+ filterCountries(matchedCountries) {
2665
+ this.countryList.innerHTML = "";
2666
+ let noCountriesAddedYet = true;
2667
+ for (const c of matchedCountries) {
2668
+ const listItem = c.nodeById[this.id];
2669
+ if (listItem) {
2670
+ this.countryList.appendChild(listItem);
2671
+ if (noCountriesAddedYet) {
2672
+ this.highlightListItem(listItem, false);
2673
+ noCountriesAddedYet = false;
2674
+ }
2675
+ }
2676
+ }
2677
+ if (noCountriesAddedYet) {
2678
+ this.highlightListItem(null, false);
2679
+ if (this.searchNoResults) {
2680
+ this.searchNoResults.classList.remove(CLASSES.HIDE);
2681
+ }
2682
+ } else if (this.searchNoResults) {
2683
+ this.searchNoResults.classList.add(CLASSES.HIDE);
2684
+ }
2685
+ this.countryList.scrollTop = 0;
2686
+ this.updateSearchResultsA11yText();
2687
+ }
2688
+ destroy() {
2689
+ this.telInput.iti = void 0;
2690
+ delete this.telInput.dataset.intlTelInputId;
2691
+ if (this.options.separateDialCode) {
2692
+ this.telInput.style.paddingLeft = this.originalPaddingLeft;
2693
+ }
2694
+ const wrapper = this.telInput.parentNode;
2695
+ wrapper.before(this.telInput);
2696
+ wrapper.remove();
2697
+ this.telInput = null;
2698
+ this.countryContainer = null;
2699
+ this.selectedCountry = null;
2700
+ this.selectedCountryInner = null;
2701
+ this.selectedDialCode = null;
2702
+ this.dropdownArrow = null;
2703
+ this.dropdownContent = null;
2704
+ this.searchInput = null;
2705
+ this.searchIcon = null;
2706
+ this.searchClearButton = null;
2707
+ this.searchNoResults = null;
2708
+ this.searchResultsA11yText = null;
2709
+ this.countryList = null;
2710
+ this.dropdown = null;
2711
+ this.hiddenInput = null;
2712
+ this.hiddenInputCountry = null;
2713
+ this.highlightedItem = null;
2714
+ for (const c of this.countries) {
2715
+ delete c.nodeById[this.id];
2716
+ }
2717
+ this.countries = null;
2718
+ }
2719
+ };
2720
+
2721
+ // src/js/modules/data/country-data.ts
2722
+ var processAllCountries = (options) => {
2723
+ const { onlyCountries, excludeCountries } = options;
2724
+ if (onlyCountries.length) {
2725
+ const lowerCaseOnlyCountries = onlyCountries.map(
2726
+ (country) => country.toLowerCase()
2727
+ );
2728
+ return data_default.filter(
2729
+ (country) => lowerCaseOnlyCountries.includes(country.iso2)
2730
+ );
2731
+ } else if (excludeCountries.length) {
2732
+ const lowerCaseExcludeCountries = excludeCountries.map(
2733
+ (country) => country.toLowerCase()
2734
+ );
2735
+ return data_default.filter(
2736
+ (country) => !lowerCaseExcludeCountries.includes(country.iso2)
2737
+ );
2738
+ }
2739
+ return data_default;
2740
+ };
2741
+ var translateCountryNames = (countries, options) => {
2742
+ for (const c of countries) {
2743
+ const iso2 = c.iso2.toLowerCase();
2744
+ if (options.i18n[iso2]) {
2745
+ c.name = options.i18n[iso2];
2746
+ }
2747
+ }
2748
+ };
2749
+ var processDialCodes = (countries, options) => {
2750
+ const dialCodes = /* @__PURE__ */ new Set();
2751
+ let dialCodeMaxLen = 0;
2752
+ const dialCodeToIso2Map = {};
2753
+ const _addToDialCodeMap = (iso2, dialCode, priority) => {
2754
+ if (!iso2 || !dialCode) {
2755
+ return;
2756
+ }
2757
+ if (dialCode.length > dialCodeMaxLen) {
2758
+ dialCodeMaxLen = dialCode.length;
2759
+ }
2760
+ if (!dialCodeToIso2Map.hasOwnProperty(dialCode)) {
2761
+ dialCodeToIso2Map[dialCode] = [];
2762
+ }
2763
+ const iso2List = dialCodeToIso2Map[dialCode];
2764
+ if (iso2List.includes(iso2)) {
2765
+ return;
2766
+ }
2767
+ const index = priority !== void 0 ? priority : iso2List.length;
2768
+ iso2List[index] = iso2;
2769
+ };
2770
+ for (const c of countries) {
2771
+ if (!dialCodes.has(c.dialCode)) {
2772
+ dialCodes.add(c.dialCode);
2773
+ }
2774
+ for (let k = 1; k < c.dialCode.length; k++) {
2775
+ const partialDialCode = c.dialCode.substring(0, k);
2776
+ _addToDialCodeMap(c.iso2, partialDialCode);
2777
+ }
2778
+ _addToDialCodeMap(c.iso2, c.dialCode, c.priority);
2779
+ }
2780
+ if (options.onlyCountries.length || options.excludeCountries.length) {
2781
+ dialCodes.forEach((dialCode) => {
2782
+ dialCodeToIso2Map[dialCode] = dialCodeToIso2Map[dialCode].filter(Boolean);
2783
+ });
2784
+ }
2785
+ for (const c of countries) {
2786
+ if (c.areaCodes) {
2787
+ const rootIso2Code = dialCodeToIso2Map[c.dialCode][0];
2788
+ for (const areaCode of c.areaCodes) {
2789
+ for (let k = 1; k < areaCode.length; k++) {
2790
+ const partialAreaCode = areaCode.substring(0, k);
2791
+ const partialDialCode = c.dialCode + partialAreaCode;
2792
+ _addToDialCodeMap(rootIso2Code, partialDialCode);
2793
+ _addToDialCodeMap(c.iso2, partialDialCode);
2794
+ }
2795
+ _addToDialCodeMap(c.iso2, c.dialCode + areaCode);
2796
+ }
2797
+ }
2798
+ }
2799
+ return { dialCodes, dialCodeMaxLen, dialCodeToIso2Map };
2800
+ };
2801
+ var sortCountries = (countries, options) => {
2802
+ if (options.countryOrder) {
2803
+ options.countryOrder = options.countryOrder.map(
2804
+ (iso2) => iso2.toLowerCase()
2805
+ );
2806
+ }
2807
+ countries.sort((a, b) => {
2808
+ const { countryOrder } = options;
2809
+ if (countryOrder) {
2810
+ const aIndex = countryOrder.indexOf(a.iso2);
2811
+ const bIndex = countryOrder.indexOf(b.iso2);
2812
+ const aIndexExists = aIndex > -1;
2813
+ const bIndexExists = bIndex > -1;
2814
+ if (aIndexExists || bIndexExists) {
2815
+ if (aIndexExists && bIndexExists) {
2816
+ return aIndex - bIndex;
2817
+ }
2818
+ return aIndexExists ? -1 : 1;
2819
+ }
2820
+ }
2821
+ return a.name.localeCompare(b.name);
2822
+ });
2823
+ };
2824
+ var cacheSearchTokens = (countries) => {
2825
+ for (const c of countries) {
2826
+ c.normalisedName = normaliseString(c.name);
2827
+ c.initials = c.normalisedName.split(/[^a-z]/).map((word) => word[0]).join("");
2828
+ c.dialCodePlus = `+${c.dialCode}`;
2829
+ }
2830
+ };
2831
+
2832
+ // src/js/modules/format/formatting.ts
2833
+ var beforeSetNumber = (fullNumber, dialCode, separateDialCode, selectedCountryData) => {
2834
+ let number = fullNumber;
2835
+ if (separateDialCode) {
2836
+ if (dialCode) {
2837
+ dialCode = `+${selectedCountryData.dialCode}`;
2838
+ const start = number[dialCode.length] === " " || number[dialCode.length] === "-" ? dialCode.length + 1 : dialCode.length;
2839
+ number = number.substring(start);
2840
+ }
2841
+ }
2842
+ return number;
2843
+ };
2844
+ var formatNumberAsYouType = (fullNumber, telInputValue, utils2, selectedCountryData, separateDialCode) => {
2845
+ const result = utils2 ? utils2.formatNumberAsYouType(fullNumber, selectedCountryData.iso2) : fullNumber;
2846
+ const { dialCode } = selectedCountryData;
2847
+ if (separateDialCode && telInputValue.charAt(0) !== "+" && result.includes(`+${dialCode}`)) {
2848
+ const afterDialCode = result.split(`+${dialCode}`)[1] || "";
2849
+ return afterDialCode.trim();
2850
+ }
2851
+ return result;
2852
+ };
2853
+
2854
+ // src/js/modules/format/caret.ts
2855
+ var translateCursorPosition = (relevantChars, formattedValue, prevCaretPos, isDeleteForwards) => {
2856
+ if (prevCaretPos === 0 && !isDeleteForwards) {
2857
+ return 0;
2858
+ }
2859
+ let relevantCharCount = 0;
2860
+ for (let i = 0; i < formattedValue.length; i++) {
2861
+ if (/[+0-9]/.test(formattedValue[i])) {
2862
+ relevantCharCount++;
2863
+ }
2864
+ if (relevantCharCount === relevantChars && !isDeleteForwards) {
2865
+ return i + 1;
2866
+ }
2867
+ if (isDeleteForwards && relevantCharCount === relevantChars + 1) {
2868
+ return i;
2869
+ }
2870
+ }
2871
+ return formattedValue.length;
2872
+ };
2873
+
2874
+ // src/js/modules/data/nanp-regionless.ts
2875
+ var regionlessNanpNumbers = [
2876
+ "800",
2877
+ "822",
2878
+ "833",
2879
+ "844",
2880
+ "855",
2881
+ "866",
2882
+ "877",
2883
+ "880",
2884
+ "881",
2885
+ "882",
2886
+ "883",
2887
+ "884",
2888
+ "885",
2889
+ "886",
2890
+ "887",
2891
+ "888",
2892
+ "889"
2893
+ ];
2894
+ var isRegionlessNanp = (number) => {
2895
+ const numeric = getNumeric(number);
2896
+ if (numeric.startsWith(DIAL.NANP) && numeric.length >= 4) {
2897
+ const areaCode = numeric.substring(1, 4);
2898
+ return regionlessNanpNumbers.includes(areaCode);
2899
+ }
2900
+ return false;
2901
+ };
2902
+
2903
+ // src/js/intl-tel-input.ts
2904
+ for (const c of data_default) {
2905
+ c.name = en_default[c.iso2];
2906
+ }
2907
+ var id = 0;
2908
+ var iso2Set = new Set(data_default.map((c) => c.iso2));
2909
+ var isIso2 = (val) => iso2Set.has(val);
2910
+ var Iti = class _Iti {
2911
+ constructor(input, customOptions = {}) {
2912
+ this.id = id++;
2913
+ this.options = { ...defaults, ...customOptions };
2914
+ applyOptionSideEffects(this.options, en_default);
2915
+ this.ui = new UI(input, this.options, this.id);
2916
+ this.isAndroid = _Iti._getIsAndroid();
2917
+ this.promise = this._createInitPromises();
2918
+ this.countries = processAllCountries(this.options);
2919
+ const { dialCodes, dialCodeMaxLen, dialCodeToIso2Map } = processDialCodes(
2920
+ this.countries,
2921
+ this.options
2922
+ );
2923
+ this.dialCodes = dialCodes;
2924
+ this.dialCodeMaxLen = dialCodeMaxLen;
2925
+ this.dialCodeToIso2Map = dialCodeToIso2Map;
2926
+ this.countryByIso2 = new Map(this.countries.map((c) => [c.iso2, c]));
2927
+ this._init();
2570
2928
  }
2571
- _maybeUpdateInputPaddingAndReveal() {
2572
- if (this.countryContainer) {
2573
- this._updateInputPadding();
2574
- this.countryContainer.classList.remove("iti__v-hide");
2575
- }
2929
+ static _getIsAndroid() {
2930
+ return typeof navigator !== "undefined" ? /Android/i.test(navigator.userAgent) : false;
2576
2931
  }
2577
- _maybeBuildHiddenInputs(wrapper) {
2578
- const { hiddenInput } = this.options;
2579
- if (hiddenInput) {
2580
- const telInputName = this.telInput.getAttribute("name") || "";
2581
- const names = hiddenInput(telInputName);
2582
- if (names.phone) {
2583
- const existingInput = this.telInput.form?.querySelector(`input[name="${names.phone}"]`);
2584
- if (existingInput) {
2585
- this.hiddenInput = existingInput;
2586
- } else {
2587
- this.hiddenInput = createEl("input", {
2588
- type: "hidden",
2589
- name: names.phone
2590
- });
2591
- wrapper.appendChild(this.hiddenInput);
2592
- }
2593
- }
2594
- if (names.country) {
2595
- const existingInput = this.telInput.form?.querySelector(`input[name="${names.country}"]`);
2596
- if (existingInput) {
2597
- this.hiddenInputCountry = existingInput;
2598
- } else {
2599
- this.hiddenInputCountry = createEl("input", {
2600
- type: "hidden",
2601
- name: names.country
2602
- });
2603
- wrapper.appendChild(this.hiddenInputCountry);
2604
- }
2605
- }
2606
- }
2932
+ _createInitPromises() {
2933
+ const autoCountryPromise = new Promise((resolve, reject) => {
2934
+ this.resolveAutoCountryPromise = resolve;
2935
+ this.rejectAutoCountryPromise = reject;
2936
+ });
2937
+ const utilsScriptPromise = new Promise((resolve, reject) => {
2938
+ this.resolveUtilsScriptPromise = resolve;
2939
+ this.rejectUtilsScriptPromise = reject;
2940
+ });
2941
+ return Promise.all([autoCountryPromise, utilsScriptPromise]);
2607
2942
  }
2608
- //* For each country: add a country list item <li> to the countryList <ul> container.
2609
- _appendListItems() {
2610
- for (let i = 0; i < this.countries.length; i++) {
2611
- const c = this.countries[i];
2612
- const extraClass = i === 0 ? "iti__highlight" : "";
2613
- const listItem = createEl(
2614
- "li",
2615
- {
2616
- id: `iti-${this.id}__item-${c.iso2}`,
2617
- class: `iti__country ${extraClass}`,
2618
- tabindex: "-1",
2619
- role: "option",
2620
- "data-dial-code": c.dialCode,
2621
- "data-country-code": c.iso2,
2622
- "aria-selected": "false"
2623
- },
2624
- this.countryList
2625
- );
2626
- c.nodeById[this.id] = listItem;
2627
- let content = "";
2628
- if (this.options.showFlags) {
2629
- content += `<div class='iti__flag iti__${c.iso2}'></div>`;
2630
- }
2631
- content += `<span class='iti__country-name'>${c.name}</span>`;
2632
- content += `<span class='iti__dial-code' dir='ltr'>+${c.dialCode}</span>`;
2633
- listItem.insertAdjacentHTML("beforeend", content);
2634
- }
2943
+ //* Can't be private as it's called from intlTelInput convenience wrapper.
2944
+ _init() {
2945
+ this.selectedCountryData = {};
2946
+ this.abortController = new AbortController();
2947
+ this._processCountryData();
2948
+ this.ui.generateMarkup(this.countries);
2949
+ this._setInitialState();
2950
+ this._initListeners();
2951
+ this._initRequests();
2952
+ }
2953
+ //********************
2954
+ //* PRIVATE METHODS
2955
+ //********************
2956
+ //* Prepare all of the country data, including onlyCountries, excludeCountries, countryOrder options.
2957
+ _processCountryData() {
2958
+ translateCountryNames(this.countries, this.options);
2959
+ sortCountries(this.countries, this.options);
2960
+ cacheSearchTokens(this.countries);
2635
2961
  }
2636
2962
  //* Set the initial state of the input value and the selected country by:
2637
2963
  //* 1. Extracting a dial code from the given number
2638
2964
  //* 2. Using explicit initialCountry
2639
2965
  _setInitialState(overrideAutoCountry = false) {
2640
- const attributeValue = this.telInput.getAttribute("value");
2641
- const inputValue = this.telInput.value;
2642
- const useAttribute = attributeValue && attributeValue.charAt(0) === "+" && (!inputValue || inputValue.charAt(0) !== "+");
2966
+ const attributeValue = this.ui.telInput.getAttribute("value");
2967
+ const inputValue = this.ui.telInput.value;
2968
+ const useAttribute = attributeValue && attributeValue.startsWith("+") && (!inputValue || !inputValue.startsWith("+"));
2643
2969
  const val = useAttribute ? attributeValue : inputValue;
2644
2970
  const dialCode = this._getDialCode(val);
2645
2971
  const isRegionlessNanpNumber = isRegionlessNanp(val);
2646
2972
  const { initialCountry, geoIpLookup } = this.options;
2647
- const isAutoCountry = initialCountry === "auto" && geoIpLookup;
2973
+ const isAutoCountry = initialCountry === INITIAL_COUNTRY.AUTO && geoIpLookup;
2648
2974
  if (dialCode && !isRegionlessNanpNumber) {
2649
2975
  this._updateCountryFromNumber(val);
2650
2976
  } else if (!isAutoCountry || overrideAutoCountry) {
@@ -2653,7 +2979,7 @@ var factoryOutput = (() => {
2653
2979
  this._setCountry(lowerInitialCountry);
2654
2980
  } else {
2655
2981
  if (dialCode && isRegionlessNanpNumber) {
2656
- this._setCountry("us");
2982
+ this._setCountry(US.ISO2);
2657
2983
  } else {
2658
2984
  this._setCountry("");
2659
2985
  }
@@ -2669,81 +2995,94 @@ var factoryOutput = (() => {
2669
2995
  if (this.options.allowDropdown) {
2670
2996
  this._initDropdownListeners();
2671
2997
  }
2672
- if ((this.hiddenInput || this.hiddenInputCountry) && this.telInput.form) {
2998
+ if ((this.ui.hiddenInput || this.ui.hiddenInputCountry) && this.ui.telInput.form) {
2673
2999
  this._initHiddenInputListener();
2674
3000
  }
2675
3001
  }
2676
3002
  //* Update hidden input on form submit.
2677
3003
  _initHiddenInputListener() {
2678
- this._handleHiddenInputSubmit = () => {
2679
- if (this.hiddenInput) {
2680
- this.hiddenInput.value = this.getNumber();
3004
+ const handleHiddenInputSubmit = () => {
3005
+ if (this.ui.hiddenInput) {
3006
+ this.ui.hiddenInput.value = this.getNumber();
2681
3007
  }
2682
- if (this.hiddenInputCountry) {
2683
- this.hiddenInputCountry.value = this.getSelectedCountryData().iso2 || "";
3008
+ if (this.ui.hiddenInputCountry) {
3009
+ this.ui.hiddenInputCountry.value = this.selectedCountryData.iso2 || "";
2684
3010
  }
2685
3011
  };
2686
- this.telInput.form?.addEventListener(
2687
- "submit",
2688
- this._handleHiddenInputSubmit
2689
- );
3012
+ this.ui.telInput.form?.addEventListener("submit", handleHiddenInputSubmit, {
3013
+ signal: this.abortController.signal
3014
+ });
2690
3015
  }
2691
3016
  //* initialise the dropdown listeners.
2692
3017
  _initDropdownListeners() {
2693
- this._handleLabelClick = (e) => {
2694
- if (this.dropdownContent.classList.contains("iti__hide")) {
2695
- this.telInput.focus();
3018
+ const signal = this.abortController.signal;
3019
+ const handleLabelClick = (e) => {
3020
+ if (this.ui.dropdownContent.classList.contains(CLASSES.HIDE)) {
3021
+ this.ui.telInput.focus();
2696
3022
  } else {
2697
3023
  e.preventDefault();
2698
3024
  }
2699
3025
  };
2700
- const label = this.telInput.closest("label");
3026
+ const label = this.ui.telInput.closest("label");
2701
3027
  if (label) {
2702
- label.addEventListener("click", this._handleLabelClick);
3028
+ label.addEventListener("click", handleLabelClick, { signal });
2703
3029
  }
2704
- this._handleClickSelectedCountry = () => {
2705
- const dropdownClosed = this.dropdownContent.classList.contains("iti__hide");
2706
- if (dropdownClosed && !this.telInput.disabled && !this.telInput.readOnly) {
3030
+ const handleClickSelectedCountry = () => {
3031
+ const dropdownClosed = this.ui.dropdownContent.classList.contains(
3032
+ CLASSES.HIDE
3033
+ );
3034
+ if (dropdownClosed && !this.ui.telInput.disabled && !this.ui.telInput.readOnly) {
2707
3035
  this._openDropdown();
2708
3036
  }
2709
3037
  };
2710
- this.selectedCountry.addEventListener("click", this._handleClickSelectedCountry);
2711
- this._handleCountryContainerKeydown = (e) => {
2712
- const isDropdownHidden = this.dropdownContent.classList.contains("iti__hide");
2713
- if (isDropdownHidden && ["ArrowUp", "ArrowDown", " ", "Enter"].includes(e.key)) {
3038
+ this.ui.selectedCountry.addEventListener(
3039
+ "click",
3040
+ handleClickSelectedCountry,
3041
+ {
3042
+ signal
3043
+ }
3044
+ );
3045
+ const handleCountryContainerKeydown = (e) => {
3046
+ const isDropdownHidden = this.ui.dropdownContent.classList.contains(
3047
+ CLASSES.HIDE
3048
+ );
3049
+ if (isDropdownHidden && [KEYS.ARROW_UP, KEYS.ARROW_DOWN, KEYS.SPACE, KEYS.ENTER].includes(e.key)) {
2714
3050
  e.preventDefault();
2715
3051
  e.stopPropagation();
2716
3052
  this._openDropdown();
2717
3053
  }
2718
- if (e.key === "Tab") {
3054
+ if (e.key === KEYS.TAB) {
2719
3055
  this._closeDropdown();
2720
3056
  }
2721
3057
  };
2722
- this.countryContainer.addEventListener(
3058
+ this.ui.countryContainer.addEventListener(
2723
3059
  "keydown",
2724
- this._handleCountryContainerKeydown
3060
+ handleCountryContainerKeydown,
3061
+ { signal }
2725
3062
  );
2726
3063
  }
2727
3064
  //* Init many requests: utils script / geo ip lookup.
2728
3065
  _initRequests() {
2729
- let { loadUtils, initialCountry, geoIpLookup } = this.options;
3066
+ const { loadUtils, initialCountry, geoIpLookup } = this.options;
2730
3067
  if (loadUtils && !intlTelInput.utils) {
2731
- this._doAttachUtils = () => {
3068
+ const doAttachUtils = () => {
2732
3069
  intlTelInput.attachUtils(loadUtils)?.catch(() => {
2733
3070
  });
2734
3071
  };
2735
3072
  if (intlTelInput.documentReady()) {
2736
- this._doAttachUtils();
3073
+ doAttachUtils();
2737
3074
  } else {
2738
- this._handlePageLoad = () => {
2739
- this._doAttachUtils();
3075
+ const handlePageLoad = () => {
3076
+ doAttachUtils();
2740
3077
  };
2741
- window.addEventListener("load", this._handlePageLoad);
3078
+ window.addEventListener("load", handlePageLoad, {
3079
+ signal: this.abortController.signal
3080
+ });
2742
3081
  }
2743
3082
  } else {
2744
3083
  this.resolveUtilsScriptPromise();
2745
3084
  }
2746
- const isAutoCountry = initialCountry === "auto" && geoIpLookup;
3085
+ const isAutoCountry = initialCountry === INITIAL_COUNTRY.AUTO && geoIpLookup;
2747
3086
  if (isAutoCountry && !this.selectedCountryData.iso2) {
2748
3087
  this._loadAutoCountry();
2749
3088
  } else {
@@ -2778,8 +3117,8 @@ var factoryOutput = (() => {
2778
3117
  }
2779
3118
  _openDropdownWithPlus() {
2780
3119
  this._openDropdown();
2781
- this.searchInput.value = "+";
2782
- this._filterCountries("");
3120
+ this.ui.searchInput.value = "+";
3121
+ this._filterCountriesByQuery("");
2783
3122
  }
2784
3123
  //* Initialize the tel input listeners.
2785
3124
  _initTelInputListeners() {
@@ -2788,55 +3127,81 @@ var factoryOutput = (() => {
2788
3127
  this._maybeBindPasteListener();
2789
3128
  }
2790
3129
  _bindInputListener() {
2791
- const { strictMode, formatAsYouType, separateDialCode, allowDropdown, countrySearch } = this.options;
3130
+ const {
3131
+ strictMode,
3132
+ formatAsYouType,
3133
+ separateDialCode,
3134
+ allowDropdown,
3135
+ countrySearch
3136
+ } = this.options;
2792
3137
  let userOverrideFormatting = false;
2793
- if (/\p{L}/u.test(this.telInput.value)) {
3138
+ if (REGEX.ALPHA_UNICODE.test(this.ui.telInput.value)) {
2794
3139
  userOverrideFormatting = true;
2795
3140
  }
2796
- this._handleInputEvent = (e) => {
3141
+ const handleInputEvent = (e) => {
2797
3142
  if (this.isAndroid && e?.data === "+" && separateDialCode && allowDropdown && countrySearch) {
2798
- const currentCaretPos = this.telInput.selectionStart || 0;
2799
- const valueBeforeCaret = this.telInput.value.substring(0, currentCaretPos - 1);
2800
- const valueAfterCaret = this.telInput.value.substring(currentCaretPos);
2801
- this.telInput.value = valueBeforeCaret + valueAfterCaret;
3143
+ const currentCaretPos = this.ui.telInput.selectionStart || 0;
3144
+ const valueBeforeCaret = this.ui.telInput.value.substring(
3145
+ 0,
3146
+ currentCaretPos - 1
3147
+ );
3148
+ const valueAfterCaret = this.ui.telInput.value.substring(currentCaretPos);
3149
+ this.ui.telInput.value = valueBeforeCaret + valueAfterCaret;
2802
3150
  this._openDropdownWithPlus();
2803
3151
  return;
2804
3152
  }
2805
- if (this._updateCountryFromNumber(this.telInput.value)) {
3153
+ if (this._updateCountryFromNumber(this.ui.telInput.value)) {
2806
3154
  this._triggerCountryChange();
2807
3155
  }
2808
- const isFormattingChar = e?.data && /[^+0-9]/.test(e.data);
2809
- const isPaste = e?.inputType === "insertFromPaste" && this.telInput.value;
3156
+ const isFormattingChar = e?.data && REGEX.NON_PLUS_NUMERIC.test(e.data);
3157
+ const isPaste = e?.inputType === INPUT_TYPES.PASTE && this.ui.telInput.value;
2810
3158
  if (isFormattingChar || isPaste && !strictMode) {
2811
3159
  userOverrideFormatting = true;
2812
- } else if (!/[^+0-9]/.test(this.telInput.value)) {
3160
+ } else if (!REGEX.NON_PLUS_NUMERIC.test(this.ui.telInput.value)) {
2813
3161
  userOverrideFormatting = false;
2814
3162
  }
2815
3163
  const isSetNumber = e?.detail && e.detail["isSetNumber"];
2816
3164
  if (formatAsYouType && !userOverrideFormatting && !isSetNumber) {
2817
- const currentCaretPos = this.telInput.selectionStart || 0;
2818
- const valueBeforeCaret = this.telInput.value.substring(0, currentCaretPos);
2819
- const relevantCharsBeforeCaret = valueBeforeCaret.replace(/[^+0-9]/g, "").length;
2820
- const isDeleteForwards = e?.inputType === "deleteContentForward";
3165
+ const currentCaretPos = this.ui.telInput.selectionStart || 0;
3166
+ const valueBeforeCaret = this.ui.telInput.value.substring(
3167
+ 0,
3168
+ currentCaretPos
3169
+ );
3170
+ const relevantCharsBeforeCaret = valueBeforeCaret.replace(
3171
+ REGEX.NON_PLUS_NUMERIC_GLOBAL,
3172
+ ""
3173
+ ).length;
3174
+ const isDeleteForwards = e?.inputType === INPUT_TYPES.DELETE_FWD;
2821
3175
  const fullNumber = this._getFullNumber();
2822
3176
  const formattedValue = formatNumberAsYouType(
2823
3177
  fullNumber,
2824
- this.telInput.value,
3178
+ this.ui.telInput.value,
2825
3179
  intlTelInput.utils,
2826
3180
  this.selectedCountryData,
2827
3181
  this.options.separateDialCode
2828
3182
  );
2829
- const newCaretPos = translateCursorPosition(relevantCharsBeforeCaret, formattedValue, currentCaretPos, isDeleteForwards);
2830
- this.telInput.value = formattedValue;
2831
- this.telInput.setSelectionRange(newCaretPos, newCaretPos);
3183
+ const newCaretPos = translateCursorPosition(
3184
+ relevantCharsBeforeCaret,
3185
+ formattedValue,
3186
+ currentCaretPos,
3187
+ isDeleteForwards
3188
+ );
3189
+ this.ui.telInput.value = formattedValue;
3190
+ this.ui.telInput.setSelectionRange(newCaretPos, newCaretPos);
2832
3191
  }
2833
3192
  };
2834
- this.telInput.addEventListener("input", this._handleInputEvent);
3193
+ this.ui.telInput.addEventListener(
3194
+ "input",
3195
+ handleInputEvent,
3196
+ {
3197
+ signal: this.abortController.signal
3198
+ }
3199
+ );
2835
3200
  }
2836
3201
  _maybeBindKeydownListener() {
2837
3202
  const { strictMode, separateDialCode, allowDropdown, countrySearch } = this.options;
2838
3203
  if (strictMode || separateDialCode) {
2839
- this._handleKeydownEvent = (e) => {
3204
+ const handleKeydownEvent = (e) => {
2840
3205
  if (e.key && e.key.length === 1 && !e.altKey && !e.ctrlKey && !e.metaKey) {
2841
3206
  if (separateDialCode && allowDropdown && countrySearch && e.key === "+") {
2842
3207
  e.preventDefault();
@@ -2844,14 +3209,17 @@ var factoryOutput = (() => {
2844
3209
  return;
2845
3210
  }
2846
3211
  if (strictMode) {
2847
- const value = this.telInput.value;
2848
- const alreadyHasPlus = value.charAt(0) === "+";
2849
- const isInitialPlus = !alreadyHasPlus && this.telInput.selectionStart === 0 && e.key === "+";
3212
+ const value = this.ui.telInput.value;
3213
+ const alreadyHasPlus = value.startsWith("+");
3214
+ const isInitialPlus = !alreadyHasPlus && this.ui.telInput.selectionStart === 0 && e.key === "+";
2850
3215
  const isNumeric = /^[0-9]$/.test(e.key);
2851
3216
  const isAllowedChar = separateDialCode ? isNumeric : isInitialPlus || isNumeric;
2852
- const newValue = value.slice(0, this.telInput.selectionStart) + e.key + value.slice(this.telInput.selectionEnd);
3217
+ const newValue = value.slice(0, this.ui.telInput.selectionStart) + e.key + value.slice(this.ui.telInput.selectionEnd);
2853
3218
  const newFullNumber = this._getFullNumber(newValue);
2854
- const coreNumber = intlTelInput.utils.getCoreNumber(newFullNumber, this.selectedCountryData.iso2);
3219
+ const coreNumber = intlTelInput.utils.getCoreNumber(
3220
+ newFullNumber,
3221
+ this.selectedCountryData.iso2
3222
+ );
2855
3223
  const hasExceededMaxLength = this.maxCoreNumberLength && coreNumber.length > this.maxCoreNumberLength;
2856
3224
  const newCountry = this._getNewCountryFromNumber(newFullNumber);
2857
3225
  const isChangingDialCode = newCountry !== null;
@@ -2861,14 +3229,16 @@ var factoryOutput = (() => {
2861
3229
  }
2862
3230
  }
2863
3231
  };
2864
- this.telInput.addEventListener("keydown", this._handleKeydownEvent);
3232
+ this.ui.telInput.addEventListener("keydown", handleKeydownEvent, {
3233
+ signal: this.abortController.signal
3234
+ });
2865
3235
  }
2866
3236
  }
2867
3237
  _maybeBindPasteListener() {
2868
3238
  if (this.options.strictMode) {
2869
- this._handlePasteEvent = (e) => {
3239
+ const handlePasteEvent = (e) => {
2870
3240
  e.preventDefault();
2871
- const input = this.telInput;
3241
+ const input = this.ui.telInput;
2872
3242
  const selStart = input.selectionStart;
2873
3243
  const selEnd = input.selectionEnd;
2874
3244
  const before = input.value.slice(0, selStart);
@@ -2877,7 +3247,7 @@ var factoryOutput = (() => {
2877
3247
  const pasted = e.clipboardData.getData("text");
2878
3248
  const initialCharSelected = selStart === 0 && selEnd > 0;
2879
3249
  const allowLeadingPlus = !input.value.startsWith("+") || initialCharSelected;
2880
- const allowedChars = pasted.replace(/[^0-9+]/g, "");
3250
+ const allowedChars = pasted.replace(REGEX.NON_PLUS_NUMERIC_GLOBAL, "");
2881
3251
  const hasLeadingPlus = allowedChars.startsWith("+");
2882
3252
  const numerics = allowedChars.replace(/\+/g, "");
2883
3253
  const sanitised = hasLeadingPlus && allowLeadingPlus ? `+${numerics}` : numerics;
@@ -2903,82 +3273,117 @@ var factoryOutput = (() => {
2903
3273
  input.setSelectionRange(caretPos, caretPos);
2904
3274
  input.dispatchEvent(new InputEvent("input", { bubbles: true }));
2905
3275
  };
2906
- this.telInput.addEventListener("paste", this._handlePasteEvent);
3276
+ this.ui.telInput.addEventListener("paste", handlePasteEvent, {
3277
+ signal: this.abortController.signal
3278
+ });
2907
3279
  }
2908
3280
  }
2909
3281
  //* Adhere to the input's maxlength attr.
2910
3282
  _cap(number) {
2911
- const max = parseInt(this.telInput.getAttribute("maxlength") || "", 10);
3283
+ const max = Number(this.ui.telInput.getAttribute("maxlength"));
2912
3284
  return max && number.length > max ? number.substring(0, max) : number;
2913
3285
  }
2914
- //* Trigger a custom event on the input.
3286
+ //* Trigger a custom event on the input (typed via ItiEventMap).
2915
3287
  _trigger(name, detailProps = {}) {
2916
3288
  const e = new CustomEvent(name, {
2917
3289
  bubbles: true,
2918
3290
  cancelable: true,
2919
3291
  detail: detailProps
2920
3292
  });
2921
- this.telInput.dispatchEvent(e);
3293
+ this.ui.telInput.dispatchEvent(e);
2922
3294
  }
2923
3295
  //* Open the dropdown.
2924
3296
  _openDropdown() {
2925
3297
  const { fixDropdownWidth, countrySearch } = this.options;
3298
+ this.dropdownAbortController = new AbortController();
2926
3299
  if (fixDropdownWidth) {
2927
- this.dropdownContent.style.width = `${this.telInput.offsetWidth}px`;
3300
+ this.ui.dropdownContent.style.width = `${this.ui.telInput.offsetWidth}px`;
2928
3301
  }
2929
- this.dropdownContent.classList.remove("iti__hide");
2930
- this.selectedCountry.setAttribute("aria-expanded", "true");
3302
+ this.ui.dropdownContent.classList.remove(CLASSES.HIDE);
3303
+ this.ui.selectedCountry.setAttribute(ARIA.EXPANDED, "true");
2931
3304
  this._setDropdownPosition();
2932
3305
  if (countrySearch) {
2933
- const firstCountryItem = this.countryList.firstElementChild;
3306
+ const firstCountryItem = this.ui.countryList.firstElementChild;
2934
3307
  if (firstCountryItem) {
2935
- this._highlightListItem(firstCountryItem, false);
2936
- this.countryList.scrollTop = 0;
3308
+ this.ui.highlightListItem(firstCountryItem, false);
3309
+ this.ui.countryList.scrollTop = 0;
2937
3310
  }
2938
- this.searchInput.focus();
3311
+ this.ui.searchInput.focus();
2939
3312
  }
2940
3313
  this._bindDropdownListeners();
2941
- this.dropdownArrow.classList.add("iti__arrow--up");
2942
- this._trigger("open:countrydropdown");
3314
+ this.ui.dropdownArrow.classList.add(CLASSES.ARROW_UP);
3315
+ this._trigger(EVENTS.OPEN_COUNTRY_DROPDOWN);
2943
3316
  }
2944
3317
  //* Set the dropdown position
2945
3318
  _setDropdownPosition() {
2946
3319
  if (this.options.dropdownContainer) {
2947
- this.options.dropdownContainer.appendChild(this.dropdown);
3320
+ this.options.dropdownContainer.appendChild(this.ui.dropdown);
2948
3321
  }
2949
3322
  if (!this.options.useFullscreenPopup) {
2950
- const inputPosRelativeToVP = this.telInput.getBoundingClientRect();
2951
- const inputHeight = this.telInput.offsetHeight;
3323
+ const inputPosRelativeToVP = this.ui.telInput.getBoundingClientRect();
3324
+ const inputHeight = this.ui.telInput.offsetHeight;
2952
3325
  if (this.options.dropdownContainer) {
2953
- this.dropdown.style.top = `${inputPosRelativeToVP.top + inputHeight}px`;
2954
- this.dropdown.style.left = `${inputPosRelativeToVP.left}px`;
2955
- this._handleWindowScroll = () => this._closeDropdown();
2956
- window.addEventListener("scroll", this._handleWindowScroll);
3326
+ this.ui.dropdown.style.top = `${inputPosRelativeToVP.top + inputHeight}px`;
3327
+ this.ui.dropdown.style.left = `${inputPosRelativeToVP.left}px`;
3328
+ const handleWindowScroll = () => this._closeDropdown();
3329
+ window.addEventListener("scroll", handleWindowScroll, {
3330
+ signal: this.dropdownAbortController.signal
3331
+ });
2957
3332
  }
2958
3333
  }
2959
3334
  }
2960
3335
  //* We only bind dropdown listeners when the dropdown is open.
2961
3336
  _bindDropdownListeners() {
2962
- this._handleMouseoverCountryList = (e) => {
2963
- const listItem = e.target?.closest(".iti__country");
3337
+ const signal = this.dropdownAbortController.signal;
3338
+ this._bindDropdownMouseoverListener(signal);
3339
+ this._bindDropdownCountryClickListener(signal);
3340
+ this._bindDropdownClickOffListener(signal);
3341
+ this._bindDropdownKeydownListener(signal);
3342
+ if (this.options.countrySearch) {
3343
+ this._bindDropdownSearchListeners(signal);
3344
+ }
3345
+ }
3346
+ //* When mouse over a list item, just highlight that one
3347
+ //* we add the class "highlight", so if they hit "enter" we know which one to select.
3348
+ _bindDropdownMouseoverListener(signal) {
3349
+ const handleMouseoverCountryList = (e) => {
3350
+ const listItem = e.target?.closest(
3351
+ `.${CLASSES.COUNTRY_ITEM}`
3352
+ );
2964
3353
  if (listItem) {
2965
- this._highlightListItem(listItem, false);
3354
+ this.ui.highlightListItem(listItem, false);
2966
3355
  }
2967
3356
  };
2968
- this.countryList.addEventListener(
3357
+ this.ui.countryList.addEventListener(
2969
3358
  "mouseover",
2970
- this._handleMouseoverCountryList
3359
+ handleMouseoverCountryList,
3360
+ {
3361
+ signal
3362
+ }
2971
3363
  );
2972
- this._handleClickCountryList = (e) => {
2973
- const listItem = e.target?.closest(".iti__country");
3364
+ }
3365
+ //* Listen for country selection.
3366
+ _bindDropdownCountryClickListener(signal) {
3367
+ const handleClickCountryList = (e) => {
3368
+ const listItem = e.target?.closest(
3369
+ `.${CLASSES.COUNTRY_ITEM}`
3370
+ );
2974
3371
  if (listItem) {
2975
3372
  this._selectListItem(listItem);
2976
3373
  }
2977
3374
  };
2978
- this.countryList.addEventListener("click", this._handleClickCountryList);
2979
- this._handleClickOffToClose = (e) => {
3375
+ this.ui.countryList.addEventListener("click", handleClickCountryList, {
3376
+ signal
3377
+ });
3378
+ }
3379
+ //* Click off to close (except when this initial opening click is bubbling up).
3380
+ //* We cannot just stopPropagation as it may be needed to close another instance.
3381
+ _bindDropdownClickOffListener(signal) {
3382
+ const handleClickOffToClose = (e) => {
2980
3383
  const target = e.target;
2981
- const clickedInsideDropdown = !!target.closest(`#iti-${this.id}__dropdown-content`);
3384
+ const clickedInsideDropdown = !!target.closest(
3385
+ `#iti-${this.id}__dropdown-content`
3386
+ );
2982
3387
  if (!clickedInsideDropdown) {
2983
3388
  this._closeDropdown();
2984
3389
  }
@@ -2986,24 +3391,37 @@ var factoryOutput = (() => {
2986
3391
  setTimeout(() => {
2987
3392
  document.documentElement.addEventListener(
2988
3393
  "click",
2989
- this._handleClickOffToClose
3394
+ handleClickOffToClose,
3395
+ { signal }
2990
3396
  );
2991
3397
  }, 0);
3398
+ }
3399
+ //* Listen for up/down scrolling, enter to select, or escape to close.
3400
+ //* Use keydown as keypress doesn't fire for non-char keys and we want to catch if they
3401
+ //* just hit down and hold it to scroll down (no keyup event).
3402
+ //* Listen on the document because that's where key events are triggered if no input has focus.
3403
+ _bindDropdownKeydownListener(signal) {
2992
3404
  let query = "";
2993
3405
  let queryTimer = null;
2994
- this._handleKeydownOnDropdown = (e) => {
2995
- if (["ArrowUp", "ArrowDown", "Enter", "Escape"].includes(e.key)) {
3406
+ const handleKeydownOnDropdown = (e) => {
3407
+ const allowedKeys = [
3408
+ KEYS.ARROW_UP,
3409
+ KEYS.ARROW_DOWN,
3410
+ KEYS.ENTER,
3411
+ KEYS.ESC
3412
+ ];
3413
+ if (allowedKeys.includes(e.key)) {
2996
3414
  e.preventDefault();
2997
3415
  e.stopPropagation();
2998
- if (e.key === "ArrowUp" || e.key === "ArrowDown") {
3416
+ if (e.key === KEYS.ARROW_UP || e.key === KEYS.ARROW_DOWN) {
2999
3417
  this._handleUpDownKey(e.key);
3000
- } else if (e.key === "Enter") {
3418
+ } else if (e.key === KEYS.ENTER) {
3001
3419
  this._handleEnterKey();
3002
- } else if (e.key === "Escape") {
3420
+ } else if (e.key === KEYS.ESC) {
3003
3421
  this._closeDropdown();
3004
3422
  }
3005
3423
  }
3006
- if (!this.options.countrySearch && /^[a-zA-ZÀ-ÿа-яА-Я ]$/.test(e.key)) {
3424
+ if (!this.options.countrySearch && REGEX.HIDDEN_SEARCH_CHAR.test(e.key)) {
3007
3425
  e.stopPropagation();
3008
3426
  if (queryTimer) {
3009
3427
  clearTimeout(queryTimer);
@@ -3012,147 +3430,78 @@ var factoryOutput = (() => {
3012
3430
  this._searchForCountry(query);
3013
3431
  queryTimer = setTimeout(() => {
3014
3432
  query = "";
3015
- }, 1e3);
3433
+ }, TIMINGS.HIDDEN_SEARCH_RESET_MS);
3016
3434
  }
3017
3435
  };
3018
- document.addEventListener("keydown", this._handleKeydownOnDropdown);
3019
- if (this.options.countrySearch) {
3020
- const doFilter = () => {
3021
- const inputQuery = this.searchInput.value.trim();
3022
- this._filterCountries(inputQuery);
3023
- if (this.searchInput.value) {
3024
- this.searchClearButton.classList.remove("iti__hide");
3025
- } else {
3026
- this.searchClearButton.classList.add("iti__hide");
3027
- }
3028
- };
3029
- let keyupTimer = null;
3030
- this._handleSearchChange = () => {
3031
- if (keyupTimer) {
3032
- clearTimeout(keyupTimer);
3033
- }
3034
- keyupTimer = setTimeout(() => {
3035
- doFilter();
3036
- keyupTimer = null;
3037
- }, 100);
3038
- };
3039
- this.searchInput.addEventListener("input", this._handleSearchChange);
3040
- this._handleSearchClear = () => {
3041
- this.searchInput.value = "";
3042
- this.searchInput.focus();
3436
+ document.addEventListener("keydown", handleKeydownOnDropdown, { signal });
3437
+ }
3438
+ //* Search input listeners when countrySearch enabled.
3439
+ _bindDropdownSearchListeners(signal) {
3440
+ const doFilter = () => {
3441
+ const inputQuery = this.ui.searchInput.value.trim();
3442
+ this._filterCountriesByQuery(inputQuery);
3443
+ if (this.ui.searchInput.value) {
3444
+ this.ui.searchClearButton.classList.remove(CLASSES.HIDE);
3445
+ } else {
3446
+ this.ui.searchClearButton.classList.add(CLASSES.HIDE);
3447
+ }
3448
+ };
3449
+ let keyupTimer = null;
3450
+ const handleSearchChange = () => {
3451
+ if (keyupTimer) {
3452
+ clearTimeout(keyupTimer);
3453
+ }
3454
+ keyupTimer = setTimeout(() => {
3043
3455
  doFilter();
3044
- };
3045
- this.searchClearButton.addEventListener("click", this._handleSearchClear);
3046
- }
3456
+ keyupTimer = null;
3457
+ }, 100);
3458
+ };
3459
+ this.ui.searchInput.addEventListener("input", handleSearchChange, {
3460
+ signal
3461
+ });
3462
+ const handleSearchClear = () => {
3463
+ this.ui.searchInput.value = "";
3464
+ this.ui.searchInput.focus();
3465
+ doFilter();
3466
+ };
3467
+ this.ui.searchClearButton.addEventListener("click", handleSearchClear, {
3468
+ signal
3469
+ });
3047
3470
  }
3048
3471
  //* Hidden search (countrySearch disabled): Find the first list item whose name starts with the query string.
3049
3472
  _searchForCountry(query) {
3050
- for (const c of this.countries) {
3051
- const startsWith = c.name.substring(0, query.length).toLowerCase() === query;
3052
- if (startsWith) {
3053
- const listItem = c.nodeById[this.id];
3054
- this._highlightListItem(listItem, false);
3055
- this._scrollTo(listItem);
3056
- break;
3057
- }
3473
+ const match = findFirstCountryStartingWith(this.countries, query);
3474
+ if (match) {
3475
+ const listItem = match.nodeById[this.id];
3476
+ this.ui.highlightListItem(listItem, false);
3477
+ this.ui.scrollTo(listItem);
3058
3478
  }
3059
3479
  }
3060
- //* Country search enabled: Filter the countries according to the search query.
3061
- _filterCountries(query) {
3062
- this.countryList.innerHTML = "";
3480
+ //* Country search: Filter the countries according to the search query.
3481
+ _filterCountriesByQuery(query) {
3063
3482
  let matchedCountries;
3064
3483
  if (query === "") {
3065
3484
  matchedCountries = this.countries;
3066
3485
  } else {
3067
- matchedCountries = this._getMatchedCountries(query);
3068
- }
3069
- let noCountriesAddedYet = true;
3070
- for (const c of matchedCountries) {
3071
- const listItem = c.nodeById[this.id];
3072
- if (listItem) {
3073
- this.countryList.appendChild(listItem);
3074
- if (noCountriesAddedYet) {
3075
- this._highlightListItem(listItem, false);
3076
- noCountriesAddedYet = false;
3077
- }
3078
- }
3079
- }
3080
- if (noCountriesAddedYet) {
3081
- this._highlightListItem(null, false);
3082
- if (this.searchNoResults) {
3083
- this.searchNoResults.classList.remove("iti__hide");
3084
- }
3085
- } else if (this.searchNoResults) {
3086
- this.searchNoResults.classList.add("iti__hide");
3087
- }
3088
- this.countryList.scrollTop = 0;
3089
- this._updateSearchResultsA11yText();
3090
- }
3091
- _getMatchedCountries(query) {
3092
- const normalisedQuery = normaliseString(query);
3093
- const iso2Matches = [];
3094
- const nameStartWith = [];
3095
- const nameContains = [];
3096
- const dialCodeMatches = [];
3097
- const dialCodeContains = [];
3098
- const initialsMatches = [];
3099
- for (const c of this.countries) {
3100
- if (c.iso2 === normalisedQuery) {
3101
- iso2Matches.push(c);
3102
- } else if (c.normalisedName.startsWith(normalisedQuery)) {
3103
- nameStartWith.push(c);
3104
- } else if (c.normalisedName.includes(normalisedQuery)) {
3105
- nameContains.push(c);
3106
- } else if (normalisedQuery === c.dialCode || normalisedQuery === c.dialCodePlus) {
3107
- dialCodeMatches.push(c);
3108
- } else if (c.dialCodePlus.includes(normalisedQuery)) {
3109
- dialCodeContains.push(c);
3110
- } else if (c.initials.includes(normalisedQuery)) {
3111
- initialsMatches.push(c);
3112
- }
3113
- }
3114
- return [
3115
- ...iso2Matches.sort((a, b) => a.priority - b.priority),
3116
- ...nameStartWith.sort((a, b) => a.priority - b.priority),
3117
- ...nameContains.sort((a, b) => a.priority - b.priority),
3118
- ...dialCodeMatches.sort((a, b) => a.priority - b.priority),
3119
- ...dialCodeContains.sort((a, b) => a.priority - b.priority),
3120
- ...initialsMatches.sort((a, b) => a.priority - b.priority)
3121
- ];
3122
- }
3123
- //* Update search results text (for a11y).
3124
- _updateSearchResultsA11yText() {
3125
- const { i18n } = this.options;
3126
- const count = this.countryList.childElementCount;
3127
- let searchText;
3128
- if (count === 0) {
3129
- searchText = i18n.zeroSearchResults;
3130
- } else {
3131
- if (i18n.searchResultsText) {
3132
- searchText = i18n.searchResultsText(count);
3133
- } else if (count === 1) {
3134
- searchText = i18n.oneSearchResult;
3135
- } else {
3136
- searchText = i18n.multipleSearchResults.replace("${count}", count.toString());
3137
- }
3486
+ matchedCountries = getMatchedCountries(this.countries, query);
3138
3487
  }
3139
- this.searchResultsA11yText.textContent = searchText;
3488
+ this.ui.filterCountries(matchedCountries);
3140
3489
  }
3141
3490
  //* Highlight the next/prev item in the list (and ensure it is visible).
3142
3491
  _handleUpDownKey(key) {
3143
- let next = key === "ArrowUp" ? this.highlightedItem?.previousElementSibling : this.highlightedItem?.nextElementSibling;
3144
- if (!next && this.countryList.childElementCount > 1) {
3145
- next = key === "ArrowUp" ? this.countryList.lastElementChild : this.countryList.firstElementChild;
3492
+ let next = key === KEYS.ARROW_UP ? this.ui.highlightedItem?.previousElementSibling : this.ui.highlightedItem?.nextElementSibling;
3493
+ if (!next && this.ui.countryList.childElementCount > 1) {
3494
+ next = key === KEYS.ARROW_UP ? this.ui.countryList.lastElementChild : this.ui.countryList.firstElementChild;
3146
3495
  }
3147
3496
  if (next) {
3148
- this._scrollTo(next);
3149
- this._highlightListItem(next, false);
3497
+ this.ui.scrollTo(next);
3498
+ this.ui.highlightListItem(next, false);
3150
3499
  }
3151
3500
  }
3152
3501
  //* Select the currently highlighted item.
3153
3502
  _handleEnterKey() {
3154
- if (this.highlightedItem) {
3155
- this._selectListItem(this.highlightedItem);
3503
+ if (this.ui.highlightedItem) {
3504
+ this._selectListItem(this.ui.highlightedItem);
3156
3505
  }
3157
3506
  }
3158
3507
  //* Update the input's value to the given val (format first if possible)
@@ -3160,7 +3509,7 @@ var factoryOutput = (() => {
3160
3509
  _updateValFromNumber(fullNumber) {
3161
3510
  let number = fullNumber;
3162
3511
  if (this.options.formatOnDisplay && intlTelInput.utils && this.selectedCountryData) {
3163
- const useNational = this.options.nationalMode || number.charAt(0) !== "+" && !this.options.separateDialCode;
3512
+ const useNational = this.options.nationalMode || !number.startsWith("+") && !this.options.separateDialCode;
3164
3513
  const { NATIONAL, INTERNATIONAL } = intlTelInput.utils.numberFormat;
3165
3514
  const format = useNational ? NATIONAL : INTERNATIONAL;
3166
3515
  number = intlTelInput.utils.formatNumber(
@@ -3170,7 +3519,7 @@ var factoryOutput = (() => {
3170
3519
  );
3171
3520
  }
3172
3521
  number = this._beforeSetNumber(number);
3173
- this.telInput.value = number;
3522
+ this.ui.telInput.value = number;
3174
3523
  }
3175
3524
  //* Check if need to select a new country based on the given number
3176
3525
  //* Note: called from _setInitialState, keyup handler, setNumber.
@@ -3184,11 +3533,11 @@ var factoryOutput = (() => {
3184
3533
  // if there is a selected country, and the number doesn't start with a dial code, then add it
3185
3534
  _ensureHasDialCode(number) {
3186
3535
  const { dialCode, nationalPrefix } = this.selectedCountryData;
3187
- const alreadyHasPlus = number.charAt(0) === "+";
3536
+ const alreadyHasPlus = number.startsWith("+");
3188
3537
  if (alreadyHasPlus || !dialCode) {
3189
3538
  return number;
3190
3539
  }
3191
- const hasPrefix = nationalPrefix && number.charAt(0) === nationalPrefix && !this.options.separateDialCode;
3540
+ const hasPrefix = nationalPrefix && number.startsWith(nationalPrefix) && !this.options.separateDialCode;
3192
3541
  const cleanNumber = hasPrefix ? number.substring(1) : number;
3193
3542
  return `+${dialCode}${cleanNumber}`;
3194
3543
  }
@@ -3215,13 +3564,15 @@ var factoryOutput = (() => {
3215
3564
  if (!selectedIso2 && this.defaultCountry && iso2Codes.includes(this.defaultCountry)) {
3216
3565
  return this.defaultCountry;
3217
3566
  }
3218
- const isRegionlessNanpNumber = selectedDialCode === "1" && isRegionlessNanp(numeric);
3567
+ const isRegionlessNanpNumber = selectedDialCode === DIAL.NANP && isRegionlessNanp(numeric);
3219
3568
  if (isRegionlessNanpNumber) {
3220
3569
  return null;
3221
3570
  }
3222
3571
  const { areaCodes, priority } = this.selectedCountryData;
3223
3572
  if (areaCodes) {
3224
- const dialCodeAreaCodes = areaCodes.map((areaCode) => `${selectedDialCode}${areaCode}`);
3573
+ const dialCodeAreaCodes = areaCodes.map(
3574
+ (areaCode) => `${selectedDialCode}${areaCode}`
3575
+ );
3225
3576
  for (const dialCodeAreaCode of dialCodeAreaCodes) {
3226
3577
  if (numeric.startsWith(dialCodeAreaCode)) {
3227
3578
  return null;
@@ -3235,33 +3586,13 @@ var factoryOutput = (() => {
3235
3586
  if (!isValidSelection && !alreadySelected) {
3236
3587
  return iso2Codes[0];
3237
3588
  }
3238
- } else if (number.charAt(0) === "+" && numeric.length) {
3589
+ } else if (number.startsWith("+") && numeric.length) {
3239
3590
  return "";
3240
3591
  } else if ((!number || number === "+") && !selectedIso2) {
3241
3592
  return this.defaultCountry;
3242
3593
  }
3243
3594
  return null;
3244
3595
  }
3245
- //* Remove highlighting from other list items and highlight the given item.
3246
- _highlightListItem(listItem, shouldFocus) {
3247
- const prevItem = this.highlightedItem;
3248
- if (prevItem) {
3249
- prevItem.classList.remove("iti__highlight");
3250
- prevItem.setAttribute("aria-selected", "false");
3251
- }
3252
- this.highlightedItem = listItem;
3253
- if (this.highlightedItem) {
3254
- this.highlightedItem.classList.add("iti__highlight");
3255
- this.highlightedItem.setAttribute("aria-selected", "true");
3256
- if (this.options.countrySearch) {
3257
- const activeDescendant = this.highlightedItem.getAttribute("id") || "";
3258
- this.searchInput.setAttribute("aria-activedescendant", activeDescendant);
3259
- }
3260
- }
3261
- if (shouldFocus) {
3262
- this.highlightedItem.focus();
3263
- }
3264
- }
3265
3596
  //* Update the selected country, dial code (if separateDialCode), placeholder, title, and active list item.
3266
3597
  //* Note: called from _setInitialState, _updateCountryFromNumber, _selectListItem, setCountry.
3267
3598
  _setCountry(iso2) {
@@ -3271,8 +3602,8 @@ var factoryOutput = (() => {
3271
3602
  if (this.selectedCountryData.iso2) {
3272
3603
  this.defaultCountry = this.selectedCountryData.iso2;
3273
3604
  }
3274
- if (this.selectedCountry) {
3275
- const flagClass = iso2 && showFlags ? `iti__flag iti__${iso2}` : "iti__flag iti__globe";
3605
+ if (this.ui.selectedCountry) {
3606
+ const flagClass = iso2 && showFlags ? `${CLASSES.FLAG} iti__${iso2}` : `${CLASSES.FLAG} ${CLASSES.GLOBE}`;
3276
3607
  let ariaLabel, title;
3277
3608
  if (iso2) {
3278
3609
  const { name, dialCode } = this.selectedCountryData;
@@ -3282,28 +3613,19 @@ var factoryOutput = (() => {
3282
3613
  title = i18n.noCountrySelected;
3283
3614
  ariaLabel = i18n.noCountrySelected;
3284
3615
  }
3285
- this.selectedCountryInner.className = flagClass;
3286
- this.selectedCountry.setAttribute("title", title);
3287
- this.selectedCountry.setAttribute("aria-label", ariaLabel);
3616
+ this.ui.selectedCountryInner.className = flagClass;
3617
+ this.ui.selectedCountry.setAttribute("title", title);
3618
+ this.ui.selectedCountry.setAttribute(ARIA.LABEL, ariaLabel);
3288
3619
  }
3289
3620
  if (separateDialCode) {
3290
3621
  const dialCode = this.selectedCountryData.dialCode ? `+${this.selectedCountryData.dialCode}` : "";
3291
- this.selectedDialCode.innerHTML = dialCode;
3292
- this._updateInputPadding();
3622
+ this.ui.selectedDialCode.textContent = dialCode;
3623
+ this.ui.updateInputPadding();
3293
3624
  }
3294
3625
  this._updatePlaceholder();
3295
3626
  this._updateMaxLength();
3296
3627
  return prevIso2 !== iso2;
3297
3628
  }
3298
- //* Update the input padding to make space for the selected country/dial code.
3299
- _updateInputPadding() {
3300
- if (this.selectedCountry) {
3301
- const saneDefaultWidth = this.options.separateDialCode ? 78 : 42;
3302
- const selectedCountryWidth = this.selectedCountry.offsetWidth || this._getHiddenSelectedCountryWidth() || saneDefaultWidth;
3303
- const inputPadding = selectedCountryWidth + 6;
3304
- this.telInput.style.paddingLeft = `${inputPadding}px`;
3305
- }
3306
- }
3307
3629
  //* Update the maximum valid number length for the currently selected country.
3308
3630
  _updateMaxLength() {
3309
3631
  const { strictMode, placeholderNumberType, validationNumberTypes } = this.options;
@@ -3318,7 +3640,11 @@ var factoryOutput = (() => {
3318
3640
  true
3319
3641
  );
3320
3642
  let validNumber = exampleNumber;
3321
- while (intlTelInput.utils.isPossibleNumber(exampleNumber, iso2, validationNumberTypes)) {
3643
+ while (intlTelInput.utils.isPossibleNumber(
3644
+ exampleNumber,
3645
+ iso2,
3646
+ validationNumberTypes
3647
+ )) {
3322
3648
  validNumber = exampleNumber;
3323
3649
  exampleNumber += "0";
3324
3650
  }
@@ -3332,31 +3658,6 @@ var factoryOutput = (() => {
3332
3658
  }
3333
3659
  }
3334
3660
  }
3335
- //* When input is in a hidden container during init, we cannot calculate the selected country width.
3336
- //* Fix: clone the markup, make it invisible, add it to the end of the DOM, and then measure it's width.
3337
- //* To get the right styling to apply, all we need is a shallow clone of the container,
3338
- //* and then to inject a deep clone of the selectedCountry element.
3339
- _getHiddenSelectedCountryWidth() {
3340
- if (this.telInput.parentNode) {
3341
- let body;
3342
- try {
3343
- body = window.top.document.body;
3344
- } catch (e) {
3345
- body = document.body;
3346
- }
3347
- const containerClone = this.telInput.parentNode.cloneNode(false);
3348
- containerClone.style.visibility = "hidden";
3349
- body.appendChild(containerClone);
3350
- const countryContainerClone = this.countryContainer.cloneNode();
3351
- containerClone.appendChild(countryContainerClone);
3352
- const selectedCountryClone = this.selectedCountry.cloneNode(true);
3353
- countryContainerClone.appendChild(selectedCountryClone);
3354
- const width = selectedCountryClone.offsetWidth;
3355
- body.removeChild(containerClone);
3356
- return width;
3357
- }
3358
- return 0;
3359
- }
3360
3661
  //* Update the input placeholder to an example number from the currently selected country.
3361
3662
  _updatePlaceholder() {
3362
3663
  const {
@@ -3365,7 +3666,7 @@ var factoryOutput = (() => {
3365
3666
  nationalMode,
3366
3667
  customPlaceholder
3367
3668
  } = this.options;
3368
- const shouldSetPlaceholder = autoPlaceholder === "aggressive" || !this.hadInitialPlaceholder && autoPlaceholder === "polite";
3669
+ const shouldSetPlaceholder = autoPlaceholder === "aggressive" || !this.ui.hadInitialPlaceholder && autoPlaceholder === "polite";
3369
3670
  if (intlTelInput.utils && shouldSetPlaceholder) {
3370
3671
  const numberType = intlTelInput.utils.numberType[placeholderNumberType];
3371
3672
  let placeholder = this.selectedCountryData.iso2 ? intlTelInput.utils.getExampleNumber(
@@ -3377,98 +3678,66 @@ var factoryOutput = (() => {
3377
3678
  if (typeof customPlaceholder === "function") {
3378
3679
  placeholder = customPlaceholder(placeholder, this.selectedCountryData);
3379
3680
  }
3380
- this.telInput.setAttribute("placeholder", placeholder);
3681
+ this.ui.telInput.setAttribute("placeholder", placeholder);
3381
3682
  }
3382
3683
  }
3383
3684
  //* Called when the user selects a list item from the dropdown.
3384
3685
  _selectListItem(listItem) {
3385
- const iso2 = listItem.getAttribute("data-country-code");
3686
+ const iso2 = listItem.dataset[DATA_KEYS.COUNTRY_CODE];
3386
3687
  const countryChanged = this._setCountry(iso2);
3387
3688
  this._closeDropdown();
3388
- const dialCode = listItem.getAttribute("data-dial-code");
3689
+ const dialCode = listItem.dataset[DATA_KEYS.DIAL_CODE];
3389
3690
  this._updateDialCode(dialCode);
3390
3691
  if (this.options.formatOnDisplay) {
3391
- this._updateValFromNumber(this.telInput.value);
3692
+ this._updateValFromNumber(this.ui.telInput.value);
3392
3693
  }
3393
- this.telInput.focus();
3694
+ this.ui.telInput.focus();
3394
3695
  if (countryChanged) {
3395
3696
  this._triggerCountryChange();
3396
3697
  }
3397
3698
  }
3398
3699
  //* Close the dropdown and unbind any listeners.
3399
3700
  _closeDropdown() {
3400
- this.dropdownContent.classList.add("iti__hide");
3401
- this.selectedCountry.setAttribute("aria-expanded", "false");
3402
- if (this.highlightedItem) {
3403
- this.highlightedItem.setAttribute("aria-selected", "false");
3701
+ if (this.ui.dropdownContent.classList.contains(CLASSES.HIDE)) {
3702
+ return;
3404
3703
  }
3405
- if (this.options.countrySearch) {
3406
- this.searchInput.removeAttribute("aria-activedescendant");
3704
+ this.ui.dropdownContent.classList.add(CLASSES.HIDE);
3705
+ this.ui.selectedCountry.setAttribute(ARIA.EXPANDED, "false");
3706
+ if (this.ui.highlightedItem) {
3707
+ this.ui.highlightedItem.setAttribute(ARIA.SELECTED, "false");
3407
3708
  }
3408
- this.dropdownArrow.classList.remove("iti__arrow--up");
3409
3709
  if (this.options.countrySearch) {
3410
- this.searchInput.removeEventListener("input", this._handleSearchChange);
3411
- this.searchClearButton.removeEventListener("click", this._handleSearchClear);
3710
+ this.ui.searchInput.removeAttribute(ARIA.ACTIVE_DESCENDANT);
3412
3711
  }
3413
- document.removeEventListener("keydown", this._handleKeydownOnDropdown);
3414
- document.documentElement.removeEventListener(
3415
- "click",
3416
- this._handleClickOffToClose
3417
- );
3418
- this.countryList.removeEventListener(
3419
- "mouseover",
3420
- this._handleMouseoverCountryList
3421
- );
3422
- this.countryList.removeEventListener("click", this._handleClickCountryList);
3712
+ this.ui.dropdownArrow.classList.remove(CLASSES.ARROW_UP);
3713
+ this.dropdownAbortController.abort();
3714
+ this.dropdownAbortController = null;
3423
3715
  if (this.options.dropdownContainer) {
3424
- if (!this.options.useFullscreenPopup) {
3425
- window.removeEventListener("scroll", this._handleWindowScroll);
3426
- }
3427
- if (this.dropdown.parentNode) {
3428
- this.dropdown.parentNode.removeChild(this.dropdown);
3429
- }
3430
- }
3431
- this._trigger("close:countrydropdown");
3432
- }
3433
- //* Check if an element is visible within it's container, else scroll until it is.
3434
- _scrollTo(element) {
3435
- const container = this.countryList;
3436
- const scrollTop = document.documentElement.scrollTop;
3437
- const containerHeight = container.offsetHeight;
3438
- const containerTop = container.getBoundingClientRect().top + scrollTop;
3439
- const containerBottom = containerTop + containerHeight;
3440
- const elementHeight = element.offsetHeight;
3441
- const elementTop = element.getBoundingClientRect().top + scrollTop;
3442
- const elementBottom = elementTop + elementHeight;
3443
- const newScrollTop = elementTop - containerTop + container.scrollTop;
3444
- if (elementTop < containerTop) {
3445
- container.scrollTop = newScrollTop;
3446
- } else if (elementBottom > containerBottom) {
3447
- const heightDifference = containerHeight - elementHeight;
3448
- container.scrollTop = newScrollTop - heightDifference;
3716
+ this.ui.dropdown.remove();
3449
3717
  }
3718
+ this._trigger(EVENTS.CLOSE_COUNTRY_DROPDOWN);
3450
3719
  }
3451
3720
  //* Replace any existing dial code with the new one
3452
3721
  //* Note: called from _selectListItem and setCountry
3453
3722
  _updateDialCode(newDialCodeBare) {
3454
- const inputVal = this.telInput.value;
3723
+ const inputVal = this.ui.telInput.value;
3455
3724
  const newDialCode = `+${newDialCodeBare}`;
3456
3725
  let newNumber;
3457
- if (inputVal.charAt(0) === "+") {
3726
+ if (inputVal.startsWith("+")) {
3458
3727
  const prevDialCode = this._getDialCode(inputVal);
3459
3728
  if (prevDialCode) {
3460
3729
  newNumber = inputVal.replace(prevDialCode, newDialCode);
3461
3730
  } else {
3462
3731
  newNumber = newDialCode;
3463
3732
  }
3464
- this.telInput.value = newNumber;
3733
+ this.ui.telInput.value = newNumber;
3465
3734
  }
3466
3735
  }
3467
3736
  //* Try and extract a valid international dial code from a full telephone number.
3468
3737
  //* Note: returns the raw string inc plus character and any whitespace/dots etc.
3469
3738
  _getDialCode(number, includeAreaCode) {
3470
3739
  let dialCode = "";
3471
- if (number.charAt(0) === "+") {
3740
+ if (number.startsWith("+")) {
3472
3741
  let numericChars = "";
3473
3742
  for (let i = 0; i < number.length; i++) {
3474
3743
  const c = number.charAt(i);
@@ -3494,11 +3763,11 @@ var factoryOutput = (() => {
3494
3763
  }
3495
3764
  //* Get the input val, adding the dial code if separateDialCode is enabled.
3496
3765
  _getFullNumber(overrideVal) {
3497
- const val = overrideVal || this.telInput.value.trim();
3766
+ const val = overrideVal || this.ui.telInput.value.trim();
3498
3767
  const { dialCode } = this.selectedCountryData;
3499
3768
  let prefix;
3500
3769
  const numericVal = getNumeric(val);
3501
- if (this.options.separateDialCode && val.charAt(0) !== "+" && dialCode && numericVal) {
3770
+ if (this.options.separateDialCode && !val.startsWith("+") && dialCode && numericVal) {
3502
3771
  prefix = `+${dialCode}`;
3503
3772
  } else {
3504
3773
  prefix = "";
@@ -3518,16 +3787,16 @@ var factoryOutput = (() => {
3518
3787
  }
3519
3788
  //* Trigger the 'countrychange' event.
3520
3789
  _triggerCountryChange() {
3521
- this._trigger("countrychange");
3790
+ this._trigger(EVENTS.COUNTRY_CHANGE);
3522
3791
  }
3523
3792
  //**************************
3524
3793
  //* SECRET PUBLIC METHODS
3525
3794
  //**************************
3526
3795
  //* This is called when the geoip call returns.
3527
3796
  handleAutoCountry() {
3528
- if (this.options.initialCountry === "auto" && intlTelInput.autoCountry) {
3797
+ if (this.options.initialCountry === INITIAL_COUNTRY.AUTO && intlTelInput.autoCountry) {
3529
3798
  this.defaultCountry = intlTelInput.autoCountry;
3530
- const hasSelectedCountryOrGlobe = this.selectedCountryData.iso2 || this.selectedCountryInner.classList.contains("iti__globe");
3799
+ const hasSelectedCountryOrGlobe = this.selectedCountryData.iso2 || this.ui.selectedCountryInner.classList.contains(CLASSES.GLOBE);
3531
3800
  if (!hasSelectedCountryOrGlobe) {
3532
3801
  this.setCountry(this.defaultCountry);
3533
3802
  }
@@ -3537,8 +3806,8 @@ var factoryOutput = (() => {
3537
3806
  //* This is called when the utils request completes.
3538
3807
  handleUtils() {
3539
3808
  if (intlTelInput.utils) {
3540
- if (this.telInput.value) {
3541
- this._updateValFromNumber(this.telInput.value);
3809
+ if (this.ui.telInput.value) {
3810
+ this._updateValFromNumber(this.ui.telInput.value);
3542
3811
  }
3543
3812
  if (this.selectedCountryData.iso2) {
3544
3813
  this._updatePlaceholder();
@@ -3552,45 +3821,20 @@ var factoryOutput = (() => {
3552
3821
  //********************
3553
3822
  //* Remove plugin.
3554
3823
  destroy() {
3555
- this.telInput.iti = void 0;
3556
- const { allowDropdown, separateDialCode } = this.options;
3557
- if (allowDropdown) {
3558
- this._closeDropdown();
3559
- this.selectedCountry.removeEventListener(
3560
- "click",
3561
- this._handleClickSelectedCountry
3562
- );
3563
- this.countryContainer.removeEventListener(
3564
- "keydown",
3565
- this._handleCountryContainerKeydown
3566
- );
3567
- const label = this.telInput.closest("label");
3568
- if (label) {
3569
- label.removeEventListener("click", this._handleLabelClick);
3570
- }
3571
- }
3572
- const { form } = this.telInput;
3573
- if (this._handleHiddenInputSubmit && form) {
3574
- form.removeEventListener("submit", this._handleHiddenInputSubmit);
3575
- }
3576
- this.telInput.removeEventListener("input", this._handleInputEvent);
3577
- if (this._handleKeydownEvent) {
3578
- this.telInput.removeEventListener("keydown", this._handleKeydownEvent);
3579
- }
3580
- if (this._handlePasteEvent) {
3581
- this.telInput.removeEventListener("paste", this._handlePasteEvent);
3824
+ if (!this.ui.telInput) {
3825
+ return;
3582
3826
  }
3583
- if (this._handlePageLoad) {
3584
- window.removeEventListener("load", this._handlePageLoad);
3827
+ if (this.options.allowDropdown) {
3828
+ this._closeDropdown();
3585
3829
  }
3586
- this.telInput.removeAttribute("data-intl-tel-input-id");
3587
- if (separateDialCode) {
3588
- this.telInput.style.paddingLeft = this.originalPaddingLeft;
3830
+ this.abortController.abort();
3831
+ this.abortController = null;
3832
+ this.ui.destroy();
3833
+ if (intlTelInput.instances instanceof Map) {
3834
+ intlTelInput.instances.delete(this.id);
3835
+ } else {
3836
+ delete intlTelInput.instances[this.id];
3589
3837
  }
3590
- const wrapper = this.telInput.parentNode;
3591
- wrapper?.parentNode?.insertBefore(this.telInput, wrapper);
3592
- wrapper?.parentNode?.removeChild(wrapper);
3593
- delete intlTelInput.instances[this.id];
3594
3838
  }
3595
3839
  //* Get the extension from the current number.
3596
3840
  getExtension() {
@@ -3622,7 +3866,7 @@ var factoryOutput = (() => {
3622
3866
  this.selectedCountryData.iso2
3623
3867
  );
3624
3868
  }
3625
- return -99;
3869
+ return SENTINELS.UNKNOWN_NUMBER_TYPE;
3626
3870
  }
3627
3871
  //* Get the country data for the currently selected country.
3628
3872
  getSelectedCountryData() {
@@ -3634,15 +3878,15 @@ var factoryOutput = (() => {
3634
3878
  const { iso2 } = this.selectedCountryData;
3635
3879
  return intlTelInput.utils.getValidationError(this._getFullNumber(), iso2);
3636
3880
  }
3637
- return -99;
3881
+ return SENTINELS.UNKNOWN_VALIDATION_ERROR;
3638
3882
  }
3639
3883
  //* Validate the input val using number length only
3640
3884
  isValidNumber() {
3641
3885
  const { dialCode, iso2 } = this.selectedCountryData;
3642
- if (dialCode === "44" && intlTelInput.utils) {
3886
+ if (dialCode === UK.DIAL_CODE && intlTelInput.utils) {
3643
3887
  const number = this._getFullNumber();
3644
3888
  const coreNumber = intlTelInput.utils.getCoreNumber(number, iso2);
3645
- if (coreNumber[0] === "7" && coreNumber.length !== 10) {
3889
+ if (coreNumber[0] === UK.MOBILE_PREFIX && coreNumber.length !== UK.MOBILE_CORE_LENGTH) {
3646
3890
  return false;
3647
3891
  }
3648
3892
  }
@@ -3653,7 +3897,11 @@ var factoryOutput = (() => {
3653
3897
  return this._validateNumber(true);
3654
3898
  }
3655
3899
  _utilsIsPossibleNumber(val) {
3656
- return intlTelInput.utils ? intlTelInput.utils.isPossibleNumber(val, this.selectedCountryData.iso2, this.options.validationNumberTypes) : null;
3900
+ return intlTelInput.utils ? intlTelInput.utils.isPossibleNumber(
3901
+ val,
3902
+ this.selectedCountryData.iso2,
3903
+ this.options.validationNumberTypes
3904
+ ) : null;
3657
3905
  }
3658
3906
  //* Shared internal validation logic to handle alpha character extension rules.
3659
3907
  _validateNumber(precise) {
@@ -3665,7 +3913,7 @@ var factoryOutput = (() => {
3665
3913
  }
3666
3914
  const testValidity = (s) => precise ? this._utilsIsValidNumber(s) : this._utilsIsPossibleNumber(s);
3667
3915
  const val = this._getFullNumber();
3668
- const alphaCharPosition = val.search(/\p{L}/u);
3916
+ const alphaCharPosition = val.search(REGEX.ALPHA_UNICODE);
3669
3917
  const hasAlphaChar = alphaCharPosition > -1;
3670
3918
  if (hasAlphaChar && !this.options.allowPhonewords) {
3671
3919
  const beforeAlphaChar = val.substring(0, alphaCharPosition);
@@ -3676,7 +3924,11 @@ var factoryOutput = (() => {
3676
3924
  return testValidity(val);
3677
3925
  }
3678
3926
  _utilsIsValidNumber(val) {
3679
- return intlTelInput.utils ? intlTelInput.utils.isValidNumber(val, this.selectedCountryData.iso2, this.options.validationNumberTypes) : null;
3927
+ return intlTelInput.utils ? intlTelInput.utils.isValidNumber(
3928
+ val,
3929
+ this.selectedCountryData.iso2,
3930
+ this.options.validationNumberTypes
3931
+ ) : null;
3680
3932
  }
3681
3933
  //* Update the selected country, and update the input val accordingly.
3682
3934
  setCountry(iso2) {
@@ -3690,7 +3942,7 @@ var factoryOutput = (() => {
3690
3942
  this._setCountry(iso2Lower);
3691
3943
  this._updateDialCode(this.selectedCountryData.dialCode);
3692
3944
  if (this.options.formatOnDisplay) {
3693
- this._updateValFromNumber(this.telInput.value);
3945
+ this._updateValFromNumber(this.ui.telInput.value);
3694
3946
  }
3695
3947
  this._triggerCountryChange();
3696
3948
  }
@@ -3702,7 +3954,7 @@ var factoryOutput = (() => {
3702
3954
  if (countryChanged) {
3703
3955
  this._triggerCountryChange();
3704
3956
  }
3705
- this._trigger("input", { isSetNumber: true });
3957
+ this._trigger(EVENTS.INPUT, { isSetNumber: true });
3706
3958
  }
3707
3959
  //* Set the placeholder number typ
3708
3960
  setPlaceholderNumberType(type) {
@@ -3710,11 +3962,11 @@ var factoryOutput = (() => {
3710
3962
  this._updatePlaceholder();
3711
3963
  }
3712
3964
  setDisabled(disabled) {
3713
- this.telInput.disabled = disabled;
3965
+ this.ui.telInput.disabled = disabled;
3714
3966
  if (disabled) {
3715
- this.selectedCountry.setAttribute("disabled", "true");
3967
+ this.ui.selectedCountry.setAttribute("disabled", "true");
3716
3968
  } else {
3717
- this.selectedCountry.removeAttribute("disabled");
3969
+ this.ui.selectedCountry.removeAttribute("disabled");
3718
3970
  }
3719
3971
  }
3720
3972
  };
@@ -3728,13 +3980,19 @@ var factoryOutput = (() => {
3728
3980
  return Promise.reject(error);
3729
3981
  }
3730
3982
  } else {
3731
- return Promise.reject(new TypeError(`The argument passed to attachUtils must be a function that returns a promise for the utilities module, not ${typeof source}`));
3983
+ return Promise.reject(
3984
+ new TypeError(
3985
+ `The argument passed to attachUtils must be a function that returns a promise for the utilities module, not ${typeof source}`
3986
+ )
3987
+ );
3732
3988
  }
3733
3989
  intlTelInput.startedLoadingUtilsScript = true;
3734
3990
  return loadCall.then((module) => {
3735
3991
  const utils2 = module?.default;
3736
3992
  if (!utils2 || typeof utils2 !== "object") {
3737
- throw new TypeError("The loader function passed to attachUtils did not resolve to a module object with utils as its default export.");
3993
+ throw new TypeError(
3994
+ "The loader function passed to attachUtils did not resolve to a module object with utils as its default export."
3995
+ );
3738
3996
  }
3739
3997
  intlTelInput.utils = utils2;
3740
3998
  forEachInstance("handleUtils");
@@ -3746,11 +4004,17 @@ var factoryOutput = (() => {
3746
4004
  }
3747
4005
  return null;
3748
4006
  };
4007
+ var forEachInstance = (method, ...args) => {
4008
+ Object.values(intlTelInput.instances).forEach((instance) => {
4009
+ const fn = instance[method];
4010
+ if (typeof fn === "function") {
4011
+ fn.apply(instance, args);
4012
+ }
4013
+ });
4014
+ };
3749
4015
  var intlTelInput = Object.assign(
3750
4016
  (input, options) => {
3751
4017
  const iti = new Iti(input, options);
3752
- iti._init();
3753
- input.setAttribute("data-intl-tel-input-id", iti.id.toString());
3754
4018
  intlTelInput.instances[iti.id] = iti;
3755
4019
  input.iti = iti;
3756
4020
  return iti;
@@ -3763,7 +4027,7 @@ var factoryOutput = (() => {
3763
4027
  getCountryData: () => data_default,
3764
4028
  //* A getter for the plugin instance.
3765
4029
  getInstance: (input) => {
3766
- const id2 = input.getAttribute("data-intl-tel-input-id");
4030
+ const id2 = input.dataset.intlTelInputId;
3767
4031
  return id2 ? intlTelInput.instances[id2] : null;
3768
4032
  },
3769
4033
  //* A map from instance ID to instance object.
@@ -3771,7 +4035,7 @@ var factoryOutput = (() => {
3771
4035
  attachUtils,
3772
4036
  startedLoadingUtilsScript: false,
3773
4037
  startedLoadingAutoCountry: false,
3774
- version: "25.10.12"
4038
+ version: "25.11.1"
3775
4039
  }
3776
4040
  );
3777
4041
  var intl_tel_input_default = intlTelInput;
@@ -6881,7 +7145,7 @@ var factoryOutput = (() => {
6881
7145
  ,
6882
7146
  ,
6883
7147
  [7, 8, 9]
6884
- ], [, , "(?:1(?:0[0-8]|1[0-7]|2[014]|30)|7\\d\\d)\\d{6}", , , , "712123456", , , [9]], [, , "800[02-8]\\d{5,6}", , , , "800223456", , , [9, 10]], [, , "900[02-9]\\d{5}", , , , "900223456", , , [9]], [, , , , , , , , , [-1]], [, , , , , , , , , [-1]], [, , , , , , , , , [-1]], "KE", 254, "000", "0", , , "0", , , , [[, "(\\d{2})(\\d{5,7})", "$1 $2", ["[24-6]"], "0$1"], [, "(\\d{3})(\\d{6})", "$1 $2", ["[17]"], "0$1"], [, "(\\d{3})(\\d{3})(\\d{3,4})", "$1 $2 $3", ["[89]"], "0$1"]], , [, , , , , , , , , [-1]], , , [, , , , , , , , , [-1]], [, , , , , , , , , [-1]], , , [, , , , , , , , , [-1]]],
7148
+ ], [, , "(?:1(?:0[0-8]|1\\d|2[014]|[34]0)|7\\d\\d)\\d{6}", , , , "712123456", , , [9]], [, , "800[02-8]\\d{5,6}", , , , "800223456", , , [9, 10]], [, , "900[02-9]\\d{5}", , , , "900223456", , , [9]], [, , , , , , , , , [-1]], [, , , , , , , , , [-1]], [, , , , , , , , , [-1]], "KE", 254, "000", "0", , , "0", , , , [[, "(\\d{2})(\\d{5,7})", "$1 $2", ["[24-6]"], "0$1"], [, "(\\d{3})(\\d{6})", "$1 $2", ["[17]"], "0$1"], [, "(\\d{3})(\\d{3})(\\d{3,4})", "$1 $2 $3", ["[89]"], "0$1"]], , [, , , , , , , , , [-1]], , , [, , , , , , , , , [-1]], [, , , , , , , , , [-1]], , , [, , , , , , , , , [-1]]],
6885
7149
  KG: [, [
6886
7150
  ,
6887
7151
  ,
@@ -8937,7 +9201,7 @@ var factoryOutput = (() => {
8937
9201
  ,
8938
9202
  ,
8939
9203
  [5, 6, 7]
8940
- ], [, , "72[48]0\\d{5}|7(?:[014-8]\\d|2[067]|36|9[0189])\\d{6}", , , , "712345678"], [, , "800[1-3]\\d{5}", , , , "800123456"], [, , "90[1-3]\\d{6}", , , , "901123456"], [, , , , , , , , , [-1]], [, , , , , , , , , [-1]], [, , , , , , , , , [-1]], "UG", 256, "00[057]", "0", , , "0", , , , [[, "(\\d{4})(\\d{5})", "$1 $2", ["202", "2024"], "0$1"], [, "(\\d{3})(\\d{6})", "$1 $2", ["[27-9]|4(?:6[45]|[7-9])"], "0$1"], [, "(\\d{2})(\\d{7})", "$1 $2", ["[34]"], "0$1"]], , [, , , , , , , , , [-1]], , , [, , , , , , , , , [-1]], [, , , , , , , , , [-1]], , , [, , , , , , , , , [-1]]],
9204
+ ], [, , "72[48]0\\d{5}|7(?:[014-8]\\d|2[067]|36|9[0-289])\\d{6}", , , , "712345678"], [, , "800[1-3]\\d{5}", , , , "800123456"], [, , "90[1-3]\\d{6}", , , , "901123456"], [, , , , , , , , , [-1]], [, , , , , , , , , [-1]], [, , , , , , , , , [-1]], "UG", 256, "00[057]", "0", , , "0", , , , [[, "(\\d{4})(\\d{5})", "$1 $2", ["202", "2024"], "0$1"], [, "(\\d{3})(\\d{6})", "$1 $2", ["[27-9]|4(?:6[45]|[7-9])"], "0$1"], [, "(\\d{2})(\\d{7})", "$1 $2", ["[34]"], "0$1"]], , [, , , , , , , , , [-1]], , , [, , , , , , , , , [-1]], [, , , , , , , , , [-1]], , , [, , , , , , , , , [-1]]],
8941
9205
  US: [, [
8942
9206
  ,
8943
9207
  ,
@@ -8953,7 +9217,7 @@ var factoryOutput = (() => {
8953
9217
  ], [
8954
9218
  ,
8955
9219
  ,
8956
- "(?:3052(?:0[0-8]|[1-9]\\d)|5056(?:[0-35-9]\\d|4[0-68]))\\d{4}|(?:2742|305[3-9]|(?:472|983)[2-47-9]|505[2-57-9])\\d{6}|(?:2(?:0[1-35-9]|1[02-9]|2[03-57-9]|3[1459]|4[08]|5[1-46]|6[0279]|7[0269]|8[13])|3(?:0[1-47-9]|1[02-9]|2[0135-79]|3[0-24679]|4[167]|5[0-2]|6[01349]|8[056])|4(?:0[124-9]|1[02-579]|2[3-5]|3[0245]|4[023578]|58|6[349]|7[0589]|8[04])|5(?:0[1-47-9]|1[0235-8]|20|3[0149]|4[01]|5[179]|6[1-47]|7[0-5]|8[0256])|6(?:0[1-35-9]|1[024-9]|2[03689]|3[016]|4[0156]|5[01679]|6[0-279]|78|8[0-269])|7(?:0[1-46-8]|1[2-9]|2[04-8]|3[0-247]|4[0378]|5[47]|6[02359]|7[0-59]|8[156])|8(?:0[1-68]|1[02-8]|2[0168]|3[0-2589]|4[03578]|5[046-9]|6[02-5]|7[028])|9(?:0[1346-9]|1[02-9]|2[0589]|3[0146-8]|4[01357-9]|5[12469]|7[0-3589]|8[04-69]))[2-9]\\d{6}",
9220
+ "3052(?:0[0-8]|[1-9]\\d)\\d{4}|(?:2742|305[3-9])\\d{6}|(?:472|983)[2-47-9]\\d{6}|(?:2(?:0[1-35-9]|1[02-9]|2[03-57-9]|3[1459]|4[08]|5[1-46]|6[0279]|7[0269]|8[13])|3(?:0[1-47-9]|1[02-9]|2[0135-79]|3[0-24679]|4[167]|5[0-2]|6[01349]|8[056])|4(?:0[124-9]|1[02-579]|2[3-5]|3[0245]|4[023578]|58|6[349]|7[0589]|8[04])|5(?:0[1-57-9]|1[0235-8]|20|3[0149]|4[01]|5[179]|6[1-47]|7[0-5]|8[0256])|6(?:0[1-35-9]|1[024-9]|2[03689]|3[016]|4[0156]|5[01679]|6[0-279]|78|8[0-269])|7(?:0[1-46-8]|1[2-9]|2[04-8]|3[0-247]|4[0378]|5[47]|6[02359]|7[0-59]|8[156])|8(?:0[1-68]|1[02-8]|2[0168]|3[0-2589]|4[03578]|5[046-9]|6[02-5]|7[028])|9(?:0[1346-9]|1[02-9]|2[0589]|3[0146-8]|4[01357-9]|5[12469]|7[0-3589]|8[04-69]))[2-9]\\d{6}",
8957
9221
  ,
8958
9222
  ,
8959
9223
  ,
@@ -8965,7 +9229,7 @@ var factoryOutput = (() => {
8965
9229
  ], [
8966
9230
  ,
8967
9231
  ,
8968
- "(?:3052(?:0[0-8]|[1-9]\\d)|5056(?:[0-35-9]\\d|4[0-68]))\\d{4}|(?:2742|305[3-9]|(?:472|983)[2-47-9]|505[2-57-9])\\d{6}|(?:2(?:0[1-35-9]|1[02-9]|2[03-57-9]|3[1459]|4[08]|5[1-46]|6[0279]|7[0269]|8[13])|3(?:0[1-47-9]|1[02-9]|2[0135-79]|3[0-24679]|4[167]|5[0-2]|6[01349]|8[056])|4(?:0[124-9]|1[02-579]|2[3-5]|3[0245]|4[023578]|58|6[349]|7[0589]|8[04])|5(?:0[1-47-9]|1[0235-8]|20|3[0149]|4[01]|5[179]|6[1-47]|7[0-5]|8[0256])|6(?:0[1-35-9]|1[024-9]|2[03689]|3[016]|4[0156]|5[01679]|6[0-279]|78|8[0-269])|7(?:0[1-46-8]|1[2-9]|2[04-8]|3[0-247]|4[0378]|5[47]|6[02359]|7[0-59]|8[156])|8(?:0[1-68]|1[02-8]|2[0168]|3[0-2589]|4[03578]|5[046-9]|6[02-5]|7[028])|9(?:0[1346-9]|1[02-9]|2[0589]|3[0146-8]|4[01357-9]|5[12469]|7[0-3589]|8[04-69]))[2-9]\\d{6}",
9232
+ "3052(?:0[0-8]|[1-9]\\d)\\d{4}|(?:2742|305[3-9])\\d{6}|(?:472|983)[2-47-9]\\d{6}|(?:2(?:0[1-35-9]|1[02-9]|2[03-57-9]|3[1459]|4[08]|5[1-46]|6[0279]|7[0269]|8[13])|3(?:0[1-47-9]|1[02-9]|2[0135-79]|3[0-24679]|4[167]|5[0-2]|6[01349]|8[056])|4(?:0[124-9]|1[02-579]|2[3-5]|3[0245]|4[023578]|58|6[349]|7[0589]|8[04])|5(?:0[1-57-9]|1[0235-8]|20|3[0149]|4[01]|5[179]|6[1-47]|7[0-5]|8[0256])|6(?:0[1-35-9]|1[024-9]|2[03689]|3[016]|4[0156]|5[01679]|6[0-279]|78|8[0-269])|7(?:0[1-46-8]|1[2-9]|2[04-8]|3[0-247]|4[0378]|5[47]|6[02359]|7[0-59]|8[156])|8(?:0[1-68]|1[02-8]|2[0168]|3[0-2589]|4[03578]|5[046-9]|6[02-5]|7[028])|9(?:0[1346-9]|1[02-9]|2[0589]|3[0146-8]|4[01357-9]|5[12469]|7[0-3589]|8[04-69]))[2-9]\\d{6}",
8969
9233
  ,
8970
9234
  ,
8971
9235
  ,