Skip to content

Commit d064a7a

Browse files
authored
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)
1 parent ab301dc commit d064a7a

18 files changed

Lines changed: 830 additions & 398 deletions

.github/workflows/deploy-demo.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Deploy Demo to GitHub Pages
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- master
8+
workflow_dispatch: # Allows manual triggering
9+
10+
permissions:
11+
contents: read
12+
pages: write
13+
id-token: write
14+
15+
concurrency:
16+
group: "pages"
17+
cancel-in-progress: false
18+
19+
jobs:
20+
build:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v5
25+
26+
- name: Setup Node.js
27+
uses: actions/setup-node@v4
28+
with:
29+
node-version: '20'
30+
cache: 'npm'
31+
32+
- name: Install dependencies
33+
run: npm ci
34+
35+
- name: Build library
36+
run: npx ng build ngxsmk-tel-input --configuration production
37+
38+
- name: Build demo
39+
run: |
40+
REPO_NAME=${GITHUB_REPOSITORY#*/}
41+
npx ng build demo --configuration production --base-href /$REPO_NAME/
42+
43+
- name: Setup Pages
44+
uses: actions/configure-pages@v5
45+
46+
- name: Upload artifact
47+
uses: actions/upload-pages-artifact@v3
48+
with:
49+
path: './dist/demo/browser'
50+
51+
deploy:
52+
environment:
53+
name: github-pages
54+
url: ${{ steps.deployment.outputs.page_url }}
55+
runs-on: ubuntu-latest
56+
needs: build
57+
steps:
58+
- name: Deploy to GitHub Pages
59+
id: deployment
60+
uses: actions/deploy-pages@v4
61+

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.6.10] - 2026-01-19
11+
1012
### Changed
13+
- **Dependencies**: Updated `intl-tel-input` to version 25 compatibility.
14+
- **Internal**: Migrated `preferredCountries` to `countryOrder` to support `intl-tel-input` v25.
1115
- **Example Components**: All example components (E-commerce Checkout, User Registration, Profile Management) now default to dark mode theme
1216
- **Demo App**: Default theme changed to dark mode for better visibility and consistency
1317
- **Navigation UI**: Fixed icon and text colors in dark mode navigation menu for better contrast and readability

CONTRIBUTING.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ By participating in this project, you are expected to uphold the project's goals
66

77
---
88

9-
## 💡 How to Contribute
9+
## How to Contribute
1010

1111
There are several ways you can help improve this project:
1212

1313
1. **Report Bugs:** Submit an issue if you find a problem.
1414
2. **Suggest Features:** Open an issue to propose new functionality.
1515
3. **Contribute Code:** Submit a Pull Request with bug fixes or new features.
1616

17-
## 🐛 Reporting Bugs
17+
## Reporting Bugs
1818

1919
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.
2020

@@ -24,13 +24,13 @@ When submitting a new bug report, please include:
2424
* Your **Angular version** and the **browser** you are using.
2525
* A minimal reproduction link (e.g., CodePen, JSFiddle) if possible.
2626

27-
## Suggesting Enhancements
27+
## Suggesting Enhancements
2828

2929
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).
3030

3131
Describe the feature, why you think it would be useful, and how it aligns with the goals of the library.
3232

33-
## 💻 Code Contributions (Pull Requests)
33+
## Code Contributions (Pull Requests)
3434

3535
We welcome pull requests for bug fixes and new features.
3636

DEPLOYMENT.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Deployment Guide
2+
3+
This guide explains how to deploy the demo application to GitHub Pages using GitHub Actions.
4+
5+
## Prerequisites
6+
7+
1. GitHub repository with GitHub Pages enabled
8+
2. GitHub Actions enabled in your repository
9+
10+
## Setup GitHub Pages
11+
12+
1. Go to your repository **Settings****Pages**
13+
2. Under **Source**, select **GitHub Actions**
14+
3. Save the settings
15+
16+
## Automatic Deployment
17+
18+
The demo is automatically deployed when you push to the `main` or `master` branch.
19+
20+
### Workflow File
21+
22+
The deployment workflow is located at `.github/workflows/deploy-demo.yml`
23+
24+
### Manual Deployment
25+
26+
You can also trigger the deployment manually:
27+
28+
1. Go to **Actions** tab in your repository
29+
2. Select **Deploy Demo to GitHub Pages**
30+
3. Click **Run workflow**
31+
4. Select the branch and click **Run workflow**
32+
33+
## Build Configuration
34+
35+
The workflow:
36+
1. Installs dependencies
37+
2. Builds the library (`ngxsmk-tel-input`)
38+
3. Builds the demo application with the correct `base-href`
39+
4. Deploys to GitHub Pages
40+
41+
### Base Href
42+
43+
The `base-href` is automatically set based on your repository name:
44+
- Repository: `owner/ngxsmk-tel-input` → Base href: `/ngxsmk-tel-input/`
45+
46+
If your repository name is different, update the workflow file:
47+
```yaml
48+
--base-href /your-repo-name/
49+
```
50+
51+
## Custom Domain
52+
53+
If you're using a custom domain:
54+
55+
1. Update the `base-href` in the workflow to `/`
56+
2. Configure your custom domain in **Settings****Pages****Custom domain**
57+
58+
## Troubleshooting
59+
60+
### Build Fails
61+
62+
- Check Node.js version (should be 20)
63+
- Verify all dependencies are in `package.json`
64+
- Check build logs in GitHub Actions
65+
66+
### Pages Not Updating
67+
68+
- Ensure GitHub Pages is set to use **GitHub Actions** as source
69+
- Check workflow run status in **Actions** tab
70+
- Verify the deployment job completed successfully
71+
72+
### 404 Errors
73+
74+
- Verify the `base-href` matches your repository name
75+
- Check that routes are configured correctly in Angular
76+
- Ensure `index.html` has the correct `<base href>` tag
77+
78+
## Local Testing
79+
80+
Test the production build locally:
81+
82+
```bash
83+
# Build with production config
84+
npm run build:demo
85+
86+
# Serve the built files (requires a local server)
87+
npx http-server dist/demo/browser -p 4200
88+
```
89+
90+
Visit `http://localhost:4200` to verify the build works correctly.
91+
92+
## Environment Variables
93+
94+
No environment variables are required for basic deployment. If you need to add environment-specific configurations, add them to the workflow file.
95+

README.md

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,65 @@
11
# ngxsmk-tel-input
22

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`.
55

66
> Emits **E.164** by default (e.g. `+14155550123`). SSR‑safe via lazy browser‑only import.
77
8-
## 🚀 Try it live on StackBlitz
8+
## Try it live on StackBlitz
99

1010
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/~/github.com/toozuuu/ngxsmk-tel-input)
1111

1212
---
1313

14-
## Features
14+
## Features
1515

1616
* Country dropdown with flags
1717
* E.164 output (display can be national with `nationalMode`)
1818
* Reactive & template‑driven Forms support (CVA)
1919
* Built‑in validation using libphonenumber‑js
2020
* **Enhanced validation**: Detects invalid country codes (like "11", "99") and shows appropriate error states
2121
* **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
2323
* **Accessibility**: Full ARIA support, screen reader compatibility, keyboard navigation
2424
* SSR‑friendly (no `window` on the server)
2525
* Easy theming via CSS variables
2626
* Nice UX options: label/hint/error text, sizes, variants, clear button, autofocus, select-on-focus
2727
* Masking & caret-friendly as-you-type formatting (optional)
2828
* Format only when valid (formatWhenValid) and lock once valid (lockWhenValid) to prevent extra digits
2929

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+
3039
---
3140

32-
## Requirements
41+
## Requirements
3342

3443
* Angular **17+** (17, 18, 19, 20, 21+)
3544
* Node **18** or **20**
3645

3746
> Library `peerDependencies` target Angular `>=17`. Fully compatible with Angular 17, 18, 19, 20, 21, and future versions.
3847
39-
### 🔄 Zone.js Compatibility
48+
### Zone.js Compatibility
4049

4150
This component works seamlessly with **both Zone.js and zoneless Angular**:
4251

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+)
4857

4958
The component automatically detects whether Zone.js is available and adapts its change detection strategy accordingly.
5059

5160
---
5261

53-
## 📦 Install
62+
## Install
5463

5564
```bash
5665
npm i ngxsmk-tel-input intl-tel-input libphonenumber-js
@@ -110,7 +119,7 @@ Ensure your app includes a proper viewport meta tag:
110119

111120
---
112121

113-
## 🚀 Quick start (Reactive Forms)
122+
## Quick start (Reactive Forms)
114123

115124
```ts
116125
// app.component.ts
@@ -171,7 +180,7 @@ export class AppComponent {
171180

172181
---
173182

174-
## 📝 Template‑driven usage
183+
## Template‑driven usage
175184

176185
```html
177186
<form #f="ngForm">
@@ -182,7 +191,7 @@ export class AppComponent {
182191

183192
---
184193

185-
## 🈺 Localization & RTL
194+
## Localization & RTL
186195

187196
You can localize the dropdown/search labels and override country names.
188197

@@ -232,7 +241,7 @@ Arabic + RTL example
232241
```
233242

234243

235-
## ️ API
244+
## ️ API
236245

237246
### Inputs
238247

@@ -278,15 +287,18 @@ Arabic + RTL example
278287
| `countryChange` | `{ iso2: CountryCode }` | Fired when selected country changes. |
279288
| `validityChange` | `boolean` | Fired when validity flips. |
280289
| `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). |
281291

282292
### Public methods
283293

284294
* `focus(): void`
285295
* `selectCountry(iso2: CountryCode): void`
286296

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+
287299
---
288300

289-
## 🧠 Formatting & validity behavior
301+
## Formatting & validity behavior
290302

291303
* No formatting while invalid. As-you-type masking only starts when the digits form a valid number for the selected country.
292304

@@ -299,7 +311,7 @@ For rare patterns not covered by libphonenumber-js, the control falls back to ra
299311
---
300312

301313

302-
## 🎨 Theming
314+
## Theming
303315

304316
### CSS Variables
305317

@@ -353,7 +365,7 @@ Dark mode: wrap in a `.dark` parent or use `[theme]="'dark'"` — tokens adapt a
353365

354366
---
355367

356-
## ️ Validation patterns
368+
## ️ Validation patterns
357369

358370
```html
359371
<ngxsmk-tel-input formControlName="phone"></ngxsmk-tel-input>
@@ -389,14 +401,14 @@ The component now includes enhanced validation that detects and handles various
389401
390402
---
391403

392-
## 🌐 SSR notes
404+
## SSR notes
393405

394406
* The library lazy‑imports `intl-tel-input` only in the **browser** (guards with `isPlatformBrowser`).
395407
* No `window`/`document` usage on the server path.
396408

397409
---
398410

399-
## 🧪 Local development
411+
## Local development
400412

401413
This repo is an Angular workspace with a library.
402414

@@ -417,7 +429,7 @@ npm i ../path-to-workspace/dist/ngxsmk-tel-input/ngxsmk-tel-input-<version>.tgz
417429
418430
---
419431

420-
## 🧯 Troubleshooting
432+
## Troubleshooting
421433

422434
**UI looks unstyled / bullets in dropdown**
423435
Add the CSS and assets in `angular.json` (see Install). Restart the dev server.
@@ -436,13 +448,13 @@ Clear `.angular/cache`, rebuild the lib, and restart `ng serve`.
436448

437449
---
438450

439-
## 📃 License
451+
## License
440452

441453
[MIT](./LICENSE)
442454

443-
## 🙌 Credits
455+
## Credits
444456

445457
* UI powered by [`intl-tel-input`](https://github.com/jackocnr/intl-tel-input)
446458
* Parsing & validation by [`libphonenumber-js`](https://github.com/catamphetamine/libphonenumber-js)
447459

448-
Last updated: 2025-01-21
460+
Last updated: 2026-05-01

0 commit comments

Comments
 (0)