Skip to content

Commit 7798bb7

Browse files
authored
docs(material/chips): clean up forms examples (#33185)
Cleans up the examples showing how to use chips with the forms module so that they have a single source of truth and better match our coding standards. Fixes #33179.
1 parent 75511d8 commit 7798bb7

5 files changed

Lines changed: 48 additions & 53 deletions

File tree

src/components-examples/material/chips/chips-reactive-form/chips-reactive-form-example.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ <h4>Chips inside of a Reactive form</h4>
33
<mat-form-field class="example-form-field">
44
<mat-label>Video keywords</mat-label>
55
<mat-chip-grid #reactiveChipGrid aria-label="Enter reactive form keywords" [formControl]="formControl">
6-
@for (keyword of reactiveKeywords(); track keyword) {
7-
<mat-chip-row (removed)="removeReactiveKeyword(keyword)">
6+
@for (keyword of formControl.value; track keyword) {
7+
<mat-chip-row (removed)="removeKeyword(keyword)">
88
{{keyword}}
99
<button matChipRemove [attr.aria-label]="'remove reactive form' + keyword">
1010
<mat-icon>cancel</mat-icon>
@@ -15,7 +15,7 @@ <h4>Chips inside of a Reactive form</h4>
1515
<input
1616
placeholder="New keyword..."
1717
[matChipInputFor]="reactiveChipGrid"
18-
(matChipInputTokenEnd)="addReactiveKeyword($event)"
18+
(matChipInputTokenEnd)="addKeyword($event)"
1919
/>
2020
</mat-form-field>
2121
</section>
Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {LiveAnnouncer} from '@angular/cdk/a11y';
2-
import {ChangeDetectionStrategy, Component, inject, signal} from '@angular/core';
2+
import {ChangeDetectionStrategy, Component, inject} from '@angular/core';
33
import {FormControl, ReactiveFormsModule} from '@angular/forms';
44
import {MatButtonModule} from '@angular/material/button';
55
import {MatChipInputEvent, MatChipsModule} from '@angular/material/chips';
@@ -23,34 +23,31 @@ import {MatIconModule} from '@angular/material/icon';
2323
changeDetection: ChangeDetectionStrategy.OnPush,
2424
})
2525
export class ChipsReactiveFormExample {
26-
readonly reactiveKeywords = signal(['angular', 'how-to', 'tutorial', 'accessibility']);
27-
readonly formControl = new FormControl(['angular']);
26+
private _announcer = inject(LiveAnnouncer);
2827

29-
announcer = inject(LiveAnnouncer);
28+
readonly formControl = new FormControl(['angular', 'how-to', 'tutorial', 'accessibility'], {
29+
nonNullable: true,
30+
});
3031

31-
removeReactiveKeyword(keyword: string) {
32-
this.reactiveKeywords.update(keywords => {
33-
const index = keywords.indexOf(keyword);
34-
if (index < 0) {
35-
return keywords;
36-
}
37-
38-
keywords.splice(index, 1);
39-
this.announcer.announce(`removed ${keyword} from reactive form`);
40-
return [...keywords];
41-
});
42-
}
43-
44-
addReactiveKeyword(event: MatChipInputEvent): void {
32+
addKeyword(event: MatChipInputEvent): void {
4533
const value = (event.value || '').trim();
4634

47-
// Add our keyword
4835
if (value) {
49-
this.reactiveKeywords.update(keywords => [...keywords, value]);
50-
this.announcer.announce(`added ${value} to reactive form`);
36+
this.formControl.setValue([...this.formControl.value, value]);
37+
this._announcer.announce(`added ${value} to reactive form`);
5138
}
5239

53-
// Clear the input value
54-
event.chipInput!.clear();
40+
event.chipInput.clear();
41+
}
42+
43+
removeKeyword(keyword: string) {
44+
const keywords = this.formControl.value;
45+
const index = keywords.lastIndexOf(keyword);
46+
47+
if (index > -1) {
48+
keywords.splice(index, 1);
49+
this.formControl.setValue([...keywords]);
50+
this._announcer.announce(`removed ${keyword} from reactive form`);
51+
}
5552
}
5653
}

src/components-examples/material/chips/chips-template-form/chips-template-form-example.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
<h4>Chips inside of a Template-driven form</h4>
33
<mat-form-field class="example-form-field">
44
<mat-label>Video keywords</mat-label>
5-
<mat-chip-grid #templateChipGrid aria-label="Enter template form keywords" [(ngModel)]="templateKeywords">
6-
@for (keyword of templateKeywords(); track keyword) {
7-
<mat-chip-row (removed)="removeTemplateKeyword(keyword)">
5+
<mat-chip-grid #templateChipGrid aria-label="Enter template form keywords" [(ngModel)]="keywords">
6+
@for (keyword of keywords(); track keyword) {
7+
<mat-chip-row (removed)="removeKeyword(keyword)">
88
{{keyword}}
99
<button matChipRemove [attr.aria-label]="'remove template form' + keyword">
1010
<mat-icon>cancel</mat-icon>
@@ -15,7 +15,7 @@ <h4>Chips inside of a Template-driven form</h4>
1515
<input
1616
placeholder="New keyword..."
1717
[matChipInputFor]="templateChipGrid"
18-
(matChipInputTokenEnd)="addTemplateKeyword($event)"
18+
(matChipInputTokenEnd)="addKeyword($event)"
1919
/>
2020
</mat-form-field>
2121
</section>

src/components-examples/material/chips/chips-template-form/chips-template-form-example.ts

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,33 +17,30 @@ import {MatIconModule} from '@angular/material/icon';
1717
changeDetection: ChangeDetectionStrategy.OnPush,
1818
})
1919
export class ChipsTemplateFormExample {
20-
readonly templateKeywords = signal(['angular', 'how-to', 'tutorial', 'accessibility']);
20+
private _announcer = inject(LiveAnnouncer);
21+
readonly keywords = signal(['angular', 'how-to', 'tutorial', 'accessibility']);
2122

22-
announcer = inject(LiveAnnouncer);
23+
addKeyword(event: MatChipInputEvent): void {
24+
const value = (event.value || '').trim();
25+
26+
if (value) {
27+
this.keywords.update(keywords => [...keywords, value]);
28+
this._announcer.announce(`added ${value} to template form`);
29+
}
2330

24-
removeTemplateKeyword(keyword: string) {
25-
this.templateKeywords.update(keywords => {
31+
event.chipInput.clear();
32+
}
33+
34+
removeKeyword(keyword: string) {
35+
this.keywords.update(keywords => {
2636
const index = keywords.indexOf(keyword);
2737
if (index < 0) {
2838
return keywords;
2939
}
3040

3141
keywords.splice(index, 1);
32-
this.announcer.announce(`removed ${keyword} from template form`);
42+
this._announcer.announce(`removed ${keyword} from template form`);
3343
return [...keywords];
3444
});
3545
}
36-
37-
addTemplateKeyword(event: MatChipInputEvent): void {
38-
const value = (event.value || '').trim();
39-
40-
// Add our keyword
41-
if (value) {
42-
this.templateKeywords.update(keywords => [...keywords, value]);
43-
this.announcer.announce(`added ${value} to template form`);
44-
}
45-
46-
// Clear the input value
47-
event.chipInput!.clear();
48-
}
4946
}

src/material/tooltip/tooltip.spec.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,24 +1270,25 @@ describe('MatTooltip', () => {
12701270
platform.ANDROID = true;
12711271
});
12721272

1273-
it('should have a delay when showing on touchstart', async () => {
1273+
// Note: switching this test away from `fakeAsync` causes it to fail only on CI.
1274+
it('should have a delay when showing on touchstart', fakeAsync(() => {
12741275
const fixture = TestBed.createComponent(BasicTooltipDemo);
12751276
fixture.detectChanges();
12761277
const button: HTMLButtonElement = fixture.nativeElement.querySelector('button');
12771278

12781279
dispatchFakeEvent(button, 'touchstart');
12791280
fixture.detectChanges();
1280-
await wait(250); // Halfway through the delay.
1281+
tick(250); // Halfway through the delay.
12811282

12821283
assertTooltipInstance(fixture.componentInstance.tooltip, false);
12831284

1284-
await wait(600); // Finish the delay.
1285+
tick(500); // Finish the delay.
12851286
fixture.detectChanges();
1286-
await fixture.whenStable();
12871287
finishCurrentTooltipAnimation(overlayContainerElement, true); // Finish the animation.
12881288

12891289
assertTooltipInstance(fixture.componentInstance.tooltip, true);
1290-
});
1290+
flush();
1291+
}));
12911292

12921293
it('should be able to disable opening on touch', async () => {
12931294
const fixture = TestBed.createComponent(BasicTooltipDemo);

0 commit comments

Comments
 (0)