@alikhalilll/a-tel-input 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +124 -0
  3. package/dist/index.cjs +5846 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +791 -0
  6. package/dist/index.d.ts +791 -0
  7. package/dist/index.js +5804 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/nuxt/index.cjs +30 -0
  10. package/dist/nuxt/index.cjs.map +1 -0
  11. package/dist/nuxt/index.d.cts +15 -0
  12. package/dist/nuxt/index.d.ts +15 -0
  13. package/dist/nuxt/index.js +30 -0
  14. package/dist/nuxt/index.js.map +1 -0
  15. package/dist/resolver/index.cjs +25 -0
  16. package/dist/resolver/index.cjs.map +1 -0
  17. package/dist/resolver/index.d.cts +14 -0
  18. package/dist/resolver/index.d.ts +14 -0
  19. package/dist/resolver/index.js +25 -0
  20. package/dist/resolver/index.js.map +1 -0
  21. package/dist/styles.css +520 -0
  22. package/package.json +123 -0
  23. package/src/components/ACountryFlag.vue +78 -0
  24. package/src/components/ACountrySelect.vue +674 -0
  25. package/src/components/ATelInput.vue +742 -0
  26. package/src/composables/useCountryDetection.ts +247 -0
  27. package/src/composables/useCountryMatching.ts +213 -0
  28. package/src/composables/usePhoneValidation.ts +573 -0
  29. package/src/composables/useTelInputValidation.ts +136 -0
  30. package/src/composables/useTypingPhase.ts +88 -0
  31. package/src/icons/AlertCircleIcon.vue +17 -0
  32. package/src/icons/CheckCircleIcon.vue +16 -0
  33. package/src/icons/CheckIcon.vue +15 -0
  34. package/src/icons/ChevronDownIcon.vue +15 -0
  35. package/src/icons/SearchIcon.vue +16 -0
  36. package/src/icons/SpinnerIcon.vue +28 -0
  37. package/src/icons/index.ts +6 -0
  38. package/src/index.ts +36 -0
  39. package/src/nuxt/index.ts +37 -0
  40. package/src/resolver/index.ts +29 -0
  41. package/src/types.ts +389 -0
  42. package/src/utils/digits.ts +42 -0
  43. package/src/utils/flag-url.ts +10 -0
  44. package/web-types.json +526 -0
package/web-types.json ADDED
@@ -0,0 +1,526 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/web-types",
3
+ "name": "@alikhalilll/a-tel-input",
4
+ "version": "1.0.1",
5
+ "js-types-syntax": "typescript",
6
+ "description-markup": "markdown",
7
+ "framework": "vue",
8
+ "framework-config": {
9
+ "enable-when": {
10
+ "node-packages": [
11
+ "vue"
12
+ ]
13
+ }
14
+ },
15
+ "contributions": {
16
+ "html": {
17
+ "vue-components": [
18
+ {
19
+ "name": "ATelInput",
20
+ "source": {
21
+ "module": "@alikhalilll/a-tel-input",
22
+ "symbol": "ATelInput"
23
+ },
24
+ "props": [
25
+ {
26
+ "name": "allowedDialCodes",
27
+ "type": "string[]",
28
+ "required": false,
29
+ "description": "Whitelist of allowed dial-digit codes (no `+`), e.g. `['20', '966']`.\nCountries outside this list are still shown in the picker but rendered as disabled."
30
+ },
31
+ {
32
+ "name": "class",
33
+ "type": "ClassValue",
34
+ "required": false
35
+ },
36
+ {
37
+ "name": "contentClass",
38
+ "type": "string",
39
+ "required": false,
40
+ "description": "Forwarded to ACountrySelect: classes for the popover content surface."
41
+ },
42
+ {
43
+ "name": "countries",
44
+ "type": "CountryOption<RestCountry>[]",
45
+ "required": false,
46
+ "description": "Provide your own country list, forwarded to ACountrySelect."
47
+ },
48
+ {
49
+ "name": "defaultCountry",
50
+ "type": "string",
51
+ "required": false,
52
+ "description": "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\npre-selected — overrides the hidden-until-detected default."
53
+ },
54
+ {
55
+ "name": "detectCountry",
56
+ "type": "DetectionStrategy",
57
+ "required": false,
58
+ "description": "Country auto-detect strategy. Defaults to `'auto'` — try IP geolocation first, then\ntimezone, then `navigator.language`, finally `defaultCountry`."
59
+ },
60
+ {
61
+ "name": "detectDebounceMs",
62
+ "type": "number",
63
+ "required": false,
64
+ "description": "Debounce window (ms) for `detectFromInput` detection. Each keystroke schedules the\nlibphonenumber parse + lookup; bursts of typing/paste collapse into a single call.\nClearing the input is not debounced — the picker hides immediately. Default 150ms."
65
+ },
66
+ {
67
+ "name": "detectFromInput",
68
+ "type": "boolean",
69
+ "required": false,
70
+ "description": "When true, the country picker is hidden until a leading dial code is detected in the\nphone input. Every keystroke runs a longest-prefix match against known dial codes; on\nfirst match the picker reveals with that country and the matched dial digits are\nstripped from `phone`. Skips the onMount IP/timezone/locale detection chain."
71
+ },
72
+ {
73
+ "name": "detector",
74
+ "type": "((options: DetectCountryOptions) => Promise<string | null | undefined>)",
75
+ "required": false,
76
+ "description": "Fully custom country detection. When provided, this function runs in place of the\nbuilt-in chain — `detectCountry`-style options are still honored but the function\nreceives them and is free to ignore them."
77
+ },
78
+ {
79
+ "name": "dir",
80
+ "type": "ATelInputDir",
81
+ "required": false,
82
+ "description": "Text direction. Omit (or pass `'auto'`) to inherit from the page — RTL pages get an\nRTL field automatically. Pass `'ltr'` / `'rtl'` to force it."
83
+ },
84
+ {
85
+ "name": "disabled",
86
+ "type": "boolean",
87
+ "required": false
88
+ },
89
+ {
90
+ "name": "drawerClass",
91
+ "type": "string",
92
+ "required": false,
93
+ "description": "Forwarded to ACountrySelect: classes for the mobile drawer surface."
94
+ },
95
+ {
96
+ "name": "emptyText",
97
+ "type": "string",
98
+ "required": false
99
+ },
100
+ {
101
+ "name": "errorClass",
102
+ "type": "string",
103
+ "required": false,
104
+ "description": "Classes for the error message line."
105
+ },
106
+ {
107
+ "name": "errorMessages",
108
+ "type": "Partial<Record<PhoneValidationReason, string>>",
109
+ "required": false,
110
+ "description": "Error labels keyed by reason. Each gets a sensible English default."
111
+ },
112
+ {
113
+ "name": "fieldClass",
114
+ "type": "string",
115
+ "required": false,
116
+ "description": "Classes for the outer wrapper that holds country select + input."
117
+ },
118
+ {
119
+ "name": "flagUrl",
120
+ "type": "((iso2: string, width: number) => string)",
121
+ "required": false,
122
+ "description": "Override the flag URL builder, forwarded to ACountrySelect."
123
+ },
124
+ {
125
+ "name": "hintClass",
126
+ "type": "string",
127
+ "required": false,
128
+ "description": "Classes for the helper hint line."
129
+ },
130
+ {
131
+ "name": "inputClass",
132
+ "type": "string",
133
+ "required": false,
134
+ "description": "Classes for the inner phone field input element."
135
+ },
136
+ {
137
+ "name": "ipEndpoint",
138
+ "type": "string",
139
+ "required": false,
140
+ "description": "Override the IP geolocation endpoint. Must return JSON with `country_code` or `country`."
141
+ },
142
+ {
143
+ "name": "loading",
144
+ "type": "boolean",
145
+ "required": false
146
+ },
147
+ {
148
+ "name": "loadingText",
149
+ "type": "string",
150
+ "required": false
151
+ },
152
+ {
153
+ "name": "locale",
154
+ "type": "string",
155
+ "required": false,
156
+ "description": "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."
157
+ },
158
+ {
159
+ "name": "messages",
160
+ "type": "TelInputMessagesInput",
161
+ "required": false,
162
+ "description": "Localized UI strings. A single bag covering the picker, validation errors, and a11y\nlabels. Individual props (`searchPlaceholder`, `emptyText`, `loadingText`,\n`errorMessages`) take precedence over the matching `messages` key when both are set."
163
+ },
164
+ {
165
+ "name": "placeholder",
166
+ "type": "string",
167
+ "required": false
168
+ },
169
+ {
170
+ "name": "popoverClass",
171
+ "type": "string",
172
+ "required": false,
173
+ "description": "Forwarded to ACountrySelect: classes for the desktop popover surface."
174
+ },
175
+ {
176
+ "name": "scrollLock",
177
+ "type": "\"none\" | \"events\" | \"body\"",
178
+ "required": false,
179
+ "description": "How page scroll is blocked while the country popover is open. Defaults to `'events'`\n(sticky-safe document-level lock). Pass `'body'` for the legacy\n`body { overflow: hidden }` lock, or `'none'` to leave page scrolling alone."
180
+ },
181
+ {
182
+ "name": "searcher",
183
+ "type": "((query: string, country: CountryOption) => boolean)",
184
+ "required": false,
185
+ "description": "Custom search predicate, forwarded to ACountrySelect."
186
+ },
187
+ {
188
+ "name": "searchPlaceholder",
189
+ "type": "string",
190
+ "required": false,
191
+ "description": "Localized strings for the country picker UI."
192
+ },
193
+ {
194
+ "name": "showValidation",
195
+ "type": "boolean",
196
+ "required": false,
197
+ "description": "Light up the field's validation styling — coloured border + ring on the input and the\nerror message line below — when the number is valid / invalid. Default `false`, so the\nfield stays neutral and validation surfacing is left to the consumer (via the\n`validation` ref exposure)."
198
+ },
199
+ {
200
+ "name": "showValidationIcon",
201
+ "type": "boolean",
202
+ "required": false,
203
+ "description": "Show the green check / red alert icon at the end of the field. Default `false`; opt\nin with `true`. Independent of `showValidation` — you can show the icon without the\ncoloured field, or vice versa. The slots `#valid-icon` / `#error-icon` still apply."
204
+ },
205
+ {
206
+ "name": "size",
207
+ "type": "Size",
208
+ "required": false
209
+ }
210
+ ],
211
+ "slots": [
212
+ {
213
+ "name": "chevron",
214
+ "description": "Forwarded to ACountrySelect — replace the chevron."
215
+ },
216
+ {
217
+ "name": "detecting",
218
+ "description": "Replace the spinner shown in the picker slot during the debounce window."
219
+ },
220
+ {
221
+ "name": "empty"
222
+ },
223
+ {
224
+ "name": "error",
225
+ "description": "Replace the error message rendered when invalid."
226
+ },
227
+ {
228
+ "name": "error-icon",
229
+ "description": "Replace the warning icon shown when the number fails validation."
230
+ },
231
+ {
232
+ "name": "flag",
233
+ "description": "Forwarded — replace any flag rendering."
234
+ },
235
+ {
236
+ "name": "group-header",
237
+ "description": "Forwarded — section header."
238
+ },
239
+ {
240
+ "name": "hint",
241
+ "description": "Replace the dim helper line shown below the input when empty."
242
+ },
243
+ {
244
+ "name": "item",
245
+ "description": "Forwarded — replace each country list row."
246
+ },
247
+ {
248
+ "name": "loading"
249
+ },
250
+ {
251
+ "name": "prefix",
252
+ "description": "Content before the country select trigger (e.g. an icon)."
253
+ },
254
+ {
255
+ "name": "search",
256
+ "description": "Forwarded — search bar."
257
+ },
258
+ {
259
+ "name": "suffix",
260
+ "description": "Content between the input and the validation icons."
261
+ },
262
+ {
263
+ "name": "trigger",
264
+ "description": "Forwarded to ACountrySelect — replace the trigger button."
265
+ },
266
+ {
267
+ "name": "valid-icon",
268
+ "description": "Replace the green check shown when the number validates."
269
+ }
270
+ ],
271
+ "js": {
272
+ "events": [
273
+ {
274
+ "name": "update:country"
275
+ },
276
+ {
277
+ "name": "update:phone"
278
+ }
279
+ ]
280
+ }
281
+ },
282
+ {
283
+ "name": "ACountrySelect",
284
+ "source": {
285
+ "module": "@alikhalilll/a-tel-input",
286
+ "symbol": "ACountrySelect"
287
+ },
288
+ "description": "Props for ACountrySelect — the standalone country picker. Surface\nseparately so it can be used outside `ATelInput` with full type support.",
289
+ "props": [
290
+ {
291
+ "name": "allCountriesLabel",
292
+ "type": "string",
293
+ "required": false
294
+ },
295
+ {
296
+ "name": "allowedDialCodes",
297
+ "type": "string[]",
298
+ "required": false,
299
+ "description": "ISO2 codes that are selectable. Others are listed but disabled."
300
+ },
301
+ {
302
+ "name": "class",
303
+ "type": "ClassValue",
304
+ "required": false
305
+ },
306
+ {
307
+ "name": "contentClass",
308
+ "type": "ClassValue",
309
+ "required": false
310
+ },
311
+ {
312
+ "name": "countries",
313
+ "type": "CountryOption<RestCountry>[]",
314
+ "required": false,
315
+ "description": "Provide your own country list (bypasses the REST Countries fetch)."
316
+ },
317
+ {
318
+ "name": "countryLabel",
319
+ "type": "string",
320
+ "required": false,
321
+ "description": "Prefix of the trigger's `aria-label` when a country is selected, e.g. `\"Country\"`."
322
+ },
323
+ {
324
+ "name": "disabled",
325
+ "type": "boolean",
326
+ "required": false
327
+ },
328
+ {
329
+ "name": "drawerClass",
330
+ "type": "ClassValue",
331
+ "required": false
332
+ },
333
+ {
334
+ "name": "emptyText",
335
+ "type": "string",
336
+ "required": false
337
+ },
338
+ {
339
+ "name": "flagUrl",
340
+ "type": "((iso2: string, width: number) => string)",
341
+ "required": false,
342
+ "description": "Override the flag URL builder, e.g. `(iso, w) => `/flags/${iso}.svg``."
343
+ },
344
+ {
345
+ "name": "kbdClose",
346
+ "type": "string | null",
347
+ "required": false
348
+ },
349
+ {
350
+ "name": "kbdOpen",
351
+ "type": "string | null",
352
+ "required": false,
353
+ "description": "Override the right-side kbd hints. Pass `null` to hide."
354
+ },
355
+ {
356
+ "name": "loadingText",
357
+ "type": "string",
358
+ "required": false
359
+ },
360
+ {
361
+ "name": "locale",
362
+ "type": "string",
363
+ "required": false,
364
+ "description": "BCP-47 locale — country names render localized via `Intl.DisplayNames`."
365
+ },
366
+ {
367
+ "name": "maxResults",
368
+ "type": "number",
369
+ "required": false,
370
+ "description": "Cap the number of matching countries shown in search results."
371
+ },
372
+ {
373
+ "name": "popoverClass",
374
+ "type": "ClassValue",
375
+ "required": false
376
+ },
377
+ {
378
+ "name": "scrollLock",
379
+ "type": "\"none\" | \"events\" | \"body\"",
380
+ "required": false,
381
+ "description": "How page scroll is blocked while the popover is open. Default `'events'`."
382
+ },
383
+ {
384
+ "name": "searcher",
385
+ "type": "((query: string, country: CountryOption) => boolean)",
386
+ "required": false,
387
+ "description": "Custom search predicate. Default: substring match on the precomputed `search_key`."
388
+ },
389
+ {
390
+ "name": "searchPlaceholder",
391
+ "type": "string",
392
+ "required": false
393
+ },
394
+ {
395
+ "name": "selectCountryLabel",
396
+ "type": "string",
397
+ "required": false,
398
+ "description": "Trigger's `aria-label` when no country is selected."
399
+ },
400
+ {
401
+ "name": "size",
402
+ "type": "Size",
403
+ "required": false,
404
+ "description": "Drives the trigger button padding + text size. Matches ATelInput's `size`."
405
+ },
406
+ {
407
+ "name": "suggestedLabel",
408
+ "type": "string",
409
+ "required": false
410
+ },
411
+ {
412
+ "name": "suggestedLimit",
413
+ "type": "number",
414
+ "required": false,
415
+ "description": "Max items rendered under the \"Suggested\" header (current + recents, deduped)."
416
+ },
417
+ {
418
+ "name": "triggerClass",
419
+ "type": "ClassValue",
420
+ "required": false
421
+ }
422
+ ],
423
+ "slots": [
424
+ {
425
+ "name": "chevron",
426
+ "description": "Replace the chevron icon."
427
+ },
428
+ {
429
+ "name": "empty",
430
+ "description": "Replace the empty/no-results state."
431
+ },
432
+ {
433
+ "name": "flag",
434
+ "description": "Replace just the flag rendered in the trigger and items."
435
+ },
436
+ {
437
+ "name": "group-header",
438
+ "description": "Replace a section header."
439
+ },
440
+ {
441
+ "name": "item",
442
+ "description": "Replace each country list row."
443
+ },
444
+ {
445
+ "name": "item-check",
446
+ "description": "Replace just the right-side check icon for the selected row."
447
+ },
448
+ {
449
+ "name": "loading",
450
+ "description": "Replace the loading state."
451
+ },
452
+ {
453
+ "name": "search",
454
+ "description": "Replace the entire search bar (input + icon + kbd)."
455
+ },
456
+ {
457
+ "name": "search-icon",
458
+ "description": "Replace the search-bar leading icon."
459
+ },
460
+ {
461
+ "name": "trigger",
462
+ "description": "Replace the entire country picker trigger button."
463
+ }
464
+ ],
465
+ "js": {
466
+ "events": [
467
+ {
468
+ "name": "update:selected"
469
+ }
470
+ ]
471
+ }
472
+ },
473
+ {
474
+ "name": "ACountryFlag",
475
+ "source": {
476
+ "module": "@alikhalilll/a-tel-input",
477
+ "symbol": "ACountryFlag"
478
+ },
479
+ "description": "Props for ACountryFlag — the standalone flag image component. Renders a\n`flagcdn` image for an ISO2 code with an automatic text-badge fallback when the\nimage fails to load. Surface separately so it can be used outside `ATelInput`\n(e.g., in a custom country picker).",
480
+ "props": [
481
+ {
482
+ "name": "alt",
483
+ "type": "string",
484
+ "required": false
485
+ },
486
+ {
487
+ "name": "class",
488
+ "type": "ClassValue",
489
+ "required": false
490
+ },
491
+ {
492
+ "name": "flagUrl",
493
+ "type": "FlagUrlBuilder",
494
+ "required": false,
495
+ "description": "Function `(iso2, width) => string` — fully replace the URL builder."
496
+ },
497
+ {
498
+ "name": "iso2",
499
+ "type": "string",
500
+ "required": true,
501
+ "description": "ISO 3166-1 alpha-2 country code, case-insensitive."
502
+ },
503
+ {
504
+ "name": "src",
505
+ "type": "string | null",
506
+ "required": false,
507
+ "description": "Optional explicit URL override. When set, `iso2` / `width` / `flagUrl` are ignored."
508
+ },
509
+ {
510
+ "name": "width",
511
+ "type": "number",
512
+ "required": false,
513
+ "description": "Pixel width served by flagcdn. 40 is crisp at retina up to ~24px wide."
514
+ }
515
+ ],
516
+ "slots": [
517
+ {
518
+ "name": "empty",
519
+ "description": "Rendered when the flag URL is unavailable and no ISO2 text fallback can be derived."
520
+ }
521
+ ]
522
+ }
523
+ ]
524
+ }
525
+ }
526
+ }