intl-tel-input 28.0.9 → 29.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/css/intlTelInput-no-assets.css +20 -11
- package/dist/css/intlTelInput-no-assets.min.css +1 -1
- package/dist/css/intlTelInput.css +20 -11
- package/dist/css/intlTelInput.min.css +1 -1
- package/dist/js/data.js +1 -1
- package/dist/js/data.min.js +1 -1
- package/dist/js/intlTelInput.d.ts +38 -23
- package/dist/js/intlTelInput.js +392 -324
- package/dist/js/intlTelInput.min.js +2 -2
- package/dist/js/intlTelInput.mjs +391 -323
- package/dist/js/intlTelInputWithUtils.js +680 -614
- package/dist/js/intlTelInputWithUtils.min.js +2 -2
- package/dist/js/intlTelInputWithUtils.mjs +679 -613
- package/dist/js/{i18n → locale}/ar.js +3 -3
- package/dist/js/{i18n → locale}/bg.js +2 -2
- package/dist/js/{i18n → locale}/bn.js +2 -2
- package/dist/js/{i18n → locale}/bs.js +2 -2
- package/dist/js/{i18n → locale}/ca.js +2 -2
- package/dist/js/{i18n → locale}/cs.js +2 -2
- package/dist/js/{i18n → locale}/da.js +2 -2
- package/dist/js/{i18n → locale}/de.js +2 -2
- package/dist/js/{i18n → locale}/el.js +2 -2
- package/dist/js/{i18n → locale}/es.js +2 -2
- package/dist/js/{i18n → locale}/et.js +2 -2
- package/dist/js/{i18n → locale}/fa.js +2 -5
- package/dist/js/{i18n → locale}/fi.js +2 -2
- package/dist/js/locale/fil.js +16 -0
- package/dist/js/{i18n → locale}/fr.js +2 -2
- package/dist/js/locale/he.js +19 -0
- package/dist/js/{i18n → locale}/hi.js +2 -2
- package/dist/js/{i18n → locale}/hr.js +2 -2
- package/dist/js/{i18n → locale}/hu.js +2 -5
- package/dist/js/locale/hy.js +19 -0
- package/dist/js/{i18n → locale}/id.js +2 -5
- package/dist/js/{i18n → locale}/index.js +9 -0
- package/dist/js/locale/is.js +21 -0
- package/dist/js/{i18n → locale}/it.js +2 -2
- package/dist/js/{i18n → locale}/ja.js +2 -5
- package/dist/js/{i18n → locale}/kn.js +2 -2
- package/dist/js/{i18n → locale}/ko.js +2 -5
- package/dist/js/{i18n → locale}/lt.js +2 -2
- package/dist/js/locale/lv.js +24 -0
- package/dist/js/locale/mk.js +21 -0
- package/dist/js/{i18n → locale}/mr.js +2 -2
- package/dist/js/locale/ms.js +16 -0
- package/dist/js/{i18n → locale}/nl.js +2 -2
- package/dist/js/{i18n → locale}/no.js +2 -2
- package/dist/js/{i18n → locale}/pl.js +2 -2
- package/dist/js/{i18n → locale}/pt.js +2 -2
- package/dist/js/{i18n → locale}/ro.js +4 -4
- package/dist/js/{i18n → locale}/ru.js +2 -2
- package/dist/js/{i18n → locale}/sk.js +5 -8
- package/dist/js/{i18n → locale}/sl.js +2 -2
- package/dist/js/{i18n → locale}/sq.js +2 -2
- package/dist/js/{i18n → locale}/sr.js +2 -2
- package/dist/js/{i18n → locale}/sv.js +2 -5
- package/dist/js/locale/sw.js +19 -0
- package/dist/js/locale/ta.js +19 -0
- package/dist/js/{i18n → locale}/te.js +2 -2
- package/dist/js/{i18n → locale}/th.js +2 -5
- package/dist/js/{i18n → locale}/tr.js +2 -5
- package/dist/js/{i18n → locale}/uk.js +2 -2
- package/dist/js/{i18n → locale}/ur.js +2 -2
- package/dist/js/{i18n → locale}/uz.js +2 -5
- package/dist/js/{i18n → locale}/vi.js +2 -5
- package/dist/js/{i18n → locale}/zh-hk.js +2 -5
- package/dist/js/{i18n → locale}/zh.js +2 -5
- package/dist/js/locale.d.ts +124 -0
- package/dist/js/utils.js +51 -51
- package/package.json +7 -7
- package/dist/js/i18n.d.ts +0 -106
- /package/dist/js/{i18n → locale}/en.js +0 -0
- /package/dist/js/{i18n → locale}/types.js +0 -0
package/dist/js/intlTelInput.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* International Telephone Input
|
|
2
|
+
* International Telephone Input v29.0.0
|
|
3
3
|
* git+https://github.com/jackocnr/intl-tel-input.git
|
|
4
4
|
* Licensed under the MIT license
|
|
5
5
|
*/
|
|
@@ -26,9 +26,11 @@ var _factory = (() => {
|
|
|
26
26
|
// packages/core/src/js/intlTelInput.ts
|
|
27
27
|
var intlTelInput_exports = {};
|
|
28
28
|
__export(intlTelInput_exports, {
|
|
29
|
+
COUNTRY_SELECTOR_MODE: () => COUNTRY_SELECTOR_MODE,
|
|
29
30
|
Iti: () => Iti,
|
|
30
31
|
NUMBER_FORMAT: () => NUMBER_FORMAT,
|
|
31
32
|
NUMBER_TYPE: () => NUMBER_TYPE,
|
|
33
|
+
PLACEHOLDER_POLICY: () => PLACEHOLDER_POLICY,
|
|
32
34
|
VALIDATION_ERROR: () => VALIDATION_ERROR,
|
|
33
35
|
default: () => intlTelInput_default
|
|
34
36
|
});
|
|
@@ -1787,8 +1789,8 @@ var _factory = (() => {
|
|
|
1787
1789
|
|
|
1788
1790
|
// packages/core/src/js/constants.ts
|
|
1789
1791
|
var EVENTS = {
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
+
OPEN_COUNTRY_SELECTOR: "open:countryselector",
|
|
1793
|
+
CLOSE_COUNTRY_SELECTOR: "close:countryselector",
|
|
1792
1794
|
COUNTRY_CHANGE: "countrychange",
|
|
1793
1795
|
INPUT: "input",
|
|
1794
1796
|
// used for synthetic input trigger
|
|
@@ -1802,7 +1804,8 @@ var _factory = (() => {
|
|
|
1802
1804
|
FLAG: "iti__flag",
|
|
1803
1805
|
LOADING: "iti__loading",
|
|
1804
1806
|
COUNTRY_ITEM: "iti__country",
|
|
1805
|
-
HIGHLIGHT: "iti__highlight"
|
|
1807
|
+
HIGHLIGHT: "iti__highlight",
|
|
1808
|
+
STRICT_REJECT_ANIMATION: "iti__strict-reject-animation"
|
|
1806
1809
|
};
|
|
1807
1810
|
var KEYS = {
|
|
1808
1811
|
ARROW_UP: "ArrowUp",
|
|
@@ -1834,9 +1837,9 @@ var _factory = (() => {
|
|
|
1834
1837
|
var LAYOUT = {
|
|
1835
1838
|
NARROW_VIEWPORT_WIDTH: 500,
|
|
1836
1839
|
// keep in sync with .iti__country-list CSS media query
|
|
1837
|
-
|
|
1840
|
+
FALLBACK_SELECTED_COUNTRY_WITH_DIAL_WIDTH: 78,
|
|
1838
1841
|
// px width fallback when separateDialCode enabled
|
|
1839
|
-
|
|
1842
|
+
FALLBACK_SELECTED_COUNTRY_NO_DIAL_WIDTH: 42,
|
|
1840
1843
|
// px width fallback when no separate dial code
|
|
1841
1844
|
INPUT_PADDING_EXTRA_LEFT: 6,
|
|
1842
1845
|
// px gap between selected country container and input text
|
|
@@ -1864,14 +1867,17 @@ var _factory = (() => {
|
|
|
1864
1867
|
DIAL_CODE: "1"
|
|
1865
1868
|
// +1 United States
|
|
1866
1869
|
};
|
|
1867
|
-
var
|
|
1868
|
-
AGGRESSIVE: "
|
|
1869
|
-
POLITE: "
|
|
1870
|
-
OFF: "
|
|
1871
|
-
};
|
|
1872
|
-
var INITIAL_COUNTRY = {
|
|
1873
|
-
AUTO: "auto"
|
|
1870
|
+
var PLACEHOLDER_POLICY = {
|
|
1871
|
+
AGGRESSIVE: "AGGRESSIVE",
|
|
1872
|
+
POLITE: "POLITE",
|
|
1873
|
+
OFF: "OFF"
|
|
1874
1874
|
};
|
|
1875
|
+
var COUNTRY_SELECTOR_MODES = [
|
|
1876
|
+
"OFF",
|
|
1877
|
+
"DROPDOWN",
|
|
1878
|
+
"FULLSCREEN",
|
|
1879
|
+
"AUTO"
|
|
1880
|
+
];
|
|
1875
1881
|
var NUMBER_FORMATS = [
|
|
1876
1882
|
"E164",
|
|
1877
1883
|
"INTERNATIONAL",
|
|
@@ -1904,8 +1910,9 @@ var _factory = (() => {
|
|
|
1904
1910
|
var NUMBER_FORMAT = toEnumObject(NUMBER_FORMATS);
|
|
1905
1911
|
var NUMBER_TYPE = toEnumObject(NUMBER_TYPES);
|
|
1906
1912
|
var VALIDATION_ERROR = toEnumObject(VALIDATION_ERRORS);
|
|
1913
|
+
var COUNTRY_SELECTOR_MODE = toEnumObject(COUNTRY_SELECTOR_MODES);
|
|
1907
1914
|
var DATA_KEYS = {
|
|
1908
|
-
// e.g. <li data-iso2="us"> for country items in
|
|
1915
|
+
// e.g. <li data-iso2="us"> for country items in the country list
|
|
1909
1916
|
ISO2: "iso2",
|
|
1910
1917
|
DIAL_CODE: "dialCode",
|
|
1911
1918
|
// e.g. <input data-intl-tel-input-id="0"> on the input element
|
|
@@ -1923,7 +1930,7 @@ var _factory = (() => {
|
|
|
1923
1930
|
MODAL: "aria-modal"
|
|
1924
1931
|
};
|
|
1925
1932
|
|
|
1926
|
-
// packages/core/src/js/
|
|
1933
|
+
// packages/core/src/js/locale/en.ts
|
|
1927
1934
|
var interfaceTranslations = {
|
|
1928
1935
|
selectedCountryAriaLabel: "Change country for phone number, currently selected ${countryName} (${dialCode})",
|
|
1929
1936
|
noCountrySelected: "Select country for phone number",
|
|
@@ -1946,63 +1953,63 @@ var _factory = (() => {
|
|
|
1946
1953
|
// packages/core/src/js/core/options.ts
|
|
1947
1954
|
var mediaQuery = (q) => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(q).matches;
|
|
1948
1955
|
var isNarrowViewport = () => mediaQuery(`(max-width: ${LAYOUT.NARROW_VIEWPORT_WIDTH}px)`);
|
|
1949
|
-
var
|
|
1956
|
+
var resolveAutoCountrySelectorMode = () => {
|
|
1950
1957
|
if (typeof navigator !== "undefined" && typeof window !== "undefined") {
|
|
1951
1958
|
const isShortViewport = mediaQuery("(max-height: 600px)");
|
|
1952
1959
|
const isCoarsePointer = mediaQuery("(pointer: coarse)");
|
|
1953
|
-
|
|
1960
|
+
if (isNarrowViewport() || isCoarsePointer && isShortViewport) {
|
|
1961
|
+
return COUNTRY_SELECTOR_MODE.FULLSCREEN;
|
|
1962
|
+
}
|
|
1954
1963
|
}
|
|
1955
|
-
return
|
|
1964
|
+
return COUNTRY_SELECTOR_MODE.DROPDOWN;
|
|
1956
1965
|
};
|
|
1957
1966
|
var defaults = {
|
|
1958
|
-
//*
|
|
1959
|
-
|
|
1967
|
+
//* How the country selector is displayed. "DROPDOWN" vs "FULLSCREEN", or "AUTO" to decide itself, or "OFF".
|
|
1968
|
+
countrySelectorMode: COUNTRY_SELECTOR_MODE.AUTO,
|
|
1960
1969
|
//* The number type to enforce during validation.
|
|
1961
1970
|
allowedNumberTypes: [NUMBER_TYPE.MOBILE, NUMBER_TYPE.FIXED_LINE],
|
|
1962
1971
|
//* Whether or not to allow extensions after the main number.
|
|
1963
1972
|
allowNumberExtensions: false,
|
|
1964
1973
|
// Allow alphanumeric "phonewords" (e.g. +1 800 FLOWERS) as valid numbers
|
|
1965
1974
|
allowPhonewords: false,
|
|
1966
|
-
//* Add a placeholder in the input with an example number for the selected country.
|
|
1967
|
-
autoPlaceholder: PLACEHOLDER_MODES.POLITE,
|
|
1968
1975
|
//* Add a custom class to the (injected) container element.
|
|
1969
1976
|
containerClass: "",
|
|
1970
1977
|
//* Locale for localising country names via Intl.DisplayNames.
|
|
1971
1978
|
countryNameLocale: "en",
|
|
1972
1979
|
//* Override individual country names by iso2 code.
|
|
1973
1980
|
countryNameOverrides: {},
|
|
1974
|
-
//* The order of the countries in the
|
|
1981
|
+
//* The order of the countries in the country list. Defaults to alphabetical.
|
|
1975
1982
|
countryOrder: null,
|
|
1976
|
-
//* Add a country search input at the top of the
|
|
1983
|
+
//* Add a country search input at the top of the country selector.
|
|
1977
1984
|
countrySearch: true,
|
|
1978
1985
|
//* Modify the auto placeholder.
|
|
1979
1986
|
customPlaceholder: null,
|
|
1980
1987
|
//* Always show the dropdown
|
|
1981
1988
|
dropdownAlwaysOpen: false,
|
|
1982
|
-
//*
|
|
1983
|
-
|
|
1989
|
+
//* Optional DOM element to append the dropdown to (used to escape ancestors with overflow:hidden, or to mount in a custom container). Only consulted in dropdown rendering; ignored when the country selector renders as a fullscreen popup.
|
|
1990
|
+
dropdownParent: null,
|
|
1984
1991
|
//* Don't display these countries.
|
|
1985
1992
|
excludeCountries: null,
|
|
1986
1993
|
//* Fix the dropdown width to the input width (rather than being as wide as the longest country name).
|
|
1987
|
-
|
|
1994
|
+
matchDropdownWidth: true,
|
|
1988
1995
|
//* Format the number as the user types
|
|
1989
1996
|
formatAsYouType: true,
|
|
1990
|
-
//*
|
|
1991
|
-
|
|
1992
|
-
//*
|
|
1993
|
-
|
|
1994
|
-
//* Inject a hidden input with the name returned from this function, and on submit, populate it with the result of getNumber.
|
|
1995
|
-
hiddenInput: null,
|
|
1996
|
-
//* Internationalise the core library text e.g. search input placeholder, country names.
|
|
1997
|
-
i18n: {},
|
|
1997
|
+
//* Inject hidden inputs with the names returned from this function, and on submit, populate them with the full number and selected country iso2.
|
|
1998
|
+
hiddenInputs: null,
|
|
1999
|
+
//* Translations for the core library UI strings e.g. search input placeholder, country names.
|
|
2000
|
+
uiTranslations: {},
|
|
1998
2001
|
//* Initial country.
|
|
1999
2002
|
initialCountry: "",
|
|
2003
|
+
//* Async lookup function used to determine the initial country (e.g. via IP). Ignored if initialCountry is set.
|
|
2004
|
+
initialCountryLookup: null,
|
|
2000
2005
|
//* A function to load the utils script.
|
|
2001
2006
|
loadUtils: null,
|
|
2002
|
-
//*
|
|
2003
|
-
|
|
2007
|
+
//* Format used when displaying numbers (placeholder examples and stored values). One of "E164", "INTERNATIONAL", "NATIONAL".
|
|
2008
|
+
numberDisplayFormat: NUMBER_FORMAT.INTERNATIONAL,
|
|
2004
2009
|
//* Display only these countries.
|
|
2005
2010
|
onlyCountries: null,
|
|
2011
|
+
//* When to set the placeholder to an example number for the selected country: "POLITE" only when the input has no manually-set placeholder, "AGGRESSIVE" always, "OFF" never.
|
|
2012
|
+
placeholderNumberPolicy: PLACEHOLDER_POLICY.POLITE,
|
|
2006
2013
|
//* Number type to use for placeholders.
|
|
2007
2014
|
placeholderNumberType: NUMBER_TYPE.MOBILE,
|
|
2008
2015
|
//* Add custom classes to the search input element.
|
|
@@ -2011,12 +2018,10 @@ var _factory = (() => {
|
|
|
2011
2018
|
separateDialCode: true,
|
|
2012
2019
|
//* When strictMode rejects a key (etc), play a short feedback animation
|
|
2013
2020
|
strictRejectAnimation: true,
|
|
2014
|
-
//* Show flags - for both the selected country, and in the country
|
|
2021
|
+
//* Show flags - for both the selected country, and in the country list
|
|
2015
2022
|
showFlags: true,
|
|
2016
2023
|
//* Only allow certain chars e.g. a plus followed by numeric digits, and cap at max valid length.
|
|
2017
|
-
strictMode: true
|
|
2018
|
-
//* Use full screen popup instead of dropdown for country list.
|
|
2019
|
-
useFullscreenPopup: computeDefaultUseFullscreenPopup()
|
|
2024
|
+
strictMode: true
|
|
2020
2025
|
};
|
|
2021
2026
|
var toString = (val) => JSON.stringify(val);
|
|
2022
2027
|
var isPlainObject = (val) => Boolean(val) && typeof val === "object" && !Array.isArray(val);
|
|
@@ -2028,7 +2033,7 @@ var _factory = (() => {
|
|
|
2028
2033
|
const v = val;
|
|
2029
2034
|
return v.nodeType === 1 && typeof v.tagName === "string" && typeof v.appendChild === "function";
|
|
2030
2035
|
};
|
|
2031
|
-
var
|
|
2036
|
+
var placeholderPolicySet = new Set(Object.values(PLACEHOLDER_POLICY));
|
|
2032
2037
|
var warn = (message) => {
|
|
2033
2038
|
console.warn(`[intl-tel-input] ${message}`);
|
|
2034
2039
|
};
|
|
@@ -2074,30 +2079,48 @@ var _factory = (() => {
|
|
|
2074
2079
|
continue;
|
|
2075
2080
|
}
|
|
2076
2081
|
switch (key) {
|
|
2077
|
-
case "allowDropdown":
|
|
2078
2082
|
case "allowNumberExtensions":
|
|
2079
2083
|
case "allowPhonewords":
|
|
2080
2084
|
case "countrySearch":
|
|
2081
2085
|
case "dropdownAlwaysOpen":
|
|
2082
|
-
case "
|
|
2086
|
+
case "matchDropdownWidth":
|
|
2083
2087
|
case "formatAsYouType":
|
|
2084
|
-
case "formatOnDisplay":
|
|
2085
|
-
case "nationalMode":
|
|
2086
2088
|
case "showFlags":
|
|
2087
2089
|
case "separateDialCode":
|
|
2088
2090
|
case "strictMode":
|
|
2089
2091
|
case "strictRejectAnimation":
|
|
2090
|
-
case "useFullscreenPopup":
|
|
2091
2092
|
if (typeof value !== "boolean") {
|
|
2092
2093
|
warnOption(key, "a boolean", value);
|
|
2093
2094
|
break;
|
|
2094
2095
|
}
|
|
2095
2096
|
validatedOptions[key] = value;
|
|
2096
2097
|
break;
|
|
2097
|
-
case "
|
|
2098
|
-
if (typeof value !== "string" || !
|
|
2099
|
-
|
|
2100
|
-
|
|
2098
|
+
case "countrySelectorMode":
|
|
2099
|
+
if (typeof value !== "string" || !COUNTRY_SELECTOR_MODES.includes(value)) {
|
|
2100
|
+
warnOption(
|
|
2101
|
+
"countrySelectorMode",
|
|
2102
|
+
`one of ${COUNTRY_SELECTOR_MODES.map((m) => `"${m}"`).join(", ")}`,
|
|
2103
|
+
value
|
|
2104
|
+
);
|
|
2105
|
+
break;
|
|
2106
|
+
}
|
|
2107
|
+
validatedOptions[key] = value;
|
|
2108
|
+
break;
|
|
2109
|
+
case "numberDisplayFormat":
|
|
2110
|
+
if (typeof value !== "string" || value === NUMBER_FORMAT.RFC3966 || !(value === NUMBER_FORMAT.E164 || value === NUMBER_FORMAT.INTERNATIONAL || value === NUMBER_FORMAT.NATIONAL)) {
|
|
2111
|
+
warnOption(
|
|
2112
|
+
"numberDisplayFormat",
|
|
2113
|
+
'one of "E164", "INTERNATIONAL", "NATIONAL"',
|
|
2114
|
+
value
|
|
2115
|
+
);
|
|
2116
|
+
break;
|
|
2117
|
+
}
|
|
2118
|
+
validatedOptions[key] = value;
|
|
2119
|
+
break;
|
|
2120
|
+
case "placeholderNumberPolicy":
|
|
2121
|
+
if (typeof value !== "string" || !placeholderPolicySet.has(value)) {
|
|
2122
|
+
const validPolicies = Array.from(placeholderPolicySet).join(", ");
|
|
2123
|
+
warnOption("placeholderNumberPolicy", `one of ${validPolicies}`, value);
|
|
2101
2124
|
break;
|
|
2102
2125
|
}
|
|
2103
2126
|
validatedOptions[key] = value;
|
|
@@ -2123,8 +2146,8 @@ var _factory = (() => {
|
|
|
2123
2146
|
break;
|
|
2124
2147
|
}
|
|
2125
2148
|
case "customPlaceholder":
|
|
2126
|
-
case "
|
|
2127
|
-
case "
|
|
2149
|
+
case "hiddenInputs":
|
|
2150
|
+
case "initialCountryLookup":
|
|
2128
2151
|
case "loadUtils":
|
|
2129
2152
|
if (value !== null && !isFunction(value)) {
|
|
2130
2153
|
warnOption(key, "a function or null", value);
|
|
@@ -2132,9 +2155,9 @@ var _factory = (() => {
|
|
|
2132
2155
|
}
|
|
2133
2156
|
validatedOptions[key] = value;
|
|
2134
2157
|
break;
|
|
2135
|
-
case "
|
|
2158
|
+
case "dropdownParent":
|
|
2136
2159
|
if (value !== null && !isElLike(value)) {
|
|
2137
|
-
warnOption("
|
|
2160
|
+
warnOption("dropdownParent", "an HTMLElement or null", value);
|
|
2138
2161
|
break;
|
|
2139
2162
|
}
|
|
2140
2163
|
validatedOptions[key] = value;
|
|
@@ -2151,9 +2174,9 @@ var _factory = (() => {
|
|
|
2151
2174
|
}
|
|
2152
2175
|
break;
|
|
2153
2176
|
}
|
|
2154
|
-
case "
|
|
2177
|
+
case "uiTranslations":
|
|
2155
2178
|
if (value && !isPlainObject(value)) {
|
|
2156
|
-
warnOption("
|
|
2179
|
+
warnOption("uiTranslations", "an object", value);
|
|
2157
2180
|
break;
|
|
2158
2181
|
}
|
|
2159
2182
|
validatedOptions[key] = value;
|
|
@@ -2171,12 +2194,8 @@ var _factory = (() => {
|
|
|
2171
2194
|
break;
|
|
2172
2195
|
}
|
|
2173
2196
|
const lower = value.toLowerCase();
|
|
2174
|
-
if (lower &&
|
|
2175
|
-
warnOption(
|
|
2176
|
-
"initialCountry",
|
|
2177
|
-
"a valid iso2 country code or 'auto'",
|
|
2178
|
-
value
|
|
2179
|
-
);
|
|
2197
|
+
if (lower && !isIso2(lower)) {
|
|
2198
|
+
warnOption("initialCountry", "a valid iso2 country code", value);
|
|
2180
2199
|
break;
|
|
2181
2200
|
}
|
|
2182
2201
|
validatedOptions[key] = value;
|
|
@@ -2239,30 +2258,29 @@ var _factory = (() => {
|
|
|
2239
2258
|
}
|
|
2240
2259
|
};
|
|
2241
2260
|
var applyOptionSideEffects = (o) => {
|
|
2261
|
+
if (o.countrySelectorMode === COUNTRY_SELECTOR_MODE.AUTO) {
|
|
2262
|
+
o.countrySelectorMode = resolveAutoCountrySelectorMode();
|
|
2263
|
+
}
|
|
2242
2264
|
if (o.dropdownAlwaysOpen) {
|
|
2243
|
-
o.
|
|
2244
|
-
o.allowDropdown = true;
|
|
2265
|
+
o.countrySelectorMode = COUNTRY_SELECTOR_MODE.DROPDOWN;
|
|
2245
2266
|
}
|
|
2246
|
-
if (o.
|
|
2247
|
-
o.
|
|
2267
|
+
if (o.countrySelectorMode === COUNTRY_SELECTOR_MODE.FULLSCREEN) {
|
|
2268
|
+
o.matchDropdownWidth = false;
|
|
2248
2269
|
} else {
|
|
2249
2270
|
if (isNarrowViewport()) {
|
|
2250
|
-
o.
|
|
2271
|
+
o.matchDropdownWidth = true;
|
|
2251
2272
|
}
|
|
2252
2273
|
}
|
|
2253
2274
|
if (o.onlyCountries?.length === 1) {
|
|
2254
2275
|
o.initialCountry = o.onlyCountries[0];
|
|
2255
2276
|
}
|
|
2256
|
-
if (o.separateDialCode) {
|
|
2257
|
-
o.
|
|
2277
|
+
if (o.separateDialCode && o.numberDisplayFormat === NUMBER_FORMAT.NATIONAL) {
|
|
2278
|
+
o.numberDisplayFormat = NUMBER_FORMAT.INTERNATIONAL;
|
|
2258
2279
|
}
|
|
2259
|
-
if (o.
|
|
2260
|
-
o.
|
|
2280
|
+
if (o.countrySelectorMode !== COUNTRY_SELECTOR_MODE.OFF && !o.showFlags && !o.separateDialCode && o.numberDisplayFormat === NUMBER_FORMAT.NATIONAL) {
|
|
2281
|
+
o.numberDisplayFormat = NUMBER_FORMAT.INTERNATIONAL;
|
|
2261
2282
|
}
|
|
2262
|
-
|
|
2263
|
-
o.dropdownContainer = document.body;
|
|
2264
|
-
}
|
|
2265
|
-
o.i18n = { ...en_default, ...o.i18n };
|
|
2283
|
+
o.uiTranslations = { ...en_default, ...o.uiTranslations };
|
|
2266
2284
|
};
|
|
2267
2285
|
|
|
2268
2286
|
// packages/core/src/js/helpers/string.ts
|
|
@@ -2473,6 +2491,7 @@ var _factory = (() => {
|
|
|
2473
2491
|
};
|
|
2474
2492
|
|
|
2475
2493
|
// packages/core/src/js/core/ui.ts
|
|
2494
|
+
var supportsCssAnchor = typeof CSS !== "undefined" && typeof CSS.supports === "function" && CSS.supports("anchor-name: --x");
|
|
2476
2495
|
var UI = class _UI {
|
|
2477
2496
|
// private
|
|
2478
2497
|
#options;
|
|
@@ -2487,8 +2506,8 @@ var _factory = (() => {
|
|
|
2487
2506
|
#selectedCountryEl;
|
|
2488
2507
|
#selectedFlagEl;
|
|
2489
2508
|
#selectedDialCodeEl;
|
|
2490
|
-
#
|
|
2491
|
-
#
|
|
2509
|
+
#arrowEl;
|
|
2510
|
+
#countrySelectorEl;
|
|
2492
2511
|
#searchIconEl;
|
|
2493
2512
|
#searchInputEl;
|
|
2494
2513
|
#searchClearButtonEl;
|
|
@@ -2497,11 +2516,11 @@ var _factory = (() => {
|
|
|
2497
2516
|
#hiddenInputCountryEl;
|
|
2498
2517
|
#noResultsMessageEl;
|
|
2499
2518
|
#searchResultsLiveRegionEl;
|
|
2500
|
-
#
|
|
2519
|
+
#detachedCountrySelectorEl;
|
|
2501
2520
|
#selectedListItemEl = null;
|
|
2502
2521
|
#highlightedListItemEl = null;
|
|
2503
2522
|
#listItemByIso2 = /* @__PURE__ */ new Map();
|
|
2504
|
-
#
|
|
2523
|
+
#countrySelectorAbortController = null;
|
|
2505
2524
|
#resizeObserver;
|
|
2506
2525
|
// public
|
|
2507
2526
|
telInputEl;
|
|
@@ -2526,7 +2545,7 @@ var _factory = (() => {
|
|
|
2526
2545
|
);
|
|
2527
2546
|
}
|
|
2528
2547
|
}
|
|
2529
|
-
//* Generate all of the markup for the core library: the selected country overlay, and the
|
|
2548
|
+
//* Generate all of the markup for the core library: the selected country overlay, and the country selector.
|
|
2530
2549
|
buildMarkup(countries, searchTokens) {
|
|
2531
2550
|
this.#countries = countries;
|
|
2532
2551
|
this.#searchTokens = searchTokens;
|
|
@@ -2549,13 +2568,13 @@ var _factory = (() => {
|
|
|
2549
2568
|
this.ensureDropdownWidthSet();
|
|
2550
2569
|
}
|
|
2551
2570
|
#createWrapperAndInsert() {
|
|
2552
|
-
const {
|
|
2571
|
+
const { countrySelectorMode, showFlags, containerClass } = this.#options;
|
|
2553
2572
|
const parentClasses = buildClassNames({
|
|
2554
2573
|
iti: true,
|
|
2555
2574
|
"iti--input-container": true,
|
|
2556
|
-
"iti--
|
|
2575
|
+
"iti--has-country-selector": countrySelectorMode !== COUNTRY_SELECTOR_MODE.OFF,
|
|
2557
2576
|
"iti--show-flags": showFlags,
|
|
2558
|
-
"iti--inline-
|
|
2577
|
+
"iti--inline-country-selector": countrySelectorMode !== COUNTRY_SELECTOR_MODE.FULLSCREEN,
|
|
2559
2578
|
[containerClass]: Boolean(containerClass)
|
|
2560
2579
|
});
|
|
2561
2580
|
const wrapper = createEl("div", { class: parentClasses });
|
|
@@ -2566,8 +2585,9 @@ var _factory = (() => {
|
|
|
2566
2585
|
return wrapper;
|
|
2567
2586
|
}
|
|
2568
2587
|
#buildCountryContainer(wrapper) {
|
|
2569
|
-
const {
|
|
2570
|
-
|
|
2588
|
+
const { countrySelectorMode, separateDialCode, showFlags } = this.#options;
|
|
2589
|
+
const enableCountrySelector = countrySelectorMode !== COUNTRY_SELECTOR_MODE.OFF;
|
|
2590
|
+
if (!enableCountrySelector && !showFlags && !separateDialCode) {
|
|
2571
2591
|
return;
|
|
2572
2592
|
}
|
|
2573
2593
|
this.#countryContainerEl = createEl(
|
|
@@ -2576,16 +2596,16 @@ var _factory = (() => {
|
|
|
2576
2596
|
{ class: `iti__country-container ${CLASSES.V_HIDE}` },
|
|
2577
2597
|
wrapper
|
|
2578
2598
|
);
|
|
2579
|
-
if (
|
|
2599
|
+
if (enableCountrySelector) {
|
|
2580
2600
|
this.#selectedCountryEl = createEl(
|
|
2581
2601
|
"button",
|
|
2582
2602
|
{
|
|
2583
2603
|
type: "button",
|
|
2584
2604
|
class: "iti__selected-country",
|
|
2585
2605
|
[ARIA.EXPANDED]: "false",
|
|
2586
|
-
[ARIA.LABEL]: this.#options.
|
|
2606
|
+
[ARIA.LABEL]: this.#options.uiTranslations.noCountrySelected,
|
|
2587
2607
|
[ARIA.HASPOPUP]: "dialog",
|
|
2588
|
-
[ARIA.CONTROLS]: `iti-${this.#id}
|
|
2608
|
+
[ARIA.CONTROLS]: `iti-${this.#id}__country-selector`
|
|
2589
2609
|
},
|
|
2590
2610
|
this.#countryContainerEl
|
|
2591
2611
|
);
|
|
@@ -2609,8 +2629,8 @@ var _factory = (() => {
|
|
|
2609
2629
|
{ class: CLASSES.FLAG },
|
|
2610
2630
|
selectedCountryPrimary
|
|
2611
2631
|
);
|
|
2612
|
-
if (
|
|
2613
|
-
this.#
|
|
2632
|
+
if (enableCountrySelector) {
|
|
2633
|
+
this.#arrowEl = createEl(
|
|
2614
2634
|
"div",
|
|
2615
2635
|
{ class: "iti__arrow", [ARIA.HIDDEN]: "true" },
|
|
2616
2636
|
selectedCountryPrimary
|
|
@@ -2623,38 +2643,39 @@ var _factory = (() => {
|
|
|
2623
2643
|
this.#selectedCountryEl
|
|
2624
2644
|
);
|
|
2625
2645
|
}
|
|
2626
|
-
if (
|
|
2627
|
-
this.#
|
|
2646
|
+
if (enableCountrySelector) {
|
|
2647
|
+
this.#buildCountrySelector();
|
|
2628
2648
|
}
|
|
2629
2649
|
}
|
|
2630
2650
|
ensureDropdownWidthSet() {
|
|
2631
|
-
const {
|
|
2632
|
-
if (
|
|
2651
|
+
const { matchDropdownWidth, countrySelectorMode } = this.#options;
|
|
2652
|
+
if (countrySelectorMode === COUNTRY_SELECTOR_MODE.OFF || !matchDropdownWidth || this.#countrySelectorEl.style.width) {
|
|
2633
2653
|
return;
|
|
2634
2654
|
}
|
|
2635
2655
|
const inputWidth = this.telInputEl.offsetWidth;
|
|
2636
2656
|
if (inputWidth > 0) {
|
|
2637
|
-
this.#
|
|
2657
|
+
this.#countrySelectorEl.style.width = `${inputWidth}px`;
|
|
2638
2658
|
}
|
|
2639
2659
|
}
|
|
2640
|
-
#
|
|
2660
|
+
#buildCountrySelector() {
|
|
2641
2661
|
const {
|
|
2642
|
-
|
|
2643
|
-
|
|
2662
|
+
matchDropdownWidth,
|
|
2663
|
+
countrySelectorMode,
|
|
2644
2664
|
countrySearch,
|
|
2645
|
-
|
|
2646
|
-
dropdownContainer,
|
|
2665
|
+
uiTranslations,
|
|
2647
2666
|
containerClass
|
|
2648
2667
|
} = this.#options;
|
|
2649
|
-
const
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2668
|
+
const isFullscreen = countrySelectorMode === COUNTRY_SELECTOR_MODE.FULLSCREEN;
|
|
2669
|
+
const detachedParent = this.#getDetachedParent();
|
|
2670
|
+
const extraClasses = matchDropdownWidth ? "" : "iti--flexible-dropdown-width";
|
|
2671
|
+
this.#countrySelectorEl = createEl("div", {
|
|
2672
|
+
id: `iti-${this.#id}__country-selector`,
|
|
2673
|
+
class: `iti__country-selector ${CLASSES.HIDE} ${extraClasses}`,
|
|
2653
2674
|
role: "dialog",
|
|
2654
2675
|
[ARIA.MODAL]: "true"
|
|
2655
2676
|
});
|
|
2656
2677
|
if (this.#isRTL) {
|
|
2657
|
-
this.#
|
|
2678
|
+
this.#countrySelectorEl.setAttribute("dir", "rtl");
|
|
2658
2679
|
}
|
|
2659
2680
|
if (countrySearch) {
|
|
2660
2681
|
this.#buildSearchUI();
|
|
@@ -2665,40 +2686,54 @@ var _factory = (() => {
|
|
|
2665
2686
|
class: "iti__country-list",
|
|
2666
2687
|
id: `iti-${this.#id}__country-listbox`,
|
|
2667
2688
|
role: "listbox",
|
|
2668
|
-
[ARIA.LABEL]:
|
|
2689
|
+
[ARIA.LABEL]: uiTranslations.countryListAriaLabel
|
|
2669
2690
|
},
|
|
2670
|
-
this.#
|
|
2691
|
+
this.#countrySelectorEl
|
|
2671
2692
|
);
|
|
2672
2693
|
this.#appendListItems();
|
|
2673
2694
|
if (countrySearch) {
|
|
2674
2695
|
this.#updateSearchResultsA11yText();
|
|
2675
2696
|
}
|
|
2676
|
-
if (!
|
|
2697
|
+
if (!isFullscreen) {
|
|
2677
2698
|
this.#inlineDropdownHeight = this.#getHiddenInlineDropdownHeight();
|
|
2678
2699
|
if (countrySearch) {
|
|
2679
|
-
this.#
|
|
2700
|
+
this.#countrySelectorEl.style.height = `${this.#inlineDropdownHeight}px`;
|
|
2680
2701
|
}
|
|
2681
2702
|
}
|
|
2682
|
-
if (
|
|
2683
|
-
const
|
|
2703
|
+
if (detachedParent) {
|
|
2704
|
+
const wrapperClasses = buildClassNames({
|
|
2684
2705
|
iti: true,
|
|
2685
|
-
"iti--
|
|
2686
|
-
"iti--fullscreen-popup":
|
|
2687
|
-
"iti--inline-
|
|
2706
|
+
"iti--detached-country-selector": true,
|
|
2707
|
+
"iti--fullscreen-popup": isFullscreen,
|
|
2708
|
+
"iti--inline-country-selector": !isFullscreen,
|
|
2688
2709
|
[containerClass]: Boolean(containerClass)
|
|
2689
2710
|
});
|
|
2690
|
-
this.#
|
|
2691
|
-
this.#
|
|
2711
|
+
this.#detachedCountrySelectorEl = createEl("div", { class: wrapperClasses });
|
|
2712
|
+
this.#detachedCountrySelectorEl.appendChild(this.#countrySelectorEl);
|
|
2713
|
+
if (!isFullscreen) {
|
|
2714
|
+
this.#setupCssAnchorPositioning();
|
|
2715
|
+
}
|
|
2692
2716
|
} else {
|
|
2693
|
-
this.#countryContainerEl.appendChild(this.#
|
|
2717
|
+
this.#countryContainerEl.appendChild(this.#countrySelectorEl);
|
|
2694
2718
|
}
|
|
2695
2719
|
}
|
|
2720
|
+
//* Resolve the DOM element to attach the country selector to. Fullscreen always uses document.body; dropdown uses the consumer-supplied dropdownParent (if any); otherwise the country selector renders inline within the input wrapper (no detached element).
|
|
2721
|
+
#getDetachedParent() {
|
|
2722
|
+
const { countrySelectorMode, dropdownParent } = this.#options;
|
|
2723
|
+
if (countrySelectorMode === COUNTRY_SELECTOR_MODE.FULLSCREEN) {
|
|
2724
|
+
return document.body;
|
|
2725
|
+
}
|
|
2726
|
+
if (countrySelectorMode === COUNTRY_SELECTOR_MODE.DROPDOWN) {
|
|
2727
|
+
return dropdownParent;
|
|
2728
|
+
}
|
|
2729
|
+
return null;
|
|
2730
|
+
}
|
|
2696
2731
|
#buildSearchUI() {
|
|
2697
|
-
const {
|
|
2732
|
+
const { uiTranslations, searchInputClass } = this.#options;
|
|
2698
2733
|
const searchWrapper = createEl(
|
|
2699
2734
|
"div",
|
|
2700
2735
|
{ class: "iti__search-input-wrapper" },
|
|
2701
|
-
this.#
|
|
2736
|
+
this.#countrySelectorEl
|
|
2702
2737
|
);
|
|
2703
2738
|
this.#searchIconEl = createEl(
|
|
2704
2739
|
"span",
|
|
@@ -2716,11 +2751,11 @@ var _factory = (() => {
|
|
|
2716
2751
|
// Chrome says inputs need either a name or an id
|
|
2717
2752
|
type: "search",
|
|
2718
2753
|
class: `iti__search-input ${searchInputClass}`,
|
|
2719
|
-
placeholder:
|
|
2754
|
+
placeholder: uiTranslations.searchPlaceholder,
|
|
2720
2755
|
// 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
|
|
2721
2756
|
role: "combobox",
|
|
2722
2757
|
[ARIA.EXPANDED]: "true",
|
|
2723
|
-
[ARIA.LABEL]:
|
|
2758
|
+
[ARIA.LABEL]: uiTranslations.searchPlaceholder,
|
|
2724
2759
|
[ARIA.CONTROLS]: `iti-${this.#id}__country-listbox`,
|
|
2725
2760
|
[ARIA.AUTOCOMPLETE]: "list",
|
|
2726
2761
|
autocomplete: "off"
|
|
@@ -2732,7 +2767,7 @@ var _factory = (() => {
|
|
|
2732
2767
|
{
|
|
2733
2768
|
type: "button",
|
|
2734
2769
|
class: `iti__search-clear ${CLASSES.HIDE}`,
|
|
2735
|
-
[ARIA.LABEL]:
|
|
2770
|
+
[ARIA.LABEL]: uiTranslations.clearSearchAriaLabel,
|
|
2736
2771
|
tabindex: "-1"
|
|
2737
2772
|
},
|
|
2738
2773
|
searchWrapper
|
|
@@ -2741,7 +2776,7 @@ var _factory = (() => {
|
|
|
2741
2776
|
this.#searchResultsLiveRegionEl = createEl(
|
|
2742
2777
|
"span",
|
|
2743
2778
|
{ class: "iti__a11y-text" },
|
|
2744
|
-
this.#
|
|
2779
|
+
this.#countrySelectorEl
|
|
2745
2780
|
);
|
|
2746
2781
|
this.#noResultsMessageEl = createEl(
|
|
2747
2782
|
"div",
|
|
@@ -2750,9 +2785,9 @@ var _factory = (() => {
|
|
|
2750
2785
|
[ARIA.HIDDEN]: "true"
|
|
2751
2786
|
// all a11y messaging happens in this.#searchResultsLiveRegionEl
|
|
2752
2787
|
},
|
|
2753
|
-
this.#
|
|
2788
|
+
this.#countrySelectorEl
|
|
2754
2789
|
);
|
|
2755
|
-
this.#noResultsMessageEl.textContent =
|
|
2790
|
+
this.#noResultsMessageEl.textContent = uiTranslations.searchEmptyState ?? null;
|
|
2756
2791
|
}
|
|
2757
2792
|
#updateInputPaddingAndReveal() {
|
|
2758
2793
|
if (!this.#countryContainerEl) {
|
|
@@ -2762,12 +2797,12 @@ var _factory = (() => {
|
|
|
2762
2797
|
this.#countryContainerEl.classList.remove(CLASSES.V_HIDE);
|
|
2763
2798
|
}
|
|
2764
2799
|
#buildHiddenInputs(wrapper) {
|
|
2765
|
-
const {
|
|
2766
|
-
if (!
|
|
2800
|
+
const { hiddenInputs } = this.#options;
|
|
2801
|
+
if (!hiddenInputs) {
|
|
2767
2802
|
return;
|
|
2768
2803
|
}
|
|
2769
2804
|
const telInputName = this.telInputEl.getAttribute("name") || "";
|
|
2770
|
-
const names =
|
|
2805
|
+
const names = hiddenInputs(telInputName);
|
|
2771
2806
|
if (names.phone) {
|
|
2772
2807
|
const existingInput = this.telInputEl.form?.querySelector(
|
|
2773
2808
|
`input[name="${names.phone}"]`
|
|
@@ -2832,7 +2867,7 @@ var _factory = (() => {
|
|
|
2832
2867
|
//* Update the input padding to make space for (1) the selected country/globe, (2) the arrow, and (3) the separate dial code, all of which are optional, hence handling this in the JS rather than CSS.
|
|
2833
2868
|
#updateInputPadding() {
|
|
2834
2869
|
if (this.#selectedCountryEl) {
|
|
2835
|
-
const fallbackWidth = this.#options.separateDialCode ? LAYOUT.
|
|
2870
|
+
const fallbackWidth = this.#options.separateDialCode ? LAYOUT.FALLBACK_SELECTED_COUNTRY_WITH_DIAL_WIDTH : LAYOUT.FALLBACK_SELECTED_COUNTRY_NO_DIAL_WIDTH;
|
|
2836
2871
|
const selectedCountryWidth = this.#selectedCountryEl.offsetWidth || this.#getHiddenSelectedCountryWidth() || fallbackWidth;
|
|
2837
2872
|
const inputPadding = selectedCountryWidth + LAYOUT.INPUT_PADDING_EXTRA_LEFT;
|
|
2838
2873
|
this.telInputEl.style.paddingLeft = `${inputPadding}px`;
|
|
@@ -2886,24 +2921,24 @@ var _factory = (() => {
|
|
|
2886
2921
|
// Get the dropdown height (before it is added to the DOM)
|
|
2887
2922
|
#getHiddenInlineDropdownHeight() {
|
|
2888
2923
|
const body = _UI.#getBody();
|
|
2889
|
-
this.#
|
|
2924
|
+
this.#countrySelectorEl.classList.remove(CLASSES.HIDE);
|
|
2890
2925
|
const tempContainer = createEl("div", {
|
|
2891
|
-
class: "iti iti--inline-
|
|
2926
|
+
class: "iti iti--inline-country-selector"
|
|
2892
2927
|
});
|
|
2893
|
-
tempContainer.appendChild(this.#
|
|
2928
|
+
tempContainer.appendChild(this.#countrySelectorEl);
|
|
2894
2929
|
tempContainer.style.visibility = "hidden";
|
|
2895
2930
|
body.appendChild(tempContainer);
|
|
2896
|
-
const height = this.#
|
|
2931
|
+
const height = this.#countrySelectorEl.offsetHeight;
|
|
2897
2932
|
body.removeChild(tempContainer);
|
|
2898
2933
|
tempContainer.style.visibility = "";
|
|
2899
|
-
this.#
|
|
2934
|
+
this.#countrySelectorEl.classList.add(CLASSES.HIDE);
|
|
2900
2935
|
return height > 0 ? height : LAYOUT.FALLBACK_DROPDOWN_HEIGHT;
|
|
2901
2936
|
}
|
|
2902
2937
|
//* Update search results text (for a11y).
|
|
2903
2938
|
#updateSearchResultsA11yText() {
|
|
2904
|
-
const {
|
|
2939
|
+
const { uiTranslations } = this.#options;
|
|
2905
2940
|
const count = this.#countryListEl.childElementCount;
|
|
2906
|
-
this.#searchResultsLiveRegionEl.textContent =
|
|
2941
|
+
this.#searchResultsLiveRegionEl.textContent = uiTranslations.searchSummaryAria(count);
|
|
2907
2942
|
}
|
|
2908
2943
|
//* Country search: Filter the countries according to the search query.
|
|
2909
2944
|
#filterCountriesByQuery(query) {
|
|
@@ -2921,8 +2956,8 @@ var _factory = (() => {
|
|
|
2921
2956
|
this.#showFilteredCountries(matchedCountries);
|
|
2922
2957
|
}
|
|
2923
2958
|
//* Pre-fill the search input with "+" and show all countries
|
|
2924
|
-
//* (used when user types "+" in the phone input to open the
|
|
2925
|
-
//* Explicitly focus the search input (
|
|
2959
|
+
//* (used when user types "+" in the phone input to open the country selector).
|
|
2960
|
+
//* Explicitly focus the search input (openCountrySelector skips this when
|
|
2926
2961
|
//* dropdownAlwaysOpen, but here we need focus to redirect subsequent keystrokes).
|
|
2927
2962
|
prefillSearchWithPlus() {
|
|
2928
2963
|
this.#searchInputEl.value = "+";
|
|
@@ -3005,15 +3040,15 @@ var _factory = (() => {
|
|
|
3005
3040
|
{ signal }
|
|
3006
3041
|
);
|
|
3007
3042
|
}
|
|
3008
|
-
//* Wire up triggers that open/close the
|
|
3043
|
+
//* Wire up triggers that open/close the country selector: label click (focus input or swallow repeat click),
|
|
3009
3044
|
//* selected-country click (open), and keydown on countryContainer (open on arrow/space/enter, close on tab).
|
|
3010
|
-
|
|
3045
|
+
bindAllInitialCountrySelectorListeners(signal, onOpen, onClose) {
|
|
3011
3046
|
const label = this.telInputEl.closest("label");
|
|
3012
3047
|
if (label) {
|
|
3013
3048
|
label.addEventListener(
|
|
3014
3049
|
"click",
|
|
3015
3050
|
(e) => {
|
|
3016
|
-
if (!this.
|
|
3051
|
+
if (!this.isCountrySelectorOpen()) {
|
|
3017
3052
|
this.telInputEl.focus();
|
|
3018
3053
|
} else {
|
|
3019
3054
|
e.preventDefault();
|
|
@@ -3025,7 +3060,7 @@ var _factory = (() => {
|
|
|
3025
3060
|
this.#selectedCountryEl.addEventListener(
|
|
3026
3061
|
"click",
|
|
3027
3062
|
() => {
|
|
3028
|
-
if (!this.
|
|
3063
|
+
if (!this.isCountrySelectorOpen() && !this.telInputEl.disabled && !this.telInputEl.readOnly) {
|
|
3029
3064
|
onOpen();
|
|
3030
3065
|
}
|
|
3031
3066
|
},
|
|
@@ -3040,7 +3075,7 @@ var _factory = (() => {
|
|
|
3040
3075
|
KEYS.SPACE,
|
|
3041
3076
|
KEYS.ENTER
|
|
3042
3077
|
];
|
|
3043
|
-
if (!this.
|
|
3078
|
+
if (!this.isCountrySelectorOpen() && openKeys.includes(e.key)) {
|
|
3044
3079
|
e.preventDefault();
|
|
3045
3080
|
e.stopPropagation();
|
|
3046
3081
|
onOpen();
|
|
@@ -3052,24 +3087,24 @@ var _factory = (() => {
|
|
|
3052
3087
|
{ signal }
|
|
3053
3088
|
);
|
|
3054
3089
|
}
|
|
3055
|
-
//* Open the
|
|
3056
|
-
//*
|
|
3057
|
-
|
|
3058
|
-
const { countrySearch, dropdownAlwaysOpen
|
|
3059
|
-
this.#
|
|
3090
|
+
//* Open the country selector: create a fresh AbortController, do the DOM work, and wire up all
|
|
3091
|
+
//* open-state listeners (which invoke the caller's onSelect / onClose callbacks).
|
|
3092
|
+
openCountrySelector(onSelect, onClose) {
|
|
3093
|
+
const { countrySearch, dropdownAlwaysOpen } = this.#options;
|
|
3094
|
+
this.#countrySelectorAbortController = new AbortController();
|
|
3060
3095
|
this.ensureDropdownWidthSet();
|
|
3061
|
-
if (
|
|
3062
|
-
this.#
|
|
3096
|
+
if (this.#detachedCountrySelectorEl) {
|
|
3097
|
+
this.#injectAndPositionDetachedCountrySelector();
|
|
3063
3098
|
} else {
|
|
3064
|
-
const positionBelow = this.#
|
|
3099
|
+
const positionBelow = this.#shouldPositionDropdownBelowInput();
|
|
3065
3100
|
const distance = this.telInputEl.offsetHeight + LAYOUT.DROPDOWN_MARGIN;
|
|
3066
3101
|
if (positionBelow) {
|
|
3067
|
-
this.#
|
|
3102
|
+
this.#countrySelectorEl.style.top = `${distance}px`;
|
|
3068
3103
|
} else {
|
|
3069
|
-
this.#
|
|
3104
|
+
this.#countrySelectorEl.style.bottom = `${distance}px`;
|
|
3070
3105
|
}
|
|
3071
3106
|
}
|
|
3072
|
-
this.#
|
|
3107
|
+
this.#countrySelectorEl.classList.remove(CLASSES.HIDE);
|
|
3073
3108
|
this.#selectedCountryEl.setAttribute(ARIA.EXPANDED, "true");
|
|
3074
3109
|
const itemToHighlight = this.#selectedListItemEl ?? this.#countryListEl.firstElementChild;
|
|
3075
3110
|
if (itemToHighlight) {
|
|
@@ -3078,7 +3113,7 @@ var _factory = (() => {
|
|
|
3078
3113
|
if (countrySearch && !dropdownAlwaysOpen) {
|
|
3079
3114
|
this.#searchInputEl.focus();
|
|
3080
3115
|
}
|
|
3081
|
-
if (this.#options.
|
|
3116
|
+
if (this.#options.countrySelectorMode === COUNTRY_SELECTOR_MODE.FULLSCREEN && this.#detachedCountrySelectorEl && window.visualViewport) {
|
|
3082
3117
|
window.visualViewport.addEventListener(
|
|
3083
3118
|
"resize",
|
|
3084
3119
|
() => {
|
|
@@ -3087,29 +3122,29 @@ var _factory = (() => {
|
|
|
3087
3122
|
this.#scrollCountryListToItem(this.#highlightedListItemEl);
|
|
3088
3123
|
}
|
|
3089
3124
|
},
|
|
3090
|
-
{ signal: this.#
|
|
3125
|
+
{ signal: this.#countrySelectorAbortController.signal }
|
|
3091
3126
|
);
|
|
3092
3127
|
}
|
|
3093
|
-
this.#
|
|
3094
|
-
this.#
|
|
3128
|
+
this.#arrowEl.classList.add(CLASSES.ARROW_UP);
|
|
3129
|
+
this.#bindCountrySelectorOpenListeners(onSelect, onClose);
|
|
3095
3130
|
}
|
|
3096
|
-
//* Wire up all listeners needed while the
|
|
3131
|
+
//* Wire up all listeners needed while the country selector is open: list-item hover (highlight),
|
|
3097
3132
|
//* list-item click & enter key (select), click-off & escape (close), search input (filter),
|
|
3098
|
-
//* (when countrySearch disabled) typed-char hidden search, and (when
|
|
3099
|
-
//* container)
|
|
3100
|
-
#
|
|
3101
|
-
const signal = this.#
|
|
3133
|
+
//* (when countrySearch disabled) typed-char hidden search, and (when the country selector is in an
|
|
3134
|
+
//* external container) update (fixed) position on scroll/resize.
|
|
3135
|
+
#bindCountrySelectorOpenListeners(onSelect, onClose) {
|
|
3136
|
+
const signal = this.#countrySelectorAbortController.signal;
|
|
3102
3137
|
this.#bindListItemHover(signal);
|
|
3103
3138
|
this.#bindListItemClick(signal, onSelect);
|
|
3104
3139
|
if (!this.#options.dropdownAlwaysOpen) {
|
|
3105
3140
|
this.#bindOutsideClickToClose(signal, onClose);
|
|
3106
3141
|
}
|
|
3107
|
-
this.#
|
|
3142
|
+
this.#bindCountrySelectorKeydownListener(signal, onSelect, onClose);
|
|
3108
3143
|
if (this.#options.countrySearch) {
|
|
3109
3144
|
this.#bindSearchInputListener(signal);
|
|
3110
3145
|
}
|
|
3111
|
-
if (
|
|
3112
|
-
|
|
3146
|
+
if (this.#options.countrySelectorMode === COUNTRY_SELECTOR_MODE.DROPDOWN && this.#options.dropdownParent && !supportsCssAnchor) {
|
|
3147
|
+
document.addEventListener("scroll", onClose, { signal, capture: true, passive: true });
|
|
3113
3148
|
}
|
|
3114
3149
|
}
|
|
3115
3150
|
//* When mouse over a list item, just highlight that one (so if they hit "enter" we know which to select).
|
|
@@ -3142,13 +3177,13 @@ var _factory = (() => {
|
|
|
3142
3177
|
{ signal }
|
|
3143
3178
|
);
|
|
3144
3179
|
}
|
|
3145
|
-
//* Invoke onClickOff when the user clicks anywhere outside the
|
|
3180
|
+
//* Invoke onClickOff when the user clicks anywhere outside the country selector.
|
|
3146
3181
|
#bindOutsideClickToClose(signal, onClickOff) {
|
|
3147
3182
|
setTimeout(() => {
|
|
3148
3183
|
document.documentElement.addEventListener(
|
|
3149
3184
|
"click",
|
|
3150
3185
|
(e) => {
|
|
3151
|
-
if (!this.#
|
|
3186
|
+
if (!this.#countrySelectorEl.contains(e.target)) {
|
|
3152
3187
|
onClickOff();
|
|
3153
3188
|
}
|
|
3154
3189
|
},
|
|
@@ -3156,11 +3191,10 @@ var _factory = (() => {
|
|
|
3156
3191
|
);
|
|
3157
3192
|
}, 0);
|
|
3158
3193
|
}
|
|
3159
|
-
//* Keyboard navigation while the
|
|
3160
|
-
//* and enter/escape invoke the caller's callbacks (which handle country selection /
|
|
3161
|
-
//* Listens on document because key events go there when no input has focus.
|
|
3194
|
+
//* Keyboard navigation while the country selector is open: arrow keys navigate, hidden-search keys filter,
|
|
3195
|
+
//* and enter/escape invoke the caller's callbacks (which handle country selection / close).
|
|
3162
3196
|
//* Uses keydown rather than keypress so non-char keys (arrow, esc) fire and so holding a key repeats.
|
|
3163
|
-
#
|
|
3197
|
+
#bindCountrySelectorKeydownListener(signal, onEnter, onEscape) {
|
|
3164
3198
|
let query = "";
|
|
3165
3199
|
let queryTimer = null;
|
|
3166
3200
|
const handleKeydown = (e) => {
|
|
@@ -3182,7 +3216,7 @@ var _factory = (() => {
|
|
|
3182
3216
|
this.#selectedCountryEl.focus();
|
|
3183
3217
|
}
|
|
3184
3218
|
}
|
|
3185
|
-
if (!this.#options.countrySearch &&
|
|
3219
|
+
if (!this.#options.countrySearch && REGEX.HIDDEN_SEARCH_CHAR.test(e.key)) {
|
|
3186
3220
|
e.stopPropagation();
|
|
3187
3221
|
if (queryTimer) {
|
|
3188
3222
|
clearTimeout(queryTimer);
|
|
@@ -3194,7 +3228,8 @@ var _factory = (() => {
|
|
|
3194
3228
|
}, TIMINGS.HIDDEN_SEARCH_RESET_MS);
|
|
3195
3229
|
}
|
|
3196
3230
|
};
|
|
3197
|
-
|
|
3231
|
+
this.#selectedCountryEl?.addEventListener("keydown", handleKeydown, { signal });
|
|
3232
|
+
this.#countrySelectorEl?.addEventListener("keydown", handleKeydown, { signal });
|
|
3198
3233
|
}
|
|
3199
3234
|
//* Wire up country search input listener: typing filters the list, the clear button resets it.
|
|
3200
3235
|
#bindSearchInputListener(signal) {
|
|
@@ -3231,7 +3266,7 @@ var _factory = (() => {
|
|
|
3231
3266
|
this.#highlightListItem(next);
|
|
3232
3267
|
}
|
|
3233
3268
|
}
|
|
3234
|
-
// Update the selected list item in the
|
|
3269
|
+
// Update the selected list item in the country list
|
|
3235
3270
|
#updateSelectedListItem(iso2) {
|
|
3236
3271
|
if (this.#selectedListItemEl && this.#selectedListItemEl.dataset[DATA_KEYS.ISO2] !== iso2) {
|
|
3237
3272
|
this.#selectedListItemEl.setAttribute(ARIA.SELECTED, "false");
|
|
@@ -3282,12 +3317,12 @@ var _factory = (() => {
|
|
|
3282
3317
|
this.#countryListEl.scrollTop = 0;
|
|
3283
3318
|
this.#updateSearchResultsA11yText();
|
|
3284
3319
|
}
|
|
3285
|
-
// UI: Close the
|
|
3286
|
-
|
|
3287
|
-
const { countrySearch
|
|
3288
|
-
this.#
|
|
3289
|
-
this.#
|
|
3290
|
-
this.#
|
|
3320
|
+
// UI: Close the country selector (DOM + abort scoped listeners).
|
|
3321
|
+
closeCountrySelector() {
|
|
3322
|
+
const { countrySearch } = this.#options;
|
|
3323
|
+
this.#countrySelectorAbortController.abort();
|
|
3324
|
+
this.#countrySelectorAbortController = null;
|
|
3325
|
+
this.#countrySelectorEl.classList.add(CLASSES.HIDE);
|
|
3291
3326
|
this.#selectedCountryEl.setAttribute(ARIA.EXPANDED, "false");
|
|
3292
3327
|
if (countrySearch) {
|
|
3293
3328
|
this.#searchInputEl.removeAttribute(ARIA.ACTIVE_DESCENDANT);
|
|
@@ -3298,19 +3333,19 @@ var _factory = (() => {
|
|
|
3298
3333
|
this.#highlightedListItemEl = null;
|
|
3299
3334
|
}
|
|
3300
3335
|
}
|
|
3301
|
-
this.#
|
|
3302
|
-
if (
|
|
3303
|
-
this.#
|
|
3304
|
-
this.#
|
|
3305
|
-
this.#
|
|
3306
|
-
this.#
|
|
3307
|
-
this.#
|
|
3336
|
+
this.#arrowEl.classList.remove(CLASSES.ARROW_UP);
|
|
3337
|
+
if (this.#detachedCountrySelectorEl) {
|
|
3338
|
+
this.#detachedCountrySelectorEl.remove();
|
|
3339
|
+
this.#detachedCountrySelectorEl.style.top = "";
|
|
3340
|
+
this.#detachedCountrySelectorEl.style.bottom = "";
|
|
3341
|
+
this.#detachedCountrySelectorEl.style.paddingLeft = "";
|
|
3342
|
+
this.#detachedCountrySelectorEl.style.paddingRight = "";
|
|
3308
3343
|
} else {
|
|
3309
|
-
this.#
|
|
3310
|
-
this.#
|
|
3344
|
+
this.#countrySelectorEl.style.top = "";
|
|
3345
|
+
this.#countrySelectorEl.style.bottom = "";
|
|
3311
3346
|
}
|
|
3312
3347
|
}
|
|
3313
|
-
#
|
|
3348
|
+
#shouldPositionDropdownBelowInput() {
|
|
3314
3349
|
if (this.#options.dropdownAlwaysOpen) {
|
|
3315
3350
|
return true;
|
|
3316
3351
|
}
|
|
@@ -3319,50 +3354,83 @@ var _factory = (() => {
|
|
|
3319
3354
|
const spaceBelow = window.innerHeight - inputPos.bottom;
|
|
3320
3355
|
return spaceBelow >= this.#inlineDropdownHeight || spaceBelow >= spaceAbove;
|
|
3321
3356
|
}
|
|
3322
|
-
// inject
|
|
3323
|
-
#
|
|
3324
|
-
const
|
|
3325
|
-
|
|
3357
|
+
// inject the country selector into its detached wrapper and apply positioning styles
|
|
3358
|
+
#injectAndPositionDetachedCountrySelector() {
|
|
3359
|
+
const isFullscreen = this.#options.countrySelectorMode === COUNTRY_SELECTOR_MODE.FULLSCREEN;
|
|
3360
|
+
const detachedParent = this.#getDetachedParent();
|
|
3361
|
+
if (isFullscreen) {
|
|
3326
3362
|
if (window.innerWidth >= LAYOUT.NARROW_VIEWPORT_WIDTH) {
|
|
3327
3363
|
const inputPos = this.telInputEl.getBoundingClientRect();
|
|
3328
|
-
this.#
|
|
3329
|
-
this.#
|
|
3364
|
+
this.#detachedCountrySelectorEl.style.paddingLeft = `${inputPos.left}px`;
|
|
3365
|
+
this.#detachedCountrySelectorEl.style.paddingRight = `${window.innerWidth - inputPos.right}px`;
|
|
3330
3366
|
}
|
|
3331
|
-
} else {
|
|
3367
|
+
} else if (!supportsCssAnchor) {
|
|
3332
3368
|
const inputPos = this.telInputEl.getBoundingClientRect();
|
|
3333
|
-
this.#
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
this.#detachedDropdownEl.style.top = `${inputPos.bottom + LAYOUT.DROPDOWN_MARGIN}px`;
|
|
3369
|
+
this.#detachedCountrySelectorEl.style.left = `${inputPos.left}px`;
|
|
3370
|
+
if (this.#shouldPositionDropdownBelowInput()) {
|
|
3371
|
+
this.#detachedCountrySelectorEl.style.top = `${inputPos.bottom + LAYOUT.DROPDOWN_MARGIN}px`;
|
|
3337
3372
|
} else {
|
|
3338
|
-
this.#
|
|
3339
|
-
this.#
|
|
3373
|
+
this.#detachedCountrySelectorEl.style.top = "unset";
|
|
3374
|
+
this.#detachedCountrySelectorEl.style.bottom = `${window.innerHeight - inputPos.top + LAYOUT.DROPDOWN_MARGIN}px`;
|
|
3340
3375
|
}
|
|
3341
3376
|
}
|
|
3342
|
-
|
|
3377
|
+
detachedParent.appendChild(this.#detachedCountrySelectorEl);
|
|
3378
|
+
}
|
|
3379
|
+
//* Wire up CSS Anchor Positioning between the input and the detached country selector using a
|
|
3380
|
+
//* unique anchor name per instance. Called once at build time — the matching styles in
|
|
3381
|
+
//* intlTelInput.css only take effect in browsers that support anchor(); elsewhere these
|
|
3382
|
+
//* properties are inert. We append our name to any existing anchor-name (read via
|
|
3383
|
+
//* getComputedStyle so we pick up CSS-defined values), so consumer-set anchors on the input
|
|
3384
|
+
//* are preserved. Caveat: this snapshots the consumer's value once — if they later change
|
|
3385
|
+
//* anchor-name via CSS (e.g. a class swap), our inline write will shadow the change.
|
|
3386
|
+
#setupCssAnchorPositioning() {
|
|
3387
|
+
const anchorName = `--iti-anchor-${this.#id}`;
|
|
3388
|
+
const existing = getComputedStyle(this.telInputEl).anchorName;
|
|
3389
|
+
this.telInputEl.style.anchorName = existing && existing !== "none" ? `${existing}, ${anchorName}` : anchorName;
|
|
3390
|
+
this.#detachedCountrySelectorEl.style.positionAnchor = anchorName;
|
|
3343
3391
|
}
|
|
3344
3392
|
// Adjust the fullscreen popup dimensions to match the visual viewport,
|
|
3345
3393
|
// so it stays above the virtual keyboard on mobile devices.
|
|
3346
3394
|
#adjustFullscreenPopupToViewport() {
|
|
3347
3395
|
const vv = window.visualViewport;
|
|
3348
|
-
if (!vv || !this.#
|
|
3396
|
+
if (!vv || !this.#detachedCountrySelectorEl) {
|
|
3349
3397
|
return;
|
|
3350
3398
|
}
|
|
3351
3399
|
const virtualKeyboardHeight = window.innerHeight - vv.height;
|
|
3352
|
-
this.#
|
|
3400
|
+
this.#detachedCountrySelectorEl.style.bottom = `${virtualKeyboardHeight}px`;
|
|
3353
3401
|
}
|
|
3354
|
-
// UI: Whether the
|
|
3355
|
-
|
|
3356
|
-
return !this.#
|
|
3402
|
+
// UI: Whether the country selector is currently open (visible).
|
|
3403
|
+
isCountrySelectorOpen() {
|
|
3404
|
+
return !this.#countrySelectorEl.classList.contains(CLASSES.HIDE);
|
|
3357
3405
|
}
|
|
3358
3406
|
// Toggle the loading spinner on the selected flag (used during auto-country geoIP lookup).
|
|
3359
3407
|
setLoading(isLoading) {
|
|
3360
3408
|
this.#selectedFlagEl.classList.toggle(CLASSES.LOADING, isLoading);
|
|
3361
3409
|
}
|
|
3410
|
+
//* Play the strict-reject animation (shake, or background-colour flash under prefers-reduced-motion) on the wrapper.
|
|
3411
|
+
//* Called when strictMode rejects the whole input (keystroke, or whole paste).
|
|
3412
|
+
//* Uses the wrapper (not the input) so any separateDialCode / country button move together with the input.
|
|
3413
|
+
playStrictRejectAnimation() {
|
|
3414
|
+
if (!this.#options.strictRejectAnimation) {
|
|
3415
|
+
return;
|
|
3416
|
+
}
|
|
3417
|
+
const wrapperEl = this.telInputEl.parentElement;
|
|
3418
|
+
if (!wrapperEl) {
|
|
3419
|
+
return;
|
|
3420
|
+
}
|
|
3421
|
+
wrapperEl.classList.remove(CLASSES.STRICT_REJECT_ANIMATION);
|
|
3422
|
+
void wrapperEl.offsetWidth;
|
|
3423
|
+
wrapperEl.classList.add(CLASSES.STRICT_REJECT_ANIMATION);
|
|
3424
|
+
wrapperEl.addEventListener(
|
|
3425
|
+
"animationend",
|
|
3426
|
+
() => wrapperEl.classList.remove(CLASSES.STRICT_REJECT_ANIMATION),
|
|
3427
|
+
{ once: true }
|
|
3428
|
+
);
|
|
3429
|
+
}
|
|
3362
3430
|
isLoading() {
|
|
3363
3431
|
return this.#selectedFlagEl.classList.contains(CLASSES.LOADING);
|
|
3364
3432
|
}
|
|
3365
|
-
// Set the disabled state of the input and
|
|
3433
|
+
// Set the disabled state of the input and country selector.
|
|
3366
3434
|
setDisabled(disabled) {
|
|
3367
3435
|
this.telInputEl.disabled = disabled;
|
|
3368
3436
|
if (this.#selectedCountryEl) {
|
|
@@ -3373,7 +3441,7 @@ var _factory = (() => {
|
|
|
3373
3441
|
}
|
|
3374
3442
|
}
|
|
3375
3443
|
}
|
|
3376
|
-
// Set the readonly state of the input and
|
|
3444
|
+
// Set the readonly state of the input and country selector.
|
|
3377
3445
|
setReadonly(readonly) {
|
|
3378
3446
|
this.telInputEl.readOnly = readonly;
|
|
3379
3447
|
if (this.#selectedCountryEl) {
|
|
@@ -3384,12 +3452,12 @@ var _factory = (() => {
|
|
|
3384
3452
|
}
|
|
3385
3453
|
}
|
|
3386
3454
|
}
|
|
3387
|
-
|
|
3388
|
-
const {
|
|
3389
|
-
const name =
|
|
3390
|
-
const dialCode =
|
|
3391
|
-
const iso2 =
|
|
3392
|
-
if (
|
|
3455
|
+
setSelectedCountry(selectedCountry) {
|
|
3456
|
+
const { countrySelectorMode, showFlags, separateDialCode, uiTranslations } = this.#options;
|
|
3457
|
+
const name = selectedCountry?.name;
|
|
3458
|
+
const dialCode = selectedCountry?.dialCode;
|
|
3459
|
+
const iso2 = selectedCountry?.iso2 ?? "";
|
|
3460
|
+
if (countrySelectorMode !== COUNTRY_SELECTOR_MODE.OFF) {
|
|
3393
3461
|
this.#updateSelectedListItem(iso2);
|
|
3394
3462
|
}
|
|
3395
3463
|
if (this.#selectedCountryEl) {
|
|
@@ -3398,13 +3466,13 @@ var _factory = (() => {
|
|
|
3398
3466
|
let flagContent = null;
|
|
3399
3467
|
if (iso2) {
|
|
3400
3468
|
title = name;
|
|
3401
|
-
ariaLabel =
|
|
3469
|
+
ariaLabel = uiTranslations.selectedCountryAriaLabel.replace("${countryName}", name).replace("${dialCode}", `+${dialCode}`);
|
|
3402
3470
|
if (!showFlags) {
|
|
3403
3471
|
flagContent = buildGlobeIcon();
|
|
3404
3472
|
}
|
|
3405
3473
|
} else {
|
|
3406
|
-
title =
|
|
3407
|
-
ariaLabel =
|
|
3474
|
+
title = uiTranslations.noCountrySelected;
|
|
3475
|
+
ariaLabel = uiTranslations.noCountrySelected;
|
|
3408
3476
|
flagContent = buildGlobeIcon();
|
|
3409
3477
|
}
|
|
3410
3478
|
this.#selectedFlagEl.className = flagClass;
|
|
@@ -3553,17 +3621,17 @@ var _factory = (() => {
|
|
|
3553
3621
|
};
|
|
3554
3622
|
|
|
3555
3623
|
// packages/core/src/js/format/formatting.ts
|
|
3556
|
-
var stripSeparateDialCode = (fullNumber, hasValidDialCode, separateDialCode,
|
|
3624
|
+
var stripSeparateDialCode = (fullNumber, hasValidDialCode, separateDialCode, selectedCountry) => {
|
|
3557
3625
|
if (!separateDialCode || !hasValidDialCode) {
|
|
3558
3626
|
return fullNumber;
|
|
3559
3627
|
}
|
|
3560
|
-
const dialCode = `+${
|
|
3628
|
+
const dialCode = `+${selectedCountry.dialCode}`;
|
|
3561
3629
|
const start = fullNumber[dialCode.length] === " " || fullNumber[dialCode.length] === "-" ? dialCode.length + 1 : dialCode.length;
|
|
3562
3630
|
return fullNumber.substring(start);
|
|
3563
3631
|
};
|
|
3564
|
-
var formatNumberAsYouType = (fullNumber, telInputValue, utils,
|
|
3565
|
-
const result = utils ? utils.formatNumberAsYouType(fullNumber,
|
|
3566
|
-
const dialCode =
|
|
3632
|
+
var formatNumberAsYouType = (fullNumber, telInputValue, utils, selectedCountry, separateDialCode) => {
|
|
3633
|
+
const result = utils ? utils.formatNumberAsYouType(fullNumber, selectedCountry?.iso2) : fullNumber;
|
|
3634
|
+
const dialCode = selectedCountry?.dialCode;
|
|
3567
3635
|
if (separateDialCode && telInputValue.charAt(0) !== "+" && result.includes(`+${dialCode}`)) {
|
|
3568
3636
|
const afterDialCode = result.split(`+${dialCode}`)[1] || "";
|
|
3569
3637
|
return afterDialCode.trim();
|
|
@@ -3694,8 +3762,8 @@ var _factory = (() => {
|
|
|
3694
3762
|
this.#ui.telInputEl.value = this.#numerals.denormalise(asciiValue);
|
|
3695
3763
|
}
|
|
3696
3764
|
#createInitPromise(options) {
|
|
3697
|
-
const { initialCountry,
|
|
3698
|
-
const needsAutoCountryDeferred = initialCountry
|
|
3765
|
+
const { initialCountry, initialCountryLookup, loadUtils } = options;
|
|
3766
|
+
const needsAutoCountryDeferred = !initialCountry && Boolean(initialCountryLookup);
|
|
3699
3767
|
const needsUtilsDeferred = Boolean(loadUtils) && !intlTelInput.utils;
|
|
3700
3768
|
if (needsAutoCountryDeferred) {
|
|
3701
3769
|
this.#autoCountryDeferred = createDeferred();
|
|
@@ -3717,7 +3785,7 @@ var _factory = (() => {
|
|
|
3717
3785
|
this.#initListeners();
|
|
3718
3786
|
this.#startAsyncLoads();
|
|
3719
3787
|
if (this.#options.dropdownAlwaysOpen) {
|
|
3720
|
-
this
|
|
3788
|
+
this.openCountrySelector();
|
|
3721
3789
|
}
|
|
3722
3790
|
}
|
|
3723
3791
|
//********************
|
|
@@ -3740,8 +3808,8 @@ var _factory = (() => {
|
|
|
3740
3808
|
const value = useAttribute ? attributeValue : inputValue;
|
|
3741
3809
|
const dialCode = this.#getDialCode(value);
|
|
3742
3810
|
const isRegionlessNanpNumber = isRegionlessNanp(value);
|
|
3743
|
-
const { initialCountry,
|
|
3744
|
-
const isAutoCountry = initialCountry
|
|
3811
|
+
const { initialCountry, initialCountryLookup } = this.#options;
|
|
3812
|
+
const isAutoCountry = !initialCountry && Boolean(initialCountryLookup);
|
|
3745
3813
|
const resolvedInitialCountry = isAutoCountry && intlTelInput.autoCountry ? intlTelInput.autoCountry : initialCountry;
|
|
3746
3814
|
const doingAutoCountryLookup = isAutoCountry && !overrideAutoCountry && !intlTelInput.autoCountry;
|
|
3747
3815
|
const isValidInitialCountry = isIso2(resolvedInitialCountry);
|
|
@@ -3770,11 +3838,11 @@ var _factory = (() => {
|
|
|
3770
3838
|
//* Initialise the main event listeners: input keyup, and click selected country.
|
|
3771
3839
|
#initListeners() {
|
|
3772
3840
|
this.#bindAllTelInputListeners();
|
|
3773
|
-
if (this.#options.
|
|
3774
|
-
this.#ui.
|
|
3841
|
+
if (this.#options.countrySelectorMode !== COUNTRY_SELECTOR_MODE.OFF) {
|
|
3842
|
+
this.#ui.bindAllInitialCountrySelectorListeners(
|
|
3775
3843
|
this.#abortController.signal,
|
|
3776
|
-
() => this
|
|
3777
|
-
() => this.#
|
|
3844
|
+
() => this.openCountrySelector(),
|
|
3845
|
+
() => this.#closeCountrySelectorInternal()
|
|
3778
3846
|
);
|
|
3779
3847
|
}
|
|
3780
3848
|
this.#ui.bindHiddenInputSubmitListener(
|
|
@@ -3783,7 +3851,7 @@ var _factory = (() => {
|
|
|
3783
3851
|
() => this.#selectedCountry?.iso2 || ""
|
|
3784
3852
|
);
|
|
3785
3853
|
}
|
|
3786
|
-
//* Init requests: utils script /
|
|
3854
|
+
//* Init requests: utils script / initial country lookup.
|
|
3787
3855
|
#startAsyncLoads() {
|
|
3788
3856
|
if (this.#utilsDeferred) {
|
|
3789
3857
|
const { loadUtils } = this.#options;
|
|
@@ -3807,7 +3875,7 @@ var _factory = (() => {
|
|
|
3807
3875
|
}
|
|
3808
3876
|
}
|
|
3809
3877
|
}
|
|
3810
|
-
//* Perform the
|
|
3878
|
+
//* Perform the initial country lookup.
|
|
3811
3879
|
async #loadAutoCountry() {
|
|
3812
3880
|
if (intlTelInput.autoCountry) {
|
|
3813
3881
|
this.#handleAutoCountryLoaded();
|
|
@@ -3818,14 +3886,14 @@ var _factory = (() => {
|
|
|
3818
3886
|
return;
|
|
3819
3887
|
}
|
|
3820
3888
|
intlTelInput.startedLoadingAutoCountry = true;
|
|
3821
|
-
if (typeof this.#options.
|
|
3889
|
+
if (typeof this.#options.initialCountryLookup === "function") {
|
|
3822
3890
|
let timeoutId;
|
|
3823
3891
|
try {
|
|
3824
3892
|
const iso2 = await Promise.race([
|
|
3825
|
-
this.#options.
|
|
3893
|
+
this.#options.initialCountryLookup(),
|
|
3826
3894
|
new Promise((_, reject) => {
|
|
3827
3895
|
timeoutId = setTimeout(
|
|
3828
|
-
() => reject(new Error("intl-tel-input:
|
|
3896
|
+
() => reject(new Error("intl-tel-input: initialCountryLookup timed out after 10s")),
|
|
3829
3897
|
1e4
|
|
3830
3898
|
);
|
|
3831
3899
|
})
|
|
@@ -3848,8 +3916,8 @@ var _factory = (() => {
|
|
|
3848
3916
|
}
|
|
3849
3917
|
}
|
|
3850
3918
|
}
|
|
3851
|
-
#
|
|
3852
|
-
this
|
|
3919
|
+
#openCountrySelectorWithPlus() {
|
|
3920
|
+
this.openCountrySelector();
|
|
3853
3921
|
this.#ui.prefillSearchWithPlus();
|
|
3854
3922
|
}
|
|
3855
3923
|
//* Delete the character just typed (the one immediately before the caret). Used by Android workarounds where we can't preventDefault on keydown.
|
|
@@ -3869,13 +3937,13 @@ var _factory = (() => {
|
|
|
3869
3937
|
//* Android workaround for handling plus when separateDialCode enabled (as impossible to handle with keydown/keyup, for which e.key always returns "Unidentified", see https://stackoverflow.com/q/59584061/217866)
|
|
3870
3938
|
#handleAndroidPlusKey(inputValue) {
|
|
3871
3939
|
this.#removeJustTypedChar(inputValue);
|
|
3872
|
-
this.#
|
|
3940
|
+
this.#openCountrySelectorWithPlus();
|
|
3873
3941
|
}
|
|
3874
3942
|
//* Android strictMode workaround: the keydown-based filter can't block these because e.key is "Unidentified" on Android virtual keyboards, so strip them here on input.
|
|
3875
3943
|
#handleAndroidStrictReject(inputValue, rejectedInput) {
|
|
3876
3944
|
const newCaretPos = this.#removeJustTypedChar(inputValue);
|
|
3877
3945
|
this.#ui.telInputEl.setSelectionRange(newCaretPos, newCaretPos);
|
|
3878
|
-
this.#playStrictRejectAnimation();
|
|
3946
|
+
this.#ui.playStrictRejectAnimation();
|
|
3879
3947
|
this.#dispatchEvent(EVENTS.STRICT_REJECT, {
|
|
3880
3948
|
source: "key",
|
|
3881
3949
|
rejectedInput,
|
|
@@ -3939,7 +4007,7 @@ var _factory = (() => {
|
|
|
3939
4007
|
strictMode,
|
|
3940
4008
|
formatAsYouType,
|
|
3941
4009
|
separateDialCode,
|
|
3942
|
-
|
|
4010
|
+
countrySelectorMode,
|
|
3943
4011
|
countrySearch
|
|
3944
4012
|
} = this.#options;
|
|
3945
4013
|
const detail = e?.detail;
|
|
@@ -3949,7 +4017,7 @@ var _factory = (() => {
|
|
|
3949
4017
|
let inputValue = this.#getTelInputValue();
|
|
3950
4018
|
const isPaste = e?.inputType === INPUT_TYPES.PASTE;
|
|
3951
4019
|
const isStrictPaste = strictMode && isPaste;
|
|
3952
|
-
if (this.#isAndroid && !isPaste && e?.data === "+" && separateDialCode &&
|
|
4020
|
+
if (this.#isAndroid && !isPaste && e?.data === "+" && separateDialCode && countrySelectorMode !== COUNTRY_SELECTOR_MODE.OFF && countrySearch) {
|
|
3953
4021
|
this.#handleAndroidPlusKey(inputValue);
|
|
3954
4022
|
return;
|
|
3955
4023
|
}
|
|
@@ -3996,13 +4064,13 @@ var _factory = (() => {
|
|
|
3996
4064
|
//* On keydown event: (1) if strictMode then prevent invalid characters, (2) if separateDialCode then handle plus key
|
|
3997
4065
|
//* Note that this fires BEFORE the input is updated.
|
|
3998
4066
|
#handleKeydownEvent = (e) => {
|
|
3999
|
-
const { strictMode, separateDialCode,
|
|
4067
|
+
const { strictMode, separateDialCode, countrySelectorMode, countrySearch } = this.#options;
|
|
4000
4068
|
if (!e.key || e.key.length !== 1 || e.altKey || e.ctrlKey || e.metaKey) {
|
|
4001
4069
|
return;
|
|
4002
4070
|
}
|
|
4003
|
-
if (separateDialCode &&
|
|
4071
|
+
if (separateDialCode && countrySelectorMode !== COUNTRY_SELECTOR_MODE.OFF && countrySearch && e.key === "+") {
|
|
4004
4072
|
e.preventDefault();
|
|
4005
|
-
this.#
|
|
4073
|
+
this.#openCountrySelectorWithPlus();
|
|
4006
4074
|
return;
|
|
4007
4075
|
}
|
|
4008
4076
|
if (!strictMode) {
|
|
@@ -4032,7 +4100,7 @@ var _factory = (() => {
|
|
|
4032
4100
|
const newCountry = this.#resolveCountryChangeFromNumber(newFullNumber);
|
|
4033
4101
|
const isChangingDialCode = newCountry !== null;
|
|
4034
4102
|
if (!isAllowedChar || hasExceededMaxLength && !isChangingDialCode && !isInitialPlus) {
|
|
4035
|
-
this.#playStrictRejectAnimation();
|
|
4103
|
+
this.#ui.playStrictRejectAnimation();
|
|
4036
4104
|
this.#dispatchEvent(EVENTS.STRICT_REJECT, {
|
|
4037
4105
|
source: "key",
|
|
4038
4106
|
rejectedInput: e.key,
|
|
@@ -4087,7 +4155,7 @@ var _factory = (() => {
|
|
|
4087
4155
|
let newValue = before + sanitised + after;
|
|
4088
4156
|
let rejectReason = sanitised !== pasted ? "invalid" : null;
|
|
4089
4157
|
if (newValue.length > 30) {
|
|
4090
|
-
this.#playStrictRejectAnimation();
|
|
4158
|
+
this.#ui.playStrictRejectAnimation();
|
|
4091
4159
|
this.#dispatchEvent(EVENTS.STRICT_REJECT, {
|
|
4092
4160
|
source: "paste",
|
|
4093
4161
|
rejectedInput: pastedRaw,
|
|
@@ -4103,7 +4171,7 @@ var _factory = (() => {
|
|
|
4103
4171
|
coreNumber = intlTelInput.utils.getCoreNumber(newValue, iso2);
|
|
4104
4172
|
}
|
|
4105
4173
|
if (!coreNumber) {
|
|
4106
|
-
this.#playStrictRejectAnimation();
|
|
4174
|
+
this.#ui.playStrictRejectAnimation();
|
|
4107
4175
|
this.#dispatchEvent(EVENTS.STRICT_REJECT, {
|
|
4108
4176
|
source: "paste",
|
|
4109
4177
|
rejectedInput: pastedRaw,
|
|
@@ -4118,7 +4186,7 @@ var _factory = (() => {
|
|
|
4118
4186
|
newValue = newValue.slice(0, newValue.length - trimLength);
|
|
4119
4187
|
rejectReason = "max-length";
|
|
4120
4188
|
} else {
|
|
4121
|
-
this.#playStrictRejectAnimation();
|
|
4189
|
+
this.#ui.playStrictRejectAnimation();
|
|
4122
4190
|
this.#dispatchEvent(EVENTS.STRICT_REJECT, {
|
|
4123
4191
|
source: "paste",
|
|
4124
4192
|
rejectedInput: pastedRaw,
|
|
@@ -4134,7 +4202,7 @@ var _factory = (() => {
|
|
|
4134
4202
|
input.setSelectionRange(caretPos, caretPos);
|
|
4135
4203
|
if (rejectReason) {
|
|
4136
4204
|
if (pasted.length > 0 && sanitised.length === 0) {
|
|
4137
|
-
this.#playStrictRejectAnimation();
|
|
4205
|
+
this.#ui.playStrictRejectAnimation();
|
|
4138
4206
|
}
|
|
4139
4207
|
this.#dispatchEvent(EVENTS.STRICT_REJECT, {
|
|
4140
4208
|
source: "paste",
|
|
@@ -4156,21 +4224,6 @@ var _factory = (() => {
|
|
|
4156
4224
|
const max = Number(this.#ui.telInputEl.getAttribute("maxlength"));
|
|
4157
4225
|
return max && number.length > max ? number.substring(0, max) : number;
|
|
4158
4226
|
}
|
|
4159
|
-
//* Play the strict-reject animation (shake, or background-colour flash under prefers-reduced-motion) on the wrapper.
|
|
4160
|
-
//* Called when strictMode rejects the whole input (keystroke, or whole paste).
|
|
4161
|
-
//* Uses the wrapper (not the input) so any separateDialCode / country button move together with the input.
|
|
4162
|
-
#playStrictRejectAnimation() {
|
|
4163
|
-
if (!this.#options.strictRejectAnimation) {
|
|
4164
|
-
return;
|
|
4165
|
-
}
|
|
4166
|
-
const wrapperEl = this.#ui.telInputEl.parentElement;
|
|
4167
|
-
if (!wrapperEl) {
|
|
4168
|
-
return;
|
|
4169
|
-
}
|
|
4170
|
-
wrapperEl.classList.remove("iti__strict-reject-animation");
|
|
4171
|
-
void wrapperEl.offsetWidth;
|
|
4172
|
-
wrapperEl.classList.add("iti__strict-reject-animation");
|
|
4173
|
-
}
|
|
4174
4227
|
//* Trigger a custom event on the input (typed via ItiEventMap).
|
|
4175
4228
|
#dispatchEvent(name, detailProps = {}) {
|
|
4176
4229
|
const e = new CustomEvent(name, {
|
|
@@ -4180,27 +4233,36 @@ var _factory = (() => {
|
|
|
4180
4233
|
});
|
|
4181
4234
|
this.#ui.telInputEl.dispatchEvent(e);
|
|
4182
4235
|
}
|
|
4183
|
-
//* Open the
|
|
4184
|
-
//* and its listeners leak. Reachable via
|
|
4185
|
-
|
|
4186
|
-
|
|
4236
|
+
//* Open the country selector. Bail if already open — otherwise the existing AbortController gets overwritten
|
|
4237
|
+
//* and its listeners leak. Reachable via openCountrySelectorWithPlus when dropdownAlwaysOpen is set.
|
|
4238
|
+
//* Public so consumers can programmatically open the country selector.
|
|
4239
|
+
openCountrySelector() {
|
|
4240
|
+
if (this.#ui.isCountrySelectorOpen()) {
|
|
4187
4241
|
return;
|
|
4188
4242
|
}
|
|
4189
|
-
this.#ui.
|
|
4243
|
+
this.#ui.openCountrySelector(
|
|
4190
4244
|
(li) => this.#selectListItem(li),
|
|
4191
|
-
() => this.#
|
|
4245
|
+
() => this.#closeCountrySelectorInternal()
|
|
4192
4246
|
);
|
|
4193
|
-
this.#dispatchEvent(EVENTS.
|
|
4247
|
+
this.#dispatchEvent(EVENTS.OPEN_COUNTRY_SELECTOR);
|
|
4194
4248
|
}
|
|
4195
4249
|
//* Update the input's value to the given number (format first if possible)
|
|
4196
4250
|
//* NOTE: this is called from setInitialState, handleUtilsLoaded and setNumber.
|
|
4197
4251
|
#updateValueFromNumber(fullNumber) {
|
|
4198
|
-
const {
|
|
4252
|
+
const { numberDisplayFormat, separateDialCode } = this.#options;
|
|
4199
4253
|
let number = fullNumber;
|
|
4200
|
-
if (
|
|
4254
|
+
if (intlTelInput.utils && this.#selectedCountry) {
|
|
4201
4255
|
const isRegionless = hasRegionlessDialCode(fullNumber);
|
|
4202
|
-
const
|
|
4203
|
-
const
|
|
4256
|
+
const preserveUserNational = !number.startsWith("+") && !separateDialCode;
|
|
4257
|
+
const useNational = numberDisplayFormat === NUMBER_FORMAT.NATIONAL && !isRegionless || preserveUserNational;
|
|
4258
|
+
let format;
|
|
4259
|
+
if (useNational) {
|
|
4260
|
+
format = NUMBER_FORMAT.NATIONAL;
|
|
4261
|
+
} else if (numberDisplayFormat === NUMBER_FORMAT.E164 && !isRegionless) {
|
|
4262
|
+
format = NUMBER_FORMAT.E164;
|
|
4263
|
+
} else {
|
|
4264
|
+
format = NUMBER_FORMAT.INTERNATIONAL;
|
|
4265
|
+
}
|
|
4204
4266
|
number = intlTelInput.utils.formatNumber(
|
|
4205
4267
|
number,
|
|
4206
4268
|
this.#selectedCountry?.iso2,
|
|
@@ -4297,14 +4359,14 @@ var _factory = (() => {
|
|
|
4297
4359
|
return null;
|
|
4298
4360
|
}
|
|
4299
4361
|
//* Update the selected country, dial code (if separateDialCode), placeholder, title, and selected list item.
|
|
4300
|
-
//* Note: called from setInitialState, updateCountryFromNumber, selectListItem,
|
|
4362
|
+
//* Note: called from setInitialState, updateCountryFromNumber, selectListItem, setSelectedCountry.
|
|
4301
4363
|
#updateSelectedCountry(iso2) {
|
|
4302
4364
|
const prevIso2 = this.#selectedCountry?.iso2 || "";
|
|
4303
4365
|
this.#selectedCountry = iso2 ? this.#countryByIso2.get(iso2) : null;
|
|
4304
4366
|
if (this.#selectedCountry) {
|
|
4305
4367
|
this.#fallbackCountryIso2 = this.#selectedCountry.iso2;
|
|
4306
4368
|
}
|
|
4307
|
-
this.#ui.
|
|
4369
|
+
this.#ui.setSelectedCountry(this.#selectedCountry);
|
|
4308
4370
|
this.#updatePlaceholder();
|
|
4309
4371
|
this.#updateMaxCoreNumberLength();
|
|
4310
4372
|
return prevIso2 !== iso2;
|
|
@@ -4322,12 +4384,11 @@ var _factory = (() => {
|
|
|
4322
4384
|
}
|
|
4323
4385
|
let exampleNumber = intlTelInput.utils.getExampleNumber(
|
|
4324
4386
|
iso2,
|
|
4325
|
-
false,
|
|
4326
4387
|
placeholderNumberType,
|
|
4327
|
-
|
|
4388
|
+
NUMBER_FORMAT.E164
|
|
4328
4389
|
);
|
|
4329
4390
|
let validNumber = exampleNumber;
|
|
4330
|
-
while (intlTelInput.utils.
|
|
4391
|
+
while (intlTelInput.utils.isValidNumber(
|
|
4331
4392
|
exampleNumber,
|
|
4332
4393
|
iso2,
|
|
4333
4394
|
allowedNumberTypes
|
|
@@ -4344,19 +4405,19 @@ var _factory = (() => {
|
|
|
4344
4405
|
//* Update the input placeholder to an example number from the currently selected country.
|
|
4345
4406
|
#updatePlaceholder() {
|
|
4346
4407
|
const {
|
|
4347
|
-
|
|
4408
|
+
placeholderNumberPolicy,
|
|
4348
4409
|
placeholderNumberType,
|
|
4349
|
-
|
|
4410
|
+
numberDisplayFormat,
|
|
4350
4411
|
customPlaceholder
|
|
4351
4412
|
} = this.#options;
|
|
4352
|
-
const shouldSetPlaceholder =
|
|
4413
|
+
const shouldSetPlaceholder = placeholderNumberPolicy === PLACEHOLDER_POLICY.AGGRESSIVE || !this.#ui.hadInitialPlaceholder && placeholderNumberPolicy === PLACEHOLDER_POLICY.POLITE;
|
|
4353
4414
|
if (!intlTelInput.utils || !shouldSetPlaceholder) {
|
|
4354
4415
|
return;
|
|
4355
4416
|
}
|
|
4356
4417
|
let placeholder = this.#selectedCountry ? intlTelInput.utils.getExampleNumber(
|
|
4357
4418
|
this.#selectedCountry.iso2,
|
|
4358
|
-
|
|
4359
|
-
|
|
4419
|
+
placeholderNumberType,
|
|
4420
|
+
numberDisplayFormat
|
|
4360
4421
|
) : "";
|
|
4361
4422
|
placeholder = this.#prepareNumberForInput(placeholder);
|
|
4362
4423
|
if (typeof customPlaceholder === "function") {
|
|
@@ -4364,36 +4425,40 @@ var _factory = (() => {
|
|
|
4364
4425
|
}
|
|
4365
4426
|
this.#ui.telInputEl.setAttribute("placeholder", placeholder);
|
|
4366
4427
|
}
|
|
4367
|
-
//* Called when the user selects a list item from the
|
|
4428
|
+
//* Called when the user selects a list item from the country list (no-op if listItem is null).
|
|
4368
4429
|
#selectListItem(listItem) {
|
|
4369
4430
|
if (!listItem) {
|
|
4370
4431
|
return;
|
|
4371
4432
|
}
|
|
4372
4433
|
const iso2 = listItem.dataset[DATA_KEYS.ISO2];
|
|
4373
4434
|
const countryChanged = this.#updateSelectedCountry(iso2);
|
|
4374
|
-
this.#
|
|
4435
|
+
this.#closeCountrySelectorInternal();
|
|
4375
4436
|
const dialCode = listItem.dataset[DATA_KEYS.DIAL_CODE];
|
|
4376
4437
|
this.#updateDialCode(dialCode);
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
this.#updateValueFromNumber(inputValue);
|
|
4380
|
-
}
|
|
4438
|
+
const inputValue = this.#getTelInputValue();
|
|
4439
|
+
this.#updateValueFromNumber(inputValue);
|
|
4381
4440
|
this.#ui.telInputEl.focus();
|
|
4382
4441
|
if (countryChanged) {
|
|
4383
4442
|
this.#dispatchCountryChangeEvent();
|
|
4384
4443
|
this.#dispatchEvent(EVENTS.INPUT, { isCountryChange: true });
|
|
4385
4444
|
}
|
|
4386
4445
|
}
|
|
4387
|
-
//*
|
|
4388
|
-
|
|
4389
|
-
|
|
4446
|
+
//* Public: close the country selector (consumer-callable; delegates to the internal helper
|
|
4447
|
+
//* without the destroy-specific path).
|
|
4448
|
+
closeCountrySelector() {
|
|
4449
|
+
this.#closeCountrySelectorInternal();
|
|
4450
|
+
}
|
|
4451
|
+
//* Close the country selector and unbind any listeners. The isDestroy flag forces close even
|
|
4452
|
+
//* when dropdownAlwaysOpen is set, so destroy() can fully tear down.
|
|
4453
|
+
#closeCountrySelectorInternal(isDestroy) {
|
|
4454
|
+
if (!this.#ui.isCountrySelectorOpen() || this.#options.dropdownAlwaysOpen && !isDestroy) {
|
|
4390
4455
|
return;
|
|
4391
4456
|
}
|
|
4392
|
-
this.#ui.
|
|
4393
|
-
this.#dispatchEvent(EVENTS.
|
|
4457
|
+
this.#ui.closeCountrySelector();
|
|
4458
|
+
this.#dispatchEvent(EVENTS.CLOSE_COUNTRY_SELECTOR);
|
|
4394
4459
|
}
|
|
4395
4460
|
//* Replace any existing dial code with the new one
|
|
4396
|
-
//* Note: called from selectListItem and
|
|
4461
|
+
//* Note: called from selectListItem and setSelectedCountry
|
|
4397
4462
|
#updateDialCode(newDialCodeDigits) {
|
|
4398
4463
|
const inputValue = this.#getTelInputValue();
|
|
4399
4464
|
if (!inputValue.startsWith("+")) {
|
|
@@ -4473,7 +4538,7 @@ var _factory = (() => {
|
|
|
4473
4538
|
//**************************
|
|
4474
4539
|
//* INTERNAL METHODS
|
|
4475
4540
|
//**************************
|
|
4476
|
-
//* Called when the
|
|
4541
|
+
//* Called when the initial country lookup returns.
|
|
4477
4542
|
#handleAutoCountryLoaded() {
|
|
4478
4543
|
if (!this.#autoCountryDeferred || !intlTelInput.autoCountry) {
|
|
4479
4544
|
return;
|
|
@@ -4482,15 +4547,17 @@ var _factory = (() => {
|
|
|
4482
4547
|
this.#autoCountryDeferred.resolve();
|
|
4483
4548
|
return;
|
|
4484
4549
|
}
|
|
4485
|
-
|
|
4486
|
-
|
|
4550
|
+
const isFocused = document.activeElement === this.#ui.telInputEl;
|
|
4551
|
+
const hasTypedValue = Boolean(this.#getTelInputValue());
|
|
4552
|
+
if (this.#ui.isLoading() && !(isFocused && hasTypedValue)) {
|
|
4553
|
+
this.setSelectedCountry(intlTelInput.autoCountry);
|
|
4487
4554
|
} else {
|
|
4488
4555
|
this.#fallbackCountryIso2 = intlTelInput.autoCountry;
|
|
4489
4556
|
}
|
|
4490
4557
|
this.#ui.setLoading(false);
|
|
4491
4558
|
this.#autoCountryDeferred.resolve();
|
|
4492
4559
|
}
|
|
4493
|
-
//* Called when the
|
|
4560
|
+
//* Called when the initial country lookup fails or times out.
|
|
4494
4561
|
#handleAutoCountryFailure() {
|
|
4495
4562
|
if (!this.#isActive) {
|
|
4496
4563
|
this.#autoCountryDeferred?.reject();
|
|
@@ -4511,7 +4578,8 @@ var _factory = (() => {
|
|
|
4511
4578
|
return;
|
|
4512
4579
|
}
|
|
4513
4580
|
const inputValue = this.#getTelInputValue();
|
|
4514
|
-
|
|
4581
|
+
const isFocused = document.activeElement === this.#ui.telInputEl;
|
|
4582
|
+
if (inputValue && !isFocused) {
|
|
4515
4583
|
this.#updateValueFromNumber(inputValue);
|
|
4516
4584
|
}
|
|
4517
4585
|
if (this.#selectedCountry) {
|
|
@@ -4537,8 +4605,8 @@ var _factory = (() => {
|
|
|
4537
4605
|
return;
|
|
4538
4606
|
}
|
|
4539
4607
|
this.#isActive = false;
|
|
4540
|
-
if (this.#options.
|
|
4541
|
-
this.#
|
|
4608
|
+
if (this.#options.countrySelectorMode !== COUNTRY_SELECTOR_MODE.OFF) {
|
|
4609
|
+
this.#closeCountrySelectorInternal(true);
|
|
4542
4610
|
}
|
|
4543
4611
|
this.#abortController.abort();
|
|
4544
4612
|
this.#ui.destroy();
|
|
@@ -4586,7 +4654,7 @@ var _factory = (() => {
|
|
|
4586
4654
|
);
|
|
4587
4655
|
}
|
|
4588
4656
|
//* Get the country data for the currently selected country.
|
|
4589
|
-
|
|
4657
|
+
getSelectedCountry() {
|
|
4590
4658
|
return this.#selectedCountry ?? null;
|
|
4591
4659
|
}
|
|
4592
4660
|
//* Get the validation error e.g. "TOO_SHORT" / "TOO_LONG", or null if it can't be determined / instance is destroyed.
|
|
@@ -4641,7 +4709,7 @@ var _factory = (() => {
|
|
|
4641
4709
|
if (!this.#selectedCountry && !hasRegionlessDialCode(value)) {
|
|
4642
4710
|
return false;
|
|
4643
4711
|
}
|
|
4644
|
-
const check = mode === "precise" ? intlTelInput.utils.
|
|
4712
|
+
const check = mode === "precise" ? intlTelInput.utils.isValidNumberPrecise : intlTelInput.utils.isValidNumber;
|
|
4645
4713
|
if (!check(value, iso2, allowedNumberTypes)) {
|
|
4646
4714
|
return false;
|
|
4647
4715
|
}
|
|
@@ -4654,7 +4722,7 @@ var _factory = (() => {
|
|
|
4654
4722
|
return true;
|
|
4655
4723
|
}
|
|
4656
4724
|
//* Update the selected country, and update the input value accordingly.
|
|
4657
|
-
|
|
4725
|
+
setSelectedCountry(iso2) {
|
|
4658
4726
|
if (!this.#isActive) {
|
|
4659
4727
|
return;
|
|
4660
4728
|
}
|
|
@@ -4669,10 +4737,8 @@ var _factory = (() => {
|
|
|
4669
4737
|
}
|
|
4670
4738
|
this.#updateSelectedCountry(iso2Lower);
|
|
4671
4739
|
this.#updateDialCode(this.#selectedCountry?.dialCode || "");
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
this.#updateValueFromNumber(inputValue);
|
|
4675
|
-
}
|
|
4740
|
+
const inputValue = this.#getTelInputValue();
|
|
4741
|
+
this.#updateValueFromNumber(inputValue);
|
|
4676
4742
|
this.#dispatchCountryChangeEvent();
|
|
4677
4743
|
this.#dispatchEvent(EVENTS.INPUT, { isCountryChange: true });
|
|
4678
4744
|
}
|
|
@@ -4697,14 +4763,14 @@ var _factory = (() => {
|
|
|
4697
4763
|
this.#options.placeholderNumberType = type;
|
|
4698
4764
|
this.#updatePlaceholder();
|
|
4699
4765
|
}
|
|
4700
|
-
// Set the disabled state of the input and
|
|
4766
|
+
// Set the disabled state of the input and country selector.
|
|
4701
4767
|
setDisabled(disabled) {
|
|
4702
4768
|
if (!this.#isActive) {
|
|
4703
4769
|
return;
|
|
4704
4770
|
}
|
|
4705
4771
|
this.#ui.setDisabled(disabled);
|
|
4706
4772
|
}
|
|
4707
|
-
// Set the readonly state of the input and
|
|
4773
|
+
// Set the readonly state of the input and country selector.
|
|
4708
4774
|
setReadonly(readonly) {
|
|
4709
4775
|
if (!this.#isActive) {
|
|
4710
4776
|
return;
|
|
@@ -4714,7 +4780,7 @@ var _factory = (() => {
|
|
|
4714
4780
|
//********************
|
|
4715
4781
|
//* STATIC METHODS
|
|
4716
4782
|
//********************
|
|
4717
|
-
// Internal instance notification used by utils/
|
|
4783
|
+
// Internal instance notification used by utils/initial-country loaders.
|
|
4718
4784
|
// Kept public so module-level helpers (e.g. attachUtils) can call it, while still allowing
|
|
4719
4785
|
// access to private instance methods.
|
|
4720
4786
|
static forEachInstance(method, ...args) {
|
|
@@ -4778,8 +4844,8 @@ var _factory = (() => {
|
|
|
4778
4844
|
defaults,
|
|
4779
4845
|
//* Using a static var like this allows us to mock it in the tests.
|
|
4780
4846
|
documentReady: () => document.readyState === "complete",
|
|
4781
|
-
//* Get the
|
|
4782
|
-
|
|
4847
|
+
//* Get the full list of all countries the library knows about.
|
|
4848
|
+
getAllCountries: () => data_default,
|
|
4783
4849
|
//* A getter for the core library instance.
|
|
4784
4850
|
getInstance: (input) => {
|
|
4785
4851
|
const id = input.dataset[DATA_KEYS.INSTANCE_ID];
|
|
@@ -4790,10 +4856,12 @@ var _factory = (() => {
|
|
|
4790
4856
|
attachUtils,
|
|
4791
4857
|
startedLoadingUtils: false,
|
|
4792
4858
|
startedLoadingAutoCountry: false,
|
|
4793
|
-
version: "
|
|
4859
|
+
version: "29.0.0",
|
|
4794
4860
|
NUMBER_FORMAT,
|
|
4795
4861
|
NUMBER_TYPE,
|
|
4796
|
-
VALIDATION_ERROR
|
|
4862
|
+
VALIDATION_ERROR,
|
|
4863
|
+
PLACEHOLDER_POLICY,
|
|
4864
|
+
COUNTRY_SELECTOR_MODE
|
|
4797
4865
|
}
|
|
4798
4866
|
);
|
|
4799
4867
|
var intlTelInput_default = intlTelInput;
|