@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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 alikhalilll
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # @alikhalilll/a-tel-input
2
+
3
+ Headless, [shadcn-vue](https://www.shadcn-vue.com) style Vue 3 **international telephone input**.
4
+ Detects the country from what the user types (debounced, NANP-aware via
5
+ [`libphonenumber-js`](https://github.com/catamphetamine/libphonenumber-js)), validates + formats the
6
+ number, and offers a country picker that's a **popover on desktop / drawer on mobile**. RTL, i18n,
7
+ and alternative-numeral (Arabic-Indic, Persian, Devanagari, Bengali) input all work out of the box.
8
+
9
+ Components: **`ATelInput`** · **`ACountrySelect`** · **`ACountryFlag`**.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ pnpm add @alikhalilll/a-tel-input
15
+ ```
16
+
17
+ (Pulls in `@alikhalilll/a-responsive-popover` → `a-popover` + `a-drawer` automatically. Design
18
+ tokens are bundled into each component's `styles.css`, so there's no separate base package to install.)
19
+
20
+ ## Styles
21
+
22
+ The picker renders the popover/drawer, so import their stylesheets too:
23
+
24
+ ```ts
25
+ import '@alikhalilll/a-popover/styles.css';
26
+ import '@alikhalilll/a-drawer/styles.css';
27
+ import '@alikhalilll/a-tel-input/styles.css';
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ ```vue
33
+ <script setup lang="ts">
34
+ import { ref } from 'vue';
35
+ import { ATelInput } from '@alikhalilll/a-tel-input';
36
+
37
+ const phone = ref('');
38
+ const country = ref<number | null>(null);
39
+ </script>
40
+
41
+ <template>
42
+ <ATelInput v-model:phone="phone" v-model:country="country" default-country="SA" show-validation />
43
+ </template>
44
+ ```
45
+
46
+ By default the picker is hidden and reveals once a leading dial code is detected from typing. Pass
47
+ `default-country` (ISO2 like `"EG"` or a dial code like `"20"`) to show it pre-selected, or
48
+ `:detect-from-input="false"` for the legacy always-visible picker.
49
+
50
+ ## API
51
+
52
+ ### Key props
53
+
54
+ | Prop | Type | Default | Description |
55
+ | ------------------------------------- | ------------------------------ | -------- | -------------------------------------------------------- |
56
+ | `phone` | `string` | — | `v-model:phone` — the raw national number. |
57
+ | `country` | `number \| null` | — | `v-model:country` — selected dial code. |
58
+ | `defaultCountry` | `string` | — | Initial country: ISO2 (`"EG"`) or dial code (`"20"`). |
59
+ | `detectCountry` | `DetectionStrategy` | `auto` | Silent IP → timezone → `navigator.language` hint. |
60
+ | `detectFromInput` | `boolean` | `true` | Reveal the picker on first dial-code match while typing. |
61
+ | `detectDebounceMs` | `number` | — | Debounce for input-based detection. |
62
+ | `allowedDialCodes` | `string[]` | — | Whitelist of dial codes; others render disabled. |
63
+ | `size` | `Size` (`xs`–`xl`) | `md` | Control size. |
64
+ | `dir` | `'ltr' \| 'rtl' \| 'auto'` | `auto` | Text direction (inherits from the page by default). |
65
+ | `locale` | `string` | — | BCP-47 locale for country names + numerals. |
66
+ | `messages` | `TelInputMessagesInput` | — | Localize every UI string in one bag. |
67
+ | `showValidation` | `boolean` | `false` | Colour the field border/ring by validity. |
68
+ | `showValidationIcon` | `boolean` | `false` | Show the valid/error icon at the field end. |
69
+ | `disabled` / `loading` | `boolean` | `false` | Field state. |
70
+ | `flagUrl` | `(iso2, width) => string` | — | Override the flag image source. |
71
+ | `countries` / `searcher` / `detector` | — | — | Override the data sources. |
72
+ | `ipEndpoint` | `string` | — | Override the IP-geolocation endpoint. |
73
+ | `scrollLock` | `'events' \| 'body' \| 'none'` | `events` | Desktop scroll-lock behaviour of the picker. |
74
+
75
+ Class hooks: `class`, `fieldClass`, `inputClass`, `contentClass`, `popoverClass`, `drawerClass`,
76
+ `hintClass`, `errorClass`. Full prop/type reference:
77
+ [docs](https://alikhalilll.github.io/ali-nuxt-toolkit/ui/tell-input).
78
+
79
+ ### Events
80
+
81
+ | Event | Payload |
82
+ | ---------------- | ---------------- |
83
+ | `update:phone` | `string` |
84
+ | `update:country` | `number \| null` |
85
+
86
+ ### Slots
87
+
88
+ Every visual region is a slot, so you can recompose the field entirely:
89
+ `prefix`, `suffix`, `trigger`, `chevron`, `flag`, `search`, `loading`, `empty`, `detecting`,
90
+ `group-header`, `item`, `valid-icon`, `error-icon`, `hint`, `error`. Slots receive typed context —
91
+ e.g. `error` gets `{ message, reason, validation }`, `flag` gets `{ country, context }`.
92
+
93
+ ### Composables & helpers (also exported)
94
+
95
+ `usePhoneValidation`, `useCountryDetection`, `useCountryMatching`, `useTypingPhase`,
96
+ `useTelInputValidation`, `normalizeDigits`, `LOCALE_DIGIT_RANGES`, `defaultFlagUrl`,
97
+ `aTelInputVariants`, `DEFAULT_MESSAGES`, `resolveMessages` — compose your own field from the same
98
+ primitives `ATelInput` uses (see `ACountrySelect` / `AInput`).
99
+
100
+ ## Auto-import
101
+
102
+ **Nuxt:**
103
+
104
+ ```ts
105
+ export default defineNuxtConfig({
106
+ modules: ['@alikhalilll/a-tel-input/nuxt'],
107
+ css: [
108
+ '@alikhalilll/a-popover/styles.css',
109
+ '@alikhalilll/a-drawer/styles.css',
110
+ '@alikhalilll/a-tel-input/styles.css',
111
+ ],
112
+ });
113
+ ```
114
+
115
+ **Vite:** register `@alikhalilll/a-tel-input/resolver` in `unplugin-vue-components`.
116
+
117
+ ## SSR
118
+
119
+ Country detection runs only in `onMounted` — the field renders immediately with `defaultCountry`
120
+ (or empty), and IP/timezone/locale resolution patches in on hydration. No SSR network calls.
121
+
122
+ ## License
123
+
124
+ MIT