Skip to content

Commit 794f5cc

Browse files
committed
feat: Drop @input in favor of signals
1 parent 1ca4a59 commit 794f5cc

File tree

5 files changed

+48
-46
lines changed

5 files changed

+48
-46
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## v0.15.0
4+
5+
- Drop `@Input` in favor of `signals`.
6+
37
## v0.14.0
48

59
- `angular 19` migration.

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ $ npm install intl-tel-input-ng --save / yarn add intl-tel-input-ng
3131

3232
- Add `node_modules/intl-tel-input/build/js/utils.js` to the `scripts` section in your `angular.json`.
3333
- Add `node_modules/intl-tel-input/build/css/intlTelInput.css` to the `styles` section in your `angular.json`.
34-
- Import ``IntlTelInputNgModule.forRoot()`` in your main application module.
3534

3635
## Options
3736
- `options`: An object wrapping the `intl-tel-input` [options](https://github.com/jackocnr/intl-tel-input#options).

src/lib/components/intl-tel-input.component.html

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
@if (label && name) {
2-
<label [attr.for]="name" [ngClass]="labelCssClass" >{{ label }}</label>
1+
@if (label() && name()) {
2+
<label [attr.for]="name()" [ngClass]="labelCssClass()" >{{ label() }}</label>
33
}
44
<input
55
type="text"
6-
[ngClass]="cssClass"
7-
[attr.id]="name"
8-
[attr.name]="name"
9-
[name]="name"
10-
[attr.aria-required]="required || null"
11-
[required]="required"
6+
[ngClass]="cssClass()"
7+
[attr.id]="name()"
8+
[attr.name]="name()"
9+
[name]="name()"
10+
[attr.aria-required]="required() || null"
11+
[required]="required()"
1212
[(ngModel)]="phoneNumber"
1313
(countrychange)="i18nizePhoneNumber()"
1414
#intlTelInput>

src/lib/components/intl-tel-input.component.spec.ts

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -40,37 +40,37 @@ describe('IntlTelInputComponent', () => {
4040
});
4141

4242
it('should convert phone number to E164 format', () => {
43-
component.options = {
43+
component.options.set({
4444
preferredCountries: ['ch'],
4545
onlyCountries: ['ch', 'fr']
46-
};
46+
});
4747
component.ngAfterViewInit();
4848

4949
component.phoneNumber = '0797703808';
5050

51-
expect(component.E164PhoneNumber).toBe('+41797703808');
51+
expect(component.E164PhoneNumber()).toBe('+41797703808');
5252
});
5353

5454
it('should re-set E164 phone number on countryChange', () => {
55-
component.options = {
55+
component.options.set({
5656
preferredCountries: ['ch'],
5757
onlyCountries: ['ch', 'fr']
58-
};
58+
});
5959
component.ngAfterViewInit();
6060

6161
component.phoneNumber = '0797703808';
6262

63-
expect(component.E164PhoneNumber).toBe('+41797703808');
63+
expect(component.E164PhoneNumber()).toBe('+41797703808');
6464

6565
component.phoneNumber = '0681215656';
6666
component.intlTelInput.setCountry('fr');
6767

68-
expect(component.E164PhoneNumber).toBe('+33681215656');
68+
expect(component.E164PhoneNumber()).toBe('+33681215656');
6969
});
7070

7171
it('should add a label tag if label attribute is set', () => {
7272
const labelText = 'label text';
73-
component.label = labelText;
73+
component.label.set(labelText);
7474
fixture.detectChanges();
7575

7676
const element = fixture
@@ -91,7 +91,7 @@ describe('IntlTelInputComponent', () => {
9191
});
9292

9393
it('should not have a css class by default for the label', () => {
94-
component.label = 'label';
94+
component.label.set('label');
9595
fixture.detectChanges();
9696

9797
const element = fixture
@@ -103,20 +103,20 @@ describe('IntlTelInputComponent', () => {
103103
});
104104

105105
it('should be possible to specify a css class for the label', () => {
106-
component.label = 'label';
107-
component.labelCssClass = 'label-css-class';
106+
component.label.set('label');
107+
component.labelCssClass.set('label-css-class');
108108
fixture.detectChanges();
109109

110110
const element = fixture
111111
.debugElement
112112
.query(By.css('label'))
113113
.nativeElement;
114114

115-
expect(element.className).toContain(component.labelCssClass);
115+
expect(element.className).toContain(component.labelCssClass());
116116
});
117117

118118
it('should set both required and aria-required if specified', () => {
119-
component.required = true;
119+
component.required.set(true);
120120
fixture.detectChanges();
121121

122122
const element: HTMLElement = fixture
@@ -134,26 +134,26 @@ describe('IntlTelInputComponent', () => {
134134
.query(By.css('input'))
135135
.nativeElement;
136136

137-
expect(element.getAttribute('name')).toBe(component.name);
137+
expect(element.getAttribute('name')).toBe(component.name());
138138
expect(element.getAttribute('name')).toBe(element.getAttribute('id'));
139139
});
140140

141141
it('should set name and id to the same value', () => {
142-
component.name = 'custom-name';
142+
component.name.set('custom-name');
143143
fixture.detectChanges();
144144

145145
const element: HTMLElement = fixture
146146
.debugElement
147147
.query(By.css('input'))
148148
.nativeElement;
149-
150-
expect(element.getAttribute('name')).toBe(component.name);
149+
console.log(component.name());
150+
expect(element.getAttribute('name')).toBe(component.name());
151151
expect(element.getAttribute('name')).toBe(element.getAttribute('id'));
152152
});
153153

154154
it('should allow specifying a css class', () => {
155155
const cssClass = 'my-css-class';
156-
component.cssClass = cssClass;
156+
component.cssClass.set(cssClass);
157157
fixture.detectChanges();
158158

159159
const element: HTMLElement = fixture
@@ -165,32 +165,33 @@ describe('IntlTelInputComponent', () => {
165165
});
166166

167167
it('should be possible to set preferredCountries option', () => {
168-
component.options = {
168+
component.options.set({
169169
countrySearch: false,
170170
preferredCountries: ['ch'],
171171
onlyCountries: ['ch']
172-
};
172+
});
173173
component.ngAfterViewInit();
174174

175175
fixture.detectChanges();
176-
176+
console.log(fixture
177+
.debugElement);
177178
const element = fixture
178179
.debugElement
179180
.query(By.css('#intl-tel-input-name'))
180181
.nativeElement
181182
.parentNode
182183
.querySelector('.iti__preferred');
183184

184-
expect(element.getAttribute('data-country-code')).toBe(component.options.onlyCountries?.[0]);
185+
expect(element.getAttribute('data-country-code')).toBe(component.options().onlyCountries?.[0]);
185186
});
186187

187188
it('should be possible to set i18n option', () => {
188189
const localizedCountryName = 'Suisse';
189-
component.options = {
190+
component.options.set({
190191
preferredCountries: ['ch'],
191192
i18n: { ch: localizedCountryName },
192193
onlyCountries: ['ch']
193-
};
194+
});
194195
component.ngAfterViewInit();
195196

196197
fixture.detectChanges();

src/lib/components/intl-tel-input.component.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
88
*/
99

10-
import { AfterViewInit, Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core';
10+
import { AfterViewInit, Component, ElementRef, model, ViewChild } from '@angular/core';
1111
import { ControlContainer, FormsModule, NgForm } from '@angular/forms';
1212
import intlTelInput from 'intl-tel-input';
1313
import { IntlTelInputOptions } from '../model/intl-tel-input-options';
@@ -24,21 +24,20 @@ import { NgClass } from "@angular/common";
2424
})
2525
export class IntlTelInputComponent implements AfterViewInit {
2626

27-
@Input() cssClass!: string;
28-
@Input() E164PhoneNumber!: string | null;
29-
@Input() label!: string;
30-
@Input() labelCssClass!: string;
31-
@Input() name = 'intl-tel-input-name';
32-
@Input() options: IntlTelInputOptions = {};
33-
@Input() required!: boolean;
34-
@Output() private E164PhoneNumberChange = new EventEmitter<string | null>();
27+
cssClass = model<string>();
28+
label = model<string>();
29+
labelCssClass = model<string>();
30+
name = model<string>('intl-tel-input-name');
31+
options = model<IntlTelInputOptions>({});
32+
required = model<boolean>(false);
33+
E164PhoneNumber = model<string | null>();
3534
@ViewChild('intlTelInput') private _inputElement!: ElementRef;
3635
private _phoneNumber!: string;
3736
private _intlTelInput!: IntlTelInput;
3837

3938
ngAfterViewInit(): void {
4039
const intlTelInputInstance = intlTelInput;
41-
this._intlTelInput = intlTelInputInstance(this._inputElement.nativeElement, this.options);
40+
this._intlTelInput = intlTelInputInstance(this._inputElement.nativeElement, this.options());
4241
}
4342

4443
get intlTelInput(): IntlTelInput {
@@ -58,10 +57,9 @@ export class IntlTelInputComponent implements AfterViewInit {
5857
}
5958

6059
i18nizePhoneNumber(): void {
61-
this.E164PhoneNumber = null;
60+
this.E164PhoneNumber.set(null);
6261
if (this._intlTelInput.isValidNumber()) {
63-
this.E164PhoneNumber = this._intlTelInput.getNumber();
62+
this.E164PhoneNumber.set(this._intlTelInput.getNumber());
6463
}
65-
this.E164PhoneNumberChange.emit(this.E164PhoneNumber);
6664
}
6765
}

0 commit comments

Comments
 (0)