@alikhalilll/ui 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +155 -187
  2. package/dist/chunks/ADrawerContent.vue_vue_type_script_setup_true_lang-BivIZvV1.mjs +108 -0
  3. package/dist/chunks/ADrawerContent.vue_vue_type_script_setup_true_lang-BivIZvV1.mjs.map +1 -0
  4. package/dist/chunks/AInput.vue_vue_type_script_setup_true_lang-BJUP7ePq.mjs +81 -0
  5. package/dist/chunks/AInput.vue_vue_type_script_setup_true_lang-BJUP7ePq.mjs.map +1 -0
  6. package/dist/chunks/APopoverContent.vue_vue_type_script_setup_true_lang-o1XhV9DM.mjs +132 -0
  7. package/dist/chunks/APopoverContent.vue_vue_type_script_setup_true_lang-o1XhV9DM.mjs.map +1 -0
  8. package/dist/chunks/AResponsivePopoverContent.vue_vue_type_script_setup_true_lang-BYEb5UBL.mjs +92 -0
  9. package/dist/chunks/AResponsivePopoverContent.vue_vue_type_script_setup_true_lang-BYEb5UBL.mjs.map +1 -0
  10. package/dist/chunks/ATellInput.vue_vue_type_script_setup_true_lang-Clc-B8SW.mjs +1353 -0
  11. package/dist/chunks/ATellInput.vue_vue_type_script_setup_true_lang-Clc-B8SW.mjs.map +1 -0
  12. package/dist/chunks/cn-B6yFEsav.mjs +9 -0
  13. package/dist/chunks/cn-B6yFEsav.mjs.map +1 -0
  14. package/dist/chunks/sizes-B_9MfLkz.mjs +34 -0
  15. package/dist/chunks/sizes-B_9MfLkz.mjs.map +1 -0
  16. package/dist/drawer.d.ts +116 -0
  17. package/dist/drawer.mjs +8 -0
  18. package/dist/drawer.mjs.map +1 -0
  19. package/dist/index.d.ts +84 -57
  20. package/dist/index.mjs +35 -1516
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/input.d.ts +65 -0
  23. package/dist/input.mjs +5 -0
  24. package/dist/input.mjs.map +1 -0
  25. package/dist/popover.d.ts +117 -0
  26. package/dist/popover.mjs +8 -0
  27. package/dist/popover.mjs.map +1 -0
  28. package/dist/responsive-popover.d.ts +124 -0
  29. package/dist/responsive-popover.mjs +7 -0
  30. package/dist/responsive-popover.mjs.map +1 -0
  31. package/dist/tell-input.d.ts +637 -0
  32. package/dist/tell-input.mjs +13 -0
  33. package/dist/tell-input.mjs.map +1 -0
  34. package/dist/utils.d.ts +29 -0
  35. package/dist/utils.mjs +12 -0
  36. package/dist/utils.mjs.map +1 -0
  37. package/entries/drawer/README.md +39 -0
  38. package/entries/input/README.md +42 -0
  39. package/entries/popover/README.md +37 -0
  40. package/entries/responsive-popover/README.md +47 -0
  41. package/entries/tell-input/README.md +52 -0
  42. package/package.json +30 -4
  43. /package/dist/{styles.css → assets/styles.css} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ATellInput.vue_vue_type_script_setup_true_lang-Clc-B8SW.mjs","sources":["../../entries/tell-input/composables/usePhoneValidation.ts","../../entries/tell-input/composables/useCountryDetection.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 * 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';\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 | { country: { iso2: string; dial_code?: string } | null | undefined; phone?: undefined }\n | { country: { iso2: string; dial_code?: string } | null | undefined; phone: string | null };\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 return String(v ?? '').replace(/\\D/g, '');\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 String(input ?? '')\n .toLowerCase()\n .replace(/\\s+/g, ' ')\n .trim()\n .replace(/[^\\da-z+ ]/g, '');\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(country: { iso2: string; dial_code?: string }): 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(country: {\n iso2: string;\n dial_code?: 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. ${digitsExample}` : '',\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 });\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 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\nexport interface ATellInputProps {\n class?: HTMLAttributes['class'];\n placeholder?: string;\n disabled?: boolean;\n loading?: boolean;\n size?: ATellInputSize;\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 /** Show validation error text beneath the input when invalid. */\n showValidation?: 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 * 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 { usePhoneValidation, type CountryOption } 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 }>(),\n {\n searchPlaceholder: 'Search country or +code…',\n emptyText: 'No countries found.',\n loadingText: 'Loading countries…',\n suggestedLabel: 'Suggested',\n allCountriesLabel: 'All countries',\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.\n * ------------------------------------------------------------- */\nconst effectiveCountries = computed<CountryOption[]>(() =>\n props.countries && props.countries.length ? props.countries : internalCountries.value\n);\n\nconst customByValue = computed<Map<string, CountryOption>>(() => {\n if (!props.countries || !props.countries.length) return new Map();\n return new Map(props.countries.map((c) => [c.value, c]));\n});\n\nfunction lookup(iso2: string): CountryOption | null {\n if (!iso2) return null;\n return customByValue.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). Only fall back\n // to a manual filter when we need to honor a custom `searcher` or `countries` source.\n if (!props.countries && !props.searcher) {\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\">\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-muted/50 hover:bg-muted focus-visible:bg-muted data-[state=open]:bg-muted focus-visible:ring-ring border-input inline-flex h-full shrink-0 items-center gap-2 border-r 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 ? `Country: ${selectedCountry.raw_data.name}` : 'Select country'\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 <span class=\"text-foreground font-medium tabular-nums\">\n {{ selectedCountry ? selectedCountry.raw_data.dial_code : '+?' }}\n </span>\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=\"start\"\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-b p-1.5\">\n <div\n class=\"bg-muted/40 ring-border focus-within:ring-ring relative flex items-center rounded-md ring-1 transition-shadow focus-within:ring-2\"\n >\n <slot name=\"search-icon\">\n <Search\n class=\"text-muted-foreground absolute top-1/2 left-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-8 w-full bg-transparent pr-14 pl-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 right-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 right-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, watch } from 'vue';\nimport { useDebounceFn } from '@vueuse/core';\nimport { CheckCircle2, AlertCircle } from 'lucide-vue-next';\nimport { parsePhoneNumberFromString, type CountryCode } from 'libphonenumber-js';\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 { controlPaddingX, controlTextSize, DEFAULT_SIZE } from '@/utils';\nimport { aTellInputVariants, DEFAULT_ERROR_MESSAGES, type ATellInputProps } from '../utils/types';\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\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: 150,\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}>();\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\nvoid getCountries();\n\nconst userPickedCountry = ref(false);\nconst autoSettingCountry = ref(false);\n\n/** Synchronous dial-digit → ISO2 fallback for common countries, in case the async REST\n * Countries fetch hasn't populated `getCountriesByDial`'s index yet during setup. */\nconst 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/** 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. */\nfunction 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 (gives the right answer when multiple share a dial);\n // fall 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/** 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\nconst RECENTS_KEY = 'ali_ui_country_recents_v1';\nfunction readRecents(): string[] {\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 return Array.isArray(parsed) ? parsed.filter((v): v is string => typeof v === 'string') : [];\n } catch {\n return [];\n }\n}\n\ninterface DialMatch {\n country: CountryOption;\n /** The national significant number — what `phone` should become, with both dial code\n * and national prefix (e.g. Egyptian leading `0`) stripped. */\n nationalNumber: string;\n}\n\nfunction matchLeadingDialCode(digits: string): DialMatch | null {\n if (!digits) return null;\n\n // Tier 1: international parse — disambiguates NANP (+1 ... area code → US/CA/etc.) and\n // returns the canonical NSN with the country calling code already stripped.\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 (IP/timezone/locale)\n // as a hint. Catches local formats like Egyptian `01066105963` where there's no leading\n // dial code to match against. libphonenumber strips the national prefix (the leading 0\n // for EG, etc.) so the resulting `nationalNumber` is the canonical NSN.\n const hint = inferredCountry.value;\n if (hint && digits.length >= 4) {\n try {\n const parsed = parsePhoneNumberFromString(digits, hint as CountryCode);\n if (parsed?.isValid()) {\n const matched = getCountryByValue(parsed.country || hint);\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 our own dial-digits index — handles partial\n // international input like `44` or `20` before libphonenumber can disambiguate.\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 = selectedIso2.value\n ? group.find((c) => c.value === selectedIso2.value.toUpperCase())\n : 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\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 = matchLeadingDialCode(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/** Compute the dial digits (as a number) for an ISO2 code. Falls back to the synchronous\n * dial table if the async country list hasn't populated yet. */\nfunction 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/** 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/** Debounced detection — re-evaluates `phone.value` at the time the timer fires (not the\n * value captured when scheduled), so a burst of keystrokes collapses into one parse. */\nconst detectAndApply = useDebounceFn(\n () => {\n if (!props.detectFromInput) return;\n if (userPickedCountry.value || selectedIso2.value) return;\n const current = phone.value;\n if (!current) return;\n const match = matchLeadingDialCode(current);\n if (!match) return;\n autoSettingCountry.value = true;\n selectedIso2.value = match.country.value;\n phone.value = match.nationalNumber;\n },\n computed(() => Math.max(0, props.detectDebounceMs))\n);\n\nfunction handlePhoneInput(e: Event) {\n const target = e.target as HTMLInputElement;\n const cleaned = target.value.replace(/\\D/g, '');\n if (cleaned !== target.value) target.value = cleaned;\n\n if (props.detectFromInput) {\n if (!cleaned) {\n // Always reset on clear — even after a manual pick. Instant (not debounced) so the\n // picker hides the moment the input goes empty.\n autoSettingCountry.value = true;\n selectedIso2.value = '';\n phone.value = '';\n userPickedCountry.value = false;\n return;\n }\n phone.value = cleaned;\n if (!userPickedCountry.value && !selectedIso2.value) {\n detectAndApply();\n }\n return;\n }\n\n phone.value = cleaned;\n}\n\nwatch(\n () => phone.value,\n (next, prev) => {\n const cleaned = String(next ?? '').replace(/\\D/g, '');\n if (cleaned !== next && cleaned !== prev) phone.value = cleaned;\n },\n { flush: 'post' }\n);\n\nconst required = computed(() =>\n selectedIso2.value ? getRequiredInfo({ iso2: selectedIso2.value }) : null\n);\n\nconst validation = computed<PhoneValidationResult>(() =>\n validate({\n country: selectedIso2.value ? { iso2: selectedIso2.value } : null,\n phone: phone.value ?? '',\n })\n);\n\nconst effectivePlaceholder = computed(\n () => props.placeholder || required.value?.format_hint || 'Phone number'\n);\n\nconst errorMessage = computed(() => {\n const v = validation.value;\n if (v.ok || !v.reason) return null;\n if (!phone.value) return null;\n return props.errorMessages?.[v.reason] ?? DEFAULT_ERROR_MESSAGES[v.reason];\n});\n\nconst selectedDialCode = computed(() => {\n if (!selectedIso2.value) return null;\n return getCountryByValue(selectedIso2.value)?.raw_data.dial_code ?? null;\n});\n\nconst inputSizeClasses = computed(\n () => `${controlPaddingX[props.size]} ${controlTextSize[props.size]}`\n);\n\nconst validationState = computed<'idle' | 'valid' | 'error'>(() => {\n if (!phone.value) return 'idle';\n return validation.value.ok ? 'valid' : 'error';\n});\n\ndefineExpose({ validation, required, selectedDialCode, validationState });\n</script>\n\n<template>\n <div :class=\"cn('flex w-full flex-col gap-1.5', $attrs.class as string)\" data-slot=\"tell-input\">\n <div class=\"flex items-center gap-2\">\n <div\n :class=\"\n cn(\n aTellInputVariants({ size: props.size }),\n 'focus-within:ring-2 focus-within:ring-offset-0',\n validationState === 'idle' && 'focus-within:ring-ring/40',\n validationState === 'valid' &&\n 'border-emerald-500/60 ring-1 ring-emerald-500/20 focus-within:ring-emerald-500/40',\n validationState === '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=\"validationState\"\n dir=\"ltr\"\n >\n <slot name=\"prefix\" />\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 -translate-x-1 max-w-0\"\n leave-to-class=\"opacity-0 -translate-x-1 max-w-0\"\n enter-to-class=\"max-w-[12rem]\"\n leave-from-class=\"max-w-[12rem]\"\n >\n <ACountrySelect\n v-if=\"!props.detectFromInput || selectedIso2\"\n v-model:selected=\"selectedIso2\"\n :allowed-dial-codes=\"props.allowedDialCodes\"\n :disabled=\"props.disabled || props.loading\"\n :size=\"props.size\"\n :search-placeholder=\"props.searchPlaceholder\"\n :empty-text=\"props.emptyText\"\n :loading-text=\"props.loadingText\"\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 >\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 </Transition>\n\n <input\n v-model=\"phone\"\n type=\"tel\"\n inputmode=\"numeric\"\n autocomplete=\"tel\"\n data-slot=\"tell-input-field\"\n :disabled=\"props.disabled || props.loading\"\n :placeholder=\"effectivePlaceholder\"\n :aria-invalid=\"validationState === 'error' || undefined\"\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 props.inputClass\n )\n \"\n @input=\"handlePhoneInput\"\n />\n\n <slot name=\"suffix\" :validation-state=\"validationState\" :validation=\"validation\" />\n </div>\n\n <Transition\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=\"validationState === '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=\"validationState === '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 <slot\n v-if=\"props.showValidation && errorMessage\"\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=\"!phone && required?.format_hint\"\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</template>\n"],"names":["STORAGE_KEY","REST_COUNTRIES_URL","EX","examples","isBrowser","toDigits","v","ensurePlusDial","dial","d","normalizeIso2","iso2","dropLeadingZeros","digits","buildFullE164","dialClean","nsn","inferLengthFromExample","national","n","buildDialCode","idd","root","suffix","out","normalizeSearchKey","input","makeFallback","name","dialDigits","FALLBACK_COUNTRIES","usePhoneValidation","countries","ref","isCountriesLoading","byValue","byDialDigits","rebuildIndexes","list","valueMap","dialMap","item","bucket","upsertCountries","normalizeRestCountries","c","flag","search_key","map","prev","prevScore","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","aTellInputVariants","cva","controlHeight","controlTextSize","DEFAULT_ERROR_MESSAGES","defaultFlagUrl","width","props","__props","url","computed","failed","watch","iso2Label","_createElementBlock","_normalizeClass","_unref","cn","_hoisted_2","_renderSlot","_ctx","_createElementVNode","RECENTS_KEY","triggerSizeClasses","controlPaddingX","selected","_useModel","internalCountries","defaultSearch","lookupInternal","open","search","effectiveCountries","customByValue","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","_toDisplayString","ChevronDown","AResponsivePopoverContent","_hoisted_3","_hoisted_4","Search","_openBlock","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_Fragment","_hoisted_11","_hoisted_12","_renderList","_hoisted_16","_hoisted_17","Check","_hoisted_18","_hoisted_19","_hoisted_23","_hoisted_24","phone","selectedIso2","userPickedCountry","autoSettingCountry","DIAL_TO_ISO2_FALLBACK","resolveCountryIdentifier","match","inferredCountry","readRecents","matchLeadingDialCode","parsedCountry","hint","matched","len","prefix","group","nationalNumber","current","recentHit","seed","detectOpts","detected","dialNumberFor","wasAutoSet","nextDial","detectAndApply","useDebounceFn","handlePhoneInput","target","cleaned","validation","effectivePlaceholder","errorMessage","selectedDialCode","inputSizeClasses","validationState","$attrs","_hoisted_1","_Transition","ACountrySelect","$slots","_withCtx","slotProps","CheckCircle2","AlertCircle"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { clsx as o } from "clsx";
2
+ import { twMerge as t } from "tailwind-merge";
3
+ function m(...r) {
4
+ return t(o(r));
5
+ }
6
+ export {
7
+ m as c
8
+ };
9
+ //# sourceMappingURL=cn-B6yFEsav.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cn-B6yFEsav.mjs","sources":["../../utils/cn.ts"],"sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"names":["cn","inputs","twMerge","clsx"],"mappings":";;AAGO,SAASA,KAAMC,GAAsB;AAC1C,SAAOC,EAAQC,EAAKF,CAAM,CAAC;AAC7B;"}
@@ -0,0 +1,34 @@
1
+ const s = ["xs", "sm", "md", "lg", "xl"], x = "md", t = {
2
+ xs: "h-7",
3
+ sm: "h-9",
4
+ md: "h-[43px]",
5
+ lg: "h-[52px]",
6
+ xl: "h-[60px]"
7
+ }, o = {
8
+ xs: "px-2",
9
+ sm: "px-2.5",
10
+ md: "px-3",
11
+ lg: "px-3.5",
12
+ xl: "px-4"
13
+ }, l = {
14
+ xs: "text-xs",
15
+ sm: "text-sm",
16
+ md: "text-sm",
17
+ lg: "text-base",
18
+ xl: "text-base"
19
+ }, m = {
20
+ xs: 28,
21
+ sm: 36,
22
+ md: 43,
23
+ lg: 52,
24
+ xl: 60
25
+ };
26
+ export {
27
+ x as D,
28
+ s as S,
29
+ m as a,
30
+ o as b,
31
+ t as c,
32
+ l as d
33
+ };
34
+ //# sourceMappingURL=sizes-B_9MfLkz.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sizes-B_9MfLkz.mjs","sources":["../../utils/sizes.ts"],"sourcesContent":["/**\n * Shared size scale for every interactive UI component in @alikhalilll/ui.\n *\n * xs = 28px · sm = 36px · md = 43px (default) · lg = 52px · xl = 60px\n *\n * Use the {@link controlHeight}, {@link controlPaddingX}, {@link controlTextSize}\n * maps when building a CVA variant so every component stays in lockstep.\n */\n\nexport type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\nexport const SIZES: readonly Size[] = ['xs', 'sm', 'md', 'lg', 'xl'] as const;\n\nexport const DEFAULT_SIZE: Size = 'md';\n\n/** Tailwind height utility per size. md uses an arbitrary value because 43px isn't on the spacing scale. */\nexport const controlHeight: Record<Size, string> = {\n xs: 'h-7',\n sm: 'h-9',\n md: 'h-[43px]',\n lg: 'h-[52px]',\n xl: 'h-[60px]',\n};\n\nexport const controlPaddingX: Record<Size, string> = {\n xs: 'px-2',\n sm: 'px-2.5',\n md: 'px-3',\n lg: 'px-3.5',\n xl: 'px-4',\n};\n\nexport const controlTextSize: Record<Size, string> = {\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-sm',\n lg: 'text-base',\n xl: 'text-base',\n};\n\n/** Pixel values exposed so non-template code (icons, ResizeObserver, etc.) can read the height. */\nexport const controlHeightPx: Record<Size, number> = {\n xs: 28,\n sm: 36,\n md: 43,\n lg: 52,\n xl: 60,\n};\n"],"names":["SIZES","DEFAULT_SIZE","controlHeight","controlPaddingX","controlTextSize","controlHeightPx"],"mappings":"AAWO,MAAMA,IAAyB,CAAC,MAAM,MAAM,MAAM,MAAM,IAAI,GAEtDC,IAAqB,MAGrBC,IAAsC;AAAA,EACjD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAEaC,IAAwC;AAAA,EACnD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAEaC,IAAwC;AAAA,EACnD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAGaC,IAAwC;AAAA,EACnD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;"}
@@ -0,0 +1,116 @@
1
+ import { ComponentOptionsMixin } from 'vue';
2
+ import { ComponentProvideOptions } from 'vue';
3
+ import { DefineComponent } from 'vue';
4
+ import { DialogContentProps } from 'reka-ui';
5
+ import { DialogOverlayProps } from 'reka-ui';
6
+ import { DrawerRootProps } from 'vaul-vue';
7
+ import { DrawerTriggerProps } from 'vaul-vue';
8
+ import { FocusOutsideEvent } from 'reka-ui';
9
+ import { HTMLAttributes } from 'vue';
10
+ import { PointerDownOutsideEvent } from 'reka-ui';
11
+ import { PublicProps } from 'vue';
12
+
13
+ declare const __VLS_component: DefineComponent<DrawerRootProps, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
14
+ "update:open": (open: boolean) => any;
15
+ animationEnd: (open: boolean) => any;
16
+ drag: (percentageDragged: number) => any;
17
+ release: (open: boolean) => any;
18
+ close: () => any;
19
+ "update:activeSnapPoint": (val: string | number) => any;
20
+ }, string, PublicProps, Readonly<DrawerRootProps> & Readonly<{
21
+ "onUpdate:open"?: ((open: boolean) => any) | undefined;
22
+ onAnimationEnd?: ((open: boolean) => any) | undefined;
23
+ onDrag?: ((percentageDragged: number) => any) | undefined;
24
+ onRelease?: ((open: boolean) => any) | undefined;
25
+ onClose?: (() => any) | undefined;
26
+ "onUpdate:activeSnapPoint"?: ((val: string | number) => any) | undefined;
27
+ }>, {
28
+ shouldScaleBackground: boolean;
29
+ }, {}, {}, {}, string, ComponentProvideOptions, false, {}, any>;
30
+
31
+ declare const __VLS_component_2: DefineComponent<DrawerTriggerProps, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<DrawerTriggerProps> & Readonly<{}>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, any>;
32
+
33
+ declare const __VLS_component_3: DefineComponent<__VLS_Props, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
34
+ escapeKeyDown: (event: KeyboardEvent) => any;
35
+ pointerDownOutside: (event: PointerDownOutsideEvent) => any;
36
+ focusOutside: (event: FocusOutsideEvent) => any;
37
+ interactOutside: (event: PointerDownOutsideEvent | FocusOutsideEvent) => any;
38
+ openAutoFocus: (event: Event) => any;
39
+ closeAutoFocus: (event: Event) => any;
40
+ }, string, PublicProps, Readonly<__VLS_Props> & Readonly<{
41
+ onEscapeKeyDown?: ((event: KeyboardEvent) => any) | undefined;
42
+ onPointerDownOutside?: ((event: PointerDownOutsideEvent) => any) | undefined;
43
+ onFocusOutside?: ((event: FocusOutsideEvent) => any) | undefined;
44
+ onInteractOutside?: ((event: PointerDownOutsideEvent | FocusOutsideEvent) => any) | undefined;
45
+ onOpenAutoFocus?: ((event: Event) => any) | undefined;
46
+ onCloseAutoFocus?: ((event: Event) => any) | undefined;
47
+ }>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, any>;
48
+
49
+ declare type __VLS_Props = DialogContentProps & {
50
+ class?: HTMLAttributes['class'];
51
+ };
52
+
53
+ declare type __VLS_Props_2 = DialogOverlayProps & {
54
+ class?: HTMLAttributes['class'];
55
+ };
56
+
57
+ declare function __VLS_template(): {
58
+ attrs: Partial<{}>;
59
+ slots: {
60
+ default?(_: {}): any;
61
+ };
62
+ refs: {};
63
+ rootEl: any;
64
+ };
65
+
66
+ declare function __VLS_template_2(): {
67
+ attrs: Partial<{}>;
68
+ slots: {
69
+ default?(_: {}): any;
70
+ };
71
+ refs: {};
72
+ rootEl: any;
73
+ };
74
+
75
+ declare function __VLS_template_3(): {
76
+ attrs: Partial<{}>;
77
+ slots: {
78
+ default?(_: {}): any;
79
+ };
80
+ refs: {};
81
+ rootEl: any;
82
+ };
83
+
84
+ declare type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
85
+
86
+ declare type __VLS_TemplateResult_2 = ReturnType<typeof __VLS_template_2>;
87
+
88
+ declare type __VLS_TemplateResult_3 = ReturnType<typeof __VLS_template_3>;
89
+
90
+ declare type __VLS_WithTemplateSlots<T, S> = T & {
91
+ new (): {
92
+ $slots: S;
93
+ };
94
+ };
95
+
96
+ declare type __VLS_WithTemplateSlots_2<T, S> = T & {
97
+ new (): {
98
+ $slots: S;
99
+ };
100
+ };
101
+
102
+ declare type __VLS_WithTemplateSlots_3<T, S> = T & {
103
+ new (): {
104
+ $slots: S;
105
+ };
106
+ };
107
+
108
+ export declare const ADrawer: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
109
+
110
+ export declare const ADrawerContent: __VLS_WithTemplateSlots_3<typeof __VLS_component_3, __VLS_TemplateResult_3["slots"]>;
111
+
112
+ export declare const ADrawerOverlay: DefineComponent<__VLS_Props_2, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<__VLS_Props_2> & Readonly<{}>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, any>;
113
+
114
+ export declare const ADrawerTrigger: __VLS_WithTemplateSlots_2<typeof __VLS_component_2, __VLS_TemplateResult_2["slots"]>;
115
+
116
+ export { }
@@ -0,0 +1,8 @@
1
+ import { _ as e, a as s, b as w, c as A } from "./chunks/ADrawerContent.vue_vue_type_script_setup_true_lang-BivIZvV1.mjs";
2
+ export {
3
+ e as ADrawer,
4
+ s as ADrawerContent,
5
+ w as ADrawerOverlay,
6
+ A as ADrawerTrigger
7
+ };
8
+ //# sourceMappingURL=drawer.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drawer.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";"}