You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix initialCountry behavior for empty phone values and expose missing input typings (#84)
This PR addresses the behavior reported in Discussion #83 where
`initialCountry` was not applied when the form control value is an empty
string (`''`), causing the US flag to appear by default in first-render
scenarios. It also aligns public typings so documented inputs (e.g.
`formatOnBlur`) are recognized correctly.
## Context
In Angular form-first flows (initial value = `''`), consumers could not
reliably set the initial country via `[initialCountry]` or early
`selectCountry(...)` calls. Some users also reported missing input
typings in installed package definitions.
## What this PR changes
- Ensures `initialCountry` is respected when the bound phone value is
empty.
- Avoids transient UI artifacts (like brief duplicate dial code render)
when initializing country state.
- Aligns exported typings with supported component inputs (including
`formatOnBlur` if supported in this version).
- Keeps existing behavior unchanged for non-empty initial values and
explicit E.164 values.
## Why
- Fixes first-render country mismatch for empty values.
- Improves migration experience for teams moving from other telephone
input libraries.
- Reduces confusion caused by documentation vs typings mismatch.
## Validation
- Verified empty initial form value (`''`) with
`[initialCountry]="'AR'"` correctly shows the AR flag on first render.
- Verified no dial-code flicker/double-render during initial mount.
- Verified typings expose expected inputs in Angular templates.
- Confirmed no regressions for existing valid-number initialization
paths.
## Related discussion
- [Setting initialCountry in an empty phone ('') scenario · Discussion
#83](#83)
Copy file name to clipboardExpand all lines: CONTRIBUTING.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,15 +6,15 @@ By participating in this project, you are expected to uphold the project's goals
6
6
7
7
---
8
8
9
-
## 💡 How to Contribute
9
+
## How to Contribute
10
10
11
11
There are several ways you can help improve this project:
12
12
13
13
1.**Report Bugs:** Submit an issue if you find a problem.
14
14
2.**Suggest Features:** Open an issue to propose new functionality.
15
15
3.**Contribute Code:** Submit a Pull Request with bug fixes or new features.
16
16
17
-
## 🐛 Reporting Bugs
17
+
## Reporting Bugs
18
18
19
19
If you find a bug, please check the [Issues page](https://github.com/toozuuu/ngxsmk-tel-input/issues) to see if it has already been reported.
20
20
@@ -24,13 +24,13 @@ When submitting a new bug report, please include:
24
24
* Your **Angular version** and the **browser** you are using.
25
25
* A minimal reproduction link (e.g., CodePen, JSFiddle) if possible.
26
26
27
-
## ✨ Suggesting Enhancements
27
+
## Suggesting Enhancements
28
28
29
29
If you have an idea for a new feature or an enhancement, please open a new issue on the [Issues page](https://github.com/toozuuu/ngxsmk-tel-input/issues).
30
30
31
31
Describe the feature, why you think it would be useful, and how it aligns with the goals of the library.
32
32
33
-
## 💻 Code Contributions (Pull Requests)
33
+
## Code Contributions (Pull Requests)
34
34
35
35
We welcome pull requests for bug fixes and new features.
Copy file name to clipboardExpand all lines: README.md
+38-26Lines changed: 38 additions & 26 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,56 +1,65 @@
1
1
# ngxsmk-tel-input
2
2
3
-
An Angular **telephone input** component with country dropdown, flags, and robust validation/formatting.
4
-
Wraps [`intl-tel-input`](https://github.com/jackocnr/intl-tel-input)for the UI and [`libphonenumber-js`](https://github.com/catamphetamine/libphonenumber-js) for parsing/validation. Implements `ControlValueAccessor` so it plugs into Angular Forms.
3
+
An Angular **phone input / telephone input** component with country dropdown, flags, international formatting, and robust validation.
4
+
Built on top of [`intl-tel-input`](https://github.com/jackocnr/intl-tel-input)+ [`libphonenumber-js`](https://github.com/catamphetamine/libphonenumber-js), and fully compatible with Angular Reactive Forms and template-driven forms through `ControlValueAccessor`.
5
5
6
6
> Emits **E.164** by default (e.g. `+14155550123`). SSR‑safe via lazy browser‑only import.
7
7
8
-
## 🚀 Try it live on StackBlitz
8
+
## Try it live on StackBlitz
9
9
10
10
[](https://stackblitz.com/~/github.com/toozuuu/ngxsmk-tel-input)
11
11
12
12
---
13
13
14
-
## ✨ Features
14
+
## Features
15
15
16
16
* Country dropdown with flags
17
17
* E.164 output (display can be national with `nationalMode`)
18
18
* Reactive & template‑driven Forms support (CVA)
19
19
* Built‑in validation using libphonenumber‑js
20
20
***Enhanced validation**: Detects invalid country codes (like "11", "99") and shows appropriate error states
21
21
***Mobile responsive**: Optimized for touch devices with proper tap targets, prevents iOS zoom, and responsive dropdown
22
-
***Dark & Light themes**: Comprehensive theme system with automatic system preference detection
22
+
***Dark & Light themes**: Improved dark-mode contrast, consistent code/readout colors, and automatic system preference detection
23
23
***Accessibility**: Full ARIA support, screen reader compatibility, keyboard navigation
* Format only when valid (formatWhenValid) and lock once valid (lockWhenValid) to prevent extra digits
29
29
30
+
### Demo app highlights
31
+
32
+
The workspace demo (`ng serve demo`) now includes:
33
+
34
+
* polished documentation-style layout with improved spacing and visual hierarchy
35
+
* responsive sidebar/header behavior for mobile and desktop
36
+
* cleaner dark-mode palette with better text/background contrast
37
+
* improved focus states and reduced-motion support for accessibility
38
+
30
39
---
31
40
32
-
## ✅ Requirements
41
+
## Requirements
33
42
34
43
* Angular **17+** (17, 18, 19, 20, 21+)
35
44
* Node **18** or **20**
36
45
37
46
> Library `peerDependencies` target Angular `>=17`. Fully compatible with Angular 17, 18, 19, 20, 21, and future versions.
38
47
39
-
### 🔄 Zone.js Compatibility
48
+
### Zone.js Compatibility
40
49
41
50
This component works seamlessly with **both Zone.js and zoneless Angular**:
42
51
43
-
*✅**With Zone.js** (traditional Angular): Full compatibility
44
-
*✅**Without Zone.js** (Angular 18+ zoneless): Full compatibility
45
-
*✅**All data binding types**: Property bindings, event bindings, two-way bindings
46
-
*✅**Reactive Forms & Template-driven Forms**: Full support
47
-
*✅**Signals**: Compatible with Angular signals (Angular 16+)
52
+
***With Zone.js** (traditional Angular): Full compatibility
53
+
***Without Zone.js** (Angular 18+ zoneless): Full compatibility
54
+
***All data binding types**: Property bindings, event bindings, two-way bindings
55
+
***Reactive Forms & Template-driven Forms**: Full support
56
+
***Signals**: Compatible with Angular signals (Angular 16+)
48
57
49
58
The component automatically detects whether Zone.js is available and adapts its change detection strategy accordingly.
50
59
51
60
---
52
61
53
-
## 📦 Install
62
+
## Install
54
63
55
64
```bash
56
65
npm i ngxsmk-tel-input intl-tel-input libphonenumber-js
@@ -110,7 +119,7 @@ Ensure your app includes a proper viewport meta tag:
110
119
111
120
---
112
121
113
-
## 🚀 Quick start (Reactive Forms)
122
+
## Quick start (Reactive Forms)
114
123
115
124
```ts
116
125
// app.component.ts
@@ -171,7 +180,7 @@ export class AppComponent {
171
180
172
181
---
173
182
174
-
## 📝 Template‑driven usage
183
+
## Template‑driven usage
175
184
176
185
```html
177
186
<form#f="ngForm">
@@ -182,7 +191,7 @@ export class AppComponent {
182
191
183
192
---
184
193
185
-
## 🈺 Localization & RTL
194
+
## Localization & RTL
186
195
187
196
You can localize the dropdown/search labels and override country names.
188
197
@@ -232,7 +241,7 @@ Arabic + RTL example
232
241
```
233
242
234
243
235
-
## ⚙️ API
244
+
## ️ API
236
245
237
246
### Inputs
238
247
@@ -278,15 +287,18 @@ Arabic + RTL example
278
287
|`countryChange`|`{ iso2: CountryCode }`| Fired when selected country changes. |
279
288
|`validityChange`|`boolean`| Fired when validity flips. |
280
289
|`inputChange`|`{ raw: string; e164: string \| null; iso2: CountryCode }`| Emitted on every keystroke. |
290
+
|`ready`|`void`| Emitted after plugin + listeners finish wiring (including each re-init cycle). |
281
291
282
292
### Public methods
283
293
284
294
*`focus(): void`
285
295
*`selectCountry(iso2: CountryCode): void`
286
296
297
+
For deterministic first render behavior, prefer setting `[initialCountry]` directly. If you call imperative APIs like `selectCountry(...)` immediately after mount, wait for `(ready)` first.
298
+
287
299
---
288
300
289
-
## 🧠 Formatting & validity behavior
301
+
## Formatting & validity behavior
290
302
291
303
* No formatting while invalid. As-you-type masking only starts when the digits form a valid number for the selected country.
292
304
@@ -299,7 +311,7 @@ For rare patterns not covered by libphonenumber-js, the control falls back to ra
299
311
---
300
312
301
313
302
-
## 🎨 Theming
314
+
## Theming
303
315
304
316
### CSS Variables
305
317
@@ -353,7 +365,7 @@ Dark mode: wrap in a `.dark` parent or use `[theme]="'dark'"` — tokens adapt a
0 commit comments