@alikhalilll/ui 1.1.1 → 1.2.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.
- package/README.md +1 -1
- package/dist/chunks/{ADrawerContent.vue_vue_type_script_setup_true_lang-BivIZvV1.mjs → ADrawerContent.vue_vue_type_script_setup_true_lang-W28CSzER.mjs} +15 -15
- package/dist/chunks/ADrawerContent.vue_vue_type_script_setup_true_lang-W28CSzER.mjs.map +1 -0
- package/dist/chunks/{APopoverContent.vue_vue_type_script_setup_true_lang-o1XhV9DM.mjs → APopoverContent.vue_vue_type_script_setup_true_lang-CjiJ12DR.mjs} +6 -6
- package/dist/chunks/APopoverContent.vue_vue_type_script_setup_true_lang-CjiJ12DR.mjs.map +1 -0
- package/dist/chunks/{AResponsivePopoverContent.vue_vue_type_script_setup_true_lang-BYEb5UBL.mjs → AResponsivePopoverContent.vue_vue_type_script_setup_true_lang-5YbO6FdM.mjs} +3 -3
- package/dist/chunks/{AResponsivePopoverContent.vue_vue_type_script_setup_true_lang-BYEb5UBL.mjs.map → AResponsivePopoverContent.vue_vue_type_script_setup_true_lang-5YbO6FdM.mjs.map} +1 -1
- package/dist/chunks/ATellInput.vue_vue_type_script_setup_true_lang-D7hPj1g1.mjs +1489 -0
- package/dist/chunks/ATellInput.vue_vue_type_script_setup_true_lang-D7hPj1g1.mjs.map +1 -0
- package/dist/drawer.mjs +1 -1
- package/dist/index.d.ts +105 -2
- package/dist/index.mjs +34 -29
- package/dist/popover.mjs +1 -1
- package/dist/responsive-popover.mjs +1 -1
- package/dist/tell-input.d.ts +105 -2
- package/dist/tell-input.mjs +11 -6
- package/entries/tell-input/README.md +18 -2
- package/package.json +1 -1
- package/dist/chunks/ADrawerContent.vue_vue_type_script_setup_true_lang-BivIZvV1.mjs.map +0 -1
- package/dist/chunks/APopoverContent.vue_vue_type_script_setup_true_lang-o1XhV9DM.mjs.map +0 -1
- package/dist/chunks/ATellInput.vue_vue_type_script_setup_true_lang-Clc-B8SW.mjs +0 -1353
- package/dist/chunks/ATellInput.vue_vue_type_script_setup_true_lang-Clc-B8SW.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ATellInput.vue_vue_type_script_setup_true_lang-D7hPj1g1.mjs","sources":["../../entries/tell-input/utils/digits.ts","../../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 * 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 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 {\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 <ACountrySelectItem />. */\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\">\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 { 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, 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\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 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}>();\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\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 (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 commitPhone('');\n userPickedCountry.value = false;\n return;\n }\n commitPhone(cleaned);\n if (!userPickedCountry.value && !selectedIso2.value) {\n detectAndApply();\n }\n return;\n }\n\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\nconst required = computed(() =>\n selectedIso2.value ? getRequiredInfo({ iso2: selectedIso2.value }, props.locale) : null\n);\n\nconst validation = computed<PhoneValidationResult>(() =>\n validate({\n country: selectedIso2.value ? { iso2: selectedIso2.value } : null,\n phone: phone.value ?? '',\n locale: props.locale,\n })\n);\n\nconst effectivePlaceholder = computed(\n () => props.placeholder || required.value?.format_hint || messages.value.phoneInputLabel\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] ?? messages.value.errorMessages[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\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\nconst validationState = computed<'idle' | 'valid' | 'error'>(() => {\n if (!phone.value) return 'idle';\n return validation.value.ok ? 'valid' : 'error';\n});\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 showError = computed(() => Boolean(props.showValidation && errorMessage.value));\nconst showHint = computed(() => !showError.value && !phone.value && !!required.value?.format_hint);\nconst describedBy = computed(() => (showError.value || showHint.value ? helperId : undefined));\n\ndefineExpose({ validation, required, selectedDialCode, validationState });\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 || validationState === 'idle') && 'focus-within:ring-ring/40',\n props.showValidation &&\n validationState === 'valid' &&\n 'border-emerald-500/60 ring-1 ring-emerald-500/20 focus-within:ring-emerald-500/40',\n props.showValidation &&\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 >\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=\"validationState === '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 <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 <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 :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 >\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 <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=\"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 <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","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","DEFAULT_MESSAGES","resolveMessages","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","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","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","displayValue","phoneEditedByInput","commitPhone","handlePhoneInput","target","cleaned","handlePhoneChange","messages","dirAttr","validation","effectivePlaceholder","errorMessage","selectedDialCode","inputSizeClasses","dialPrefixClasses","validationState","helperId","useId","showError","showHint","describedBy","$attrs","_Transition","ACountrySelect","$slots","_withCtx","slotProps","CheckCircle2","AlertCircle"],"mappings":"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"}
|
package/dist/drawer.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as e, a as s, b as w, c as A } from "./chunks/ADrawerContent.vue_vue_type_script_setup_true_lang-
|
|
1
|
+
import { _ as e, a as s, b as w, c as A } from "./chunks/ADrawerContent.vue_vue_type_script_setup_true_lang-W28CSzER.mjs";
|
|
2
2
|
export {
|
|
3
3
|
e as ADrawer,
|
|
4
4
|
s as ADrawerContent,
|
package/dist/index.d.ts
CHANGED
|
@@ -49,6 +49,7 @@ size: ATellInputSize;
|
|
|
49
49
|
placeholder: string;
|
|
50
50
|
ipEndpoint: string;
|
|
51
51
|
defaultCountry: string;
|
|
52
|
+
showValidationIcon: boolean;
|
|
52
53
|
detectCountry: DetectionStrategy;
|
|
53
54
|
detectFromInput: boolean;
|
|
54
55
|
detectDebounceMs: number;
|
|
@@ -74,6 +75,8 @@ emptyText: string;
|
|
|
74
75
|
loadingText: string;
|
|
75
76
|
suggestedLabel: string;
|
|
76
77
|
allCountriesLabel: string;
|
|
78
|
+
countryLabel: string;
|
|
79
|
+
selectCountryLabel: string;
|
|
77
80
|
suggestedLimit: number;
|
|
78
81
|
maxResults: number;
|
|
79
82
|
kbdOpen: string | null;
|
|
@@ -211,6 +214,12 @@ declare type __VLS_Props_10 = {
|
|
|
211
214
|
/** Override the right-side kbd hints. Pass `null` to hide. */
|
|
212
215
|
kbdOpen?: string | null;
|
|
213
216
|
kbdClose?: string | null;
|
|
217
|
+
/** BCP-47 locale — country names render localized via `Intl.DisplayNames`. */
|
|
218
|
+
locale?: string;
|
|
219
|
+
/** Prefix of the trigger's `aria-label` when a country is selected, e.g. `"Country"`. */
|
|
220
|
+
countryLabel?: string;
|
|
221
|
+
/** Trigger's `aria-label` when no country is selected. */
|
|
222
|
+
selectCountryLabel?: string;
|
|
214
223
|
};
|
|
215
224
|
|
|
216
225
|
declare type __VLS_Props_11 = {
|
|
@@ -774,19 +783,46 @@ export declare const AResponsivePopoverTrigger: __VLS_WithTemplateSlots_9<typeof
|
|
|
774
783
|
|
|
775
784
|
export declare const ATellInput: __VLS_WithTemplateSlots_11<typeof __VLS_component_11, __VLS_TemplateResult_11["slots"]>;
|
|
776
785
|
|
|
786
|
+
/** Text direction for the field. `'auto'` (or omitting the prop) inherits from the
|
|
787
|
+
* nearest `[dir]` ancestor / `<html dir>`; `'ltr'` / `'rtl'` force it. */
|
|
788
|
+
export declare type ATellInputDir = 'ltr' | 'rtl' | 'auto';
|
|
789
|
+
|
|
777
790
|
export declare interface ATellInputProps {
|
|
778
791
|
class?: HTMLAttributes['class'];
|
|
779
792
|
placeholder?: string;
|
|
780
793
|
disabled?: boolean;
|
|
781
794
|
loading?: boolean;
|
|
782
795
|
size?: ATellInputSize;
|
|
796
|
+
/**
|
|
797
|
+
* Text direction. Omit (or pass `'auto'`) to inherit from the page — RTL pages get an
|
|
798
|
+
* RTL field automatically. Pass `'ltr'` / `'rtl'` to force it.
|
|
799
|
+
*/
|
|
800
|
+
dir?: ATellInputDir;
|
|
801
|
+
/**
|
|
802
|
+
* BCP-47 locale (e.g. `'ar'`, `'fr'`). When set, country names render localized via
|
|
803
|
+
* `Intl.DisplayNames` and the format hint uses the locale's numerals.
|
|
804
|
+
*/
|
|
805
|
+
locale?: string;
|
|
806
|
+
/**
|
|
807
|
+
* Localized UI strings. A single bag covering the picker, validation errors, and a11y
|
|
808
|
+
* labels. Individual props (`searchPlaceholder`, `emptyText`, `loadingText`,
|
|
809
|
+
* `errorMessages`) take precedence over the matching `messages` key when both are set.
|
|
810
|
+
*/
|
|
811
|
+
messages?: TellInputMessagesInput;
|
|
783
812
|
/**
|
|
784
813
|
* Whitelist of allowed dial-digit codes (no `+`), e.g. `['20', '966']`.
|
|
785
814
|
* Countries outside this list are still shown in the picker but rendered as disabled.
|
|
786
815
|
*/
|
|
787
816
|
allowedDialCodes?: string[];
|
|
788
|
-
/**
|
|
817
|
+
/** Light up the field's validation styling — coloured border + ring on the input and the
|
|
818
|
+
* error message line below — when the number is valid / invalid. Default `false`, so the
|
|
819
|
+
* field stays neutral and validation surfacing is left to the consumer (via the
|
|
820
|
+
* `validation` ref exposure). */
|
|
789
821
|
showValidation?: boolean;
|
|
822
|
+
/** Show the green check / red alert icon at the end of the field. Default `false`; opt
|
|
823
|
+
* in with `true`. Independent of `showValidation` — you can show the icon without the
|
|
824
|
+
* coloured field, or vice versa. The slots `#valid-icon` / `#error-icon` still apply. */
|
|
825
|
+
showValidationIcon?: boolean;
|
|
790
826
|
/**
|
|
791
827
|
* Country auto-detect strategy. Defaults to `'auto'` — try IP geolocation first, then
|
|
792
828
|
* timezone, then `navigator.language`, finally `defaultCountry`.
|
|
@@ -862,6 +898,9 @@ export declare interface CountryOption<T = RestCountry> {
|
|
|
862
898
|
|
|
863
899
|
export declare const DEFAULT_ERROR_MESSAGES: Record<PhoneValidationReason, string>;
|
|
864
900
|
|
|
901
|
+
/** English defaults for every {@link TellInputMessages} key. */
|
|
902
|
+
export declare const DEFAULT_MESSAGES: TellInputMessages;
|
|
903
|
+
|
|
865
904
|
export declare const DEFAULT_SIZE: Size;
|
|
866
905
|
|
|
867
906
|
/**
|
|
@@ -925,6 +964,30 @@ declare interface ExtendedProps extends ATellInputProps {
|
|
|
925
964
|
|
|
926
965
|
export declare type FlagUrlBuilder = (iso2: string, width: number) => string;
|
|
927
966
|
|
|
967
|
+
/**
|
|
968
|
+
* Base code points of contiguous decimal-digit blocks. Each block runs `base`‥`base+9`
|
|
969
|
+
* for digit `0`‥`9`, so the ASCII digit is `codePoint - base`. Add a script by appending
|
|
970
|
+
* one entry here.
|
|
971
|
+
*/
|
|
972
|
+
export declare const LOCALE_DIGIT_RANGES: {
|
|
973
|
+
name: string;
|
|
974
|
+
base: number;
|
|
975
|
+
}[];
|
|
976
|
+
|
|
977
|
+
/**
|
|
978
|
+
* Return a copy of the country list with display names localized to `locale` via
|
|
979
|
+
* `Intl.DisplayNames`. `search_key` is rebuilt (keeping the English name too) so search
|
|
980
|
+
* still matches either spelling. Unknown locales / regions fall back to the English name.
|
|
981
|
+
*/
|
|
982
|
+
export declare function localizeCountries(list: CountryOption[], locale?: string): CountryOption[];
|
|
983
|
+
|
|
984
|
+
/**
|
|
985
|
+
* Replace any supported non-ASCII decimal digit with its ASCII equivalent. Every other
|
|
986
|
+
* character (spaces, `+`, separators, letters) is left untouched — callers still run their
|
|
987
|
+
* own `\D` cleanup afterwards.
|
|
988
|
+
*/
|
|
989
|
+
export declare function normalizeDigits(input: string): string;
|
|
990
|
+
|
|
928
991
|
export declare interface PhoneRequiredInfo {
|
|
929
992
|
iso2: string;
|
|
930
993
|
dial_code: string;
|
|
@@ -957,6 +1020,12 @@ export declare interface PhoneValidationResult {
|
|
|
957
1020
|
details?: Record<string, unknown>;
|
|
958
1021
|
}
|
|
959
1022
|
|
|
1023
|
+
/**
|
|
1024
|
+
* Merge a partial `messages` override onto the English defaults. Used internally by
|
|
1025
|
+
* `ATellInput` to resolve a complete {@link TellInputMessages} object.
|
|
1026
|
+
*/
|
|
1027
|
+
export declare function resolveMessages(input?: TellInputMessagesInput): TellInputMessages;
|
|
1028
|
+
|
|
960
1029
|
export declare interface RestCountry {
|
|
961
1030
|
name?: {
|
|
962
1031
|
common?: string;
|
|
@@ -986,6 +1055,36 @@ export declare type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
|
986
1055
|
|
|
987
1056
|
export declare const SIZES: readonly Size[];
|
|
988
1057
|
|
|
1058
|
+
/**
|
|
1059
|
+
* Every user-facing string in the tell-input UI, bundled so a consumer can localize the
|
|
1060
|
+
* component in one prop. Each key has an English default in {@link DEFAULT_MESSAGES}.
|
|
1061
|
+
*/
|
|
1062
|
+
export declare interface TellInputMessages {
|
|
1063
|
+
/** Placeholder of the country-picker search box. */
|
|
1064
|
+
searchPlaceholder: string;
|
|
1065
|
+
/** Shown when a search yields no countries. */
|
|
1066
|
+
emptyText: string;
|
|
1067
|
+
/** Shown while the country list is loading. */
|
|
1068
|
+
loadingText: string;
|
|
1069
|
+
/** Header of the "Suggested" group (current + recent picks). */
|
|
1070
|
+
suggestedLabel: string;
|
|
1071
|
+
/** Header of the full country list. */
|
|
1072
|
+
allCountriesLabel: string;
|
|
1073
|
+
/** Validation error text, keyed by reason. */
|
|
1074
|
+
errorMessages: Record<PhoneValidationReason, string>;
|
|
1075
|
+
/** Prefix of the country trigger's `aria-label`, e.g. `"Country: Egypt"`. */
|
|
1076
|
+
countryLabel: string;
|
|
1077
|
+
/** `aria-label` of the country trigger when no country is selected. */
|
|
1078
|
+
selectCountryLabel: string;
|
|
1079
|
+
/** `aria-label` of the phone input element. */
|
|
1080
|
+
phoneInputLabel: string;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
/** Partial override shape for the `messages` prop — every key (and every error reason) is optional. */
|
|
1084
|
+
export declare type TellInputMessagesInput = Partial<Omit<TellInputMessages, 'errorMessages'>> & {
|
|
1085
|
+
errorMessages?: Partial<Record<PhoneValidationReason, string>>;
|
|
1086
|
+
};
|
|
1087
|
+
|
|
989
1088
|
/**
|
|
990
1089
|
* Reactive wrapper. Kicks off detection in `onMounted` so SSR renders an empty value and the
|
|
991
1090
|
* client patches in the real country once resolved.
|
|
@@ -1015,7 +1114,7 @@ export declare interface UsePhoneValidationReturn {
|
|
|
1015
1114
|
getRequiredInfo(country: {
|
|
1016
1115
|
iso2: string;
|
|
1017
1116
|
dial_code?: string;
|
|
1018
|
-
}): PhoneRequiredInfo | null;
|
|
1117
|
+
}, locale?: string): PhoneRequiredInfo | null;
|
|
1019
1118
|
validate(input: ValidateArgs): PhoneValidationResult;
|
|
1020
1119
|
}
|
|
1021
1120
|
|
|
@@ -1025,12 +1124,16 @@ export declare type ValidateArgs = {
|
|
|
1025
1124
|
dial_code?: string;
|
|
1026
1125
|
} | null | undefined;
|
|
1027
1126
|
phone?: undefined;
|
|
1127
|
+
/** BCP-47 locale — localizes the numerals in the returned `required.format_hint`. */
|
|
1128
|
+
locale?: string;
|
|
1028
1129
|
} | {
|
|
1029
1130
|
country: {
|
|
1030
1131
|
iso2: string;
|
|
1031
1132
|
dial_code?: string;
|
|
1032
1133
|
} | null | undefined;
|
|
1033
1134
|
phone: string | null;
|
|
1135
|
+
/** BCP-47 locale — localizes the numerals in the returned `required.format_hint`. */
|
|
1136
|
+
locale?: string;
|
|
1034
1137
|
};
|
|
1035
1138
|
|
|
1036
1139
|
export { }
|
package/dist/index.mjs
CHANGED
|
@@ -1,38 +1,43 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
import { _ as s, a as t, b as n, c as
|
|
3
|
-
import { _ as
|
|
4
|
-
import { _ as
|
|
5
|
-
import { _
|
|
6
|
-
import { c as
|
|
7
|
-
import { D as
|
|
1
|
+
import { _ as o } from "./chunks/AInput.vue_vue_type_script_setup_true_lang-BJUP7ePq.mjs";
|
|
2
|
+
import { _ as s, a as t, b as n, c as A } from "./chunks/APopoverContent.vue_vue_type_script_setup_true_lang-CjiJ12DR.mjs";
|
|
3
|
+
import { _ as p, a as i, b as c, c as g } from "./chunks/ADrawerContent.vue_vue_type_script_setup_true_lang-W28CSzER.mjs";
|
|
4
|
+
import { _ as S, a as u, b as D } from "./chunks/AResponsivePopoverContent.vue_vue_type_script_setup_true_lang-5YbO6FdM.mjs";
|
|
5
|
+
import { _, a as P, b as T, D as f, c as x, L as C, d as m, e as d, f as I, l as R, n as y, r as L, u as b, g as F } from "./chunks/ATellInput.vue_vue_type_script_setup_true_lang-D7hPj1g1.mjs";
|
|
6
|
+
import { c as G } from "./chunks/cn-B6yFEsav.mjs";
|
|
7
|
+
import { D as U, S as h, c as z, a as M, b as H, d as V } from "./chunks/sizes-B_9MfLkz.mjs";
|
|
8
8
|
export {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
_ as ACountryFlag,
|
|
10
|
+
P as ACountrySelect,
|
|
11
|
+
p as ADrawer,
|
|
12
12
|
i as ADrawerContent,
|
|
13
13
|
c as ADrawerOverlay,
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
g as ADrawerTrigger,
|
|
15
|
+
o as AInput,
|
|
16
16
|
s as APopover,
|
|
17
17
|
t as APopoverContent,
|
|
18
18
|
n as APopoverOverlay,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
A as APopoverTrigger,
|
|
20
|
+
S as AResponsivePopover,
|
|
21
|
+
u as AResponsivePopoverContent,
|
|
22
|
+
D as AResponsivePopoverTrigger,
|
|
23
23
|
T as ATellInput,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
24
|
+
f as DEFAULT_ERROR_MESSAGES,
|
|
25
|
+
x as DEFAULT_MESSAGES,
|
|
26
|
+
U as DEFAULT_SIZE,
|
|
27
|
+
C as LOCALE_DIGIT_RANGES,
|
|
28
|
+
h as SIZES,
|
|
29
|
+
m as aTellInputVariants,
|
|
30
|
+
G as cn,
|
|
31
|
+
z as controlHeight,
|
|
32
|
+
M as controlHeightPx,
|
|
33
|
+
H as controlPaddingX,
|
|
34
|
+
V as controlTextSize,
|
|
35
|
+
d as defaultFlagUrl,
|
|
36
|
+
I as detectCountry,
|
|
37
|
+
R as localizeCountries,
|
|
38
|
+
y as normalizeDigits,
|
|
39
|
+
L as resolveMessages,
|
|
40
|
+
b as useCountryDetection,
|
|
41
|
+
F as usePhoneValidation
|
|
37
42
|
};
|
|
38
43
|
//# sourceMappingURL=index.mjs.map
|
package/dist/popover.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as e, a, b as p, c as v } from "./chunks/APopoverContent.vue_vue_type_script_setup_true_lang-
|
|
1
|
+
import { _ as e, a, b as p, c as v } from "./chunks/APopoverContent.vue_vue_type_script_setup_true_lang-CjiJ12DR.mjs";
|
|
2
2
|
export {
|
|
3
3
|
e as APopover,
|
|
4
4
|
a as APopoverContent,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as s, a as p, b as r } from "./chunks/AResponsivePopoverContent.vue_vue_type_script_setup_true_lang-
|
|
1
|
+
import { _ as s, a as p, b as r } from "./chunks/AResponsivePopoverContent.vue_vue_type_script_setup_true_lang-5YbO6FdM.mjs";
|
|
2
2
|
export {
|
|
3
3
|
s as AResponsivePopover,
|
|
4
4
|
p as AResponsivePopoverContent,
|