Skip to content

Commit

Permalink
docs(material/chips): Update chips docs & examples (#29235)
Browse files Browse the repository at this point in the history
(cherry picked from commit ec4e974)
  • Loading branch information
mmalerba committed Jun 12, 2024
1 parent 557f2bd commit 49eddf5
Show file tree
Hide file tree
Showing 16 changed files with 174 additions and 155 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<mat-form-field class="example-chip-list">
<mat-label>Favorite Fruits</mat-label>
<mat-chip-grid #chipGrid aria-label="Fruit selection">
@for (fruit of fruits; track fruit) {
@for (fruit of fruits(); track $index) {
<mat-chip-row (removed)="remove(fruit)">
{{fruit}}
<button matChipRemove [attr.aria-label]="'remove ' + fruit">
Expand All @@ -11,12 +11,18 @@
</mat-chip-row>
}
</mat-chip-grid>
<input placeholder="New Fruit..." #fruitInput [formControl]="fruitCtrl"
[matChipInputFor]="chipGrid" [matAutocomplete]="auto"
<input
name="currentFruit"
placeholder="New Fruit..."
#fruitInput
[(ngModel)]="currentFruit"
[matChipInputFor]="chipGrid"
[matAutocomplete]="auto"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
(matChipInputTokenEnd)="add($event)"/>
(matChipInputTokenEnd)="add($event)"
/>
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
@for (fruit of filteredFruits | async; track fruit) {
@for (fruit of filteredFruits(); track fruit) {
<mat-option [value]="fruit">{{fruit}}</mat-option>
}
</mat-autocomplete>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import {LiveAnnouncer} from '@angular/cdk/a11y';
import {COMMA, ENTER} from '@angular/cdk/keycodes';
import {Component, ElementRef, ViewChild, inject} from '@angular/core';
import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms';
import {MatAutocompleteSelectedEvent, MatAutocompleteModule} from '@angular/material/autocomplete';
import {ChangeDetectionStrategy, Component, computed, inject, model, signal} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {MatAutocompleteModule, MatAutocompleteSelectedEvent} from '@angular/material/autocomplete';
import {MatChipInputEvent, MatChipsModule} from '@angular/material/chips';
import {Observable} from 'rxjs';
import {map, startWith} from 'rxjs/operators';
import {MatIconModule} from '@angular/material/icon';
import {AsyncPipe} from '@angular/common';
import {MatFormFieldModule} from '@angular/material/form-field';
import {LiveAnnouncer} from '@angular/cdk/a11y';
import {MatIconModule} from '@angular/material/icon';

/**
* @title Chips Autocomplete
Expand All @@ -18,67 +15,51 @@ import {LiveAnnouncer} from '@angular/cdk/a11y';
templateUrl: 'chips-autocomplete-example.html',
styleUrl: 'chips-autocomplete-example.css',
standalone: true,
imports: [
FormsModule,
MatFormFieldModule,
MatChipsModule,
MatIconModule,
MatAutocompleteModule,
ReactiveFormsModule,
AsyncPipe,
],
imports: [MatFormFieldModule, MatChipsModule, MatIconModule, MatAutocompleteModule, FormsModule],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ChipsAutocompleteExample {
separatorKeysCodes: number[] = [ENTER, COMMA];
fruitCtrl = new FormControl('');
filteredFruits: Observable<string[]>;
fruits: string[] = ['Lemon'];
allFruits: string[] = ['Apple', 'Lemon', 'Lime', 'Orange', 'Strawberry'];
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
readonly currentFruit = model('');
readonly fruits = signal(['Lemon']);
readonly allFruits: string[] = ['Apple', 'Lemon', 'Lime', 'Orange', 'Strawberry'];
readonly filteredFruits = computed(() => {
const currentFruit = this.currentFruit().toLowerCase();
return currentFruit
? this.allFruits.filter(fruit => fruit.toLowerCase().includes(currentFruit))
: this.allFruits.slice();
});

@ViewChild('fruitInput') fruitInput: ElementRef<HTMLInputElement>;

announcer = inject(LiveAnnouncer);

constructor() {
this.filteredFruits = this.fruitCtrl.valueChanges.pipe(
startWith(null),
map((fruit: string | null) => (fruit ? this._filter(fruit) : this.allFruits.slice())),
);
}
readonly announcer = inject(LiveAnnouncer);

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

// Add our fruit
if (value) {
this.fruits.push(value);
this.fruits.update(fruits => [...fruits, value]);
}

// Clear the input value
event.chipInput!.clear();

this.fruitCtrl.setValue(null);
this.currentFruit.set('');
}

remove(fruit: string): void {
const index = this.fruits.indexOf(fruit);

if (index >= 0) {
this.fruits.splice(index, 1);
this.fruits.update(fruits => {
const index = fruits.indexOf(fruit);
if (index < 0) {
return fruits;
}

fruits.splice(index, 1);
this.announcer.announce(`Removed ${fruit}`);
}
return [...fruits];
});
}

selected(event: MatAutocompleteSelectedEvent): void {
this.fruits.push(event.option.viewValue);
this.fruitInput.nativeElement.value = '';
this.fruitCtrl.setValue(null);
}

private _filter(value: string): string[] {
const filterValue = value.toLowerCase();

return this.allFruits.filter(fruit => fruit.toLowerCase().includes(filterValue));
this.fruits.update(fruits => [...fruits, event.option.viewValue]);
this.currentFruit.set('');
event.option.deselect();
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
<mat-chip-set aria-label="Dog selection">
<mat-chip>
<img matChipAvatar src="https://material.angular.io/assets/img/examples/shiba1.jpg" alt="Photo of a Shiba Inu"/>
<img
matChipAvatar
src="https://material.angular.io/assets/img/examples/shiba1.jpg"
alt="Photo of a Shiba Inu"
/>
Dog one
</mat-chip>
<mat-chip color="primary">
<img matChipAvatar src="https://material.angular.io/assets/img/examples/shiba1.jpg" alt="Photo of a Shiba Inu"/>
<mat-chip>
<img
matChipAvatar
src="https://material.angular.io/assets/img/examples/shiba1.jpg"
alt="Photo of a Shiba Inu"
/>
Dog two
</mat-chip>
<mat-chip color="accent">
<img matChipAvatar src="https://material.angular.io/assets/img/examples/shiba1.jpg" alt="Photo of a Shiba Inu"/>
<mat-chip>
<img
matChipAvatar
src="https://material.angular.io/assets/img/examples/shiba1.jpg"
alt="Photo of a Shiba Inu"
/>
Dog three
</mat-chip>
</mat-chip-set>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Component} from '@angular/core';
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {MatChipsModule} from '@angular/material/chips';

/**
Expand All @@ -11,5 +11,6 @@ import {MatChipsModule} from '@angular/material/chips';
styleUrl: 'chips-avatar-example.css',
standalone: true,
imports: [MatChipsModule],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ChipsAvatarExample {}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
class="example-chip"
cdkDropList
cdkDropListOrientation="horizontal"
(cdkDropListDropped)="drop($event)">
@for (vegetable of vegetables; track vegetable) {
(cdkDropListDropped)="drop($event)"
>
@for (vegetable of vegetables(); track vegetable.name) {
<mat-chip class="example-box" cdkDrag>{{vegetable.name}}</mat-chip>
}
</mat-chip-set>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Component} from '@angular/core';
import {CdkDragDrop, moveItemInArray, CdkDrag, CdkDropList} from '@angular/cdk/drag-drop';
import {CdkDrag, CdkDragDrop, CdkDropList, moveItemInArray} from '@angular/cdk/drag-drop';
import {ChangeDetectionStrategy, Component, signal} from '@angular/core';
import {MatChipsModule} from '@angular/material/chips';

export interface Vegetable {
Expand All @@ -15,18 +15,22 @@ export interface Vegetable {
styleUrl: 'chips-drag-drop-example.css',
standalone: true,
imports: [MatChipsModule, CdkDropList, CdkDrag],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ChipsDragDropExample {
vegetables: Vegetable[] = [
readonly vegetables = signal<Vegetable[]>([
{name: 'apple'},
{name: 'banana'},
{name: 'strawberry'},
{name: 'orange'},
{name: 'kiwi'},
{name: 'cherry'},
];
]);

drop(event: CdkDragDrop<Vegetable[]>) {
moveItemInArray(this.vegetables, event.previousIndex, event.currentIndex);
this.vegetables.update(vegetables => {
moveItemInArray(vegetables, event.previousIndex, event.currentIndex);
return [...vegetables];
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
</p>
<mat-form-field class="example-form-field">
<mat-label>Video keywords</mat-label>
<mat-chip-grid #chipGrid aria-label="Enter keywords" [formControl]="formControl" >
@for (keyword of keywords; track keyword) {
<mat-chip-grid #chipGrid aria-label="Enter keywords" [formControl]="formControl">
@for (keyword of keywords(); track keyword) {
<mat-chip-row (removed)="removeKeyword(keyword)">
{{keyword}}
<button matChipRemove aria-label="'remove ' + keyword">
Expand All @@ -17,11 +17,11 @@
</mat-chip-row>
}
</mat-chip-grid>
<input placeholder="New keyword..."
[matChipInputFor]="chipGrid"
(matChipInputTokenEnd)="add($event)"/>
<input
placeholder="New keyword..."
[matChipInputFor]="chipGrid"
(matChipInputTokenEnd)="add($event)"
/>
</mat-form-field>

<p>
<strong>The following keywords are entered:</strong> {{formControl.value}}
</p>
<p><strong>The following keywords are entered:</strong> {{formControl.value}}</p>
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {Component, inject} from '@angular/core';
import {LiveAnnouncer} from '@angular/cdk/a11y';
import {ChangeDetectionStrategy, Component, inject, signal} from '@angular/core';
import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms';
import {MatButtonModule} from '@angular/material/button';
import {MatChipInputEvent, MatChipsModule} from '@angular/material/chips';
import {MatIconModule} from '@angular/material/icon';
import {MatFormFieldModule} from '@angular/material/form-field';
import {MatButtonModule} from '@angular/material/button';
import {LiveAnnouncer} from '@angular/cdk/a11y';
import {MatIconModule} from '@angular/material/icon';

/**
* @title Chips with form control
Expand All @@ -22,28 +22,33 @@ import {LiveAnnouncer} from '@angular/cdk/a11y';
ReactiveFormsModule,
MatIconModule,
],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ChipsFormControlExample {
keywords = ['angular', 'how-to', 'tutorial', 'accessibility'];
formControl = new FormControl(['angular']);
readonly keywords = signal(['angular', 'how-to', 'tutorial', 'accessibility']);
readonly formControl = new FormControl(['angular']);

announcer = inject(LiveAnnouncer);

removeKeyword(keyword: string) {
const index = this.keywords.indexOf(keyword);
if (index >= 0) {
this.keywords.splice(index, 1);
this.keywords.update(keywords => {
const index = keywords.indexOf(keyword);
if (index < 0) {
return keywords;
}

keywords.splice(index, 1);
this.announcer.announce(`removed ${keyword}`);
}
return [...keywords];
});
}

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

// Add our keyword
if (value) {
this.keywords.push(value);
this.keywords.update(keywords => [...keywords, value]);
}

// Clear the input value
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Component, signal} from '@angular/core';
import {MatIconModule} from '@angular/material/icon';
import {ChangeDetectionStrategy, Component, signal} from '@angular/core';
import {MatChipsModule} from '@angular/material/chips';
import {MatIconModule} from '@angular/material/icon';

/**
* @title Testing with MatChipsHarness
Expand All @@ -10,6 +10,7 @@ import {MatChipsModule} from '@angular/material/chips';
templateUrl: 'chips-harness-example.html',
standalone: true,
imports: [MatChipsModule, MatIconModule],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ChipsHarnessExample {
isDisabled = signal(false);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
<mat-form-field class="example-chip-list">
<mat-label>Favorite Fruits</mat-label>
<mat-chip-grid #chipGrid aria-label="Enter fruits">
@for (fruit of fruits; track fruit) {
@for (fruit of fruits(); track fruit) {
<mat-chip-row
(removed)="remove(fruit)"
[editable]="true"
(edited)="edit(fruit, $event)"
[aria-description]="'press enter to edit ' + fruit.name">
[aria-description]="'press enter to edit ' + fruit.name"
>
{{fruit.name}}
<button matChipRemove [attr.aria-label]="'remove ' + fruit.name">
<mat-icon>cancel</mat-icon>
</button>
</mat-chip-row>
}
<input placeholder="New fruit..."
[matChipInputFor]="chipGrid"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="addOnBlur"
(matChipInputTokenEnd)="add($event)"/>
<input
placeholder="New fruit..."
[matChipInputFor]="chipGrid"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="addOnBlur"
(matChipInputTokenEnd)="add($event)"
/>
</mat-chip-grid>
</mat-form-field>
Loading

0 comments on commit 49eddf5

Please sign in to comment.