ngxsmk-tel-input 0.0.8 → 1.0.0
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/.changeset/README.md +8 -0
- package/.changeset/config.json +11 -0
- package/README.md +141 -101
- package/dist/README.md +263 -0
- package/{fesm2022 → dist/fesm2022}/ngxsmk-tel-input.mjs +319 -319
- package/{lib → dist/lib}/ngxsmk-tel-input.component.d.ts +76 -76
- package/ng-package.json +11 -0
- package/package.json +30 -33
- package/readme-assets/invalid.png +0 -0
- package/readme-assets/valid.png +0 -0
- package/src/lib/ngxsmk-tel-input.component.spec.ts +24 -0
- package/src/lib/ngxsmk-tel-input.component.ts +618 -0
- package/src/lib/ngxsmk-tel-input.service.spec.ts +15 -0
- package/src/lib/ngxsmk-tel-input.service.ts +17 -0
- package/src/public-api.ts +2 -0
- package/tsconfig.lib.json +13 -0
- package/tsconfig.lib.prod.json +9 -0
- package/tsconfig.spec.json +13 -0
- /package/{fesm2022 → dist/fesm2022}/ngxsmk-tel-input.mjs.map +0 -0
- /package/{index.d.ts → dist/index.d.ts} +0 -0
- /package/{lib → dist/lib}/ngxsmk-tel-input.service.d.ts +0 -0
- /package/{public-api.d.ts → dist/public-api.d.ts} +0 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Changesets
|
|
2
|
+
|
|
3
|
+
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
|
|
4
|
+
with multi-package repos, or single-package repos to help you version and publish your code. You can
|
|
5
|
+
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
|
|
6
|
+
|
|
7
|
+
We have a quick list of common questions to get you started engaging with this project in
|
|
8
|
+
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
|
|
3
|
+
"changelog": "@changesets/cli/changelog",
|
|
4
|
+
"commit": false,
|
|
5
|
+
"fixed": [],
|
|
6
|
+
"linked": [],
|
|
7
|
+
"access": "restricted",
|
|
8
|
+
"baseBranch": "main",
|
|
9
|
+
"updateInternalDependencies": "patch",
|
|
10
|
+
"ignore": []
|
|
11
|
+
}
|
package/README.md
CHANGED
|
@@ -1,44 +1,65 @@
|
|
|
1
|
-
# ngxsmk-tel-input
|
|
1
|
+
# ngxsmk-tel-input — International Telephone Input for Angular
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/ngxsmk-tel-input)
|
|
4
|
+
[](https://www.npmjs.com/package/ngxsmk-tel-input)
|
|
5
|
+
[](https://github.com/toozuuu/ngxsmk-tel-input/blob/main/LICENSE)
|
|
6
|
+
[](https://github.com/toozuuu/ngxsmk-tel-input)
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
*
|
|
8
|
-
*
|
|
8
|
+
An Angular component for entering and validating **international telephone numbers**. It adds a country flag dropdown, formats input, and validates using real numbering rules.
|
|
9
|
+
|
|
10
|
+
* UI powered by [`intl-tel-input`](https://github.com/jackocnr/intl-tel-input)
|
|
11
|
+
* Parsing & validation via [`libphonenumber-js`](https://github.com/catamphetamine/libphonenumber-js)
|
|
12
|
+
* Implements Angular **ControlValueAccessor** (works with Reactive & Template‑driven Forms)
|
|
13
|
+
|
|
14
|
+
> Emits **E.164** by default (e.g. `+14155550123`). SSR‑safe via lazy, browser‑only import.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Screenshots
|
|
19
|
+
|
|
20
|
+
<p align="left">
|
|
21
|
+
<img src="readme-assets/valid.png" alt="Valid phone number - formatted and passing validation" width="420" />
|
|
22
|
+
|
|
23
|
+
<img src="readme-assets/invalid.png" alt="Invalid phone number - error state and null value" width="420" />
|
|
24
|
+
</p>
|
|
9
25
|
|
|
10
26
|
---
|
|
11
27
|
|
|
12
|
-
##
|
|
28
|
+
## Compatibility
|
|
13
29
|
|
|
14
|
-
|
|
15
|
-
|
|
30
|
+
| ngxsmk-tel-input | Angular |
|
|
31
|
+
| ---------------- | --------------- |
|
|
32
|
+
| `0.0.x` | `17.x` – `19.x` |
|
|
16
33
|
|
|
17
|
-
>
|
|
34
|
+
> The library declares `peerDependencies` of `@angular/* >=17 <20`.
|
|
18
35
|
|
|
19
36
|
---
|
|
20
37
|
|
|
21
|
-
##
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
### 1) Install dependencies
|
|
22
41
|
|
|
23
42
|
```bash
|
|
24
43
|
npm i ngxsmk-tel-input intl-tel-input libphonenumber-js
|
|
25
44
|
```
|
|
26
45
|
|
|
27
|
-
### Add styles &
|
|
46
|
+
### 2) Add styles & flag assets (in your **app**, not the library)
|
|
28
47
|
|
|
29
|
-
Add
|
|
48
|
+
Add intl‑tel‑input CSS and copy its flag images via `angular.json`:
|
|
30
49
|
|
|
31
50
|
```jsonc
|
|
32
51
|
{
|
|
33
52
|
"projects": {
|
|
34
|
-
"
|
|
53
|
+
"your-app": {
|
|
35
54
|
"architect": {
|
|
36
55
|
"build": {
|
|
37
56
|
"options": {
|
|
38
57
|
"styles": [
|
|
39
|
-
"node_modules/intl-tel-input/build/css/intlTelInput.css"
|
|
58
|
+
"node_modules/intl-tel-input/build/css/intlTelInput.css",
|
|
59
|
+
"src/styles.css"
|
|
40
60
|
],
|
|
41
61
|
"assets": [
|
|
62
|
+
{ "glob": "**/*", "input": "src/assets" },
|
|
42
63
|
{ "glob": "**/*", "input": "node_modules/intl-tel-input/build/img", "output": "assets/intl-tel-input/img" }
|
|
43
64
|
]
|
|
44
65
|
}
|
|
@@ -49,7 +70,7 @@ Add `intl-tel-input` CSS and copy flag images via `angular.json`:
|
|
|
49
70
|
}
|
|
50
71
|
```
|
|
51
72
|
|
|
52
|
-
Optional
|
|
73
|
+
Optional (helps some bundlers resolve flags): add to your global styles
|
|
53
74
|
|
|
54
75
|
```css
|
|
55
76
|
.iti__flag { background-image: url("/assets/intl-tel-input/img/flags.png"); }
|
|
@@ -58,11 +79,13 @@ Optional flag URL override (put in your app’s global styles):
|
|
|
58
79
|
}
|
|
59
80
|
```
|
|
60
81
|
|
|
61
|
-
Restart
|
|
82
|
+
Restart your dev server after editing `angular.json`.
|
|
62
83
|
|
|
63
84
|
---
|
|
64
85
|
|
|
65
|
-
##
|
|
86
|
+
## Usage
|
|
87
|
+
|
|
88
|
+
### Reactive Forms
|
|
66
89
|
|
|
67
90
|
```ts
|
|
68
91
|
// app.component.ts
|
|
@@ -85,7 +108,7 @@ import { NgxsmkTelInputComponent } from 'ngxsmk-tel-input';
|
|
|
85
108
|
(countryChange)="onCountry($event)">
|
|
86
109
|
</ngxsmk-tel-input>
|
|
87
110
|
|
|
88
|
-
<p
|
|
111
|
+
<p *ngIf="fg.get('phone')?.hasError('phoneInvalid') && fg.get('phone')?.touched">
|
|
89
112
|
Please enter a valid phone number.
|
|
90
113
|
</p>
|
|
91
114
|
|
|
@@ -96,137 +119,154 @@ import { NgxsmkTelInputComponent } from 'ngxsmk-tel-input';
|
|
|
96
119
|
export class AppComponent {
|
|
97
120
|
fg = this.fb.group({ phone: ['', Validators.required] });
|
|
98
121
|
constructor(private readonly fb: FormBuilder) {}
|
|
99
|
-
onCountry(e: { iso2:
|
|
122
|
+
onCountry(e: { iso2: any }) { console.log('Country changed:', e.iso2); }
|
|
100
123
|
}
|
|
101
124
|
```
|
|
102
125
|
|
|
103
|
-
**Value semantics**
|
|
104
|
-
|
|
105
|
-
* Valid → control value is **E.164** string (e.g. `+14155550123`)
|
|
106
|
-
* Empty/invalid → value is **`null`**; validator sets `{ phoneInvalid: true }`
|
|
107
|
-
|
|
108
|
-
---
|
|
126
|
+
**Value semantics:** The control emits **E.164** when valid, or `null` when empty/invalid.
|
|
109
127
|
|
|
110
|
-
|
|
128
|
+
### Template‑driven
|
|
111
129
|
|
|
112
130
|
```html
|
|
113
131
|
<form #f="ngForm">
|
|
114
132
|
<ngxsmk-tel-input name="phone" [(ngModel)]="phone"></ngxsmk-tel-input>
|
|
115
133
|
</form>
|
|
116
|
-
<!-- phone is an E.164 string or null -->
|
|
117
134
|
```
|
|
118
135
|
|
|
119
136
|
---
|
|
120
137
|
|
|
121
|
-
##
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
|
126
|
-
|
|
|
127
|
-
| `
|
|
128
|
-
| `
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
| `
|
|
133
|
-
| `
|
|
134
|
-
| `
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
137
|
-
| `
|
|
138
|
-
| `
|
|
139
|
-
| `
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
144
|
-
| `
|
|
145
|
-
| `
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
|
154
|
-
|
|
|
155
|
-
| `
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
### Public methods
|
|
138
|
+
## Options (Inputs)
|
|
139
|
+
|
|
140
|
+
| Option | Type | Default | Description |
|
|
141
|
+
| ---------------------- | -------------------------------------- | ---------------------- | ---------------------------------------------------------------------- |
|
|
142
|
+
| `initialCountry` | `CountryCode \| 'auto'` | `'US'` | Starting country. `'auto'` uses a simple geo‑IP stub (defaults to US). |
|
|
143
|
+
| `preferredCountries` | `CountryCode[]` | `['US','GB']` | Countries pinned at the top. |
|
|
144
|
+
| `onlyCountries` | `CountryCode[]` | — | Restrict selectable countries. |
|
|
145
|
+
| `nationalMode` | `boolean` | `false` | Display national format in the box. Value still emits E.164. |
|
|
146
|
+
| `separateDialCode` | `boolean` | `false` | Show dial code separately to the left. |
|
|
147
|
+
| `allowDropdown` | `boolean` | `true` | Enable/disable country dropdown. |
|
|
148
|
+
| `placeholder` | `string` | `'Enter phone number'` | Input placeholder. |
|
|
149
|
+
| `autocomplete` | `string` | `'tel'` | Native autocomplete attribute. |
|
|
150
|
+
| `disabled` | `boolean` | `false` | Disable the control. |
|
|
151
|
+
| `label` | `string` | — | Optional label text. |
|
|
152
|
+
| `hint` | `string` | — | Helper text shown below. |
|
|
153
|
+
| `errorText` | `string` | — | Custom error message. |
|
|
154
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Preset sizing. |
|
|
155
|
+
| `variant` | `'outline' \| 'filled' \| 'underline'` | `'outline'` | Visual style. |
|
|
156
|
+
| `showClear` | `boolean` | `true` | Show a clear (×) button when not empty. |
|
|
157
|
+
| `autoFocus` | `boolean` | `false` | Focus on init. |
|
|
158
|
+
| `selectOnFocus` | `boolean` | `false` | Select text on focus. |
|
|
159
|
+
| `formatOnBlur` | `boolean` | `true` | Pretty‑print on blur (national if `nationalMode`). |
|
|
160
|
+
| `showErrorWhenTouched` | `boolean` | `true` | Only show error styles after the control is touched. |
|
|
161
|
+
| `dropdownAttachToBody` | `boolean` | `true` | Attach dropdown to `<body>` to avoid clipping. |
|
|
162
|
+
| `dropdownZIndex` | `number` | `2000` | Z‑index for dropdown panel. |
|
|
163
|
+
|
|
164
|
+
> `CountryCode` is the ISO‑2 code from `libphonenumber-js` (e.g. `US`, `GB`).
|
|
165
|
+
|
|
166
|
+
### Outputs (Events)
|
|
167
|
+
|
|
168
|
+
| Event | Payload | Description |
|
|
169
|
+
| ---------------- | ---------------------------------------------------------- | ---------------------------------------- |
|
|
170
|
+
| `countryChange` | `{ iso2: CountryCode }` | Fires when the selected country changes. |
|
|
171
|
+
| `validityChange` | `boolean` | Emits when validity toggles. |
|
|
172
|
+
| `inputChange` | `{ raw: string; e164: string \| null; iso2: CountryCode }` | Emitted on each input. |
|
|
173
|
+
|
|
174
|
+
### Public Methods
|
|
160
175
|
|
|
161
176
|
* `focus(): void`
|
|
162
177
|
* `selectCountry(iso2: CountryCode): void`
|
|
163
178
|
|
|
164
179
|
---
|
|
165
180
|
|
|
166
|
-
##
|
|
181
|
+
## Supported Formats
|
|
167
182
|
|
|
168
|
-
|
|
183
|
+
* **E164** → `+41446681800`
|
|
184
|
+
* **International** (display) → `+41 44 668 18 00`
|
|
185
|
+
* **National** (display) → `044 668 18 00`
|
|
186
|
+
|
|
187
|
+
> The control **emits E.164** by default. If you need the currently typed format too, use `(inputChange)`.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Theming & Styling
|
|
192
|
+
|
|
193
|
+
This component exposes CSS variables for quick theming:
|
|
169
194
|
|
|
170
195
|
```html
|
|
171
196
|
<ngxsmk-tel-input style="
|
|
172
197
|
--tel-border:#cbd5e1;
|
|
173
|
-
--tel-ring:#
|
|
174
|
-
--tel-radius:
|
|
175
|
-
--tel-dd-item-hover: rgba(
|
|
198
|
+
--tel-ring:#2563eb;
|
|
199
|
+
--tel-radius:12px;
|
|
200
|
+
--tel-dd-item-hover: rgba(37,99,235,.08);
|
|
176
201
|
--tel-dd-z: 3000;
|
|
177
202
|
"></ngxsmk-tel-input>
|
|
178
203
|
```
|
|
179
204
|
|
|
180
|
-
Key
|
|
181
|
-
|
|
182
|
-
* Input: `--tel-bg`, `--tel-fg`, `--tel-border`, `--tel-border-hover`, `--tel-ring`, `--tel-placeholder`, `--tel-error`, `--tel-radius`, `--tel-focus-shadow`
|
|
183
|
-
* Dropdown: `--tel-dd-bg`, `--tel-dd-border`, `--tel-dd-shadow`, `--tel-dd-radius`, `--tel-dd-item-hover`, `--tel-dd-search-bg`, `--tel-dd-z`
|
|
205
|
+
Key variables: `--tel-bg`, `--tel-fg`, `--tel-border`, `--tel-border-hover`, `--tel-ring`, `--tel-placeholder`, `--tel-error`, `--tel-radius`, `--tel-focus-shadow`, `--tel-dd-bg`, `--tel-dd-border`, `--tel-dd-shadow`, `--tel-dd-radius`, `--tel-dd-item-hover`, `--tel-dd-search-bg`, `--tel-dd-z`.
|
|
184
206
|
|
|
185
|
-
Dark mode: wrap in a `.dark` container
|
|
207
|
+
Dark mode: wrap in a `.dark` container; tokens adapt.
|
|
186
208
|
|
|
187
209
|
---
|
|
188
210
|
|
|
189
211
|
## SSR
|
|
190
212
|
|
|
191
|
-
|
|
192
|
-
* No direct `window`/`document` usage on the server path.
|
|
213
|
+
The library guards `intl-tel-input` import behind `isPlatformBrowser`, so Angular Universal builds won’t try to access `window` during SSR.
|
|
193
214
|
|
|
194
215
|
---
|
|
195
216
|
|
|
196
|
-
##
|
|
197
|
-
|
|
198
|
-
* **Unstyled UI / bullets** → Add CSS + assets in `angular.json`, restart dev server.
|
|
199
|
-
* **Flags missing** → Verify the images were copied to `/assets/intl-tel-input/img` or add the CSS override.
|
|
200
|
-
* **`TS2307: Cannot find module 'ngxsmk-tel-input'`** → Build the lib first; or add a `paths` alias to your app’s `tsconfig` if consuming locally.
|
|
201
|
-
* **Peer dependency conflict** → App Angular version must satisfy `>=17 <20`.
|
|
217
|
+
## Local Development
|
|
202
218
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
## Local dev & publish
|
|
219
|
+
This repository is an Angular workspace with a library.
|
|
206
220
|
|
|
207
221
|
```bash
|
|
208
222
|
# Build the library
|
|
209
223
|
ng build ngxsmk-tel-input
|
|
210
224
|
|
|
211
|
-
#
|
|
225
|
+
# Try it in a demo app inside the workspace
|
|
226
|
+
ng serve demo
|
|
227
|
+
|
|
228
|
+
# Or pack and install in another app locally
|
|
212
229
|
cd dist/ngxsmk-tel-input && npm pack
|
|
213
|
-
# in your app
|
|
214
|
-
npm i ../path-to/dist/ngxsmk-tel-input/ngxsmk-tel-input-<version>.tgz
|
|
215
230
|
|
|
216
|
-
#
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
231
|
+
# in your other app
|
|
232
|
+
npm i ../path/to/dist/ngxsmk-tel-input/ngxsmk-tel-input-<version>.tgz
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Tip: you can also map a workspace path alias in `tsconfig.base.json`:
|
|
236
|
+
|
|
237
|
+
```jsonc
|
|
238
|
+
{
|
|
239
|
+
"compilerOptions": {
|
|
240
|
+
"paths": {
|
|
241
|
+
"ngxsmk-tel-input": ["dist/ngxsmk-tel-input"]
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
221
245
|
```
|
|
222
246
|
|
|
223
247
|
---
|
|
224
248
|
|
|
225
|
-
##
|
|
249
|
+
## Troubleshooting
|
|
226
250
|
|
|
227
|
-
|
|
251
|
+
* **Unstyled dropdown / bullets / missing flags** → Ensure CSS & assets are added in your app’s `angular.json`, then restart the dev server.
|
|
252
|
+
* **`TS2307: Cannot find module 'ngxsmk-tel-input'`** → Build the library first so `dist/ngxsmk-tel-input` exists (or install from npm).
|
|
253
|
+
* **Peer dependency conflict** → Your app must be Angular 17–19 to satisfy peers.
|
|
254
|
+
* **Dropdown clipped by parent** → Keep `dropdownAttachToBody=true` or raise `dropdownZIndex`.
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Contributing
|
|
259
|
+
|
|
260
|
+
PRs welcome! Please:
|
|
261
|
+
|
|
262
|
+
1. `npm ci` and `ng build`
|
|
263
|
+
2. Cover behavior changes with tests if possible
|
|
264
|
+
3. Update README for any API changes
|
|
228
265
|
|
|
229
|
-
|
|
266
|
+
This project is open to using the [all-contributors](https://github.com/all-contributors/all-contributors) spec. Contributions of any kind welcome!
|
|
230
267
|
|
|
231
|
-
|
|
232
|
-
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## License
|
|
271
|
+
|
|
272
|
+
[MIT](./LICENSE)
|
package/dist/README.md
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# ngxsmk-tel-input — International Telephone Input for Angular
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/ngxsmk-tel-input)
|
|
4
|
+
[](https://www.npmjs.com/package/ngxsmk-tel-input)
|
|
5
|
+
[](https://github.com/toozuuu/ngxsmk-tel-input/blob/main/LICENSE)
|
|
6
|
+
[](https://bundlephobia.com/package/ngxsmk-tel-input)
|
|
7
|
+
[](https://github.com/toozuuu/ngxsmk-tel-input)
|
|
8
|
+
|
|
9
|
+
An Angular component for entering and validating **international telephone numbers**. It adds a country flag dropdown, formats input, and validates using real numbering rules.
|
|
10
|
+
|
|
11
|
+
* UI powered by [`intl-tel-input`](https://github.com/jackocnr/intl-tel-input)
|
|
12
|
+
* Parsing & validation via [`libphonenumber-js`](https://github.com/catamphetamine/libphonenumber-js)
|
|
13
|
+
* Implements Angular **ControlValueAccessor** (works with Reactive & Template‑driven Forms)
|
|
14
|
+
|
|
15
|
+
> Emits **E.164** by default (e.g. `+14155550123`). SSR‑safe via lazy, browser‑only import.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Compatibility
|
|
20
|
+
|
|
21
|
+
| ngxsmk-tel-input | Angular |
|
|
22
|
+
| ---------------- | --------------- |
|
|
23
|
+
| `0.0.x` | `17.x` – `19.x` |
|
|
24
|
+
|
|
25
|
+
> The library declares `peerDependencies` of `@angular/* >=17 <20`.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
### 1) Install dependencies
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm i ngxsmk-tel-input intl-tel-input libphonenumber-js
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 2) Add styles & flag assets (in your **app**, not the library)
|
|
38
|
+
|
|
39
|
+
Add intl‑tel‑input CSS and copy its flag images via `angular.json`:
|
|
40
|
+
|
|
41
|
+
```jsonc
|
|
42
|
+
{
|
|
43
|
+
"projects": {
|
|
44
|
+
"your-app": {
|
|
45
|
+
"architect": {
|
|
46
|
+
"build": {
|
|
47
|
+
"options": {
|
|
48
|
+
"styles": [
|
|
49
|
+
"node_modules/intl-tel-input/build/css/intlTelInput.css",
|
|
50
|
+
"src/styles.css"
|
|
51
|
+
],
|
|
52
|
+
"assets": [
|
|
53
|
+
{ "glob": "**/*", "input": "src/assets" },
|
|
54
|
+
{ "glob": "**/*", "input": "node_modules/intl-tel-input/build/img", "output": "assets/intl-tel-input/img" }
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Optional (helps some bundlers resolve flags): add to your global styles
|
|
65
|
+
|
|
66
|
+
```css
|
|
67
|
+
.iti__flag { background-image: url("/assets/intl-tel-input/img/flags.png"); }
|
|
68
|
+
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
|
|
69
|
+
.iti__flag { background-image: url("/assets/intl-tel-input/img/flags@2x.png"); }
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Restart your dev server after editing `angular.json`.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Usage
|
|
78
|
+
|
|
79
|
+
### Reactive Forms
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
// app.component.ts
|
|
83
|
+
import { Component } from '@angular/core';
|
|
84
|
+
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
|
|
85
|
+
import { NgxsmkTelInputComponent } from 'ngxsmk-tel-input';
|
|
86
|
+
|
|
87
|
+
@Component({
|
|
88
|
+
selector: 'app-root',
|
|
89
|
+
standalone: true,
|
|
90
|
+
imports: [ReactiveFormsModule, NgxsmkTelInputComponent],
|
|
91
|
+
template: `
|
|
92
|
+
<form [formGroup]="fg" style="max-width:420px;display:grid;gap:12px">
|
|
93
|
+
<ngxsmk-tel-input
|
|
94
|
+
formControlName="phone"
|
|
95
|
+
label="Phone"
|
|
96
|
+
hint="Include area code"
|
|
97
|
+
[initialCountry]="'US'"
|
|
98
|
+
[preferredCountries]="['US','GB','AU']"
|
|
99
|
+
(countryChange)="onCountry($event)">
|
|
100
|
+
</ngxsmk-tel-input>
|
|
101
|
+
|
|
102
|
+
<p *ngIf="fg.get('phone')?.hasError('phoneInvalid') && fg.get('phone')?.touched">
|
|
103
|
+
Please enter a valid phone number.
|
|
104
|
+
</p>
|
|
105
|
+
|
|
106
|
+
<pre>Value: {{ fg.value | json }}</pre>
|
|
107
|
+
</form>
|
|
108
|
+
`
|
|
109
|
+
})
|
|
110
|
+
export class AppComponent {
|
|
111
|
+
fg = this.fb.group({ phone: ['', Validators.required] });
|
|
112
|
+
constructor(private readonly fb: FormBuilder) {}
|
|
113
|
+
onCountry(e: { iso2: any }) { console.log('Country changed:', e.iso2); }
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Value semantics:** The control emits **E.164** when valid, or `null` when empty/invalid.
|
|
118
|
+
|
|
119
|
+
### Template‑driven
|
|
120
|
+
|
|
121
|
+
```html
|
|
122
|
+
<form #f="ngForm">
|
|
123
|
+
<ngxsmk-tel-input name="phone" [(ngModel)]="phone"></ngxsmk-tel-input>
|
|
124
|
+
</form>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Options (Inputs)
|
|
130
|
+
|
|
131
|
+
| Option | Type | Default | Description |
|
|
132
|
+
| ---------------------- | -------------------------------------- | ---------------------- | ---------------------------------------------------------------------- |
|
|
133
|
+
| `initialCountry` | `CountryCode \| 'auto'` | `'US'` | Starting country. `'auto'` uses a simple geo‑IP stub (defaults to US). |
|
|
134
|
+
| `preferredCountries` | `CountryCode[]` | `['US','GB']` | Countries pinned at the top. |
|
|
135
|
+
| `onlyCountries` | `CountryCode[]` | — | Restrict selectable countries. |
|
|
136
|
+
| `nationalMode` | `boolean` | `false` | Display national format in the box. Value still emits E.164. |
|
|
137
|
+
| `separateDialCode` | `boolean` | `false` | Show dial code separately to the left. |
|
|
138
|
+
| `allowDropdown` | `boolean` | `true` | Enable/disable country dropdown. |
|
|
139
|
+
| `placeholder` | `string` | `'Enter phone number'` | Input placeholder. |
|
|
140
|
+
| `autocomplete` | `string` | `'tel'` | Native autocomplete attribute. |
|
|
141
|
+
| `disabled` | `boolean` | `false` | Disable the control. |
|
|
142
|
+
| `label` | `string` | — | Optional label text. |
|
|
143
|
+
| `hint` | `string` | — | Helper text shown below. |
|
|
144
|
+
| `errorText` | `string` | — | Custom error message. |
|
|
145
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Preset sizing. |
|
|
146
|
+
| `variant` | `'outline' \| 'filled' \| 'underline'` | `'outline'` | Visual style. |
|
|
147
|
+
| `showClear` | `boolean` | `true` | Show a clear (×) button when not empty. |
|
|
148
|
+
| `autoFocus` | `boolean` | `false` | Focus on init. |
|
|
149
|
+
| `selectOnFocus` | `boolean` | `false` | Select text on focus. |
|
|
150
|
+
| `formatOnBlur` | `boolean` | `true` | Pretty‑print on blur (national if `nationalMode`). |
|
|
151
|
+
| `showErrorWhenTouched` | `boolean` | `true` | Only show error styles after the control is touched. |
|
|
152
|
+
| `dropdownAttachToBody` | `boolean` | `true` | Attach dropdown to `<body>` to avoid clipping. |
|
|
153
|
+
| `dropdownZIndex` | `number` | `2000` | Z‑index for dropdown panel. |
|
|
154
|
+
|
|
155
|
+
> `CountryCode` is the ISO‑2 code from `libphonenumber-js` (e.g. `US`, `GB`).
|
|
156
|
+
|
|
157
|
+
### Outputs (Events)
|
|
158
|
+
|
|
159
|
+
| Event | Payload | Description |
|
|
160
|
+
| ---------------- | ---------------------------------------------------------- | ---------------------------------------- |
|
|
161
|
+
| `countryChange` | `{ iso2: CountryCode }` | Fires when the selected country changes. |
|
|
162
|
+
| `validityChange` | `boolean` | Emits when validity toggles. |
|
|
163
|
+
| `inputChange` | `{ raw: string; e164: string \| null; iso2: CountryCode }` | Emitted on each input. |
|
|
164
|
+
|
|
165
|
+
### Public Methods
|
|
166
|
+
|
|
167
|
+
* `focus(): void`
|
|
168
|
+
* `selectCountry(iso2: CountryCode): void`
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Supported Formats
|
|
173
|
+
|
|
174
|
+
* **E164** → `+41446681800`
|
|
175
|
+
* **International** (display) → `+41 44 668 18 00`
|
|
176
|
+
* **National** (display) → `044 668 18 00`
|
|
177
|
+
|
|
178
|
+
> The control **emits E.164** by default. If you need the currently typed format too, use `(inputChange)`.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Theming & Styling
|
|
183
|
+
|
|
184
|
+
This component exposes CSS variables for quick theming:
|
|
185
|
+
|
|
186
|
+
```html
|
|
187
|
+
<ngxsmk-tel-input style="
|
|
188
|
+
--tel-border:#cbd5e1;
|
|
189
|
+
--tel-ring:#2563eb;
|
|
190
|
+
--tel-radius:12px;
|
|
191
|
+
--tel-dd-item-hover: rgba(37,99,235,.08);
|
|
192
|
+
--tel-dd-z: 3000;
|
|
193
|
+
"></ngxsmk-tel-input>
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Key variables: `--tel-bg`, `--tel-fg`, `--tel-border`, `--tel-border-hover`, `--tel-ring`, `--tel-placeholder`, `--tel-error`, `--tel-radius`, `--tel-focus-shadow`, `--tel-dd-bg`, `--tel-dd-border`, `--tel-dd-shadow`, `--tel-dd-radius`, `--tel-dd-item-hover`, `--tel-dd-search-bg`, `--tel-dd-z`.
|
|
197
|
+
|
|
198
|
+
Dark mode: wrap in a `.dark` container; tokens adapt.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## SSR
|
|
203
|
+
|
|
204
|
+
The library guards `intl-tel-input` import behind `isPlatformBrowser`, so Angular Universal builds won’t try to access `window` during SSR.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Local Development
|
|
209
|
+
|
|
210
|
+
This repository is an Angular workspace with a library.
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
# Build the library
|
|
214
|
+
ng build ngxsmk-tel-input
|
|
215
|
+
|
|
216
|
+
# Try it in a demo app inside the workspace
|
|
217
|
+
ng serve demo
|
|
218
|
+
|
|
219
|
+
# Or pack and install in another app locally
|
|
220
|
+
cd dist/ngxsmk-tel-input && npm pack
|
|
221
|
+
|
|
222
|
+
# in your other app
|
|
223
|
+
npm i ../path/to/dist/ngxsmk-tel-input/ngxsmk-tel-input-<version>.tgz
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Tip: you can also map a workspace path alias in `tsconfig.base.json`:
|
|
227
|
+
|
|
228
|
+
```jsonc
|
|
229
|
+
{
|
|
230
|
+
"compilerOptions": {
|
|
231
|
+
"paths": {
|
|
232
|
+
"ngxsmk-tel-input": ["dist/ngxsmk-tel-input"]
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Troubleshooting
|
|
241
|
+
|
|
242
|
+
* **Unstyled dropdown / bullets / missing flags** → Ensure CSS & assets are added in your app’s `angular.json`, then restart the dev server.
|
|
243
|
+
* **`TS2307: Cannot find module 'ngxsmk-tel-input'`** → Build the library first so `dist/ngxsmk-tel-input` exists (or install from npm).
|
|
244
|
+
* **Peer dependency conflict** → Your app must be Angular 17–19 to satisfy peers.
|
|
245
|
+
* **Dropdown clipped by parent** → Keep `dropdownAttachToBody=true` or raise `dropdownZIndex`.
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Contributing
|
|
250
|
+
|
|
251
|
+
PRs welcome! Please:
|
|
252
|
+
|
|
253
|
+
1. `npm ci` and `ng build`
|
|
254
|
+
2. Cover behavior changes with tests if possible
|
|
255
|
+
3. Update README for any API changes
|
|
256
|
+
|
|
257
|
+
This project is open to using the [all-contributors](https://github.com/all-contributors/all-contributors) spec. Contributions of any kind welcome!
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## License
|
|
262
|
+
|
|
263
|
+
[MIT](./LICENSE)
|