@alikhalilll/ui 1.2.1 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.md +68 -45
  2. package/dist/assets/styles.css +2 -74
  3. package/dist/chunks/AResponsivePopoverContent.vue_vue_type_script_setup_true_lang-BrBsDiHc.mjs +113 -0
  4. package/dist/chunks/AResponsivePopoverContent.vue_vue_type_script_setup_true_lang-BrBsDiHc.mjs.map +1 -0
  5. package/dist/chunks/ATellInput.vue_vue_type_script_setup_true_lang-D4odgAna.mjs +1606 -0
  6. package/dist/chunks/ATellInput.vue_vue_type_script_setup_true_lang-D4odgAna.mjs.map +1 -0
  7. package/dist/chunks/useEventScrollLock-BcP8fg-L.mjs +241 -0
  8. package/dist/chunks/useEventScrollLock-BcP8fg-L.mjs.map +1 -0
  9. package/dist/entries/drawer/components/ADrawer.vue.d.ts +27 -0
  10. package/dist/entries/drawer/components/ADrawer.vue.d.ts.map +1 -0
  11. package/dist/entries/drawer/components/ADrawerContent.vue.d.ts +29 -0
  12. package/dist/entries/drawer/components/ADrawerContent.vue.d.ts.map +1 -0
  13. package/dist/entries/drawer/components/ADrawerOverlay.vue.d.ts +9 -0
  14. package/dist/entries/drawer/components/ADrawerOverlay.vue.d.ts.map +1 -0
  15. package/dist/entries/drawer/components/ADrawerTrigger.vue.d.ts +11 -0
  16. package/dist/entries/drawer/components/ADrawerTrigger.vue.d.ts.map +1 -0
  17. package/dist/entries/drawer/index.d.ts +5 -0
  18. package/dist/entries/drawer/index.d.ts.map +1 -0
  19. package/dist/entries/input/components/AInput.vue.d.ts +32 -0
  20. package/dist/entries/input/components/AInput.vue.d.ts.map +1 -0
  21. package/dist/entries/input/index.d.ts +2 -0
  22. package/dist/entries/input/index.d.ts.map +1 -0
  23. package/dist/entries/popover/components/APopover.vue.d.ts +20 -0
  24. package/dist/entries/popover/components/APopover.vue.d.ts.map +1 -0
  25. package/dist/entries/popover/components/APopoverContent.vue.d.ts +44 -0
  26. package/dist/entries/popover/components/APopoverContent.vue.d.ts.map +1 -0
  27. package/dist/entries/popover/components/APopoverOverlay.vue.d.ts +17 -0
  28. package/dist/entries/popover/components/APopoverOverlay.vue.d.ts.map +1 -0
  29. package/dist/entries/popover/components/APopoverTrigger.vue.d.ts +11 -0
  30. package/dist/entries/popover/components/APopoverTrigger.vue.d.ts.map +1 -0
  31. package/dist/entries/popover/composables/useEventScrollLock.d.ts +21 -0
  32. package/dist/entries/popover/composables/useEventScrollLock.d.ts.map +1 -0
  33. package/dist/entries/popover/index.d.ts +6 -0
  34. package/dist/entries/popover/index.d.ts.map +1 -0
  35. package/dist/entries/responsive-popover/components/AResponsivePopover.vue.d.ts +46 -0
  36. package/dist/entries/responsive-popover/components/AResponsivePopover.vue.d.ts.map +1 -0
  37. package/dist/entries/responsive-popover/components/AResponsivePopoverContent.vue.d.ts +35 -0
  38. package/dist/entries/responsive-popover/components/AResponsivePopoverContent.vue.d.ts.map +1 -0
  39. package/dist/entries/responsive-popover/components/AResponsivePopoverTrigger.vue.d.ts +16 -0
  40. package/dist/entries/responsive-popover/components/AResponsivePopoverTrigger.vue.d.ts.map +1 -0
  41. package/dist/entries/responsive-popover/composables/useResponsivePopoverContext.d.ts +10 -0
  42. package/dist/entries/responsive-popover/composables/useResponsivePopoverContext.d.ts.map +1 -0
  43. package/dist/entries/responsive-popover/index.d.ts +4 -0
  44. package/dist/entries/responsive-popover/index.d.ts.map +1 -0
  45. package/dist/entries/tell-input/components/ACountryFlag.vue.d.ts +26 -0
  46. package/dist/entries/tell-input/components/ACountryFlag.vue.d.ts.map +1 -0
  47. package/dist/entries/tell-input/components/ACountrySelect.vue.d.ts +136 -0
  48. package/dist/entries/tell-input/components/ACountrySelect.vue.d.ts.map +1 -0
  49. package/dist/entries/tell-input/components/ATellInput.vue.d.ts +141 -0
  50. package/dist/entries/tell-input/components/ATellInput.vue.d.ts.map +1 -0
  51. package/dist/entries/tell-input/composables/useCountryDetection.d.ts +44 -0
  52. package/dist/entries/tell-input/composables/useCountryDetection.d.ts.map +1 -0
  53. package/dist/entries/tell-input/composables/useCountryMatching.d.ts +44 -0
  54. package/dist/entries/tell-input/composables/useCountryMatching.d.ts.map +1 -0
  55. package/dist/entries/tell-input/composables/usePhoneValidation.d.ts +110 -0
  56. package/dist/entries/tell-input/composables/usePhoneValidation.d.ts.map +1 -0
  57. package/dist/entries/tell-input/composables/useTellInputValidation.d.ts +67 -0
  58. package/dist/entries/tell-input/composables/useTellInputValidation.d.ts.map +1 -0
  59. package/dist/entries/tell-input/composables/useTypingPhase.d.ts +50 -0
  60. package/dist/entries/tell-input/composables/useTypingPhase.d.ts.map +1 -0
  61. package/dist/entries/tell-input/index.d.ts +12 -0
  62. package/dist/entries/tell-input/index.d.ts.map +1 -0
  63. package/dist/entries/tell-input/utils/digits.d.ts +22 -0
  64. package/dist/entries/tell-input/utils/digits.d.ts.map +1 -0
  65. package/dist/entries/tell-input/utils/flag-url.d.ts +8 -0
  66. package/dist/entries/tell-input/utils/flag-url.d.ts.map +1 -0
  67. package/dist/entries/tell-input/utils/types.d.ts +120 -0
  68. package/dist/entries/tell-input/utils/types.d.ts.map +1 -0
  69. package/dist/index.d.ts +7 -1139
  70. package/dist/index.d.ts.map +1 -0
  71. package/dist/index.mjs +39 -33
  72. package/dist/popover.mjs +5 -4
  73. package/dist/responsive-popover.mjs +1 -1
  74. package/dist/tell-input.mjs +14 -9
  75. package/dist/utils/cn.d.ts +3 -0
  76. package/dist/utils/cn.d.ts.map +1 -0
  77. package/dist/utils/index.d.ts +3 -0
  78. package/dist/utils/index.d.ts.map +1 -0
  79. package/dist/{utils.d.ts → utils/sizes.d.ts} +18 -29
  80. package/dist/utils/sizes.d.ts.map +1 -0
  81. package/package.json +14 -10
  82. package/dist/chunks/APopoverContent.vue_vue_type_script_setup_true_lang-CjiJ12DR.mjs +0 -132
  83. package/dist/chunks/APopoverContent.vue_vue_type_script_setup_true_lang-CjiJ12DR.mjs.map +0 -1
  84. package/dist/chunks/AResponsivePopoverContent.vue_vue_type_script_setup_true_lang-5YbO6FdM.mjs +0 -92
  85. package/dist/chunks/AResponsivePopoverContent.vue_vue_type_script_setup_true_lang-5YbO6FdM.mjs.map +0 -1
  86. package/dist/chunks/ATellInput.vue_vue_type_script_setup_true_lang-D7hPj1g1.mjs +0 -1489
  87. package/dist/chunks/ATellInput.vue_vue_type_script_setup_true_lang-D7hPj1g1.mjs.map +0 -1
  88. package/dist/drawer.d.ts +0 -116
  89. package/dist/input.d.ts +0 -65
  90. package/dist/popover.d.ts +0 -117
  91. package/dist/responsive-popover.d.ts +0 -124
  92. package/dist/tell-input.d.ts +0 -740
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ATellInput.vue_vue_type_script_setup_true_lang-D4odgAna.mjs","sources":["../../entries/tell-input/utils/digits.ts","../../entries/tell-input/composables/usePhoneValidation.ts","../../entries/tell-input/composables/useCountryDetection.ts","../../entries/tell-input/composables/useCountryMatching.ts","../../entries/tell-input/composables/useTypingPhase.ts","../../entries/tell-input/composables/useTellInputValidation.ts","../../entries/tell-input/utils/types.ts","../../entries/tell-input/utils/flag-url.ts","../../entries/tell-input/components/ACountryFlag.vue","../../entries/tell-input/components/ACountrySelect.vue","../../entries/tell-input/components/ATellInput.vue"],"sourcesContent":["/**\n * Alternative-numeral support. Phone numbers are routinely entered with the digits of the\n * user's own script — Arabic-Indic, Persian/Urdu, Devanagari, Bengali. `libphonenumber-js`\n * and our own `\\d` cleanup only understand ASCII `0-9`, so anything else silently becomes\n * an empty number. `normalizeDigits` folds those scripts down to ASCII before validation.\n */\n\n/**\n * Base code points of contiguous decimal-digit blocks. Each block runs `base`‥`base+9`\n * for digit `0`‥`9`, so the ASCII digit is `codePoint - base`. Add a script by appending\n * one entry here.\n */\nexport const LOCALE_DIGIT_RANGES: { name: string; base: number }[] = [\n { name: 'arabic-indic', base: 0x0660 }, // ٠١٢٣٤٥٦٧٨٩\n { name: 'extended-arabic', base: 0x06f0 }, // ۰۱۲۳۴۵۶۷۸۹ — Persian / Urdu\n { name: 'devanagari', base: 0x0966 }, // ०१२३४५६७८९\n { name: 'bengali', base: 0x09e6 }, // ০১২৩৪৫৬৭৮৯\n];\n\n/** Lookup of every non-ASCII digit code point → its ASCII character. */\nconst DIGIT_MAP: Map<number, string> = (() => {\n const map = new Map<number, string>();\n for (const { base } of LOCALE_DIGIT_RANGES) {\n for (let d = 0; d <= 9; d++) map.set(base + d, String(d));\n }\n return map;\n})();\n\n/**\n * Replace any supported non-ASCII decimal digit with its ASCII equivalent. Every other\n * character (spaces, `+`, separators, letters) is left untouched — callers still run their\n * own `\\D` cleanup afterwards.\n */\nexport function normalizeDigits(input: string): string {\n const str = String(input ?? '');\n let out = '';\n for (const ch of str) {\n const cp = ch.codePointAt(0);\n out += (cp != null && DIGIT_MAP.get(cp)) || ch;\n }\n return out;\n}\n","/**\n * Country list + phone validation, framework-agnostic.\n *\n * Ported from the reference @pkgs/ui ATellInput composable with these cleanups:\n * - Drop Nuxt-only `process.client` checks → use plain `typeof window !== 'undefined'`.\n * - Drop Arabic default placeholder; let consumers pass their own.\n * - Expand the offline fallback list from 2 → ~20 of the most-populated countries.\n * - Keep REST Countries fetch + localStorage cache + libphonenumber-js examples + fast `search_key`.\n */\n\nimport { ref, type Ref } from 'vue';\nimport {\n type CountryCode,\n type Examples,\n getExampleNumber,\n isValidPhoneNumber,\n parsePhoneNumberFromString,\n} from 'libphonenumber-js';\nimport examples from 'libphonenumber-js/examples.mobile.json';\nimport { normalizeDigits } from '../utils/digits';\n\n/* -----------------------------------------------------------------------------\n * Public types\n * -------------------------------------------------------------------------- */\nexport interface RestCountry {\n name?: { common?: string };\n cca2?: string;\n idd?: { root?: string; suffixes?: string[] };\n flags?: { png?: string; svg?: string };\n}\n\nexport interface CountryOption<T = RestCountry> {\n /** Display label, e.g. \"Egypt (+20)\". */\n label: string;\n /** Stable unique ID — the ISO 3166-1 alpha-2 code, e.g. \"EG\". */\n value: string;\n /** Precomputed normalized string for fast substring search. */\n search_key: string;\n raw_data: {\n iso2: string;\n dial_code: string;\n dial_digits: string;\n name: string;\n flag: string | null;\n source: 'restcountries' | 'fallback';\n original: T;\n };\n}\n\nexport interface PhoneRequiredInfo {\n iso2: string;\n dial_code: string;\n /** Empty by default — consumer passes a placeholder via the component prop. */\n placeholder: string;\n example_national: string;\n example_e164: string;\n national_number_length: { min: number | null; max: number | null };\n format_hint: string;\n}\n\nexport type PhoneValidationReason =\n | 'missing_country'\n | 'country_not_supported'\n | 'phone_has_non_digits'\n | 'too_short'\n | 'too_long'\n | 'invalid_phone'\n | 'parse_failed';\n\nexport interface PhoneValidationResult {\n ok: boolean;\n reason: PhoneValidationReason | null;\n country: { iso2: string; dial_code: string } | null;\n phone: { raw: string | null; digits: string };\n full_phone: string | null;\n required: PhoneRequiredInfo | null;\n details?: Record<string, unknown>;\n}\n\nexport type ValidateArgs =\n | {\n country: { iso2: string; dial_code?: string } | null | undefined;\n phone?: undefined;\n /** BCP-47 locale — localizes the numerals in the returned `required.format_hint`. */\n locale?: string;\n }\n | {\n country: { iso2: string; dial_code?: string } | null | undefined;\n phone: string | null;\n /** BCP-47 locale — localizes the numerals in the returned `required.format_hint`. */\n locale?: string;\n };\n\nconst STORAGE_KEY = 'ali_ui_phone_countries_v1';\nconst REST_COUNTRIES_URL = 'https://restcountries.com/v3.1/all?fields=name,cca2,idd,flags';\n\nconst EX = examples as unknown as Examples;\n\nconst isBrowser = () => typeof window !== 'undefined';\n\nfunction toDigits(v: unknown) {\n // Fold alternative numeral systems (Arabic-Indic, Persian, Devanagari, Bengali) down to\n // ASCII first, so a number typed in the user's own script still validates.\n return normalizeDigits(String(v ?? '')).replace(/\\D/g, '');\n}\n\n/**\n * Render an ASCII digit string in a locale's numeral system (e.g. `'ar'` → `٠-٩`).\n * Used only for display hints — falls back to ASCII if the locale is unknown.\n */\nfunction localizeDigits(digits: string, locale?: string): string {\n if (!locale) return digits;\n try {\n const fmt = new Intl.NumberFormat(locale, { useGrouping: false });\n return digits.replace(/[0-9]/g, (d) => fmt.format(Number(d)));\n } catch {\n return digits;\n }\n}\n\nfunction ensurePlusDial(dial: unknown) {\n const d = toDigits(dial);\n return d ? `+${d}` : '';\n}\n\nfunction normalizeIso2(iso2: unknown) {\n return String(iso2 ?? '')\n .trim()\n .toUpperCase();\n}\n\nfunction dropLeadingZeros(digits: string) {\n return String(digits ?? '').replace(/^0+/, '');\n}\n\nfunction buildFullE164(dial: string, digits: string) {\n const dialClean = ensurePlusDial(dial);\n const nsn = dropLeadingZeros(toDigits(digits));\n return dialClean && nsn ? `${dialClean}${nsn}` : null;\n}\n\nfunction inferLengthFromExample(national: string) {\n const d = toDigits(national);\n if (!d) return { min: null, max: null };\n const n = d.length;\n return { min: Math.max(4, n - 2), max: n + 2 };\n}\n\nfunction buildDialCode(idd?: RestCountry['idd']): string | null {\n const root = idd?.root?.trim();\n if (!root || !root.startsWith('+')) return null;\n const suffix = idd?.suffixes?.[0]?.trim() ?? '';\n const out = `${root}${suffix}`;\n return out.startsWith('+') ? out : null;\n}\n\nfunction normalizeSearchKey(input: string) {\n return (\n String(input ?? '')\n .toLowerCase()\n .replace(/\\s+/g, ' ')\n .trim()\n // Keep letters of every script (so localized names — Arabic, etc. — stay searchable),\n // digits, `+`, and spaces; drop punctuation/symbols.\n .replace(/[^\\p{L}\\p{N}+ ]/gu, '')\n );\n}\n\n/**\n * Return a copy of the country list with display names localized to `locale` via\n * `Intl.DisplayNames`. `search_key` is rebuilt (keeping the English name too) so search\n * still matches either spelling. Unknown locales / regions fall back to the English name.\n */\nexport function localizeCountries(list: CountryOption[], locale?: string): CountryOption[] {\n if (!locale) return list;\n let display: Intl.DisplayNames;\n try {\n display = new Intl.DisplayNames([locale], { type: 'region' });\n } catch {\n return list;\n }\n return list.map((c) => {\n let localized = c.raw_data.name;\n try {\n localized = display.of(c.raw_data.iso2) || c.raw_data.name;\n } catch {\n /* region not in CLDR data — keep English name */\n }\n if (localized === c.raw_data.name) return c;\n const dial = c.raw_data.dial_code;\n return {\n ...c,\n label: `${localized} (${dial})`,\n search_key: normalizeSearchKey(\n `${localized} ${c.raw_data.name} ${dial} ${c.raw_data.iso2} ${c.raw_data.dial_digits}`\n ),\n raw_data: { ...c.raw_data, name: localized },\n };\n });\n}\n\n/* -----------------------------------------------------------------------------\n * Offline fallback — used when the REST Countries fetch fails. ~20 most-populated\n * countries so the picker is still useful when offline.\n * -------------------------------------------------------------------------- */\nfunction makeFallback(iso2: string, name: string, dial: string): CountryOption {\n const dialDigits = toDigits(dial);\n return {\n label: `${name} (+${dialDigits})`,\n value: iso2,\n search_key: normalizeSearchKey(`${name} +${dialDigits} ${iso2}`),\n raw_data: {\n iso2,\n dial_code: `+${dialDigits}`,\n dial_digits: dialDigits,\n name,\n flag: `https://flagcdn.com/w40/${iso2.toLowerCase()}.png`,\n source: 'fallback',\n original: {},\n },\n };\n}\n\nconst FALLBACK_COUNTRIES: CountryOption[] = [\n makeFallback('SA', 'Saudi Arabia', '+966'),\n makeFallback('EG', 'Egypt', '+20'),\n makeFallback('AE', 'United Arab Emirates', '+971'),\n makeFallback('US', 'United States', '+1'),\n makeFallback('GB', 'United Kingdom', '+44'),\n makeFallback('DE', 'Germany', '+49'),\n makeFallback('FR', 'France', '+33'),\n makeFallback('ES', 'Spain', '+34'),\n makeFallback('IT', 'Italy', '+39'),\n makeFallback('TR', 'Turkey', '+90'),\n makeFallback('RU', 'Russia', '+7'),\n makeFallback('CN', 'China', '+86'),\n makeFallback('IN', 'India', '+91'),\n makeFallback('JP', 'Japan', '+81'),\n makeFallback('KR', 'South Korea', '+82'),\n makeFallback('BR', 'Brazil', '+55'),\n makeFallback('MX', 'Mexico', '+52'),\n makeFallback('CA', 'Canada', '+1'),\n makeFallback('AU', 'Australia', '+61'),\n makeFallback('NG', 'Nigeria', '+234'),\n makeFallback('PK', 'Pakistan', '+92'),\n makeFallback('ID', 'Indonesia', '+62'),\n];\n\n/* -----------------------------------------------------------------------------\n * Composable\n * -------------------------------------------------------------------------- */\nexport interface UsePhoneValidationReturn {\n countries: Ref<CountryOption[]>;\n isCountriesLoading: Ref<boolean>;\n getCountries(options?: { force?: boolean }): Promise<CountryOption[]>;\n searchCountries(keyword: string, limit?: number): CountryOption[];\n getCountryByValue(value: string): CountryOption | null;\n getCountriesByDial(dial: string): CountryOption[];\n getRequiredInfo(\n country: { iso2: string; dial_code?: string },\n locale?: string\n ): PhoneRequiredInfo | null;\n validate(input: ValidateArgs): PhoneValidationResult;\n}\n\nexport function usePhoneValidation(): UsePhoneValidationReturn {\n const countries = ref<CountryOption[]>([]);\n const isCountriesLoading = ref(false);\n\n const byValue = ref<Map<string, CountryOption>>(new Map());\n const byDialDigits = ref<Map<string, CountryOption[]>>(new Map());\n\n function rebuildIndexes(list: CountryOption[]) {\n const valueMap = new Map<string, CountryOption>();\n const dialMap = new Map<string, CountryOption[]>();\n for (const item of list) {\n valueMap.set(item.value, item);\n const dial = item.raw_data.dial_digits;\n if (dial) {\n const bucket = dialMap.get(dial) ?? [];\n bucket.push(item);\n dialMap.set(dial, bucket);\n }\n }\n byValue.value = valueMap;\n byDialDigits.value = dialMap;\n }\n\n function upsertCountries(list: CountryOption[]) {\n countries.value = list;\n rebuildIndexes(list);\n }\n\n function normalizeRestCountries(list: RestCountry[]): CountryOption[] {\n const out: CountryOption[] = [];\n for (const c of list) {\n const name = c?.name?.common?.trim();\n const iso2 = normalizeIso2(c?.cca2);\n const dial = buildDialCode(c?.idd);\n const flag = c?.flags?.png?.trim() || c?.flags?.svg?.trim() || null;\n if (!name || !iso2 || !dial) continue;\n const dialDigits = toDigits(dial);\n const search_key = normalizeSearchKey(`${name} ${dial} ${iso2} ${dialDigits}`);\n out.push({\n label: `${name} (${dial})`,\n value: iso2,\n search_key,\n raw_data: {\n iso2,\n dial_code: dial,\n dial_digits: dialDigits,\n name,\n flag,\n source: 'restcountries',\n original: c,\n },\n });\n }\n\n const map = new Map<string, CountryOption>();\n for (const item of out) {\n const prev = map.get(item.value);\n if (!prev) {\n map.set(item.value, item);\n continue;\n }\n const prevScore = (prev.raw_data.flag ? 1 : 0) + (prev.raw_data.dial_code ? 1 : 0);\n const nextScore = (item.raw_data.flag ? 1 : 0) + (item.raw_data.dial_code ? 1 : 0);\n if (nextScore > prevScore) map.set(item.value, item);\n }\n return Array.from(map.values()).sort((a, b) => a.raw_data.name.localeCompare(b.raw_data.name));\n }\n\n async function getCountries(options?: { force?: boolean }) {\n const force = Boolean(options?.force);\n if (!force && countries.value.length) return countries.value;\n\n if (!force && isBrowser()) {\n try {\n const cached = localStorage.getItem(STORAGE_KEY);\n if (cached) {\n const parsed = JSON.parse(cached) as CountryOption[];\n if (Array.isArray(parsed) && parsed.length) {\n upsertCountries(parsed);\n return countries.value;\n }\n }\n } catch {\n /* ignore parse errors */\n }\n }\n\n isCountriesLoading.value = true;\n try {\n const res = await fetch(REST_COUNTRIES_URL);\n if (!res.ok) throw new Error(`Failed to fetch countries: ${res.status}`);\n const data = (await res.json()) as RestCountry[];\n const normalized = normalizeRestCountries(data);\n upsertCountries(normalized.length ? normalized : FALLBACK_COUNTRIES);\n if (isBrowser()) {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(countries.value));\n } catch {\n /* storage full or disabled */\n }\n }\n return countries.value;\n } catch {\n upsertCountries(FALLBACK_COUNTRIES);\n return countries.value;\n } finally {\n isCountriesLoading.value = false;\n }\n }\n\n function searchCountries(keyword: string, limit = 50) {\n const q = normalizeSearchKey(keyword);\n if (!q) return countries.value.slice(0, limit);\n const res: CountryOption[] = [];\n for (const item of countries.value) {\n if (item.search_key.includes(q)) {\n res.push(item);\n if (res.length >= limit) break;\n }\n }\n return res;\n }\n\n function getCountryByValue(value: string) {\n return byValue.value.get(normalizeIso2(value)) ?? null;\n }\n\n function getCountriesByDial(dial: string) {\n return byDialDigits.value.get(toDigits(dial)) ?? [];\n }\n\n function getRequiredInfo(\n country: { iso2: string; dial_code?: string },\n locale?: string\n ): PhoneRequiredInfo | null {\n const iso2 = normalizeIso2(country.iso2);\n if (!iso2) return null;\n try {\n const example = getExampleNumber(iso2 as CountryCode, EX);\n const exampleNational = example?.formatNational?.() ?? '';\n const exampleE164 = example?.format?.('E.164') ?? '';\n const inferred = inferLengthFromExample(exampleNational);\n const dial_code = country.dial_code\n ? ensurePlusDial(country.dial_code)\n : exampleE164\n ? `+${example?.countryCallingCode}`\n : '';\n const digitsExample = toDigits(exampleNational);\n return {\n iso2,\n dial_code,\n placeholder: '',\n example_national: exampleNational,\n example_e164: exampleE164,\n national_number_length: inferred,\n format_hint: digitsExample ? `e.g. ${localizeDigits(digitsExample, locale)}` : '',\n };\n } catch {\n return null;\n }\n }\n\n function validate(input: ValidateArgs): PhoneValidationResult {\n const country = input.country ?? null;\n if (!country?.iso2) {\n return {\n ok: false,\n reason: 'missing_country',\n country: null,\n phone: { raw: ('phone' in input ? input.phone : null) ?? null, digits: '' },\n full_phone: null,\n required: null,\n };\n }\n\n const iso2 = normalizeIso2(country.iso2);\n const required = getRequiredInfo({ iso2, dial_code: country.dial_code }, input.locale);\n if (!required) {\n return {\n ok: false,\n reason: 'country_not_supported',\n country: { iso2, dial_code: ensurePlusDial(country.dial_code) },\n phone: { raw: ('phone' in input ? input.phone : null) ?? null, digits: '' },\n full_phone: null,\n required: null,\n };\n }\n\n if (!('phone' in input)) {\n return {\n ok: true,\n reason: null,\n country: { iso2: required.iso2, dial_code: required.dial_code },\n phone: { raw: null, digits: '' },\n full_phone: null,\n required,\n };\n }\n\n const raw = input.phone;\n const digits = toDigits(raw);\n\n if (!raw || !String(raw).trim()) {\n return {\n ok: true,\n reason: null,\n country: { iso2: required.iso2, dial_code: required.dial_code },\n phone: { raw: raw ?? null, digits: '' },\n full_phone: null,\n required,\n };\n }\n\n if (\n String(raw)\n .replace(/\\s+/g, '')\n .match(/[^\\d+]/)\n ) {\n return {\n ok: false,\n reason: 'phone_has_non_digits',\n country: { iso2: required.iso2, dial_code: required.dial_code },\n phone: { raw, digits },\n full_phone: buildFullE164(required.dial_code, digits),\n required,\n };\n }\n\n const nsn = dropLeadingZeros(digits);\n const { min, max } = required.national_number_length;\n\n if (min !== null && nsn.length < min) {\n return {\n ok: false,\n reason: 'too_short',\n country: { iso2: required.iso2, dial_code: required.dial_code },\n phone: { raw, digits },\n full_phone: buildFullE164(required.dial_code, digits),\n required,\n details: { min, actual: nsn.length },\n };\n }\n\n if (max !== null && nsn.length > max) {\n return {\n ok: false,\n reason: 'too_long',\n country: { iso2: required.iso2, dial_code: required.dial_code },\n phone: { raw, digits },\n full_phone: buildFullE164(required.dial_code, digits),\n required,\n details: { max, actual: nsn.length },\n };\n }\n\n const full = buildFullE164(required.dial_code, digits) ?? String(raw);\n\n try {\n const ok = isValidPhoneNumber(full, iso2 as CountryCode);\n if (!ok) {\n const parsed = parsePhoneNumberFromString(full, iso2 as CountryCode);\n return {\n ok: false,\n reason: 'invalid_phone',\n country: { iso2: required.iso2, dial_code: required.dial_code },\n phone: { raw, digits },\n full_phone: parsed?.number ?? null,\n required,\n details: {\n type: parsed?.getType?.() ?? null,\n possible: parsed?.isPossible?.() ?? null,\n country: parsed?.country ?? null,\n },\n };\n }\n const parsed = parsePhoneNumberFromString(full, iso2 as CountryCode);\n return {\n ok: true,\n reason: null,\n country: { iso2: required.iso2, dial_code: required.dial_code },\n phone: { raw, digits },\n full_phone: parsed?.number ?? full,\n required,\n };\n } catch (e) {\n return {\n ok: false,\n reason: 'parse_failed',\n country: { iso2: required.iso2, dial_code: required.dial_code },\n phone: { raw, digits },\n full_phone: buildFullE164(required.dial_code, digits),\n required,\n details: { error: (e as Error)?.message ?? String(e) },\n };\n }\n }\n\n return {\n countries,\n isCountriesLoading,\n getCountries,\n searchCountries,\n getCountryByValue,\n getCountriesByDial,\n getRequiredInfo,\n validate,\n };\n}\n","/**\n * Best-effort country detection chain: IP geolocation → timezone → navigator.language → fallback.\n * Every step is independent and degrades gracefully; the final fallback is always returned.\n *\n * The composable returns reactive state so consumers can swap in the detected ISO2 the moment it\n * resolves, while still rendering an input immediately on mount.\n */\n\nimport { onMounted, ref, type Ref } from 'vue';\n\nexport type DetectionStrategy = 'auto' | 'locale' | 'none';\n\nexport interface DetectCountryOptions {\n /**\n * - `'auto'` — try IP geolocation first, then timezone, then `navigator.language`, then default.\n * - `'locale'` — skip the network call, use timezone + locale only.\n * - `'none'` — return `defaultCountry` immediately.\n */\n strategy?: DetectionStrategy;\n /** Endpoint returning a JSON body with a `country_code` (or `country`) field. */\n ipEndpoint?: string;\n /** Fallback ISO2 used when every step fails. */\n defaultCountry?: string;\n /** Abort the IP request after this many ms. */\n timeoutMs?: number;\n /** Persist the resolved country in sessionStorage so re-mounts within the session skip detection. */\n cache?: boolean;\n}\n\nconst SESSION_CACHE_KEY = 'ali_ui_country_detected';\n\nconst isBrowser = () => typeof window !== 'undefined' && typeof document !== 'undefined';\n\n/** Hand-rolled IANA timezone → ISO2 map. Covers the most-populated zones; falls through on miss. */\nconst TIMEZONE_TO_ISO2: Record<string, string> = {\n // Africa\n 'Africa/Cairo': 'EG',\n 'Africa/Johannesburg': 'ZA',\n 'Africa/Lagos': 'NG',\n 'Africa/Casablanca': 'MA',\n 'Africa/Algiers': 'DZ',\n 'Africa/Nairobi': 'KE',\n 'Africa/Accra': 'GH',\n 'Africa/Tunis': 'TN',\n // Americas\n 'America/Argentina/Buenos_Aires': 'AR',\n 'America/Bogota': 'CO',\n 'America/Caracas': 'VE',\n 'America/Chicago': 'US',\n 'America/Denver': 'US',\n 'America/Halifax': 'CA',\n 'America/Lima': 'PE',\n 'America/Los_Angeles': 'US',\n 'America/Mexico_City': 'MX',\n 'America/New_York': 'US',\n 'America/Phoenix': 'US',\n 'America/Sao_Paulo': 'BR',\n 'America/Santiago': 'CL',\n 'America/Toronto': 'CA',\n 'America/Vancouver': 'CA',\n // Asia\n 'Asia/Baghdad': 'IQ',\n 'Asia/Bahrain': 'BH',\n 'Asia/Bangkok': 'TH',\n 'Asia/Beirut': 'LB',\n 'Asia/Damascus': 'SY',\n 'Asia/Dhaka': 'BD',\n 'Asia/Dubai': 'AE',\n 'Asia/Hong_Kong': 'HK',\n 'Asia/Jakarta': 'ID',\n 'Asia/Jerusalem': 'IL',\n 'Asia/Karachi': 'PK',\n 'Asia/Kolkata': 'IN',\n 'Asia/Kuala_Lumpur': 'MY',\n 'Asia/Kuwait': 'KW',\n 'Asia/Manila': 'PH',\n 'Asia/Muscat': 'OM',\n 'Asia/Qatar': 'QA',\n 'Asia/Riyadh': 'SA',\n 'Asia/Seoul': 'KR',\n 'Asia/Shanghai': 'CN',\n 'Asia/Singapore': 'SG',\n 'Asia/Taipei': 'TW',\n 'Asia/Tehran': 'IR',\n 'Asia/Tokyo': 'JP',\n 'Asia/Yangon': 'MM',\n // Europe\n 'Europe/Amsterdam': 'NL',\n 'Europe/Athens': 'GR',\n 'Europe/Belgrade': 'RS',\n 'Europe/Berlin': 'DE',\n 'Europe/Brussels': 'BE',\n 'Europe/Bucharest': 'RO',\n 'Europe/Budapest': 'HU',\n 'Europe/Copenhagen': 'DK',\n 'Europe/Dublin': 'IE',\n 'Europe/Helsinki': 'FI',\n 'Europe/Istanbul': 'TR',\n 'Europe/Kyiv': 'UA',\n 'Europe/Lisbon': 'PT',\n 'Europe/London': 'GB',\n 'Europe/Madrid': 'ES',\n 'Europe/Moscow': 'RU',\n 'Europe/Oslo': 'NO',\n 'Europe/Paris': 'FR',\n 'Europe/Prague': 'CZ',\n 'Europe/Rome': 'IT',\n 'Europe/Sofia': 'BG',\n 'Europe/Stockholm': 'SE',\n 'Europe/Vienna': 'AT',\n 'Europe/Warsaw': 'PL',\n 'Europe/Zurich': 'CH',\n // Oceania\n 'Australia/Brisbane': 'AU',\n 'Australia/Melbourne': 'AU',\n 'Australia/Perth': 'AU',\n 'Australia/Sydney': 'AU',\n 'Pacific/Auckland': 'NZ',\n 'Pacific/Honolulu': 'US',\n};\n\nfunction tryTimezone(): string | null {\n if (!isBrowser()) return null;\n try {\n const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;\n return TIMEZONE_TO_ISO2[tz] ?? null;\n } catch {\n return null;\n }\n}\n\nfunction tryLocale(): string | null {\n if (!isBrowser()) return null;\n try {\n const lang = navigator.language ?? '';\n const m = lang.match(/^[a-z]{2,3}-([A-Z]{2})/);\n return m ? m[1] : null;\n } catch {\n return null;\n }\n}\n\nasync function tryIp(endpoint: string, timeoutMs: number): Promise<string | null> {\n if (!isBrowser() || typeof fetch !== 'function') return null;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await fetch(endpoint, { signal: controller.signal, credentials: 'omit' });\n if (!res.ok) return null;\n const data = (await res.json()) as { country_code?: string; country?: string };\n const code = (data.country_code ?? data.country ?? '').toString().toUpperCase();\n return /^[A-Z]{2}$/.test(code) ? code : null;\n } catch {\n return null;\n } finally {\n clearTimeout(timer);\n }\n}\n\nfunction readCache(): string | null {\n if (!isBrowser()) return null;\n try {\n const v = sessionStorage.getItem(SESSION_CACHE_KEY);\n return v && /^[A-Z]{2}$/.test(v) ? v : null;\n } catch {\n return null;\n }\n}\n\nfunction writeCache(iso2: string) {\n if (!isBrowser()) return;\n try {\n sessionStorage.setItem(SESSION_CACHE_KEY, iso2);\n } catch {\n /* quota or storage disabled — silently ignore */\n }\n}\n\n/**\n * Imperative API. Use this when you want to call detection from outside Vue (e.g. inside a\n * non-component composable, server middleware, or unit test).\n */\nexport async function detectCountry(opts: DetectCountryOptions = {}): Promise<string> {\n const {\n strategy = 'auto',\n ipEndpoint = 'https://ipapi.co/json/',\n defaultCountry = 'US',\n timeoutMs = 2000,\n cache = true,\n } = opts;\n\n if (cache) {\n const cached = readCache();\n if (cached) return cached;\n }\n\n if (strategy === 'none') {\n return defaultCountry.toUpperCase();\n }\n\n if (strategy === 'auto') {\n const ipResult = await tryIp(ipEndpoint, timeoutMs);\n if (ipResult) {\n if (cache) writeCache(ipResult);\n return ipResult;\n }\n }\n\n const localResult = tryTimezone() ?? tryLocale();\n const final = (localResult ?? defaultCountry).toUpperCase();\n if (cache) writeCache(final);\n return final;\n}\n\nexport interface UseCountryDetectionReturn {\n /** Resolved ISO2 code. Initially `null` until detection completes. */\n country: Ref<string | null>;\n /** True while detection is in flight. */\n isLoading: Ref<boolean>;\n /** Manually re-run detection (e.g. after the user changes their VPN). */\n refresh: () => Promise<string>;\n}\n\n/**\n * Reactive wrapper. Kicks off detection in `onMounted` so SSR renders an empty value and the\n * client patches in the real country once resolved.\n */\nexport function useCountryDetection(opts: DetectCountryOptions = {}): UseCountryDetectionReturn {\n const country = ref<string | null>(null);\n const isLoading = ref(false);\n\n async function run() {\n isLoading.value = true;\n try {\n country.value = await detectCountry(opts);\n } finally {\n isLoading.value = false;\n }\n return country.value!;\n }\n\n onMounted(() => {\n void run();\n });\n\n return { country, isLoading, refresh: run };\n}\n","import { parsePhoneNumberFromString, type CountryCode } from 'libphonenumber-js';\nimport type { CountryOption } from './usePhoneValidation';\n\n/** Synchronous dial-digit → ISO2 fallback for common countries, used when the async\n * REST Countries fetch hasn't populated `getCountriesByDial`'s index yet at setup. */\nexport const DIAL_TO_ISO2_FALLBACK: Record<string, string> = {\n '1': 'US',\n '7': 'RU',\n '20': 'EG',\n '27': 'ZA',\n '30': 'GR',\n '31': 'NL',\n '32': 'BE',\n '33': 'FR',\n '34': 'ES',\n '39': 'IT',\n '44': 'GB',\n '46': 'SE',\n '47': 'NO',\n '48': 'PL',\n '49': 'DE',\n '52': 'MX',\n '54': 'AR',\n '55': 'BR',\n '60': 'MY',\n '61': 'AU',\n '62': 'ID',\n '63': 'PH',\n '64': 'NZ',\n '65': 'SG',\n '66': 'TH',\n '81': 'JP',\n '82': 'KR',\n '84': 'VN',\n '86': 'CN',\n '90': 'TR',\n '91': 'IN',\n '92': 'PK',\n '95': 'MM',\n '212': 'MA',\n '213': 'DZ',\n '216': 'TN',\n '218': 'LY',\n '234': 'NG',\n '254': 'KE',\n '352': 'LU',\n '353': 'IE',\n '358': 'FI',\n '359': 'BG',\n '380': 'UA',\n '420': 'CZ',\n '421': 'SK',\n '961': 'LB',\n '962': 'JO',\n '963': 'SY',\n '964': 'IQ',\n '965': 'KW',\n '966': 'SA',\n '967': 'YE',\n '968': 'OM',\n '970': 'PS',\n '971': 'AE',\n '972': 'IL',\n '973': 'BH',\n '974': 'QA',\n};\n\n/** localStorage key for the user's most recently picked countries. Used as a\n * tie-breaker when multiple countries share a dial code (e.g. all NANP). */\nexport const COUNTRY_RECENTS_KEY = 'ali_ui_country_recents_v1';\n\nexport interface DialMatch {\n country: CountryOption;\n /** The national significant number — what the phone input should hold, with both the\n * dial code and the national prefix (e.g. Egyptian leading `0`) stripped. */\n nationalNumber: string;\n}\n\nexport interface MatchLeadingDialCodeOptions {\n /** ISO2 hint for libphonenumber's national-format parse (tier 2). Typically the\n * IP/timezone/locale-resolved country. */\n hintCountry?: string;\n /** Currently selected ISO2 — preferred when a shared dial code yields multiple\n * countries (tier 3 tie-break). */\n currentIso2?: string;\n}\n\nfunction readRecents(): string[] {\n if (typeof window === 'undefined') return [];\n try {\n const raw = localStorage.getItem(COUNTRY_RECENTS_KEY);\n if (!raw) return [];\n const parsed = JSON.parse(raw);\n return Array.isArray(parsed) ? parsed.filter((v): v is string => typeof v === 'string') : [];\n } catch {\n return [];\n }\n}\n\nexport interface CountryMatchingDeps {\n /** Country lookup by ISO2 code — typically `usePhoneValidation().getCountryByValue`. */\n getCountryByValue: (value: string) => CountryOption | null;\n /** Country lookup by dial digits — typically `usePhoneValidation().getCountriesByDial`. */\n getCountriesByDial: (dial: string) => CountryOption[];\n}\n\n/**\n * Country-matching helpers used by the tel input — pure functions on top of the\n * `usePhoneValidation` country index. Split out of `ATellInput.vue` so the component\n * script stays focused on UI state and the matching logic is independently testable.\n *\n * **Important**: takes the validation lookups as dependencies rather than calling\n * `usePhoneValidation()` itself. `usePhoneValidation` creates a fresh state on every\n * call, so calling it here would produce a *second* empty country index that never gets\n * populated by the caller's `getCountries()` — the matcher would see no countries and\n * all tier-3 prefix lookups would fall through to the (much smaller) fallback table.\n */\nexport function useCountryMatching(deps: CountryMatchingDeps) {\n const { getCountryByValue, getCountriesByDial } = deps;\n\n /** Accept either an ISO2 code (`'EG'`) or a dial-digit string (`'20'`, `'+20'`).\n * Returns the canonical ISO2 for downstream consumers, or `''` if it can't resolve. */\n function resolveCountryIdentifier(raw: string | undefined | null): string {\n const v = String(raw ?? '').trim();\n if (!v) return '';\n if (/^[A-Za-z]{2}$/.test(v)) return v.toUpperCase();\n const dial = v.replace(/^\\+/, '');\n if (!/^\\d+$/.test(dial)) return '';\n // Prefer the loaded country index (right answer when multiple share a dial); fall\n // back to the synchronous table when the async list hasn't arrived yet.\n const match = getCountriesByDial(dial)[0];\n if (match) return match.value;\n return DIAL_TO_ISO2_FALLBACK[dial] ?? '';\n }\n\n /** Compute the dial digits (as a number) for an ISO2 code. Falls back to the\n * synchronous dial table if the async country list hasn't populated yet. */\n function dialNumberFor(iso2: string): number | null {\n if (!iso2) return null;\n const fromIndex = getCountryByValue(iso2)?.raw_data?.dial_digits;\n const digits =\n fromIndex ?? Object.entries(DIAL_TO_ISO2_FALLBACK).find(([, v]) => v === iso2)?.[0];\n if (!digits) return null;\n const n = Number(digits);\n return Number.isFinite(n) ? n : null;\n }\n\n /** Three-tier match of the leading digits to a country:\n * 1. libphonenumber international parse (handles NANP disambiguation).\n * 2. libphonenumber national-format parse using `hintCountry` (handles local\n * formats like Egyptian `01066105963` with no dial-code prefix).\n * 3. Longest-prefix match against the dial-digits index, with the current\n * selection / recents as tie-breakers when multiple countries share a code. */\n function matchLeadingDialCode(\n digits: string,\n options: MatchLeadingDialCodeOptions = {}\n ): DialMatch | null {\n if (!digits) return null;\n const { hintCountry, currentIso2 } = options;\n\n // Tier 1: international parse with leading `+`.\n try {\n const parsed = parsePhoneNumberFromString(`+${digits}`);\n if (parsed?.country && parsed.countryCallingCode) {\n const parsedCountry = getCountryByValue(parsed.country);\n if (parsedCountry) {\n return { country: parsedCountry, nationalNumber: String(parsed.nationalNumber ?? '') };\n }\n }\n } catch {\n /* libphonenumber throws on partial input — fall through */\n }\n\n // Tier 2: national-format parse using the silently-inferred country as a hint.\n if (hintCountry && digits.length >= 4) {\n try {\n const parsed = parsePhoneNumberFromString(digits, hintCountry as CountryCode);\n if (parsed?.isValid()) {\n const matched = getCountryByValue(parsed.country || hintCountry);\n if (matched) {\n return { country: matched, nationalNumber: String(parsed.nationalNumber ?? '') };\n }\n }\n } catch {\n /* fall through */\n }\n }\n\n // Tier 3: longest-prefix match over the dial-digits index.\n for (let len = Math.min(3, digits.length); len >= 1; len--) {\n const prefix = digits.slice(0, len);\n const group = getCountriesByDial(prefix);\n if (!group.length) continue;\n const nationalNumber = digits.slice(prefix.length);\n if (group.length === 1) return { country: group[0], nationalNumber };\n const current = currentIso2 ? group.find((c) => c.value === currentIso2.toUpperCase()) : null;\n if (current) return { country: current, nationalNumber };\n const recents = readRecents();\n const recentHit = recents\n .map((iso2) => group.find((c) => c.value === iso2))\n .find((c): c is CountryOption => Boolean(c));\n if (recentHit) return { country: recentHit, nationalNumber };\n return { country: group[0], nationalNumber };\n }\n return null;\n }\n\n return {\n resolveCountryIdentifier,\n dialNumberFor,\n matchLeadingDialCode,\n };\n}\n","import { ref, readonly, type ComputedRef, type Ref } from 'vue';\nimport { useDebounceFn } from '@vueuse/core';\n\n/**\n * Typing-phase state machine for the tel input.\n *\n * Owns the three reactive flags that drive the \"is the user still typing?\" UX:\n *\n * - `isDetecting` — true while the debounce window is in flight (user is mid-burst or\n * has just paused). Drives the loading spinner in the picker slot.\n * - `hasFinishedTyping` — false from the moment a key lands until the debounce settles.\n * Gates validation visibility, so error/success states only appear once the user pauses.\n * - `detectionAttempted` — flips true the first time the debounce fires on non-empty\n * input. Used by the consumer to keep the country picker visible after a failed\n * detection (so the user can pick manually instead of being stranded).\n *\n * Design notes:\n *\n * - The composable is pure state — it does not know about country detection, phone\n * numbers, or libphonenumber. The consumer wires the `onSettle` callback to whatever\n * \"what to do when typing pauses\" logic is appropriate (typically: try to detect a\n * country from the current digits, mark a detection attempt, and apply the match).\n *\n * - `markDetectionAttempt()` is exposed separately so the caller controls *when* the\n * \"keep the picker visible\" flag flips — not every settle triggers a real attempt\n * (e.g. when input is empty or the user already picked a country manually).\n *\n * - Refs are exposed `readonly` so external code can't bypass the state machine; all\n * transitions go through the exposed actions.\n */\nexport interface UseTypingPhaseOptions {\n /** Debounce window in ms. Reactive so consumers can change `detectDebounceMs` at runtime. */\n debounceMs: ComputedRef<number>;\n /** Fired when the debounce timer settles. Runs regardless of input state — use this\n * to clear loading UI, then perform any pause-triggered work (e.g. detection). */\n onSettle?: () => void;\n}\n\nexport interface UseTypingPhaseReturn {\n isDetecting: Readonly<Ref<boolean>>;\n hasFinishedTyping: Readonly<Ref<boolean>>;\n detectionAttempted: Readonly<Ref<boolean>>;\n /** Call from the input handler on every keystroke that produces non-empty input. */\n markTyping: () => void;\n /** Flip `detectionAttempted` to true. Call from within the `onSettle` callback when\n * a real detection attempt is about to run — so the picker stays visible after even\n * a failed match. */\n markDetectionAttempt: () => void;\n /** Reset all three flags to defaults. Call when the input is cleared. */\n reset: () => void;\n}\n\nexport function useTypingPhase(opts: UseTypingPhaseOptions): UseTypingPhaseReturn {\n const isDetecting = ref(false);\n const hasFinishedTyping = ref(true);\n const detectionAttempted = ref(false);\n\n const settle = useDebounceFn(() => {\n isDetecting.value = false;\n hasFinishedTyping.value = true;\n opts.onSettle?.();\n }, opts.debounceMs);\n\n function markTyping() {\n isDetecting.value = true;\n hasFinishedTyping.value = false;\n settle();\n }\n\n function markDetectionAttempt() {\n detectionAttempted.value = true;\n }\n\n function reset() {\n isDetecting.value = false;\n hasFinishedTyping.value = true;\n detectionAttempted.value = false;\n }\n\n return {\n isDetecting: readonly(isDetecting),\n hasFinishedTyping: readonly(hasFinishedTyping),\n detectionAttempted: readonly(detectionAttempted),\n markTyping,\n markDetectionAttempt,\n reset,\n };\n}\n","import { computed, type ComputedRef, type Ref } from 'vue';\nimport type {\n CountryOption,\n PhoneValidationReason,\n PhoneValidationResult,\n PhoneRequiredInfo,\n UsePhoneValidationReturn,\n} from './usePhoneValidation';\nimport type { TellInputMessages } from '../utils/types';\n\n/**\n * Validation surfacing facade for ATellInput.\n *\n * Wraps the raw `usePhoneValidation()` calls and produces the *view-layer* surface the\n * component needs:\n *\n * - `validation` / `validationState` — the raw + simplified state of the current input.\n * - `visibleValidationState` — `validationState` gated by the `hasFinishedTyping` flag\n * from {@link useTypingPhase}, so error tints / icons / messages only appear once the\n * user has paused. This is the value the template should bind to.\n * - `errorMessage` — localised error string for the current `validation.reason`, or\n * `null` when the input is empty or valid.\n * - `showError` / `showHint` — boolean computed properties for conditional rendering\n * in the template; both already respect `showValidation` and the typing-pause gate.\n * - `selectedDialCode` — the human-readable dial prefix (`+20`, `+1`, …) for the\n * selected country, used as an in-input prefix.\n *\n * Design notes:\n *\n * - The composable takes the `usePhoneValidation()` return value as a *dependency*\n * rather than calling `usePhoneValidation()` itself. That function creates a fresh\n * country index per invocation; calling it here would produce a second, empty index\n * that never gets populated by the caller's `getCountries()` (the same bug pattern\n * {@link useCountryMatching} avoids).\n *\n * - All inputs are `Ref` / `ComputedRef` so reactivity flows correctly. Method\n * references on the validation singleton (`validate`, `getRequiredInfo`,\n * `getCountryByValue`) are passed verbatim — their backing state is reactive.\n */\nexport interface UseTellInputValidationDeps {\n validate: UsePhoneValidationReturn['validate'];\n getRequiredInfo: UsePhoneValidationReturn['getRequiredInfo'];\n getCountryByValue: UsePhoneValidationReturn['getCountryByValue'];\n}\n\nexport interface UseTellInputValidationInputs {\n /** Digits-only national number model. */\n phone: Ref<string>;\n /** Currently selected ISO2 — empty string when no country chosen. */\n selectedIso2: Ref<string>;\n /** From {@link useTypingPhase} — gates visible state during the debounce window. */\n hasFinishedTyping: Readonly<Ref<boolean>>;\n /** Resolved i18n messages (merged defaults + consumer overrides). */\n messages: ComputedRef<TellInputMessages>;\n}\n\nexport interface UseTellInputValidationConfig {\n /** BCP-47 locale; affects `format_hint` numeral rendering. */\n locale: () => string | undefined;\n /** Light up field tinting + error message line. From props. */\n showValidation: () => boolean | undefined;\n /** Per-reason error string overrides. From props. */\n errorMessages: () => Partial<Record<PhoneValidationReason, string>> | undefined;\n}\n\nexport interface UseTellInputValidationReturn {\n validation: ComputedRef<PhoneValidationResult>;\n required: ComputedRef<PhoneRequiredInfo | null>;\n validationState: ComputedRef<'idle' | 'valid' | 'error'>;\n visibleValidationState: ComputedRef<'idle' | 'valid' | 'error'>;\n errorMessage: ComputedRef<string | null>;\n showError: ComputedRef<boolean>;\n showHint: ComputedRef<boolean>;\n selectedDialCode: ComputedRef<string | null>;\n}\n\nexport function useTellInputValidation(\n deps: UseTellInputValidationDeps,\n inputs: UseTellInputValidationInputs,\n config: UseTellInputValidationConfig\n): UseTellInputValidationReturn {\n const required = computed(() =>\n inputs.selectedIso2.value\n ? deps.getRequiredInfo({ iso2: inputs.selectedIso2.value }, config.locale())\n : null\n );\n\n const validation = computed<PhoneValidationResult>(() =>\n deps.validate({\n country: inputs.selectedIso2.value ? { iso2: inputs.selectedIso2.value } : null,\n phone: inputs.phone.value ?? '',\n locale: config.locale(),\n })\n );\n\n const validationState = computed<'idle' | 'valid' | 'error'>(() => {\n if (!inputs.phone.value) return 'idle';\n return validation.value.ok ? 'valid' : 'error';\n });\n\n const visibleValidationState = computed<'idle' | 'valid' | 'error'>(() =>\n inputs.hasFinishedTyping.value ? validationState.value : 'idle'\n );\n\n const errorMessage = computed<string | null>(() => {\n const v = validation.value;\n if (v.ok || !v.reason) return null;\n if (!inputs.phone.value) return null;\n return config.errorMessages()?.[v.reason] ?? inputs.messages.value.errorMessages[v.reason];\n });\n\n const showError = computed<boolean>(() =>\n Boolean(config.showValidation() && inputs.hasFinishedTyping.value && errorMessage.value)\n );\n\n const showHint = computed<boolean>(\n () => !showError.value && !inputs.phone.value && !!required.value?.format_hint\n );\n\n const selectedDialCode = computed<string | null>(() => {\n if (!inputs.selectedIso2.value) return null;\n const country: CountryOption | null = deps.getCountryByValue(inputs.selectedIso2.value);\n return country?.raw_data.dial_code ?? null;\n });\n\n return {\n validation,\n required,\n validationState,\n visibleValidationState,\n errorMessage,\n showError,\n showHint,\n selectedDialCode,\n };\n}\n","import type { HTMLAttributes } from 'vue';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type { DetectionStrategy } from '../composables/useCountryDetection';\nimport type { PhoneValidationReason } from '../composables/usePhoneValidation';\nimport { controlHeight, controlTextSize, type Size } from '@/utils';\n\n/** Alias for the shared `Size` scale — kept for backwards-friendly naming. */\nexport type ATellInputSize = Size;\n\nexport const aTellInputVariants = cva(\n // items-center (not items-stretch) so #prefix/#suffix icons centre vertically without distortion.\n // The country trigger button and the input element both carry `h-full`, so they still fill the\n // field height regardless of this setting.\n 'border-input bg-background ring-offset-background focus-within:ring-ring flex w-full items-center overflow-hidden rounded-md border shadow-sm transition-colors focus-within:ring-1 has-[input:disabled]:cursor-not-allowed has-[input:disabled]:opacity-50',\n {\n variants: {\n size: {\n xs: `${controlHeight.xs} ${controlTextSize.xs}`,\n sm: `${controlHeight.sm} ${controlTextSize.sm}`,\n md: `${controlHeight.md} ${controlTextSize.md}`,\n lg: `${controlHeight.lg} ${controlTextSize.lg}`,\n xl: `${controlHeight.xl} ${controlTextSize.xl}`,\n },\n },\n defaultVariants: { size: 'md' },\n }\n);\n\nexport type ATellInputVariants = VariantProps<typeof aTellInputVariants>;\n\n/** Text direction for the field. `'auto'` (or omitting the prop) inherits from the\n * nearest `[dir]` ancestor / `<html dir>`; `'ltr'` / `'rtl'` force it. */\nexport type ATellInputDir = 'ltr' | 'rtl' | 'auto';\n\n/**\n * Every user-facing string in the tell-input UI, bundled so a consumer can localize the\n * component in one prop. Each key has an English default in {@link DEFAULT_MESSAGES}.\n */\nexport interface TellInputMessages {\n /** Placeholder of the country-picker search box. */\n searchPlaceholder: string;\n /** Shown when a search yields no countries. */\n emptyText: string;\n /** Shown while the country list is loading. */\n loadingText: string;\n /** Header of the \"Suggested\" group (current + recent picks). */\n suggestedLabel: string;\n /** Header of the full country list. */\n allCountriesLabel: string;\n /** Validation error text, keyed by reason. */\n errorMessages: Record<PhoneValidationReason, string>;\n /** Prefix of the country trigger's `aria-label`, e.g. `\"Country: Egypt\"`. */\n countryLabel: string;\n /** `aria-label` of the country trigger when no country is selected. */\n selectCountryLabel: string;\n /** `aria-label` of the phone input element. */\n phoneInputLabel: string;\n}\n\n/** Partial override shape for the `messages` prop — every key (and every error reason) is optional. */\nexport type TellInputMessagesInput = Partial<Omit<TellInputMessages, 'errorMessages'>> & {\n errorMessages?: Partial<Record<PhoneValidationReason, string>>;\n};\n\nexport interface ATellInputProps {\n class?: HTMLAttributes['class'];\n placeholder?: string;\n disabled?: boolean;\n loading?: boolean;\n size?: ATellInputSize;\n /**\n * Text direction. Omit (or pass `'auto'`) to inherit from the page — RTL pages get an\n * RTL field automatically. Pass `'ltr'` / `'rtl'` to force it.\n */\n dir?: ATellInputDir;\n /**\n * BCP-47 locale (e.g. `'ar'`, `'fr'`). When set, country names render localized via\n * `Intl.DisplayNames` and the format hint uses the locale's numerals.\n */\n locale?: string;\n /**\n * Localized UI strings. A single bag covering the picker, validation errors, and a11y\n * labels. Individual props (`searchPlaceholder`, `emptyText`, `loadingText`,\n * `errorMessages`) take precedence over the matching `messages` key when both are set.\n */\n messages?: TellInputMessagesInput;\n /**\n * Whitelist of allowed dial-digit codes (no `+`), e.g. `['20', '966']`.\n * Countries outside this list are still shown in the picker but rendered as disabled.\n */\n allowedDialCodes?: string[];\n /** Light up the field's validation styling — coloured border + ring on the input and the\n * error message line below — when the number is valid / invalid. Default `false`, so the\n * field stays neutral and validation surfacing is left to the consumer (via the\n * `validation` ref exposure). */\n showValidation?: boolean;\n /** Show the green check / red alert icon at the end of the field. Default `false`; opt\n * in with `true`. Independent of `showValidation` — you can show the icon without the\n * coloured field, or vice versa. The slots `#valid-icon` / `#error-icon` still apply. */\n showValidationIcon?: boolean;\n /**\n * Country auto-detect strategy. Defaults to `'auto'` — try IP geolocation first, then\n * timezone, then `navigator.language`, finally `defaultCountry`.\n */\n detectCountry?: DetectionStrategy;\n /**\n * Initial country. Accepts either an ISO2 code (`'EG'`) or a dial-digit string\n * (`'20'`, `'+20'`). When set, the picker is visible at mount with this country\n * pre-selected — overrides the hidden-until-detected default.\n */\n defaultCountry?: string;\n /** Override the IP geolocation endpoint. Must return JSON with `country_code` or `country`. */\n ipEndpoint?: string;\n /** Localized strings for the country picker UI. */\n searchPlaceholder?: string;\n emptyText?: string;\n loadingText?: string;\n /** Error labels keyed by reason. Each gets a sensible English default. */\n errorMessages?: Partial<Record<PhoneValidationReason, string>>;\n /**\n * When true, the country picker is hidden until a leading dial code is detected in the\n * phone input. Every keystroke runs a longest-prefix match against known dial codes; on\n * first match the picker reveals with that country and the matched dial digits are\n * stripped from `phone`. Skips the onMount IP/timezone/locale detection chain.\n */\n detectFromInput?: boolean;\n /**\n * Debounce window (ms) for `detectFromInput` detection. Each keystroke schedules the\n * libphonenumber parse + lookup; bursts of typing/paste collapse into a single call.\n * Clearing the input is not debounced — the picker hides immediately. Default 150ms.\n */\n detectDebounceMs?: number;\n}\n\nexport const DEFAULT_ERROR_MESSAGES: Record<PhoneValidationReason, string> = {\n missing_country: 'Please select a country.',\n country_not_supported: 'This country is not supported.',\n phone_has_non_digits: 'Phone number can only contain digits.',\n too_short: 'Phone number is too short.',\n too_long: 'Phone number is too long.',\n invalid_phone: 'Phone number is invalid.',\n parse_failed: 'Could not parse phone number.',\n};\n\n/** English defaults for every {@link TellInputMessages} key. */\nexport const DEFAULT_MESSAGES: TellInputMessages = {\n searchPlaceholder: 'Search country or +code…',\n emptyText: 'No countries found.',\n loadingText: 'Loading countries…',\n suggestedLabel: 'Suggested',\n allCountriesLabel: 'All countries',\n errorMessages: DEFAULT_ERROR_MESSAGES,\n countryLabel: 'Country',\n selectCountryLabel: 'Select country',\n phoneInputLabel: 'Phone number',\n};\n\n/**\n * Merge a partial `messages` override onto the English defaults. Used internally by\n * `ATellInput` to resolve a complete {@link TellInputMessages} object.\n */\nexport function resolveMessages(input?: TellInputMessagesInput): TellInputMessages {\n if (!input) return DEFAULT_MESSAGES;\n return {\n ...DEFAULT_MESSAGES,\n ...input,\n errorMessages: { ...DEFAULT_ERROR_MESSAGES, ...input.errorMessages },\n };\n}\n","/**\n * Default flag URL builder — flagcdn.com hosts PNG flags at multiple widths and is\n * generous with caching + no API key required. Swap via the `flagUrl` prop on\n * ATellInput / ACountrySelect / ACountryFlag to use any other source.\n */\nexport function defaultFlagUrl(iso2: string, width = 40): string {\n return `https://flagcdn.com/w${width}/${iso2.toLowerCase()}.png`;\n}\n\nexport type FlagUrlBuilder = (iso2: string, width: number) => string;\n","<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue';\nimport { computed, ref, watch } from 'vue';\nimport { cn } from '@/utils';\nimport { defaultFlagUrl, type FlagUrlBuilder } from '../utils/flag-url';\n\nconst props = withDefaults(\n defineProps<{\n /** ISO 3166-1 alpha-2 country code, case-insensitive. */\n iso2: string;\n /** Pixel width served by flagcdn. 40 is crisp at retina up to ~24px wide. */\n width?: number;\n /** Optional explicit URL override. When set, `iso2` / `width` / `flagUrl` are ignored. */\n src?: string | null;\n /** Function `(iso2, width) => string` — fully replace the URL builder. */\n flagUrl?: FlagUrlBuilder;\n alt?: string;\n class?: HTMLAttributes['class'];\n }>(),\n { width: 40 }\n);\n\nconst url = computed(() => {\n if (props.src) return props.src;\n if (!props.iso2) return null;\n return (props.flagUrl ?? defaultFlagUrl)(props.iso2, props.width);\n});\n\n// Image load failure → fall back to the ISO2 text badge. The flag URL can change as the\n// user switches country, so reset the error flag whenever the URL changes.\nconst failed = ref(false);\nwatch(url, () => {\n failed.value = false;\n});\n\nconst iso2Label = computed(() => (props.iso2 ?? '').slice(0, 2).toUpperCase());\n</script>\n\n<template>\n <img\n v-if=\"url && !failed\"\n :src=\"url\"\n :alt=\"props.alt ?? `${props.iso2} flag`\"\n loading=\"lazy\"\n data-slot=\"country-flag\"\n :class=\"cn('ring-border/40 inline-block h-4 w-6 rounded-sm object-cover ring-1', props.class)\"\n @error=\"failed = true\"\n />\n <span\n v-else-if=\"iso2Label\"\n data-slot=\"country-flag-fallback\"\n :aria-label=\"props.alt ?? `${props.iso2} flag`\"\n :class=\"\n cn(\n 'ring-border/40 bg-muted text-muted-foreground inline-flex h-4 w-6 items-center justify-center rounded-sm text-[8px] font-semibold leading-none tracking-tight ring-1',\n props.class\n )\n \"\n >\n {{ iso2Label }}\n </span>\n <slot v-else name=\"empty\">\n <span\n data-slot=\"country-flag-empty\"\n :class=\"cn('bg-muted inline-block h-4 w-6 rounded-sm', props.class)\"\n />\n </slot>\n</template>\n","<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue';\nimport { computed, onMounted, ref, watch } from 'vue';\nimport { Check, ChevronDown, Search } from 'lucide-vue-next';\nimport { cn } from '@/utils';\nimport {\n AResponsivePopover,\n AResponsivePopoverContent,\n AResponsivePopoverTrigger,\n} from '@/entries/responsive-popover';\nimport {\n usePhoneValidation,\n localizeCountries,\n type CountryOption,\n} from '../composables/usePhoneValidation';\nimport { controlPaddingX, controlTextSize, DEFAULT_SIZE, type Size } from '@/utils';\nimport ACountryFlag from './ACountryFlag.vue';\n\nconst props = withDefaults(\n defineProps<{\n class?: HTMLAttributes['class'];\n triggerClass?: HTMLAttributes['class'];\n contentClass?: HTMLAttributes['class'];\n popoverClass?: HTMLAttributes['class'];\n drawerClass?: HTMLAttributes['class'];\n searchPlaceholder?: string;\n emptyText?: string;\n loadingText?: string;\n suggestedLabel?: string;\n allCountriesLabel?: string;\n /** ISO2 codes that are selectable. Others are listed but disabled. */\n allowedDialCodes?: string[];\n disabled?: boolean;\n /** Drives the trigger button padding + text size. Matches ATellInput's `size`. */\n size?: Size;\n /** Max items rendered under the \"Suggested\" header (current + recents, deduped). */\n suggestedLimit?: number;\n /** Cap the number of matching countries shown in search results. */\n maxResults?: number;\n /** Override the flag URL builder, e.g. `(iso, w) => \\`/flags/${iso}.svg\\``. */\n flagUrl?: (iso2: string, width: number) => string;\n /**\n * Custom search predicate. Default: substring match on the precomputed `search_key`.\n * Return `true` to keep the country in results.\n */\n searcher?: (query: string, country: CountryOption) => boolean;\n /**\n * Provide your own country list (bypasses the REST Countries fetch). Useful when you\n * already have a curated subset, an i18n'd list, or want to avoid the network call.\n */\n countries?: CountryOption[];\n /** Override the right-side kbd hints. Pass `null` to hide. */\n kbdOpen?: string | null;\n kbdClose?: string | null;\n /** BCP-47 locale — country names render localized via `Intl.DisplayNames`. */\n locale?: string;\n /** Prefix of the trigger's `aria-label` when a country is selected, e.g. `\"Country\"`. */\n countryLabel?: string;\n /** Trigger's `aria-label` when no country is selected. */\n selectCountryLabel?: string;\n /**\n * How page scroll is blocked while the popover is open. Defaults to `'events'` — an\n * event-based lock that keeps the page scrollbar visible and `position: sticky` working.\n * Pass `'body'` for the legacy `body { overflow: hidden }` lock, or `'none'` to allow\n * the page to scroll freely.\n */\n scrollLock?: 'events' | 'body' | 'none';\n }>(),\n {\n searchPlaceholder: 'Search country or +code…',\n emptyText: 'No countries found.',\n loadingText: 'Loading countries…',\n suggestedLabel: 'Suggested',\n allCountriesLabel: 'All countries',\n countryLabel: 'Country',\n selectCountryLabel: 'Select country',\n size: DEFAULT_SIZE,\n suggestedLimit: 4,\n maxResults: 80,\n kbdOpen: '⌘K',\n kbdClose: 'Esc',\n }\n);\n\ndefineSlots<{\n /** Replace the entire country picker trigger button. */\n trigger?: (props: {\n selectedCountry: CountryOption | null;\n open: boolean;\n sizeClasses: string;\n }) => unknown;\n /** Replace the chevron icon. */\n chevron?: (props: { open: boolean }) => unknown;\n /** Replace just the flag rendered in the trigger and items. */\n flag?: (props: { country: CountryOption; context: 'trigger' | 'item' }) => unknown;\n /** Replace the entire search bar (input + icon + kbd). */\n search?: (props: {\n value: string;\n setValue: (v: string) => void;\n isSearching: boolean;\n }) => unknown;\n /** Replace the search-bar leading icon. */\n 'search-icon'?: () => unknown;\n /** Replace the loading state. */\n loading?: () => unknown;\n /** Replace the empty/no-results state. */\n empty?: (props: { query: string }) => unknown;\n /** Replace a section header. */\n 'group-header'?: (props: { label: string; group: 'suggested' | 'all' }) => unknown;\n /** Replace each country list row. Default render still available via &lt;ACountrySelectItem /&gt;. */\n item?: (props: {\n country: CountryOption;\n selected: boolean;\n disabled: boolean;\n select: () => void;\n }) => unknown;\n /** Replace just the right-side check icon for the selected row. */\n 'item-check'?: (props: { country: CountryOption }) => unknown;\n}>();\n\nconst triggerSizeClasses = computed(\n () => `${controlPaddingX[props.size]} ${controlTextSize[props.size]}`\n);\n\nconst selected = defineModel<string>('selected', { default: '' });\n\nconst {\n countries: internalCountries,\n isCountriesLoading,\n getCountries,\n searchCountries: defaultSearch,\n getCountryByValue: lookupInternal,\n} = usePhoneValidation();\n\nconst open = ref(false);\nconst search = ref('');\n\nvoid getCountries();\n\n/* ---------------------------------------------------------------\n * Country source — either the user-supplied list (props.countries)\n * or the internal REST Countries + localStorage cache. A `locale`\n * localizes the internal list's display names via `Intl.DisplayNames`;\n * a caller-supplied `countries` list is used verbatim (caller owns names).\n * ------------------------------------------------------------- */\nconst effectiveCountries = computed<CountryOption[]>(() =>\n props.countries && props.countries.length\n ? props.countries\n : localizeCountries(internalCountries.value, props.locale)\n);\n\nconst effectiveByValue = computed<Map<string, CountryOption>>(\n () => new Map(effectiveCountries.value.map((c) => [c.value, c]))\n);\n\nfunction lookup(iso2: string): CountryOption | null {\n if (!iso2) return null;\n return effectiveByValue.value.get(iso2) ?? lookupInternal(iso2);\n}\n\n/* ---------------------------------------------------------------\n * Recent picks — persisted so subsequent visits surface the user's\n * actual countries above the long alphabetical list.\n * ------------------------------------------------------------- */\nconst RECENTS_KEY = 'ali_ui_country_recents_v1';\nconst recents = ref<string[]>([]);\n\nfunction loadRecents() {\n if (typeof window === 'undefined') return;\n try {\n const raw = localStorage.getItem(RECENTS_KEY);\n if (!raw) return;\n const parsed = JSON.parse(raw);\n if (!Array.isArray(parsed)) return;\n recents.value = parsed.filter((v): v is string => typeof v === 'string').slice(0, 8);\n } catch {\n /* ignore corrupt cache */\n }\n}\n\nfunction pushRecent(iso2: string) {\n if (typeof window === 'undefined' || !iso2) return;\n const next = [iso2, ...recents.value.filter((x) => x !== iso2)].slice(0, 8);\n recents.value = next;\n try {\n localStorage.setItem(RECENTS_KEY, JSON.stringify(next));\n } catch {\n /* quota or storage disabled */\n }\n}\n\nonMounted(loadRecents);\n\n/* ---------------------------------------------------------------\n * Section state\n * ------------------------------------------------------------- */\nconst isSearching = computed(() => search.value.trim().length > 0);\n\nfunction defaultSearcher(q: string, c: CountryOption): boolean {\n return c.search_key.includes(q.toLowerCase());\n}\n\nconst filtered = computed<CountryOption[]>(() => {\n if (!isSearching.value) return [];\n // When the caller didn't override the country source, the internal `searchCountries`\n // is already optimal (uses the precomputed search_key + early break). Fall back to a\n // manual filter when we need to honor a custom `searcher`/`countries` source, or a\n // `locale` (whose localized `search_key` lives only on `effectiveCountries`).\n if (!props.countries && !props.searcher && !props.locale) {\n return defaultSearch(search.value, props.maxResults);\n }\n const q = search.value.trim();\n const matcher = props.searcher ?? defaultSearcher;\n const out: CountryOption[] = [];\n for (const c of effectiveCountries.value) {\n if (matcher(q, c)) {\n out.push(c);\n if (out.length >= props.maxResults) break;\n }\n }\n return out;\n});\n\nconst suggested = computed<CountryOption[]>(() => {\n if (isSearching.value) return [];\n const seen = new Set<string>();\n const out: CountryOption[] = [];\n const candidate = (iso: string) => {\n if (!iso || seen.has(iso)) return;\n const c = lookup(iso);\n if (!c) return;\n seen.add(iso);\n out.push(c);\n };\n candidate(selected.value);\n\n const allowed = props.allowedDialCodes;\n const hasAllowed = Array.isArray(allowed) && allowed.length > 0;\n if (hasAllowed) {\n // Surface every whitelisted country in the Suggested group — they're the only\n // selectable options, so they belong at the top and the recents/limit logic is\n // irrelevant here.\n for (const c of effectiveCountries.value) {\n if (allowed.includes(c.raw_data.dial_digits)) candidate(c.value);\n }\n return out;\n }\n\n for (const r of recents.value) {\n candidate(r);\n if (out.length >= props.suggestedLimit) break;\n }\n return out.slice(0, props.suggestedLimit);\n});\n\nconst allCountries = computed<CountryOption[]>(() => {\n if (isSearching.value) return [];\n return effectiveCountries.value;\n});\n\nconst selectedCountry = computed<CountryOption | null>(() => lookup(selected.value));\n\nfunction isAllowed(option: CountryOption) {\n const allowed = props.allowedDialCodes;\n if (!allowed || allowed.length === 0) return true;\n return allowed.includes(option.raw_data.dial_digits);\n}\n\nfunction selectCountry(option: CountryOption) {\n if (!isAllowed(option)) return;\n selected.value = option.value;\n pushRecent(option.value);\n open.value = false;\n}\n\nwatch(open, (isOpen) => {\n if (!isOpen) search.value = '';\n});\n\ndefineExpose({\n open,\n setOpen: (v: boolean) => (open.value = v),\n search,\n setSearch: (v: string) => (search.value = v),\n selectedCountry,\n selectCountry,\n countries: effectiveCountries,\n recents,\n});\n</script>\n\n<template>\n <AResponsivePopover v-model:open=\"open\" :scroll-lock=\"props.scrollLock\">\n <AResponsivePopoverTrigger as-child>\n <slot\n name=\"trigger\"\n :selected-country=\"selectedCountry\"\n :open=\"open\"\n :size-classes=\"triggerSizeClasses\"\n >\n <button\n type=\"button\"\n :disabled=\"props.disabled\"\n data-slot=\"country-select-trigger\"\n :data-state=\"open ? 'open' : 'closed'\"\n :class=\"\n cn(\n 'bg-transparent hover:bg-muted focus-visible:bg-muted data-[state=open]:bg-muted focus-visible:ring-ring inline-flex h-full shrink-0 items-center gap-1.5 transition-colors focus-visible:ring-1 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',\n triggerSizeClasses,\n props.triggerClass\n )\n \"\n :aria-label=\"\n selectedCountry\n ? `${props.countryLabel}: ${selectedCountry.raw_data.name}`\n : props.selectCountryLabel\n \"\n >\n <slot v-if=\"selectedCountry\" name=\"flag\" :country=\"selectedCountry\" context=\"trigger\">\n <ACountryFlag\n :iso2=\"selectedCountry.raw_data.iso2\"\n :src=\"selectedCountry.raw_data.flag\"\n :flag-url=\"props.flagUrl\"\n />\n </slot>\n <slot name=\"chevron\" :open=\"open\">\n <ChevronDown\n class=\"text-muted-foreground size-3.5 shrink-0 transition-transform duration-200\"\n :class=\"open && 'rotate-180'\"\n />\n </slot>\n </button>\n </slot>\n </AResponsivePopoverTrigger>\n\n <AResponsivePopoverContent\n align=\"end\"\n :side-offset=\"6\"\n :class=\"cn('flex flex-col overflow-hidden p-0', props.contentClass)\"\n :popover-class=\"\n cn(\n 'w-[min(20rem,calc(100vw-2rem))] max-h-[min(22rem,var(--reka-popover-content-available-height))]',\n props.popoverClass\n )\n \"\n :drawer-class=\"cn('max-h-[80vh] pb-4', props.drawerClass)\"\n >\n <!-- Search header -->\n <slot\n name=\"search\"\n :value=\"search\"\n :set-value=\"(v: string) => (search = v)\"\n :is-searching=\"isSearching\"\n >\n <div class=\"border-border/70 border-b p-1.5\">\n <div\n class=\"bg-muted/40 ring-border/70 focus-within:ring-ring/50 relative flex items-center rounded-md ring-1 transition-shadow\"\n >\n <slot name=\"search-icon\">\n <Search\n class=\"text-muted-foreground absolute top-1/2 start-2.5 size-3.5 -translate-y-1/2\"\n />\n </slot>\n <input\n v-model=\"search\"\n type=\"text\"\n data-slot=\"country-select-search\"\n :placeholder=\"props.searchPlaceholder\"\n class=\"placeholder:text-muted-foreground h-10 w-full bg-transparent pe-14 ps-8 text-sm outline-none\"\n />\n <kbd\n v-if=\"!isSearching && props.kbdOpen\"\n class=\"bg-background text-muted-foreground border-border absolute top-1/2 end-2 hidden -translate-y-1/2 items-center gap-0.5 rounded border px-1.5 py-0.5 font-mono text-[10px] tracking-tight md:inline-flex\"\n >\n {{ props.kbdOpen }}\n </kbd>\n <kbd\n v-else-if=\"isSearching && props.kbdClose\"\n class=\"bg-background text-muted-foreground border-border absolute top-1/2 end-2 hidden -translate-y-1/2 rounded border px-1.5 py-0.5 font-mono text-[10px] tracking-tight md:inline-block\"\n >\n {{ props.kbdClose }}\n </kbd>\n </div>\n </div>\n </slot>\n\n <!-- List -->\n <div class=\"flex-1 overflow-y-auto\">\n <slot v-if=\"isCountriesLoading && effectiveCountries.length === 0\" name=\"loading\">\n <div class=\"text-muted-foreground p-4 text-center text-sm\">\n {{ props.loadingText }}\n </div>\n </slot>\n\n <slot v-else-if=\"isSearching && filtered.length === 0\" name=\"empty\" :query=\"search\">\n <div class=\"text-muted-foreground p-4 text-center text-sm\">\n {{ props.emptyText }}\n </div>\n </slot>\n\n <template v-else>\n <!-- Suggested group -->\n <section\n v-if=\"suggested.length > 0\"\n data-slot=\"country-select-group\"\n data-group=\"suggested\"\n >\n <slot name=\"group-header\" :label=\"props.suggestedLabel\" group=\"suggested\">\n <header\n class=\"text-muted-foreground bg-popover sticky top-0 z-10 px-3 py-1.5 text-[10px] font-medium tracking-wider uppercase\"\n >\n {{ props.suggestedLabel }}\n </header>\n </slot>\n <ul role=\"listbox\" :aria-label=\"props.suggestedLabel\" class=\"pb-1\">\n <li\n v-for=\"option in suggested\"\n :key=\"`s-${option.value}`\"\n role=\"option\"\n :aria-selected=\"option.value === selected\"\n :aria-disabled=\"!isAllowed(option)\"\n >\n <slot\n name=\"item\"\n :country=\"option\"\n :selected=\"option.value === selected\"\n :disabled=\"!isAllowed(option)\"\n :select=\"() => selectCountry(option)\"\n >\n <button\n type=\"button\"\n :disabled=\"!isAllowed(option)\"\n data-slot=\"country-select-item\"\n :data-selected=\"option.value === selected ? '' : undefined\"\n class=\"hover:bg-muted/60 focus-visible:bg-muted/60 data-[selected]:bg-muted flex w-full items-center gap-3 px-3 py-2 text-left text-sm transition-colors focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:bg-transparent\"\n @click=\"selectCountry(option)\"\n >\n <slot name=\"flag\" :country=\"option\" context=\"item\">\n <ACountryFlag\n :iso2=\"option.raw_data.iso2\"\n :src=\"option.raw_data.flag\"\n :flag-url=\"props.flagUrl\"\n />\n </slot>\n <span class=\"flex-1 truncate\">{{ option.raw_data.name }}</span>\n <span class=\"text-muted-foreground tabular-nums\">{{\n option.raw_data.dial_code\n }}</span>\n <slot v-if=\"option.value === selected\" name=\"item-check\" :country=\"option\">\n <Check class=\"text-foreground size-3.5 shrink-0\" />\n </slot>\n </button>\n </slot>\n </li>\n </ul>\n </section>\n\n <!-- All countries / search results -->\n <section data-slot=\"country-select-group\" data-group=\"all\">\n <slot\n v-if=\"!isSearching && allCountries.length > 0\"\n name=\"group-header\"\n :label=\"props.allCountriesLabel\"\n group=\"all\"\n >\n <header\n class=\"text-muted-foreground bg-popover sticky top-0 z-10 px-3 py-1.5 text-[10px] font-medium tracking-wider uppercase\"\n >\n {{ props.allCountriesLabel }}\n </header>\n </slot>\n <ul\n role=\"listbox\"\n :aria-label=\"isSearching ? props.searchPlaceholder : props.allCountriesLabel\"\n class=\"pb-1\"\n >\n <li\n v-for=\"option in isSearching ? filtered : allCountries\"\n :key=\"option.value\"\n role=\"option\"\n :aria-selected=\"option.value === selected\"\n :aria-disabled=\"!isAllowed(option)\"\n >\n <slot\n name=\"item\"\n :country=\"option\"\n :selected=\"option.value === selected\"\n :disabled=\"!isAllowed(option)\"\n :select=\"() => selectCountry(option)\"\n >\n <button\n type=\"button\"\n :disabled=\"!isAllowed(option)\"\n data-slot=\"country-select-item\"\n :data-selected=\"option.value === selected ? '' : undefined\"\n class=\"hover:bg-muted/60 focus-visible:bg-muted/60 data-[selected]:bg-muted flex w-full items-center gap-3 px-3 py-2 text-left text-sm transition-colors focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:bg-transparent\"\n @click=\"selectCountry(option)\"\n >\n <slot name=\"flag\" :country=\"option\" context=\"item\">\n <ACountryFlag\n :iso2=\"option.raw_data.iso2\"\n :src=\"option.raw_data.flag\"\n :flag-url=\"props.flagUrl\"\n />\n </slot>\n <span class=\"flex-1 truncate\">{{ option.raw_data.name }}</span>\n <span class=\"text-muted-foreground tabular-nums\">{{\n option.raw_data.dial_code\n }}</span>\n <slot v-if=\"option.value === selected\" name=\"item-check\" :country=\"option\">\n <Check class=\"text-foreground size-3.5 shrink-0\" />\n </slot>\n </button>\n </slot>\n </li>\n </ul>\n </section>\n </template>\n </div>\n </AResponsivePopoverContent>\n </AResponsivePopover>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, onMounted, ref, useId, watch } from 'vue';\nimport { CheckCircle2, AlertCircle, Loader2 } from 'lucide-vue-next';\nimport { cn } from '@/utils';\nimport {\n usePhoneValidation,\n type CountryOption,\n type PhoneValidationResult,\n} from '../composables/usePhoneValidation';\nimport { detectCountry, type DetectCountryOptions } from '../composables/useCountryDetection';\nimport { useCountryMatching } from '../composables/useCountryMatching';\nimport { useTypingPhase } from '../composables/useTypingPhase';\nimport { useTellInputValidation } from '../composables/useTellInputValidation';\nimport { controlPaddingX, controlTextSize, DEFAULT_SIZE } from '@/utils';\nimport { aTellInputVariants, resolveMessages, type ATellInputProps } from '../utils/types';\nimport { normalizeDigits } from '../utils/digits';\nimport ACountrySelect from './ACountrySelect.vue';\n\ninterface ExtendedProps extends ATellInputProps {\n /** Override the flag URL builder, forwarded to ACountrySelect. */\n flagUrl?: (iso2: string, width: number) => string;\n /** Custom search predicate, forwarded to ACountrySelect. */\n searcher?: (query: string, country: CountryOption) => boolean;\n /** Provide your own country list, forwarded to ACountrySelect. */\n countries?: CountryOption[];\n /**\n * Fully custom country detection. When provided, this function runs in place of the\n * built-in chain — `detectCountry`-style options are still honored but the function\n * receives them and is free to ignore them.\n */\n detector?: (options: DetectCountryOptions) => Promise<string | null | undefined>;\n /** Forwarded to ACountrySelect: classes for the popover content surface. */\n contentClass?: string;\n popoverClass?: string;\n drawerClass?: string;\n /** Classes for the inner phone field input element. */\n inputClass?: string;\n /** Classes for the outer wrapper that holds country select + input. */\n fieldClass?: string;\n /** Classes for the helper hint line. */\n hintClass?: string;\n /** Classes for the error message line. */\n errorClass?: string;\n /**\n * How page scroll is blocked while the country popover is open. Defaults to `'events'`\n * (sticky-safe document-level lock). Pass `'body'` for the legacy\n * `body { overflow: hidden }` lock, or `'none'` to leave page scrolling alone.\n */\n scrollLock?: 'events' | 'body' | 'none';\n}\n\nconst props = withDefaults(defineProps<ExtendedProps>(), {\n placeholder: 'Phone number',\n size: DEFAULT_SIZE,\n detectCountry: 'auto',\n defaultCountry: '',\n ipEndpoint: 'https://ipapi.co/json/',\n detectFromInput: true,\n detectDebounceMs: 800,\n showValidationIcon: false,\n});\n\ndefineSlots<{\n /** Content before the country select trigger (e.g. an icon). */\n prefix?: () => unknown;\n /** Content between the input and the validation icons. */\n suffix?: (props: {\n validationState: 'idle' | 'valid' | 'error';\n validation: PhoneValidationResult;\n }) => unknown;\n /** Replace the green check shown when the number validates. */\n 'valid-icon'?: () => unknown;\n /** Replace the warning icon shown when the number fails validation. */\n 'error-icon'?: (props: { reason: string }) => unknown;\n /** Replace the dim helper line shown below the input when empty. */\n hint?: (props: { country: string; formatHint: string; example: string | null }) => unknown;\n /** Replace the error message rendered when invalid. */\n error?: (props: {\n message: string;\n reason: string;\n validation: PhoneValidationResult;\n }) => unknown;\n /** Forwarded to ACountrySelect — replace the trigger button. */\n trigger?: (props: {\n selectedCountry: CountryOption | null;\n open: boolean;\n sizeClasses: string;\n }) => unknown;\n /** Forwarded to ACountrySelect — replace the chevron. */\n chevron?: (props: { open: boolean }) => unknown;\n /** Forwarded — replace any flag rendering. */\n flag?: (props: { country: CountryOption; context: 'trigger' | 'item' }) => unknown;\n /** Forwarded — replace each country list row. */\n item?: (props: {\n country: CountryOption;\n selected: boolean;\n disabled: boolean;\n select: () => void;\n }) => unknown;\n /** Forwarded — section header. */\n 'group-header'?: (props: { label: string; group: 'suggested' | 'all' }) => unknown;\n /** Forwarded — search bar. */\n search?: (props: {\n value: string;\n setValue: (v: string) => void;\n isSearching: boolean;\n }) => unknown;\n loading?: () => unknown;\n empty?: (props: { query: string }) => unknown;\n /** Replace the spinner shown in the picker slot during the debounce window. */\n detecting?: () => unknown;\n}>();\n\nconst phone = defineModel<string>('phone', { default: '' });\n/** Public `v-model:country` — the **dial number** (e.g. `20` for Egypt, `44` for the UK,\n * `1` for the NANP block). `null` means no country selected. Internally the component\n * tracks a richer ISO2 code (`selectedIso2`) because dial codes alone can't disambiguate\n * NANP (`+1` covers 25+ countries) — the picker still needs an exact country. */\nconst country = defineModel<number | null>('country', { default: null });\n\n/** Internal source of truth — the ISO2 alpha-2 code of the picker selection. Synced with\n * `country` (dial number) via watchers below. */\nconst selectedIso2 = ref<string>('');\n\nconst { getCountries, validate, getRequiredInfo, getCountryByValue, getCountriesByDial } =\n usePhoneValidation();\n// Pass the loaded lookups in — useCountryMatching can't call usePhoneValidation() itself\n// because each invocation creates a fresh, empty country index.\nconst { resolveCountryIdentifier, dialNumberFor, matchLeadingDialCode } = useCountryMatching({\n getCountryByValue,\n getCountriesByDial,\n});\n\nvoid getCountries();\n\nconst userPickedCountry = ref(false);\nconst autoSettingCountry = ref(false);\n\n/** Silently resolved via IP/timezone/locale when `detectFromInput` is on — used as a hint\n * so local-format numbers (e.g. Egyptian `01066105963`) can be parsed without a `+` prefix.\n * Seeded from `defaultCountry` so it has a usable value before async detection resolves. */\nconst inferredCountry = ref<string>(resolveCountryIdentifier(props.defaultCountry));\n\n/** Closure passed everywhere the matcher needs typing context (hint country + current\n * selection for tier-3 tie-breaks). Avoids re-reading `selectedIso2`/`inferredCountry`\n * at every call site. */\nfunction tryMatchPhone(digits: string) {\n return matchLeadingDialCode(digits, {\n hintCountry: inferredCountry.value,\n currentIso2: selectedIso2.value,\n });\n}\n\n/* ---------------------------------------------------------------\n * Typing-phase state machine — owns `isDetecting`, `hasFinishedTyping`,\n * `detectionAttempted` and the debounce timer. The `onSettle` callback\n * runs at the end of every debounce window: it short-circuits when\n * detection is disabled / the user already picked / input is empty,\n * otherwise marks a detection attempt and applies any match.\n * ------------------------------------------------------------- */\nconst typing = useTypingPhase({\n debounceMs: computed(() => Math.max(0, props.detectDebounceMs)),\n onSettle: () => {\n if (!props.detectFromInput) return;\n if (userPickedCountry.value || selectedIso2.value) return;\n const current = phone.value;\n if (!current) return;\n\n typing.markDetectionAttempt();\n\n const match = tryMatchPhone(current);\n if (!match) return;\n autoSettingCountry.value = true;\n selectedIso2.value = match.country.value;\n phone.value = match.nationalNumber;\n },\n});\nconst { isDetecting, hasFinishedTyping, detectionAttempted } = typing;\n\nonMounted(async () => {\n if (selectedIso2.value) return; // v-model has an initial value — respect it.\n\n // Explicit `defaultCountry` is treated as the initial picker value (the picker shows\n // immediately) — this is how callers opt out of the hidden-until-detected default. Accepts\n // either an ISO2 code (`'EG'`) or a dial-digit string (`'20'`, `'+20'`).\n if (props.defaultCountry) {\n const seed = resolveCountryIdentifier(props.defaultCountry);\n if (seed) {\n inferredCountry.value = seed;\n autoSettingCountry.value = true;\n selectedIso2.value = seed;\n return;\n }\n }\n\n // No defaultCountry → run the environment chain. Used as a parsing hint in detect mode,\n // or as the auto-fill source in legacy (`detectFromInput=false`) mode.\n const detectOpts: DetectCountryOptions = {\n strategy: props.detectCountry,\n ipEndpoint: props.ipEndpoint,\n defaultCountry: '',\n };\n let detected: string | null | undefined;\n if (props.detector) {\n try {\n detected = await props.detector(detectOpts);\n } catch {\n detected = null;\n }\n }\n if (!detected) {\n detected = await detectCountry(detectOpts);\n }\n const iso2 = detected ? detected.toUpperCase() : '';\n\n if (props.detectFromInput) {\n inferredCountry.value = iso2;\n // If the user has already typed something while detection was resolving, re-attempt\n // matching now that we have a hint country for the libphonenumber national-format pass.\n if (phone.value && !userPickedCountry.value && !selectedIso2.value) {\n const match = tryMatchPhone(phone.value);\n if (match) {\n autoSettingCountry.value = true;\n selectedIso2.value = match.country.value;\n phone.value = match.nationalNumber;\n }\n }\n return;\n }\n if (!selectedIso2.value && iso2) {\n autoSettingCountry.value = true;\n selectedIso2.value = iso2;\n }\n});\n\n/** External → internal: when the caller mutates `v-model:country` (dial number), resolve\n * it to an ISO2. If the current ISO2 already maps to this dial (e.g. user has Canada\n * selected and the caller writes back `1`), keep the existing selection — don't churn it. */\nwatch(\n country,\n (next) => {\n if (next == null) {\n if (selectedIso2.value) selectedIso2.value = '';\n return;\n }\n if (dialNumberFor(selectedIso2.value) === next) return; // already in sync\n const iso2 = resolveCountryIdentifier(String(next));\n if (iso2) selectedIso2.value = iso2;\n },\n { immediate: true }\n);\n\n/** Internal → external: keep `country` (dial number) in lockstep with `selectedIso2`, and\n * flag \"user manually picked from picker\" when the change isn't one we initiated.\n * `flush: 'sync'` so the `autoSettingCountry` guard is reliable. */\nwatch(\n selectedIso2,\n (iso2, prev) => {\n const wasAutoSet = autoSettingCountry.value;\n autoSettingCountry.value = false;\n\n const nextDial = dialNumberFor(iso2);\n if (country.value !== nextDial) country.value = nextDial;\n\n if (!wasAutoSet && props.detectFromInput && iso2 && prev !== iso2) {\n userPickedCountry.value = true;\n }\n },\n { flush: 'sync' }\n);\n\n/** The string shown in the `<input>`. Deliberately decoupled from `phone` (the digits-only\n * model) so the visible field is NOT rewritten mid-edit — non-digits / alternative numerals\n * are normalized into `phone` immediately, but the displayed value is only cleaned up once\n * the user finishes typing (on blur / change). */\nconst displayValue = ref<string>(String(phone.value ?? ''));\n\n/** Set when the in-flight `phone` change came from the user typing — tells the `phone`\n * watcher to leave `displayValue` alone (the user is still editing it). */\nlet phoneEditedByInput = false;\n\nfunction commitPhone(value: string) {\n phoneEditedByInput = true;\n phone.value = value;\n}\n\nfunction handlePhoneInput(e: Event) {\n const target = e.target as HTMLInputElement;\n // Keep the visible value exactly as typed — don't rewrite it mid-edit. The model still\n // receives a normalized, digits-only value so validation + detection stay correct.\n displayValue.value = target.value;\n // Fold alternative numerals (Arabic-Indic, Persian, …) to ASCII, then strip non-digits.\n const cleaned = normalizeDigits(target.value).replace(/\\D/g, '');\n\n if (!cleaned) {\n // Always reset on clear — even after a manual pick. Instant (not debounced) so the\n // picker + spinner hide the moment the input goes empty.\n typing.reset();\n if (props.detectFromInput) {\n autoSettingCountry.value = true;\n selectedIso2.value = '';\n userPickedCountry.value = false;\n }\n commitPhone('');\n return;\n }\n\n typing.markTyping();\n commitPhone(cleaned);\n}\n\n/** Fires when the user finishes editing (blur). Now it's safe to normalize the visible\n * value — fold alternative numerals to ASCII and drop any stray non-digits. */\nfunction handlePhoneChange(e: Event) {\n const target = e.target as HTMLInputElement;\n displayValue.value = normalizeDigits(target.value).replace(/\\D/g, '');\n}\n\nwatch(\n () => phone.value,\n (next) => {\n const cleaned = normalizeDigits(String(next ?? '')).replace(/\\D/g, '');\n // Normalize a programmatic value that arrived non-clean.\n if (cleaned !== next) {\n phone.value = cleaned;\n return;\n }\n // The user typing manages `displayValue` itself — don't fight their edit.\n if (phoneEditedByInput) {\n phoneEditedByInput = false;\n return;\n }\n // External or detection-driven change → reflect it in the visible input.\n displayValue.value = cleaned;\n },\n { flush: 'post' }\n);\n\n/** Resolved UI strings — `messages` prop merged onto English defaults. The individual\n * string props still win when both are set (see `errorMessage` / template bindings). */\nconst messages = computed(() => resolveMessages(props.messages));\n\n/** `dir` of the outer wrapper — drives the hint/error text alignment and the country\n * picker popover. Explicit `'ltr'`/`'rtl'` is applied; `'auto'` or an omitted prop yields\n * `undefined` so it inherits from the page. The field row itself is always LTR so the\n * dial prefix / digits / flag trigger keep a consistent order. */\nconst dirAttr = computed<'ltr' | 'rtl' | undefined>(() =>\n props.dir === 'ltr' || props.dir === 'rtl' ? props.dir : undefined\n);\n\n/* ---------------------------------------------------------------\n * Validation facade — wraps the raw `usePhoneValidation` calls and\n * produces the view-layer surface (visible state gated by the typing\n * pause, localised error message, conditional show flags, etc.).\n * ------------------------------------------------------------- */\nconst {\n validation,\n required,\n validationState,\n visibleValidationState,\n errorMessage,\n showError,\n showHint,\n selectedDialCode,\n} = useTellInputValidation(\n { validate, getRequiredInfo, getCountryByValue },\n { phone, selectedIso2, hasFinishedTyping, messages },\n {\n locale: () => props.locale,\n showValidation: () => props.showValidation,\n errorMessages: () => props.errorMessages,\n }\n);\n\nconst effectivePlaceholder = computed(\n () => props.placeholder || required.value?.format_hint || messages.value.phoneInputLabel\n);\n\nconst inputSizeClasses = computed(\n () => `${controlPaddingX[props.size]} ${controlTextSize[props.size]}`\n);\n\n/** Classes for the inline dial-code prefix — a tight `px-2` so it hugs the input digits. */\nconst dialPrefixClasses = computed(() => `px-2 ${controlTextSize[props.size]}`);\n\n/* ---------------------------------------------------------------\n * Accessibility — the helper line (hint or error) lives in a single\n * `aria-live` region; the input's `aria-describedby` points at it\n * whenever it has content.\n * ------------------------------------------------------------- */\nconst helperId = useId();\nconst describedBy = computed(() => (showError.value || showHint.value ? helperId : undefined));\n\ndefineExpose({\n validation,\n required,\n selectedDialCode,\n validationState,\n visibleValidationState,\n isDetecting,\n hasFinishedTyping,\n detectionAttempted,\n});\n</script>\n\n<template>\n <div\n :class=\"cn('flex w-full flex-col gap-1.5', $attrs.class as string)\"\n data-slot=\"tell-input\"\n :dir=\"dirAttr\"\n >\n <!-- The field row is forced LTR so its pieces (dial prefix, digits, flag trigger) keep\n the same order regardless of page direction — phone numbers read left-to-right. -->\n <div class=\"flex items-center gap-2\" dir=\"ltr\">\n <div\n :class=\"\n cn(\n aTellInputVariants({ size: props.size }),\n 'focus-within:ring-2 focus-within:ring-offset-0',\n // Validation field colors are an opt-in via `showValidation` — by default the\n // field stays neutral and the consumer drives error rendering from `validation`.\n (!props.showValidation || visibleValidationState === 'idle') &&\n 'focus-within:ring-ring/40',\n props.showValidation &&\n visibleValidationState === 'valid' &&\n 'border-emerald-500/60 ring-1 ring-emerald-500/20 focus-within:ring-emerald-500/40',\n props.showValidation &&\n visibleValidationState === 'error' &&\n 'border-destructive/80 ring-1 ring-destructive/20 focus-within:ring-destructive/40',\n props.class,\n props.fieldClass\n )\n \"\n :data-state=\"visibleValidationState\"\n >\n <slot name=\"prefix\" />\n\n <span\n v-if=\"selectedDialCode\"\n data-slot=\"tell-input-dial\"\n dir=\"ltr\"\n aria-hidden=\"true\"\n :class=\"cn('text-muted-foreground shrink-0 tabular-nums select-none', dialPrefixClasses)\"\n >\n {{ selectedDialCode }}\n </span>\n\n <input\n :value=\"displayValue\"\n type=\"tel\"\n inputmode=\"numeric\"\n autocomplete=\"tel\"\n dir=\"ltr\"\n data-slot=\"tell-input-field\"\n :disabled=\"props.disabled || props.loading\"\n :placeholder=\"effectivePlaceholder\"\n :aria-label=\"messages.phoneInputLabel\"\n :aria-invalid=\"visibleValidationState === 'error' || undefined\"\n :aria-describedby=\"describedBy\"\n :class=\"\n cn(\n 'placeholder:text-muted-foreground h-full w-full min-w-0 flex-1 bg-transparent tabular-nums outline-none disabled:cursor-not-allowed',\n inputSizeClasses,\n selectedDialCode && 'ps-1',\n props.inputClass\n )\n \"\n @input=\"handlePhoneInput\"\n @change=\"handlePhoneChange\"\n />\n\n <!-- Detection-in-flight spinner — shown only during the first debounce window,\n before the picker has appeared. Once the picker is visible (success OR a failed\n attempt that revealed the empty picker) we stop re-flashing on every keystroke. -->\n <Transition\n enter-active-class=\"transition-all duration-200 ease-out overflow-hidden\"\n leave-active-class=\"transition-all duration-150 ease-in overflow-hidden\"\n enter-from-class=\"opacity-0 max-w-0\"\n leave-to-class=\"opacity-0 max-w-0\"\n enter-to-class=\"max-w-[2.5rem]\"\n leave-from-class=\"max-w-[2.5rem]\"\n >\n <div\n v-if=\"isDetecting && !selectedIso2 && !detectionAttempted\"\n class=\"text-muted-foreground inline-flex h-full shrink-0 items-center px-2\"\n aria-hidden=\"true\"\n data-slot=\"tell-input-detecting\"\n >\n <slot name=\"detecting\">\n <Loader2 class=\"size-4 animate-spin\" />\n </slot>\n </div>\n </Transition>\n\n <Transition\n enter-active-class=\"transition-all duration-200 ease-out overflow-hidden\"\n leave-active-class=\"transition-all duration-150 ease-in overflow-hidden\"\n enter-from-class=\"opacity-0 max-w-0\"\n leave-to-class=\"opacity-0 max-w-0\"\n enter-to-class=\"max-w-[12rem]\"\n leave-from-class=\"max-w-[12rem]\"\n >\n <!-- Wrapper div gives the <Transition> a single element root to animate.\n ACountrySelect's root is the AResponsivePopover fragment (Popover/Drawer\n swap), which a Transition can't animate directly — without this wrapper\n Vue logs \"Component inside <Transition> renders non-element root node\". -->\n <div\n v-if=\"!props.detectFromInput || selectedIso2 || detectionAttempted\"\n class=\"inline-flex h-full shrink-0 items-center\"\n data-slot=\"tell-input-country-wrapper\"\n >\n <ACountrySelect\n v-model:selected=\"selectedIso2\"\n :allowed-dial-codes=\"props.allowedDialCodes\"\n :disabled=\"props.disabled || props.loading\"\n :size=\"props.size\"\n :locale=\"props.locale\"\n :search-placeholder=\"props.searchPlaceholder ?? messages.searchPlaceholder\"\n :empty-text=\"props.emptyText ?? messages.emptyText\"\n :loading-text=\"props.loadingText ?? messages.loadingText\"\n :suggested-label=\"messages.suggestedLabel\"\n :all-countries-label=\"messages.allCountriesLabel\"\n :country-label=\"messages.countryLabel\"\n :select-country-label=\"messages.selectCountryLabel\"\n :flag-url=\"props.flagUrl\"\n :searcher=\"props.searcher\"\n :countries=\"props.countries\"\n :content-class=\"props.contentClass\"\n :popover-class=\"props.popoverClass\"\n :drawer-class=\"props.drawerClass\"\n :scroll-lock=\"props.scrollLock\"\n >\n <template v-if=\"$slots.trigger\" #trigger=\"slotProps\">\n <slot name=\"trigger\" v-bind=\"slotProps\" />\n </template>\n <template v-if=\"$slots.chevron\" #chevron=\"slotProps\">\n <slot name=\"chevron\" v-bind=\"slotProps\" />\n </template>\n <template v-if=\"$slots.flag\" #flag=\"slotProps\">\n <slot name=\"flag\" v-bind=\"slotProps\" />\n </template>\n <template v-if=\"$slots.item\" #item=\"slotProps\">\n <slot name=\"item\" v-bind=\"slotProps\" />\n </template>\n <template v-if=\"$slots['group-header']\" #group-header=\"slotProps\">\n <slot name=\"group-header\" v-bind=\"slotProps\" />\n </template>\n <template v-if=\"$slots.search\" #search=\"slotProps\">\n <slot name=\"search\" v-bind=\"slotProps\" />\n </template>\n <template v-if=\"$slots.loading\" #loading>\n <slot name=\"loading\" />\n </template>\n <template v-if=\"$slots.empty\" #empty=\"slotProps\">\n <slot name=\"empty\" v-bind=\"slotProps\" />\n </template>\n </ACountrySelect>\n </div>\n </Transition>\n\n <slot name=\"suffix\" :validation-state=\"validationState\" :validation=\"validation\" />\n </div>\n\n <Transition\n v-if=\"props.showValidationIcon\"\n enter-active-class=\"transition duration-150 ease-out\"\n leave-active-class=\"transition duration-100 ease-in\"\n enter-from-class=\"opacity-0 scale-90\"\n leave-to-class=\"opacity-0 scale-90\"\n >\n <slot v-if=\"visibleValidationState === 'valid'\" name=\"valid-icon\">\n <CheckCircle2 class=\"size-5 shrink-0 text-emerald-500\" aria-hidden=\"true\" />\n </slot>\n <slot\n v-else-if=\"visibleValidationState === 'error'\"\n name=\"error-icon\"\n :reason=\"validation.reason ?? ''\"\n >\n <AlertCircle class=\"text-destructive size-5 shrink-0\" aria-hidden=\"true\" />\n </slot>\n </Transition>\n </div>\n\n <div :id=\"helperId\" aria-live=\"polite\">\n <slot\n v-if=\"showError\"\n name=\"error\"\n :message=\"errorMessage!\"\n :reason=\"validation.reason ?? ''\"\n :validation=\"validation\"\n >\n <p\n data-slot=\"tell-input-error\"\n :class=\"cn('text-destructive text-xs', props.errorClass)\"\n role=\"alert\"\n >\n {{ errorMessage }}\n </p>\n </slot>\n <slot\n v-else-if=\"showHint\"\n name=\"hint\"\n :country=\"selectedIso2\"\n :format-hint=\"required!.format_hint\"\n :example=\"required!.example_e164\"\n >\n <p\n data-slot=\"tell-input-hint\"\n :class=\"cn('text-muted-foreground text-xs tabular-nums', props.hintClass)\"\n >\n {{ required!.format_hint }}\n </p>\n </slot>\n </div>\n </div>\n</template>\n"],"names":["LOCALE_DIGIT_RANGES","DIGIT_MAP","map","base","d","normalizeDigits","input","str","out","ch","cp","STORAGE_KEY","REST_COUNTRIES_URL","EX","examples","isBrowser","toDigits","v","localizeDigits","digits","locale","fmt","ensurePlusDial","dial","normalizeIso2","iso2","dropLeadingZeros","buildFullE164","dialClean","nsn","inferLengthFromExample","national","n","buildDialCode","idd","root","suffix","normalizeSearchKey","localizeCountries","list","display","c","localized","makeFallback","name","dialDigits","FALLBACK_COUNTRIES","usePhoneValidation","countries","ref","isCountriesLoading","byValue","byDialDigits","rebuildIndexes","valueMap","dialMap","item","bucket","upsertCountries","normalizeRestCountries","flag","search_key","prev","prevScore","a","b","getCountries","options","force","cached","parsed","res","data","normalized","searchCountries","keyword","limit","q","getCountryByValue","value","getCountriesByDial","getRequiredInfo","country","example","getExampleNumber","exampleNational","exampleE164","inferred","dial_code","digitsExample","validate","required","raw","min","max","full","isValidPhoneNumber","parsePhoneNumberFromString","e","SESSION_CACHE_KEY","TIMEZONE_TO_ISO2","tryTimezone","tz","tryLocale","m","tryIp","endpoint","timeoutMs","controller","timer","code","readCache","writeCache","detectCountry","opts","strategy","ipEndpoint","defaultCountry","cache","ipResult","final","useCountryDetection","isLoading","run","onMounted","DIAL_TO_ISO2_FALLBACK","COUNTRY_RECENTS_KEY","readRecents","useCountryMatching","deps","resolveCountryIdentifier","match","dialNumberFor","matchLeadingDialCode","hintCountry","currentIso2","parsedCountry","matched","len","prefix","group","nationalNumber","current","recentHit","useTypingPhase","isDetecting","hasFinishedTyping","detectionAttempted","settle","useDebounceFn","markTyping","markDetectionAttempt","reset","readonly","useTellInputValidation","inputs","config","computed","validation","validationState","visibleValidationState","errorMessage","showError","showHint","selectedDialCode","aTellInputVariants","cva","controlHeight","controlTextSize","DEFAULT_ERROR_MESSAGES","DEFAULT_MESSAGES","resolveMessages","defaultFlagUrl","width","props","__props","url","failed","watch","iso2Label","_createElementBlock","_normalizeClass","_unref","cn","_hoisted_2","_renderSlot","_ctx","_createElementVNode","RECENTS_KEY","triggerSizeClasses","controlPaddingX","selected","_useModel","internalCountries","defaultSearch","lookupInternal","open","search","effectiveCountries","effectiveByValue","lookup","recents","loadRecents","pushRecent","next","x","isSearching","defaultSearcher","filtered","matcher","suggested","seen","candidate","iso","allowed","r","allCountries","selectedCountry","isAllowed","option","selectCountry","isOpen","__expose","_createBlock","AResponsivePopover","$event","_createVNode","AResponsivePopoverTrigger","ACountryFlag","ChevronDown","AResponsivePopoverContent","_hoisted_3","Search","_openBlock","_hoisted_5","_toDisplayString","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_Fragment","_hoisted_10","_hoisted_11","_renderList","_hoisted_15","_hoisted_16","Check","_hoisted_17","_hoisted_18","_hoisted_22","_hoisted_23","phone","selectedIso2","userPickedCountry","autoSettingCountry","inferredCountry","tryMatchPhone","typing","seed","detectOpts","detected","wasAutoSet","nextDial","displayValue","phoneEditedByInput","commitPhone","handlePhoneInput","target","cleaned","handlePhoneChange","messages","dirAttr","effectivePlaceholder","inputSizeClasses","dialPrefixClasses","helperId","useId","describedBy","$attrs","_Transition","Loader2","ACountrySelect","$slots","_withCtx","slotProps","CheckCircle2","AlertCircle"],"mappings":"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"}
@@ -0,0 +1,241 @@
1
+ import { defineComponent as v, openBlock as u, createBlock as f, unref as s, mergeProps as h, withCtx as p, renderSlot as y, normalizeProps as Y, guardReactiveProps as T, onMounted as X, onBeforeUnmount as _, createElementBlock as $, normalizeClass as A, createCommentVNode as z, createVNode as x, watch as w, toValue as B } from "vue";
2
+ import { useForwardPropsEmits as P, PopoverRoot as F, useForwardProps as H, PopoverTrigger as M, PopoverPortal as N, PopoverContent as U } from "reka-ui";
3
+ import { reactiveOmit as j } from "@vueuse/core";
4
+ import { c as b } from "./cn-B6yFEsav.mjs";
5
+ const Z = /* @__PURE__ */ v({
6
+ __name: "APopover",
7
+ props: {
8
+ defaultOpen: { type: Boolean },
9
+ open: { type: Boolean },
10
+ modal: { type: Boolean, default: !0 }
11
+ },
12
+ emits: ["update:open"],
13
+ setup(e, { emit: o }) {
14
+ const l = P(e, o);
15
+ return (i, a) => (u(), f(s(F), h({ "data-slot": "popover" }, s(l)), {
16
+ default: p((r) => [
17
+ y(i.$slots, "default", Y(T(r)))
18
+ ]),
19
+ _: 3
20
+ }, 16));
21
+ }
22
+ }), ee = /* @__PURE__ */ v({
23
+ __name: "APopoverTrigger",
24
+ props: {
25
+ asChild: { type: Boolean },
26
+ as: {}
27
+ },
28
+ setup(e) {
29
+ const n = H(e);
30
+ return (t, l) => (u(), f(s(M), h({ "data-slot": "popover-trigger" }, s(n)), {
31
+ default: p(() => [
32
+ y(t.$slots, "default")
33
+ ]),
34
+ _: 3
35
+ }, 16));
36
+ }
37
+ }), K = /* @__PURE__ */ v({
38
+ inheritAttrs: !1,
39
+ __name: "APopoverOverlay",
40
+ props: {
41
+ class: { type: [Boolean, null, String, Object, Array] },
42
+ lockScroll: { type: Boolean, default: !1 }
43
+ },
44
+ setup(e) {
45
+ const o = e;
46
+ let n = "", t = "", l = "";
47
+ function i() {
48
+ return typeof window > "u" ? 0 : window.innerWidth - document.documentElement.clientWidth;
49
+ }
50
+ return X(() => {
51
+ if (!o.lockScroll || typeof document > "u") return;
52
+ const a = document.body, r = i();
53
+ n = a.style.overflow, t = a.style.touchAction, l = a.style.paddingRight, a.style.overflow = "hidden", a.style.touchAction = "none", r > 0 && (a.style.paddingRight = `${r}px`);
54
+ }), _(() => {
55
+ if (!o.lockScroll || typeof document > "u") return;
56
+ const a = document.body;
57
+ a.style.overflow = n, a.style.touchAction = t, a.style.paddingRight = l;
58
+ }), (a, r) => (u(), $("div", {
59
+ "data-slot": "popover-overlay",
60
+ "aria-hidden": "true",
61
+ class: A(
62
+ s(b)(
63
+ // `fixed inset-0` covers the entire viewport; `pointer-events-auto` captures every
64
+ // click so it can never reach the page underneath. `z-50` keeps us above any normal
65
+ // page chrome; the popover content sits at `z-[60]`.
66
+ "fixed inset-0 z-50 bg-black/70 pointer-events-auto data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
67
+ o.class
68
+ )
69
+ )
70
+ }, null, 2));
71
+ }
72
+ }), te = /* @__PURE__ */ v({
73
+ inheritAttrs: !1,
74
+ __name: "APopoverContent",
75
+ props: {
76
+ forceMount: { type: Boolean },
77
+ side: {},
78
+ sideOffset: { default: 4 },
79
+ sideFlip: { type: Boolean },
80
+ align: { default: "center" },
81
+ alignOffset: {},
82
+ alignFlip: { type: Boolean },
83
+ avoidCollisions: { type: Boolean },
84
+ collisionBoundary: {},
85
+ collisionPadding: {},
86
+ arrowPadding: {},
87
+ hideShiftedArrow: { type: Boolean },
88
+ sticky: {},
89
+ hideWhenDetached: { type: Boolean },
90
+ positionStrategy: {},
91
+ updatePositionStrategy: {},
92
+ disableUpdateOnLayoutShift: { type: Boolean },
93
+ prioritizePosition: { type: Boolean },
94
+ reference: {},
95
+ asChild: { type: Boolean },
96
+ as: {},
97
+ disableOutsidePointerEvents: { type: Boolean },
98
+ class: { type: [Boolean, null, String, Object, Array] },
99
+ overlay: { type: Boolean, default: !1 },
100
+ overlayClass: { type: [Boolean, null, String, Object, Array] },
101
+ overlayLockScroll: { type: Boolean, default: !1 }
102
+ },
103
+ emits: ["escapeKeyDown", "pointerDownOutside", "focusOutside", "interactOutside", "openAutoFocus", "closeAutoFocus"],
104
+ setup(e, { emit: o }) {
105
+ const n = e, t = o, l = j(n, "class", "overlay", "overlayClass", "overlayLockScroll"), i = P(l, t);
106
+ return (a, r) => (u(), f(s(N), null, {
107
+ default: p(() => [
108
+ n.overlay ? (u(), f(K, {
109
+ key: 0,
110
+ class: A(n.overlayClass),
111
+ "lock-scroll": n.overlayLockScroll
112
+ }, null, 8, ["class", "lock-scroll"])) : z("", !0),
113
+ x(s(U), h({ "data-slot": "popover-content" }, { ...a.$attrs, ...s(i) }, {
114
+ class: s(b)(
115
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-[60] w-72 rounded-md border border-border/70 p-4 shadow-xl shadow-black/15 outline-none",
116
+ n.class
117
+ )
118
+ }), {
119
+ default: p(() => [
120
+ y(a.$slots, "default")
121
+ ]),
122
+ _: 3
123
+ }, 16, ["class"])
124
+ ]),
125
+ _: 3
126
+ }));
127
+ }
128
+ });
129
+ let d = 0;
130
+ const m = /* @__PURE__ */ new Set(), V = /* @__PURE__ */ new Set([
131
+ "ArrowUp",
132
+ "ArrowDown",
133
+ "ArrowLeft",
134
+ "ArrowRight",
135
+ "PageUp",
136
+ "PageDown",
137
+ "Home",
138
+ "End",
139
+ "Space",
140
+ " "
141
+ ]);
142
+ function g(e) {
143
+ if (!(e instanceof Node)) return !1;
144
+ for (const o of m) if (o.contains(e)) return !0;
145
+ return !1;
146
+ }
147
+ function k(e, o, n) {
148
+ let t = e;
149
+ for (; t; ) {
150
+ const l = getComputedStyle(t);
151
+ if ((l.overflowY === "auto" || l.overflowY === "scroll") && t.scrollHeight > t.clientHeight && n !== 0) {
152
+ const r = t.scrollTop <= 0, c = t.scrollTop + t.clientHeight >= t.scrollHeight - 1;
153
+ if (!(n < 0 && r) && !(n > 0 && c)) return !0;
154
+ }
155
+ if ((l.overflowX === "auto" || l.overflowX === "scroll") && t.scrollWidth > t.clientWidth && o !== 0) {
156
+ const r = t.scrollLeft <= 0, c = t.scrollLeft + t.clientWidth >= t.scrollWidth - 1;
157
+ if (!(o < 0 && r) && !(o > 0 && c)) return !0;
158
+ }
159
+ if (m.has(t)) break;
160
+ t = t.parentElement;
161
+ }
162
+ return !1;
163
+ }
164
+ function C(e) {
165
+ const o = e.composedPath()[0] ?? e.target;
166
+ if (!o || !g(o)) {
167
+ e.preventDefault();
168
+ return;
169
+ }
170
+ k(o, e.deltaX, e.deltaY) || e.preventDefault();
171
+ }
172
+ let L = 0, E = 0;
173
+ function O(e) {
174
+ e.touches.length === 1 && (L = e.touches[0].clientY, E = e.touches[0].clientX);
175
+ }
176
+ function D(e) {
177
+ const o = e.composedPath()[0] ?? e.target;
178
+ if (!o || !g(o)) {
179
+ e.preventDefault();
180
+ return;
181
+ }
182
+ if (e.touches.length !== 1) {
183
+ e.preventDefault();
184
+ return;
185
+ }
186
+ const n = L - e.touches[0].clientY, t = E - e.touches[0].clientX;
187
+ k(o, t, n) || e.preventDefault();
188
+ }
189
+ function R(e) {
190
+ V.has(e.key) && (g(e.target) || e.preventDefault());
191
+ }
192
+ function q() {
193
+ d === 0 && (document.addEventListener("wheel", C, {
194
+ passive: !1,
195
+ capture: !0
196
+ }), document.addEventListener("touchstart", O, {
197
+ passive: !0,
198
+ capture: !0
199
+ }), document.addEventListener("touchmove", D, {
200
+ passive: !1,
201
+ capture: !0
202
+ }), document.addEventListener("keydown", R, { capture: !0 })), d++;
203
+ }
204
+ function S() {
205
+ d = Math.max(0, d - 1), d === 0 && (document.removeEventListener("wheel", C, { capture: !0 }), document.removeEventListener("touchstart", O, { capture: !0 }), document.removeEventListener("touchmove", D, { capture: !0 }), document.removeEventListener("keydown", R, { capture: !0 }));
206
+ }
207
+ function oe(e) {
208
+ if (typeof document > "u") return;
209
+ let o = [], n = !1;
210
+ const t = () => {
211
+ const r = B(e.allowedScrollContainer), c = Array.isArray(r) ? r.filter(Boolean) : r ? [r] : [];
212
+ for (const W of c) m.add(W);
213
+ o = c;
214
+ }, l = () => {
215
+ for (const r of o) m.delete(r);
216
+ o = [];
217
+ }, i = w(
218
+ () => typeof e.active == "function" ? e.active() : e.active.value,
219
+ (r) => {
220
+ r && !n ? (t(), q(), n = !0) : !r && n && (S(), l(), n = !1);
221
+ },
222
+ { immediate: !0, flush: "post" }
223
+ ), a = w(
224
+ () => B(e.allowedScrollContainer),
225
+ () => {
226
+ n && (l(), t());
227
+ },
228
+ { flush: "post" }
229
+ );
230
+ _(() => {
231
+ i(), a(), n && (S(), l(), n = !1);
232
+ });
233
+ }
234
+ export {
235
+ Z as _,
236
+ te as a,
237
+ K as b,
238
+ ee as c,
239
+ oe as u
240
+ };
241
+ //# sourceMappingURL=useEventScrollLock-BcP8fg-L.mjs.map