UNPKG

intl-tel-input

Version:

A JavaScript plugin for entering and validating international telephone numbers

2,527 lines (2,514 loc) 480 kB
/* * International Telephone Input v26.8.0 * https://github.com/jackocnr/intl-tel-input.git * Licensed under the MIT license */ // UMD (function(factory) { if (typeof module === 'object' && module.exports) { module.exports = factory(); } else { window.intlTelInput = factory(); } }(() => { var factoryOutput = (() => { var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/js/intl-tel-input/intlTelInputWithUtils.ts var intlTelInputWithUtils_exports = {}; __export(intlTelInputWithUtils_exports, { default: () => intlTelInputWithUtils_default }); // src/js/intl-tel-input/data.ts var rawCountryData = [ [ "af", // Afghanistan "93", 0, null, "0" ], [ "ax", // Åland Islands "358", 1, ["18", "4"], // (4 is a mobile range shared with FI) "0" ], [ "al", // Albania "355", 0, null, "0" ], [ "dz", // Algeria "213", 0, null, "0" ], [ "as", // American Samoa "1", 5, ["684"], "1" ], [ "ad", // Andorra "376" ], [ "ao", // Angola "244" ], [ "ai", // Anguilla "1", 6, ["264"], "1" ], [ "ag", // Antigua and Barbuda "1", 7, ["268"], "1" ], [ "ar", // Argentina "54", 0, null, "0" ], [ "am", // Armenia "374", 0, null, "0" ], [ "aw", // Aruba "297" ], [ "ac", // Ascension Island "247" ], [ "au", // Australia "61", 0, ["4"], // (mobile range shared with CX and CC) "0" ], [ "at", // Austria "43", 0, null, "0" ], [ "az", // Azerbaijan "994", 0, null, "0" ], [ "bs", // Bahamas "1", 8, ["242"], "1" ], [ "bh", // Bahrain "973" ], [ "bd", // Bangladesh "880", 0, null, "0" ], [ "bb", // Barbados "1", 9, ["246"], "1" ], [ "by", // Belarus "375", 0, null, "8" ], [ "be", // Belgium "32", 0, null, "0" ], [ "bz", // Belize "501" ], [ "bj", // Benin "229" ], [ "bm", // Bermuda "1", 10, ["441"], "1" ], [ "bt", // Bhutan "975" ], [ "bo", // Bolivia "591", 0, null, "0" ], [ "ba", // Bosnia and Herzegovina "387", 0, null, "0" ], [ "bw", // Botswana "267" ], [ "br", // Brazil "55", 0, null, "0" ], [ "io", // British Indian Ocean Territory "246" ], [ "vg", // British Virgin Islands "1", 11, ["284"], "1" ], [ "bn", // Brunei "673" ], [ "bg", // Bulgaria "359", 0, null, "0" ], [ "bf", // Burkina Faso "226" ], [ "bi", // Burundi "257" ], [ "kh", // Cambodia "855", 0, null, "0" ], [ "cm", // Cameroon "237" ], [ "ca", // Canada "1", 1, ["204", "226", "236", "249", "250", "257", "263", "289", "306", "343", "354", "365", "367", "368", "382", "403", "416", "418", "428", "431", "437", "438", "450", "468", "474", "506", "514", "519", "548", "579", "581", "584", "587", "604", "613", "639", "647", "672", "683", "705", "709", "742", "753", "778", "780", "782", "807", "819", "825", "867", "873", "879", "902", "905", "942"], "1" ], [ "cv", // Cape Verde "238" ], [ "bq", // Caribbean Netherlands "599", 1, ["3", "4", "7"] ], [ "ky", // Cayman Islands "1", 12, ["345"], "1" ], [ "cf", // Central African Republic "236" ], [ "td", // Chad "235" ], [ "cl", // Chile "56" ], [ "cn", // China "86", 0, null, "0" ], [ "cx", // Christmas Island "61", 2, ["4", "89164"], // (4 is a mobile range shared with AU and CC) "0" ], [ "cc", // Cocos (Keeling) Islands "61", 1, ["4", "89162"], // (4 is a mobile range shared with AU and CX) "0" ], [ "co", // Colombia "57", 0, null, "0" ], [ "km", // Comoros "269" ], [ "cg", // Congo (Brazzaville) "242" ], [ "cd", // Congo (Kinshasa) "243", 0, null, "0" ], [ "ck", // Cook Islands "682" ], [ "cr", // Costa Rica "506" ], [ "ci", // Côte d'Ivoire "225" ], [ "hr", // Croatia "385", 0, null, "0" ], [ "cu", // Cuba "53", 0, null, "0" ], [ "cw", // Curaçao "599", 0 ], [ "cy", // Cyprus "357" ], [ "cz", // Czech Republic "420" ], [ "dk", // Denmark "45" ], [ "dj", // Djibouti "253" ], [ "dm", // Dominica "1", 13, ["767"], "1" ], [ "do", // Dominican Republic "1", 2, ["809", "829", "849"], "1" ], [ "ec", // Ecuador "593", 0, null, "0" ], [ "eg", // Egypt "20", 0, null, "0" ], [ "sv", // El Salvador "503" ], [ "gq", // Equatorial Guinea "240" ], [ "er", // Eritrea "291", 0, null, "0" ], [ "ee", // Estonia "372" ], [ "sz", // Eswatini "268" ], [ "et", // Ethiopia "251", 0, null, "0" ], [ "fk", // Falkland Islands (Malvinas) "500" ], [ "fo", // Faroe Islands "298" ], [ "fj", // Fiji "679" ], [ "fi", // Finland "358", 0, ["4"], // (mobile range shared with AX) "0" ], [ "fr", // France "33", 0, null, "0" ], [ "gf", // French Guiana "594", 0, null, "0" ], [ "pf", // French Polynesia "689" ], [ "ga", // Gabon "241" ], [ "gm", // Gambia "220" ], [ "ge", // Georgia "995", 0, null, "0" ], [ "de", // Germany "49", 0, null, "0" ], [ "gh", // Ghana "233", 0, null, "0" ], [ "gi", // Gibraltar "350" ], [ "gr", // Greece "30" ], [ "gl", // Greenland "299" ], [ "gd", // Grenada "1", 14, ["473"], "1" ], [ "gp", // Guadeloupe "590", 0, null, "0" ], [ "gu", // Guam "1", 15, ["671"], "1" ], [ "gt", // Guatemala "502" ], [ "gg", // Guernsey "44", 1, ["1481", "7781", "7839", "7911"], "0" ], [ "gn", // Guinea "224" ], [ "gw", // Guinea-Bissau "245" ], [ "gy", // Guyana "592" ], [ "ht", // Haiti "509" ], [ "hn", // Honduras "504" ], [ "hk", // Hong Kong SAR China "852" ], [ "hu", // Hungary "36", 0, null, "06" ], [ "is", // Iceland "354" ], [ "in", // India "91", 0, null, "0" ], [ "id", // Indonesia "62", 0, null, "0" ], [ "ir", // Iran "98", 0, null, "0" ], [ "iq", // Iraq "964", 0, null, "0" ], [ "ie", // Ireland "353", 0, null, "0" ], [ "im", // Isle of Man "44", 2, ["1624", "74576", "7524", "7624", "7924"], "0" ], [ "il", // Israel "972", 0, null, "0" ], [ "it", // Italy "39", 0, ["3"] // (mobile range shared with VA) ], [ "jm", // Jamaica "1", 4, ["658", "876"], "1" ], [ "jp", // Japan "81", 0, null, "0" ], [ "je", // Jersey "44", 3, ["1534", "7509", "7700", "7797", "7829", "7937"], "0" ], [ "jo", // Jordan "962", 0, null, "0" ], [ "kz", // Kazakhstan "7", 1, ["33", "7"], // (33 is shared with RU) "8" ], [ "ke", // Kenya "254", 0, null, "0" ], [ "ki", // Kiribati "686", 0, null, "0" ], [ "xk", // Kosovo "383", 0, null, "0" ], [ "kw", // Kuwait "965" ], [ "kg", // Kyrgyzstan "996", 0, null, "0" ], [ "la", // Laos "856", 0, null, "0" ], [ "lv", // Latvia "371" ], [ "lb", // Lebanon "961", 0, null, "0" ], [ "ls", // Lesotho "266" ], [ "lr", // Liberia "231", 0, null, "0" ], [ "ly", // Libya "218", 0, null, "0" ], [ "li", // Liechtenstein "423", 0, null, "0" ], [ "lt", // Lithuania "370", 0, null, "0" ], [ "lu", // Luxembourg "352" ], [ "mo", // Macao SAR China "853" ], [ "mg", // Madagascar "261", 0, null, "0" ], [ "mw", // Malawi "265", 0, null, "0" ], [ "my", // Malaysia "60", 0, null, "0" ], [ "mv", // Maldives "960" ], [ "ml", // Mali "223" ], [ "mt", // Malta "356" ], [ "mh", // Marshall Islands "692", 0, null, "1" ], [ "mq", // Martinique "596", 0, null, "0" ], [ "mr", // Mauritania "222" ], [ "mu", // Mauritius "230" ], [ "yt", // Mayotte "262", 1, ["269", "639"], "0" ], [ "mx", // Mexico "52" ], [ "fm", // Micronesia "691" ], [ "md", // Moldova "373", 0, null, "0" ], [ "mc", // Monaco "377", 0, null, "0" ], [ "mn", // Mongolia "976", 0, null, "0" ], [ "me", // Montenegro "382", 0, null, "0" ], [ "ms", // Montserrat "1", 16, ["664"], "1" ], [ "ma", // Morocco "212", 0, ["6", "7"], // (mobile ranges shared with EH) "0" ], [ "mz", // Mozambique "258" ], [ "mm", // Myanmar (Burma) "95", 0, null, "0" ], [ "na", // Namibia "264", 0, null, "0" ], [ "nr", // Nauru "674" ], [ "np", // Nepal "977", 0, null, "0" ], [ "nl", // Netherlands "31", 0, null, "0" ], [ "nc", // New Caledonia "687" ], [ "nz", // New Zealand "64", 0, null, "0" ], [ "ni", // Nicaragua "505" ], [ "ne", // Niger "227" ], [ "ng", // Nigeria "234", 0, null, "0" ], [ "nu", // Niue "683" ], [ "nf", // Norfolk Island "672" ], [ "kp", // North Korea "850", 0, null, "0" ], [ "mk", // North Macedonia "389", 0, null, "0" ], [ "mp", // Northern Mariana Islands "1", 17, ["670"], "1" ], [ "no", // Norway "47", 0, ["4", "9"] // (mobile ranges shared with SJ) ], [ "om", // Oman "968" ], [ "pk", // Pakistan "92", 0, null, "0" ], [ "pw", // Palau "680" ], [ "ps", // Palestinian Territories "970", 0, null, "0" ], [ "pa", // Panama "507" ], [ "pg", // Papua New Guinea "675" ], [ "py", // Paraguay "595", 0, null, "0" ], [ "pe", // Peru "51", 0, null, "0" ], [ "ph", // Philippines "63", 0, null, "0" ], [ "pl", // Poland "48" ], [ "pt", // Portugal "351" ], [ "pr", // Puerto Rico "1", 3, ["787", "939"], "1" ], [ "qa", // Qatar "974" ], [ "re", // Réunion "262", 0, null, "0" ], [ "ro", // Romania "40", 0, null, "0" ], [ "ru", // Russia "7", 0, ["33"], // (shared with KZ) "8" ], [ "rw", // Rwanda "250", 0, null, "0" ], [ "ws", // Samoa "685" ], [ "sm", // San Marino "378" ], [ "st", // São Tomé & Príncipe "239" ], [ "sa", // Saudi Arabia "966", 0, null, "0" ], [ "sn", // Senegal "221" ], [ "rs", // Serbia "381", 0, null, "0" ], [ "sc", // Seychelles "248" ], [ "sl", // Sierra Leone "232", 0, null, "0" ], [ "sg", // Singapore "65" ], [ "sx", // Sint Maarten "1", 21, ["721"], "1" ], [ "sk", // Slovakia "421", 0, null, "0" ], [ "si", // Slovenia "386", 0, null, "0" ], [ "sb", // Solomon Islands "677" ], [ "so", // Somalia "252", 0, null, "0" ], [ "za", // South Africa "27", 0, null, "0" ], [ "kr", // South Korea "82", 0, null, "0" ], [ "ss", // South Sudan "211", 0, null, "0" ], [ "es", // Spain "34" ], [ "lk", // Sri Lanka "94", 0, null, "0" ], [ "bl", // St. Barthélemy "590", 1, null, "0" ], [ "sh", // St. Helena "290" ], [ "kn", // St. Kitts & Nevis "1", 18, ["869"], "1" ], [ "lc", // St. Lucia "1", 19, ["758"], "1" ], [ "mf", // St. Martin "590", 2, null, "0" ], [ "pm", // St. Pierre & Miquelon "508", 0, null, "0" ], [ "vc", // St. Vincent & Grenadines "1", 20, ["784"], "1" ], [ "sd", // Sudan "249", 0, null, "0" ], [ "sr", // Suriname "597" ], [ "sj", // Svalbard & Jan Mayen "47", 1, ["4", "79", "9"] // (4 and 9 are mobile ranges shared with NO) ], [ "se", // Sweden "46", 0, null, "0" ], [ "ch", // Switzerland "41", 0, null, "0" ], [ "sy", // Syria "963", 0, null, "0" ], [ "tw", // Taiwan "886", 0, null, "0" ], [ "tj", // Tajikistan "992" ], [ "tz", // Tanzania "255", 0, null, "0" ], [ "th", // Thailand "66", 0, null, "0" ], [ "tl", // Timor-Leste "670" ], [ "tg", // Togo "228" ], [ "tk", // Tokelau "690" ], [ "to", // Tonga "676" ], [ "tt", // Trinidad & Tobago "1", 22, ["868"], "1" ], [ "tn", // Tunisia "216" ], [ "tr", // Turkey "90", 0, null, "0" ], [ "tm", // Turkmenistan "993", 0, null, "8" ], [ "tc", // Turks & Caicos Islands "1", 23, ["649"], "1" ], [ "tv", // Tuvalu "688" ], [ "vi", // U.S. Virgin Islands "1", 24, ["340"], "1" ], [ "ug", // Uganda "256", 0, null, "0" ], [ "ua", // Ukraine "380", 0, null, "0" ], [ "ae", // United Arab Emirates "971", 0, null, "0" ], [ "gb", // United Kingdom "44", 0, null, "0" ], [ "us", // United States "1", 0, null, "1" ], [ "uy", // Uruguay "598", 0, null, "0" ], [ "uz", // Uzbekistan "998" ], [ "vu", // Vanuatu "678" ], [ "va", // Vatican City "39", 1, ["06698", "3"] // (3 is a mobile range shared with IT) ], [ "ve", // Venezuela "58", 0, null, "0" ], [ "vn", // Vietnam "84", 0, null, "0" ], [ "wf", // Wallis & Futuna "681" ], [ "eh", // Western Sahara "212", 1, ["5288", "5289", "6", "7"], // (6 and 7 are mobile ranges shared with MA) "0" ], [ "ye", // Yemen "967", 0, null, "0" ], [ "zm", // Zambia "260", 0, null, "0" ], [ "zw", // Zimbabwe "263", 0, null, "0" ] ]; var allCountries = []; for (const c of rawCountryData) { allCountries.push({ name: "", // populated in the plugin iso2: c[0], dialCode: c[1], priority: c[2] || 0, areaCodes: c[3] || null, nodeById: {}, // populated by the plugin nationalPrefix: c[4] || null, normalisedName: "", // populated in the plugin initials: "", // populated in the plugin dialCodePlus: "" // populated in the plugin }); } var data_default = allCountries; // src/js/modules/constants.ts var EVENTS = { OPEN_COUNTRY_DROPDOWN: "open:countrydropdown", CLOSE_COUNTRY_DROPDOWN: "close:countrydropdown", COUNTRY_CHANGE: "countrychange", INPUT: "input" // used for synthetic input trigger }; var CLASSES = { HIDE: "iti__hide", V_HIDE: "iti__v-hide", ARROW_UP: "iti__arrow--up", GLOBE: "iti__globe", FLAG: "iti__flag", LOADING: "iti__loading", COUNTRY_ITEM: "iti__country", HIGHLIGHT: "iti__highlight" }; var KEYS = { ARROW_UP: "ArrowUp", ARROW_DOWN: "ArrowDown", SPACE: " ", ENTER: "Enter", ESC: "Escape", TAB: "Tab" }; var INPUT_TYPES = { PASTE: "insertFromPaste", DELETE_FWD: "deleteContentForward" }; var REGEX = { ALPHA_UNICODE: /\p{L}/u, // any kind of letter from any language NON_PLUS_NUMERIC: /[^+0-9]/, // chars that are NOT + or digit NON_PLUS_NUMERIC_GLOBAL: /[^+0-9]/g, // chars that are NOT + or digit (global) HIDDEN_SEARCH_CHAR: /^[a-zA-ZÀ-ÿа-яА-Я ]$/ // single acceptable hidden-search char }; var TIMINGS = { SEARCH_DEBOUNCE_MS: 100, HIDDEN_SEARCH_RESET_MS: 1e3, NEXT_TICK: 0 }; var SENTINELS = { UNKNOWN_NUMBER_TYPE: -99, UNKNOWN_VALIDATION_ERROR: -99 }; var LAYOUT = { NARROW_VIEWPORT_WIDTH: 500, // keep in sync with .iti__country-list CSS media query SANE_SELECTED_WITH_DIAL_WIDTH: 78, // px width fallback when separateDialCode enabled SANE_SELECTED_NO_DIAL_WIDTH: 42, // px width fallback when no separate dial code INPUT_PADDING_EXTRA_LEFT: 6, // px gap between selected country container and input text DROPDOWN_MARGIN: 3, // px margin between dropdown and tel input SANE_DROPDOWN_HEIGHT: 200 // px height fallback for dropdown }; var DIAL = { PLUS: "+", NANP: "1" // North American Numbering Plan }; var UK = { ISO2: "gb", DIAL_CODE: "44", // +44 United Kingdom MOBILE_PREFIX: "7", // UK mobile numbers start with 7 after national trunk (0) or core section MOBILE_CORE_LENGTH: 10 // core number length (excluding dial code / national prefix) for mobiles }; var US = { ISO2: "us", DIAL_CODE: "1" // +1 United States }; var PLACEHOLDER_MODES = { AGGRESSIVE: "aggressive", POLITE: "polite", OFF: "off" }; var INITIAL_COUNTRY = { AUTO: "auto" }; var NUMBER_TYPES = [ "FIXED_LINE", "MOBILE", "FIXED_LINE_OR_MOBILE", "TOLL_FREE", "PREMIUM_RATE", "SHARED_COST", "VOIP", "PERSONAL_NUMBER", "PAGER", "UAN", "VOICEMAIL", "UNKNOWN" ]; var NUMBER_TYPE_SET = new Set(NUMBER_TYPES); var DATA_KEYS = { COUNTRY_CODE: "countryCode", DIAL_CODE: "dialCode" }; var ARIA = { EXPANDED: "aria-expanded", LABEL: "aria-label", SELECTED: "aria-selected", ACTIVE_DESCENDANT: "aria-activedescendant", HASPOPUP: "aria-haspopup", CONTROLS: "aria-controls", HIDDEN: "aria-hidden", AUTOCOMPLETE: "aria-autocomplete", MODAL: "aria-modal" }; // src/js/intl-tel-input/i18n/en/index.ts var interfaceTranslations = { selectedCountryAriaLabel: "Change country, selected ${countryName} (${dialCode})", noCountrySelected: "Select country", countryListAriaLabel: "List of countries", searchPlaceholder: "Search", clearSearchAriaLabel: "Clear search", searchEmptyState: "No results found", searchSummaryAria(count) { if (count === 0) { return "No results found"; } if (count === 1) { return "1 result found"; } return `${count} results found`; } }; var en_default = interfaceTranslations; // src/js/modules/core/options.ts var mq = (q) => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(q).matches; var isNarrowViewport = () => mq(`(max-width: ${LAYOUT.NARROW_VIEWPORT_WIDTH}px)`); var computeDefaultUseFullscreenPopup = () => { if (typeof navigator !== "undefined" && typeof window !== "undefined") { const isShortViewport = mq("(max-height: 600px)"); const isCoarsePointer = mq("(pointer: coarse)"); return isNarrowViewport() || isCoarsePointer && isShortViewport; } return false; }; var defaults = { //* Whether or not to allow the dropdown. allowDropdown: true, //* The number type to enforce during validation. allowedNumberTypes: ["MOBILE", "FIXED_LINE"], //* Whether or not to allow extensions after the main number. allowNumberExtensions: false, // Allow alphanumeric "phonewords" (e.g. +1 800 FLOWERS) as valid numbers allowPhonewords: false, //* Add a placeholder in the input with an example number for the selected country. autoPlaceholder: PLACEHOLDER_MODES.POLITE, //* Add a custom class to the (injected) container element. containerClass: "", //* Locale for localising country names via Intl.DisplayNames. countryNameLocale: "en", //* The order of the countries in the dropdown. Defaults to alphabetical. countryOrder: null, //* Add a country search input at the top of the dropdown. countrySearch: true, //* Modify the auto placeholder. customPlaceholder: null, //* Always show the dropdown dropdownAlwaysOpen: false, //* Append menu to specified element. dropdownContainer: null, //* Don't display these countries. excludeCountries: [], //* Fix the dropdown width to the input width (rather than being as wide as the longest country name). fixDropdownWidth: true, //* Format the number as the user types formatAsYouType: true, //* Format the input value during initialisation and on setNumber. formatOnDisplay: true, //* geoIp lookup function. geoIpLookup: null, //* Inject a hidden input with the name returned from this function, and on submit, populate it with the result of getNumber. hiddenInput: null, //* Internationalise the plugin text e.g. search input placeholder, country names. i18n: {}, //* Initial country. initialCountry: "", //* A function to load the utils script. loadUtils: null, //* National vs international formatting for numbers e.g. placeholders and displaying existing numbers. nationalMode: true, //* Display only these countries. onlyCountries: [], //* Number type to use for placeholders. placeholderNumberType: "MOBILE", //* Add custom classes to the search input element. searchInputClass: "", //* Display the international dial code next to the selected flag. separateDialCode: false, //* Show flags - for both the selected country, and in the country dropdown showFlags: true, //* Only allow certain chars e.g. a plus followed by numeric digits, and cap at max valid length. strictMode: false, //* Use full screen popup instead of dropdown for country list. useFullscreenPopup: computeDefaultUseFullscreenPopup() }; var toString = (val) => JSON.stringify(val); var isPlainObject = (val) => Boolean(val) && typeof val === "object" && !Array.isArray(val); var isFn = (val) => typeof val === "function"; var isElLike = (val) => { if (!val || typeof val !== "object") return false; const v = val; return v.nodeType === 1 && typeof v.tagName === "string" && typeof v.appendChild === "function"; }; var iso2Set = new Set(data_default.map((c) => c.iso2)); var isIso2 = (val) => iso2Set.has(val); var placeholderModeSet = new Set(Object.values(PLACEHOLDER_MODES)); var warn = (message) => { console.warn(`[intl-tel-input] ${message}`); }; var warnOption = (optionName, expectedType, actualValue) => { warn(`Option '${optionName}' must be ${expectedType}; got ${toString(actualValue)}. Ignoring.`); }; var hasOwn = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key); var validateIso2Array = (key, value) => { const expectedType = "an array of ISO2 country code strings"; if (!Array.isArray(value)) { warnOption(key, expectedType, value); return false; } for (const v of value) { if (typeof v !== "string") { warnOption(key, expectedType, value); return false; } const lower = v.toLowerCase(); if (!isIso2(lower)) { warn(`Invalid country code in '${key}': '${v}'. Ignoring.`); return false; } } return true; }; var validateOptions = (customOptions) => { if (customOptions === void 0) { return {}; } if (!isPlainObject(customOptions)) { const error = `The second argument must be an options object; got ${toString(customOptions)}. Using defaults.`; warn(error); return {}; } const validatedOptions = {}; for (const [key, value] of Object.entries(customOptions)) { if (!hasOwn(defaults, key)) { warn(`Unknown option '${key}'. Ignoring.`); continue; } switch (key) { case "allowDropdown": case "allowNumberExtensions": case "allowPhonewords": case "countrySearch": case "dropdownAlwaysOpen": case "fixDropdownWidth": case "formatAsYouType": case "formatOnDisplay": case "nationalMode": case "showFlags": case "separateDialCode": case "strictMode": case "useFullscreenPopup": if (typeof value !== "boolean") { warnOption(key, "a boolean", value); break; } validatedOptions[key] = value; break; case "autoPlaceholder": if (typeof value !== "string" || !placeholderModeSet.has(value)) { const validModes = Array.from(placeholderModeSet).join(", "); warnOption("autoPlaceholder", `one of ${validModes}`, value); break; } validatedOptions[key] = value; break; case "containerClass": case "searchInputClass": case "countryNameLocale": if (typeof value !== "string") { warnOption(key, "a string", value); break; } validatedOptions[key] = value; break; case "countryOrder": if (value === null || validateIso2Array(key, value)) { validatedOptions[key] = value; } break; case "customPlaceholder": case "geoIpLookup": case "hiddenInput": case "loadUtils": if (value !== null && !isFn(value)) { warnOption(key, "a function or null", value); break; } validatedOptions[key] = value; break; case "dropdownContainer": if (value !== null && !isElLike(value)) { warnOption("dropdownContainer", "an HTMLElement or null", value); break; } validatedOptions[key] = value; break; case "excludeCountries": case "onlyCountries": if (validateIso2Array(key, value)) { validatedOptions[key] = value; } break; case "i18n": if (value && !isPlainObject(value)) { warnOption("i18n", "an object", value); break; } validatedOptions[key] = value; break; case "initialCountry": { if (typeof value !== "string") { warnOption("initialCountry", "a string", value); break; } const lower = value.toLowerCase(); if (lower && (lower !== INITIAL_COUNTRY.AUTO && !isIso2(lower))) { warnOption("initialCountry", "a valid ISO2 country code or 'auto'", value); break; } validatedOptions[key] = value; break; } case "placeholderNumberType": if (typeof value !== "string" || !NUMBER_TYPE_SET.has(value)) { const validTypes = Array.from(NUMBER_TYPE_SET).join(", "); warnOption("placeholderNumberType", `one of ${validTypes}`, value); break; } validatedOptions[key] = value; break; case "allowedNumberTypes": if (value !== null) { if (!Array.isArray(value)) { warnOption("allowedNumberTypes", "an array of number types or null", value); break; } let allValid = true; for (const v of value) { if (typeof v !== "string" || !NUMBER_TYPE_SET.has(v)) { const validTypes = Array.from(NUMBER_TYPE_SET).join(", "); warnOption("allowedNumberTypes", `an array of valid number types (${validTypes})`, v); allValid = false; break; } } if (allValid) { validatedOptions[key] = value; } } else { validatedOptions[key] = null; } break; } } return validatedOptions; }; var applyOptionSideEffects = (o) => { if (o.dropdownAlwaysOpen) { o.useFullscreenPopup = false; o.allowDropdown = true; } if (o.useFullscreenPopup) { o.fixDropdownWidth = false; } else { if (isNarrowViewport()) { o.fixDropdownWidth = true; } } if (o.onlyCountries.length === 1) { o.initialCountry = o.onlyCountries[0]; } if (o.separateDialCode) { o.nationalMode = false; } if (o.allowDropdown && !o.showFlags && !o.separateDialCode) { o.nationalMode = false; } if (o.useFullscreenPopup && !o.dropdownContainer) { o.dropdownContainer = document.body; } o.i18n = { ...en_default, ...o.i18n }; }; // src/js/modules/utils/string.ts var getNumeric = (s) => s.replace(/\D/g, ""); var normaliseString = (s = "") => s.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase(); // src/js/modules/utils/isAndroid.ts var getIsAndroid = () => typeof navigator !== "undefined" ? /Android/i.test(navigator.userAgent) : false; // src/js/modules/core/countrySearch.ts var getMatchedCountries = (countries, query) => { const normalisedQuery = normaliseString(query); const iso2Matches = []; const nameStartWith = []; const nameContains = []; const dialCodeMatches = []; const dialCodeContains = []; const initialsMatches = []; for (const c of countries) { if (c.iso2 === normalisedQuery) { iso2Matches.push(c); } else if (c.normalisedName.startsWith(normalisedQuery)) { nameStartWith.push(c); } else if (c.normalisedName.includes(normalisedQuery)) { nameContains.push(c); } else if (normalisedQuery === c.dialCode || normalisedQuery === c.dialCodePlus) { dialCodeMatches.push(c); } else if (c.dialCodePlus.includes(normalisedQuery)) { dialCodeContains.push(c); } else if (c.initials.includes(normalisedQuery)) { initialsMatches.push(c); } } const sortByPriority = (a, b) => a.priority - b.priority; return [ ...iso2Matches.sort(sortByPriority), ...nameStartWith.sort(sortByPriority), ...nameContains.sort(sortByPriority), ...dialCodeMatches.sort(sortByPriority), ...dialCodeContains.sort(sortByPriority), ...initialsMatches.sort(sortByPriority) ]; }; var findFirstCountryStartingWith = (countries, query) => { const lowerQuery = query.toLowerCase(); for (const c of countries) { const lowerName = c.name.toLowerCase(); if (lowerName.startsWith(lowerQuery)) { return c; } } return null; }; // src/js/modules/utils/dom.ts var buildClassNames = (flags) => Object.keys(flags).filter((k) => Boolean(flags[k])).join(" "); var createEl = (tagName, attrs, container) => { const el = document.createElement(tagName); if (attrs) { Object.entries(attrs).forEach( ([key, value]) => el.setAttribute(key, value) ); } if (container) { container.appendChild(el); } return el; }; // src/js/modules/core/icons.ts var buildSearchIcon = () => ` <svg class="iti__search-icon-svg" width="14" height="14" viewBox="0 0 24 24" focusable="false" ${ARIA.HIDDEN}="true"> <circle cx="11" cy="11" r="7" /> <line x1="21" y1="21" x2="16.65" y2="16.65" /> </svg>`; var buildClearIcon = (id2) => { const maskId = `iti-${id2}-clear-mask`; return ` <svg class="iti__search-clear-svg" width="12" height="12" viewBox="0 0 16 16" ${ARIA.HIDDEN}="true" focusable="false"> <mask id="${maskId}" maskUnits="userSpaceOnUse"> <rect width="16" height="16" fill="white" /> <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" /> </mask> <circle cx="8" cy="8" r="8" class="iti__search-clear-bg" mask="url(#${maskId})" /> </svg>`; }; var buildCheckIcon = () => ` <svg class="iti__country-check-svg" width="14" height="14" viewBox="0 0 16 16" fill="currentColor" focusable="false" ${ARIA.HIDDEN}="true"> <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0m-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/> </svg>`; var buildGlobeIcon = () => ` <svg width="256" height="256" viewBox="0 0 512 512" class="iti__globe-svg"> <path d="M508 213a240 240 0 0 0-449-87l-2 5-2 5c-8 14-13 30-17 46a65 65 0 0 1 56 4c16-10 35-19 56-27l9-3c-6 23-10 48-10 74h-16l4 6c3 4 5 8 6 13h6c0 22 3 44 8 65l2 10-25-10-4 5 12 18 9 3 6 2 8 3 9 26 1 2 16-7h1l-5-13-1-2c24 6 49 9 75 10v26l11 10 7 7v-30l1-13c22 0 44-3 65-8l10-2-21 48-1 1a317 317 0 0 1-14 23l-21 5h-2c6 16 7 33 1 50a240 240 0 0 0 211-265m-401-56-11 6c19-44 54-79 98-98-11 20-21 44-29 69-21 6-40 15-58 23m154 182v4c-29-1-57-6-81-13-7-25-12-52-13-81h94zm0-109h-94c1-29 6-56 13-81 24-7 52-12 81-13zm0-112c-22 1-44 4-65 8l-10 2 12-30 9-17 1-2a332 332 0 0 1 13-23c13-4 26-6 40-7zm187 69 6 4c4 12 6 25 6 38v1h-68c-1-26-4-51-10-74l48 20 1 1 14 8zm-14-44 10 20c-20-11-43-21-68-29-8-25-18-49-29-69 37 16 67 44 87 78M279 49h1c13 1 27 3 39 7l14 23 1 2a343 343 0 0 1 12 26l2 5 6 16c-23-6-48-9-74-10h-1zm0 87h1c29 1 56 6 81 13 7 24 12 51 12 80v1h-94zm2 207h-2v-94h95c-1 29-6 56-13 81-24 7-51 12-80 13m86 60-20 10c11-20 21-43 29-68 25-8 48-18 68-29-16 37-43 67-77 87m87-115-7 5-16 9-2 1a337 337 0 0 1-47 21c6-24 9-49 10-75h68c0 13-2 27-6 39"/> <path d="m261 428-2-2-22-21a40 40 0 0 0-32-11h-1a37 37 0 0 0-18 8l-1 1-4 2-2 2-5 4c-9-3-36-31-47-44s-32-45-34-55l3-2a151 151 0 0 0 11-9v-1a39 39 0 0 0 5-48l-3-3-11-19-3-4-5-7h-1l-3-3-4-3-5-2a35 35 0 0 0-16-3h-5c-4 1-14 5-24 11l-4 2-4 3-4 2c-9 8-17 17-18 27a380 380 0 0 0 212 259h3c12 0 25-10 36-21l10-12 6-11a39 39 0 0 0-8-40"/> </svg>`; // src/js/modules/core/ui.ts var UI = class _UI { constructor(input, options, id2) { this.#searchKeyupTimer = null; this.#inlineDropdownHeight = null; this.#dropdownForContainer = null; this.#selectedItem = null; this.highlightedItem = null; input.dataset.intlTelInputId = id2.toString(); this.telInput = input; this.#options = options; this.#id = id2; this.hadInitialPlaceholder = Boolean(input.getAttribute("placeholder")); this.#isRTL = !!this.telInput.closest("[dir=rtl]"); if (this.#options.separateDialCode) { this.#originalPaddingLeft = this.telInput.style.paddingLeft; } } // private #options; #id; #isRTL; #originalPaddingLeft; #countries; #searchKeyupTimer; #inlineDropdownHeight; #selectedDialCode; #dropdownArrow; #dropdownContent; #searchIcon; #searchNoResults; #searchResultsA11yText; #dropdownForContainer; #selectedItem; // Validate that the provided element is an HTMLInputElement. static validateInput(input) { const tagName = input?.tagName; const isInputEl = Boolean(input) && typeof input === "object" && tagName === "INPUT" && typeof input.setAttribute === "function"; if (!isInputEl) { const type = Object.prototype.toString.call(input); throw new TypeError( `The first argument must be an HTMLInputElement, not ${type}` ); } } //* Generate all of the markup for the plugin: the selected country overlay, and the dropdown. generateMarkup(countries) { this.#countries = countries; this.telInput.classList.add("iti__tel-input"); if (!this.telInput.hasAttribute("autocomplete")) { this.telInput.setAttribute("autocomplete", "tel"); } if (!this.telInput.hasAttribute("inputmode")) { this.telInput.setAttribute("inputmode", "tel"); } const wrapper = this.#createWrapperAndInsert(); this.#maybeBuildCountryContainer(wrapper); wrapper.appendChild(this.telInput); this.#maybeUpdateInputPaddingAndReveal(); this.#maybeBuildHiddenInputs(wrapper); } #createWrapperAndInsert() { const { allowDropdown, showFlags, containerClass, useFullscreenPopup } = this.#options; const parentClasses = buildClassNames({ iti: true, "iti--allow-dropdown": allowDropdown, "iti--show-flags": showFlags, "iti--inline-dropdown": !useFullscreenPopup, [containerClass]: Boolean(containerClass) }); const wrapper = createEl("div", { class: parentClasses }); if (this.#isRTL) { wrapper.setAttribute("dir", "ltr"); } this.telInput.before(wrapper); return wrapper; } #maybeBuildCountryContainer(wrapper) { const { allowDropdown, separateDialCode, showFlags } = this.#options; if (allowDropdown || showFlags || separateDialCode) { this.countryContainer = createEl( "div", // visibly hidden until we measure it's width to set the input padding correctly { class: `iti__country-container ${CLASSES.V_HIDE}` }, wrapper ); if (allowDropdown) { this.selectedCountry = createEl( "button", { type: "button", class: "iti__selected-country", [ARIA.EXPANDED]: "false", [ARIA.LABEL]: this.#options.i18n.noCountrySelected, [ARIA.HASPOPUP]: "dialog", [ARIA.CONTROLS]: `iti-${this.#id}__dropdown-content` }, this.countryContainer ); if (this.telInput.disabled) { this.selectedCountry.setAttribute("disabled", "true"); } } else { this.selectedCountry = createEl( "div", { class: "iti__selected-country" }, this.countryContainer ); } const selectedCountryPrimary = createEl( "div", { class: "iti__selected-country-primary" }, this.selectedCountry ); this.selectedCountryInner = createEl( "div", { class: CLASSES.FLAG }, selectedCountryPrimary ); if (allowDropdown) { this.#dropdownArrow = createEl( "div", { class: "iti__arrow", [ARIA.HIDDEN]: "true" }, selectedCountryPrimary ); } if (separateDialCode) { this.#selectedDialCode = createEl( "div", { class: "iti__selected-dial-code" }, this.selectedCountry ); } if (allowDropdown) { this.#buildDropdownContent(); } } } #maybeEnsureDropdownWidthSet() { const { fixDropdownWidth } = this.#options; if (fixDropdownWidth && !this.#dropdownContent.style.width) { const inputWidth = this.telInput.offsetWidth; if (inputWidth > 0) { this.#dropdownContent.style.width = `${inputWidth}px`; } } } #buildDropdownContent() { const { fixDropdownWidth, useFullscreenPopup, countrySearch, i18n, dropdownContainer, containerClass } = this.#options; const extraClasses = fixDropdownWidth ? "" : "iti--flexible-dropdown-width"; this.#dropdownContent = createEl("div", { id: `iti-${this.#id}__dropdown-content`, class: `iti__dropdown-content ${CLASSES.HIDE} ${extraClasses}`, role: "dialog", [ARIA.MODAL]: "true" }); if (this.#isRTL) { this.#dropdownContent.setAttribute("dir", "rtl"); } if (countrySearch) { this.#buildSearchUI(); } this.countryList = createEl( "ul", { class: "iti__country-list", id: `iti-${this.#id}__country-listbox`, role: "listbox", [ARIA.LABEL]: i18n.countryListAriaLabel }, this.#dropdownContent ); this.#appendListItems(); if (countrySearch) { this.#updateSearchResultsA11yText(); } if (!useFullscreenPopup) { this.#maybeEnsureDropdownWidthSet(); this.#inlineDropdownHeight = this.#getHiddenInlineDropdownHeight(); if (countrySearch) { this.#dropdownContent.style.height = `${this.#inlineDropdownHeight}px`; } } if (dropdownContainer) { const dropdownClasses = buildClassNames({ iti: true, "iti--container": true, "iti--fullscreen-popup": useFullscreenPopup, "iti--inline-dropdown": !useFullscreenPopup, [containerClass]: Boolean(containerClass) }); this.#dropdownForContainer = createEl("div", { class: dropdownClasses }); this.#dropdownForContainer.appendChild(this.#dropdownContent); } else { this.countryContainer.appendChild(this.#dropdownContent); } } #buildSearchUI() { const { i18n, searchInputClass } = this.#options; const searchWrapper = createEl( "div", { class: "iti__search-input-wrapper" }, this.#dropdownContent ); this.#searchIcon = createEl( "span", { class: "iti__search-icon", [ARIA.HIDDEN]: "true" }, searchWrapper ); this.#searchIcon.innerHTML = buildSearchIcon(); this.searchInput = createEl( "input", { id: `iti-${this.#id}__search-input`, // Chrome says inputs need either a name or an id type: "search", class: `iti__search-input ${searchInputClass}`, placeholder: i18n.searchPlaceholder, // 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 role: "combobox", [ARIA.EXPANDED]: "true", [ARIA.LABEL]: i18n.searchPlaceholder, [ARIA.CONTROLS]: `iti-${this.#id}__country-listbox`, [ARIA.AUTOCOMPLETE]: "list", autocomplete: "off" }, searchWrapper ); this.searchClearButton = createEl( "button", { type: "button", class: `iti__search-clear ${CLASSES.HIDE}`, [ARIA.LABEL]: i18n.clearSearchAriaLabel, tabindex: "-1" }, searchWrapper ); this.searchClearButton.innerHTML = buildClearIcon(this.#id); this.#searchResultsA11yText = createEl( "span", { class: "iti__a11y-text" }, this.#dropdownContent ); this.#searchNoResults = createEl( "div", { class: `iti__no-results ${CLASSES.HIDE}`, [ARIA.HIDDEN]: "true" // all a11y messaging happens in this.#searchResultsA11yText }, this.#dropdownContent ); this.#searchNoResults.textContent = i18n.searchEmptyState; } #maybeUpdateInputPaddingAndReveal() { if (this.countryContainer) { this.#updateInputPadding(); this.countryContainer.classList.remove(CLASSES.V_HIDE); } } #maybeBuildHiddenInputs(wrapper) { const { hiddenInput } = this.#options; if (hiddenInput) { const telInputName = this.telInput.getAttribute("name") || ""; const names = hiddenInput(telInputName); if (names.phone