Skip to content

Commit d91dda0

Browse files
committed
docs(material/chips): Update chips docs & examples
1 parent 3b32d0e commit d91dda0

File tree

16 files changed

+174
-155
lines changed

16 files changed

+174
-155
lines changed

src/components-examples/material/chips/chips-autocomplete/chips-autocomplete-example.html

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<mat-form-field class="example-chip-list">
33
<mat-label>Favorite Fruits</mat-label>
44
<mat-chip-grid #chipGrid aria-label="Fruit selection">
5-
@for (fruit of fruits; track fruit) {
5+
@for (fruit of fruits(); track $index) {
66
<mat-chip-row (removed)="remove(fruit)">
77
{{fruit}}
88
<button matChipRemove [attr.aria-label]="'remove ' + fruit">
@@ -11,12 +11,18 @@
1111
</mat-chip-row>
1212
}
1313
</mat-chip-grid>
14-
<input placeholder="New Fruit..." #fruitInput [formControl]="fruitCtrl"
15-
[matChipInputFor]="chipGrid" [matAutocomplete]="auto"
14+
<input
15+
name="currentFruit"
16+
placeholder="New Fruit..."
17+
#fruitInput
18+
[(ngModel)]="currentFruit"
19+
[matChipInputFor]="chipGrid"
20+
[matAutocomplete]="auto"
1621
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
17-
(matChipInputTokenEnd)="add($event)"/>
22+
(matChipInputTokenEnd)="add($event)"
23+
/>
1824
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
19-
@for (fruit of filteredFruits | async; track fruit) {
25+
@for (fruit of filteredFruits(); track fruit) {
2026
<mat-option [value]="fruit">{{fruit}}</mat-option>
2127
}
2228
</mat-autocomplete>
Lines changed: 31 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1+
import {LiveAnnouncer} from '@angular/cdk/a11y';
12
import {COMMA, ENTER} from '@angular/cdk/keycodes';
2-
import {Component, ElementRef, ViewChild, inject} from '@angular/core';
3-
import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms';
4-
import {MatAutocompleteSelectedEvent, MatAutocompleteModule} from '@angular/material/autocomplete';
3+
import {ChangeDetectionStrategy, Component, computed, inject, model, signal} from '@angular/core';
4+
import {FormsModule} from '@angular/forms';
5+
import {MatAutocompleteModule, MatAutocompleteSelectedEvent} from '@angular/material/autocomplete';
56
import {MatChipInputEvent, MatChipsModule} from '@angular/material/chips';
6-
import {Observable} from 'rxjs';
7-
import {map, startWith} from 'rxjs/operators';
8-
import {MatIconModule} from '@angular/material/icon';
9-
import {AsyncPipe} from '@angular/common';
107
import {MatFormFieldModule} from '@angular/material/form-field';
11-
import {LiveAnnouncer} from '@angular/cdk/a11y';
8+
import {MatIconModule} from '@angular/material/icon';
129

1310
/**
1411
* @title Chips Autocomplete
@@ -18,67 +15,51 @@ import {LiveAnnouncer} from '@angular/cdk/a11y';
1815
templateUrl: 'chips-autocomplete-example.html',
1916
styleUrl: 'chips-autocomplete-example.css',
2017
standalone: true,
21-
imports: [
22-
FormsModule,
23-
MatFormFieldModule,
24-
MatChipsModule,
25-
MatIconModule,
26-
MatAutocompleteModule,
27-
ReactiveFormsModule,
28-
AsyncPipe,
29-
],
18+
imports: [MatFormFieldModule, MatChipsModule, MatIconModule, MatAutocompleteModule, FormsModule],
19+
changeDetection: ChangeDetectionStrategy.OnPush,
3020
})
3121
export class ChipsAutocompleteExample {
32-
separatorKeysCodes: number[] = [ENTER, COMMA];
33-
fruitCtrl = new FormControl('');
34-
filteredFruits: Observable<string[]>;
35-
fruits: string[] = ['Lemon'];
36-
allFruits: string[] = ['Apple', 'Lemon', 'Lime', 'Orange', 'Strawberry'];
22+
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
23+
readonly currentFruit = model('');
24+
readonly fruits = signal(['Lemon']);
25+
readonly allFruits: string[] = ['Apple', 'Lemon', 'Lime', 'Orange', 'Strawberry'];
26+
readonly filteredFruits = computed(() => {
27+
const currentFruit = this.currentFruit().toLowerCase();
28+
return currentFruit
29+
? this.allFruits.filter(fruit => fruit.toLowerCase().includes(currentFruit))
30+
: this.allFruits.slice();
31+
});
3732

38-
@ViewChild('fruitInput') fruitInput: ElementRef<HTMLInputElement>;
39-
40-
announcer = inject(LiveAnnouncer);
41-
42-
constructor() {
43-
this.filteredFruits = this.fruitCtrl.valueChanges.pipe(
44-
startWith(null),
45-
map((fruit: string | null) => (fruit ? this._filter(fruit) : this.allFruits.slice())),
46-
);
47-
}
33+
readonly announcer = inject(LiveAnnouncer);
4834

4935
add(event: MatChipInputEvent): void {
5036
const value = (event.value || '').trim();
5137

5238
// Add our fruit
5339
if (value) {
54-
this.fruits.push(value);
40+
this.fruits.update(fruits => [...fruits, value]);
5541
}
5642

5743
// Clear the input value
58-
event.chipInput!.clear();
59-
60-
this.fruitCtrl.setValue(null);
44+
this.currentFruit.set('');
6145
}
6246

6347
remove(fruit: string): void {
64-
const index = this.fruits.indexOf(fruit);
65-
66-
if (index >= 0) {
67-
this.fruits.splice(index, 1);
48+
this.fruits.update(fruits => {
49+
const index = fruits.indexOf(fruit);
50+
if (index < 0) {
51+
return fruits;
52+
}
6853

54+
fruits.splice(index, 1);
6955
this.announcer.announce(`Removed ${fruit}`);
70-
}
56+
return [...fruits];
57+
});
7158
}
7259

7360
selected(event: MatAutocompleteSelectedEvent): void {
74-
this.fruits.push(event.option.viewValue);
75-
this.fruitInput.nativeElement.value = '';
76-
this.fruitCtrl.setValue(null);
77-
}
78-
79-
private _filter(value: string): string[] {
80-
const filterValue = value.toLowerCase();
81-
82-
return this.allFruits.filter(fruit => fruit.toLowerCase().includes(filterValue));
61+
this.fruits.update(fruits => [...fruits, event.option.viewValue]);
62+
this.currentFruit.set('');
63+
event.option.deselect();
8364
}
8465
}
Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,26 @@
11
<mat-chip-set aria-label="Dog selection">
22
<mat-chip>
3-
<img matChipAvatar src="https://material.angular.io/assets/img/examples/shiba1.jpg" alt="Photo of a Shiba Inu"/>
3+
<img
4+
matChipAvatar
5+
src="https://material.angular.io/assets/img/examples/shiba1.jpg"
6+
alt="Photo of a Shiba Inu"
7+
/>
48
Dog one
59
</mat-chip>
6-
<mat-chip color="primary">
7-
<img matChipAvatar src="https://material.angular.io/assets/img/examples/shiba1.jpg" alt="Photo of a Shiba Inu"/>
10+
<mat-chip>
11+
<img
12+
matChipAvatar
13+
src="https://material.angular.io/assets/img/examples/shiba1.jpg"
14+
alt="Photo of a Shiba Inu"
15+
/>
816
Dog two
917
</mat-chip>
10-
<mat-chip color="accent">
11-
<img matChipAvatar src="https://material.angular.io/assets/img/examples/shiba1.jpg" alt="Photo of a Shiba Inu"/>
18+
<mat-chip>
19+
<img
20+
matChipAvatar
21+
src="https://material.angular.io/assets/img/examples/shiba1.jpg"
22+
alt="Photo of a Shiba Inu"
23+
/>
1224
Dog three
1325
</mat-chip>
1426
</mat-chip-set>

src/components-examples/material/chips/chips-avatar/chips-avatar-example.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Component} from '@angular/core';
1+
import {ChangeDetectionStrategy, Component} from '@angular/core';
22
import {MatChipsModule} from '@angular/material/chips';
33

44
/**
@@ -11,5 +11,6 @@ import {MatChipsModule} from '@angular/material/chips';
1111
styleUrl: 'chips-avatar-example.css',
1212
standalone: true,
1313
imports: [MatChipsModule],
14+
changeDetection: ChangeDetectionStrategy.OnPush,
1415
})
1516
export class ChipsAvatarExample {}

src/components-examples/material/chips/chips-drag-drop/chips-drag-drop-example.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
class="example-chip"
33
cdkDropList
44
cdkDropListOrientation="horizontal"
5-
(cdkDropListDropped)="drop($event)">
6-
@for (vegetable of vegetables; track vegetable) {
5+
(cdkDropListDropped)="drop($event)"
6+
>
7+
@for (vegetable of vegetables(); track vegetable.name) {
78
<mat-chip class="example-box" cdkDrag>{{vegetable.name}}</mat-chip>
89
}
910
</mat-chip-set>

src/components-examples/material/chips/chips-drag-drop/chips-drag-drop-example.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import {Component} from '@angular/core';
2-
import {CdkDragDrop, moveItemInArray, CdkDrag, CdkDropList} from '@angular/cdk/drag-drop';
1+
import {CdkDrag, CdkDragDrop, CdkDropList, moveItemInArray} from '@angular/cdk/drag-drop';
2+
import {ChangeDetectionStrategy, Component, signal} from '@angular/core';
33
import {MatChipsModule} from '@angular/material/chips';
44

55
export interface Vegetable {
@@ -15,18 +15,22 @@ export interface Vegetable {
1515
styleUrl: 'chips-drag-drop-example.css',
1616
standalone: true,
1717
imports: [MatChipsModule, CdkDropList, CdkDrag],
18+
changeDetection: ChangeDetectionStrategy.OnPush,
1819
})
1920
export class ChipsDragDropExample {
20-
vegetables: Vegetable[] = [
21+
readonly vegetables = signal<Vegetable[]>([
2122
{name: 'apple'},
2223
{name: 'banana'},
2324
{name: 'strawberry'},
2425
{name: 'orange'},
2526
{name: 'kiwi'},
2627
{name: 'cherry'},
27-
];
28+
]);
2829

2930
drop(event: CdkDragDrop<Vegetable[]>) {
30-
moveItemInArray(this.vegetables, event.previousIndex, event.currentIndex);
31+
this.vegetables.update(vegetables => {
32+
moveItemInArray(vegetables, event.previousIndex, event.currentIndex);
33+
return [...vegetables];
34+
});
3135
}
3236
}

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
</p>
88
<mat-form-field class="example-form-field">
99
<mat-label>Video keywords</mat-label>
10-
<mat-chip-grid #chipGrid aria-label="Enter keywords" [formControl]="formControl" >
11-
@for (keyword of keywords; track keyword) {
10+
<mat-chip-grid #chipGrid aria-label="Enter keywords" [formControl]="formControl">
11+
@for (keyword of keywords(); track keyword) {
1212
<mat-chip-row (removed)="removeKeyword(keyword)">
1313
{{keyword}}
1414
<button matChipRemove aria-label="'remove ' + keyword">
@@ -17,11 +17,11 @@
1717
</mat-chip-row>
1818
}
1919
</mat-chip-grid>
20-
<input placeholder="New keyword..."
21-
[matChipInputFor]="chipGrid"
22-
(matChipInputTokenEnd)="add($event)"/>
20+
<input
21+
placeholder="New keyword..."
22+
[matChipInputFor]="chipGrid"
23+
(matChipInputTokenEnd)="add($event)"
24+
/>
2325
</mat-form-field>
2426

25-
<p>
26-
<strong>The following keywords are entered:</strong> {{formControl.value}}
27-
</p>
27+
<p><strong>The following keywords are entered:</strong> {{formControl.value}}</p>

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

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import {Component, inject} from '@angular/core';
1+
import {LiveAnnouncer} from '@angular/cdk/a11y';
2+
import {ChangeDetectionStrategy, Component, inject, signal} from '@angular/core';
23
import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms';
4+
import {MatButtonModule} from '@angular/material/button';
35
import {MatChipInputEvent, MatChipsModule} from '@angular/material/chips';
4-
import {MatIconModule} from '@angular/material/icon';
56
import {MatFormFieldModule} from '@angular/material/form-field';
6-
import {MatButtonModule} from '@angular/material/button';
7-
import {LiveAnnouncer} from '@angular/cdk/a11y';
7+
import {MatIconModule} from '@angular/material/icon';
88

99
/**
1010
* @title Chips with form control
@@ -22,28 +22,33 @@ import {LiveAnnouncer} from '@angular/cdk/a11y';
2222
ReactiveFormsModule,
2323
MatIconModule,
2424
],
25+
changeDetection: ChangeDetectionStrategy.OnPush,
2526
})
2627
export class ChipsFormControlExample {
27-
keywords = ['angular', 'how-to', 'tutorial', 'accessibility'];
28-
formControl = new FormControl(['angular']);
28+
readonly keywords = signal(['angular', 'how-to', 'tutorial', 'accessibility']);
29+
readonly formControl = new FormControl(['angular']);
2930

3031
announcer = inject(LiveAnnouncer);
3132

3233
removeKeyword(keyword: string) {
33-
const index = this.keywords.indexOf(keyword);
34-
if (index >= 0) {
35-
this.keywords.splice(index, 1);
34+
this.keywords.update(keywords => {
35+
const index = keywords.indexOf(keyword);
36+
if (index < 0) {
37+
return keywords;
38+
}
3639

40+
keywords.splice(index, 1);
3741
this.announcer.announce(`removed ${keyword}`);
38-
}
42+
return [...keywords];
43+
});
3944
}
4045

4146
add(event: MatChipInputEvent): void {
4247
const value = (event.value || '').trim();
4348

4449
// Add our keyword
4550
if (value) {
46-
this.keywords.push(value);
51+
this.keywords.update(keywords => [...keywords, value]);
4752
}
4853

4954
// Clear the input value

src/components-examples/material/chips/chips-harness/chips-harness-example.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import {Component, signal} from '@angular/core';
2-
import {MatIconModule} from '@angular/material/icon';
1+
import {ChangeDetectionStrategy, Component, signal} from '@angular/core';
32
import {MatChipsModule} from '@angular/material/chips';
3+
import {MatIconModule} from '@angular/material/icon';
44

55
/**
66
* @title Testing with MatChipsHarness
@@ -10,6 +10,7 @@ import {MatChipsModule} from '@angular/material/chips';
1010
templateUrl: 'chips-harness-example.html',
1111
standalone: true,
1212
imports: [MatChipsModule, MatIconModule],
13+
changeDetection: ChangeDetectionStrategy.OnPush,
1314
})
1415
export class ChipsHarnessExample {
1516
isDisabled = signal(false);
Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11
<mat-form-field class="example-chip-list">
22
<mat-label>Favorite Fruits</mat-label>
33
<mat-chip-grid #chipGrid aria-label="Enter fruits">
4-
@for (fruit of fruits; track fruit) {
4+
@for (fruit of fruits(); track fruit) {
55
<mat-chip-row
66
(removed)="remove(fruit)"
77
[editable]="true"
88
(edited)="edit(fruit, $event)"
9-
[aria-description]="'press enter to edit ' + fruit.name">
9+
[aria-description]="'press enter to edit ' + fruit.name"
10+
>
1011
{{fruit.name}}
1112
<button matChipRemove [attr.aria-label]="'remove ' + fruit.name">
1213
<mat-icon>cancel</mat-icon>
1314
</button>
1415
</mat-chip-row>
1516
}
16-
<input placeholder="New fruit..."
17-
[matChipInputFor]="chipGrid"
18-
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
19-
[matChipInputAddOnBlur]="addOnBlur"
20-
(matChipInputTokenEnd)="add($event)"/>
17+
<input
18+
placeholder="New fruit..."
19+
[matChipInputFor]="chipGrid"
20+
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
21+
[matChipInputAddOnBlur]="addOnBlur"
22+
(matChipInputTokenEnd)="add($event)"
23+
/>
2124
</mat-chip-grid>
2225
</mat-form-field>

0 commit comments

Comments
 (0)