Skip to content

Commit 2b4cd82

Browse files
committed
docs: add signal forms examples to Checkbox and Chips
1 parent ef620d8 commit 2b4cd82

16 files changed

Lines changed: 210 additions & 9 deletions
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.example-section {
2+
margin: 12px 0;
3+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<section class="example-section">
2+
<h4>Select your toppings:</h4>
3+
<p><mat-checkbox [formField]="toppingsForm.pepperoni">Pepperoni</mat-checkbox></p>
4+
<p><mat-checkbox [formField]="toppingsForm.extracheese">Extra Cheese</mat-checkbox></p>
5+
<p><mat-checkbox [formField]="toppingsForm.mushroom">Mushroom</mat-checkbox></p>
6+
</section>
7+
8+
<section class="example-section">
9+
<h4>You chose:</h4>
10+
{{toppingsForm().value() | json}}
11+
</section>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {JsonPipe} from '@angular/common';
2+
import {Component, signal} from '@angular/core';
3+
import {form, FormField} from '@angular/forms/signals';
4+
import {MatCheckboxModule} from '@angular/material/checkbox';
5+
6+
/** @title Checkboxes with signal forms */
7+
@Component({
8+
selector: 'checkbox-signal-forms-example',
9+
templateUrl: 'checkbox-signal-forms-example.html',
10+
styleUrl: 'checkbox-signal-forms-example.css',
11+
imports: [FormField, MatCheckboxModule, JsonPipe],
12+
})
13+
export class CheckboxSignalFormsExample {
14+
readonly toppingsFormModel = signal({
15+
pepperoni: false,
16+
extracheese: false,
17+
mushroom: false,
18+
});
19+
20+
readonly toppingsForm = form(this.toppingsFormModel);
21+
}

src/components-examples/material/checkbox/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export {CheckboxConfigurableExample} from './checkbox-configurable/checkbox-conf
22
export {CheckboxHarnessExample} from './checkbox-harness/checkbox-harness-example';
33
export {CheckboxOverviewExample} from './checkbox-overview/checkbox-overview-example';
44
export {CheckboxReactiveFormsExample} from './checkbox-reactive-forms/checkbox-reactive-forms-example';
5+
export {CheckboxSignalFormsExample} from './checkbox-signal-forms/checkbox-signal-forms-example';

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<mat-form-field class="example-form-field">
99
<mat-label>Video keywords</mat-label>
1010
<mat-chip-grid #chipGrid aria-label="Enter keywords" [formControl]="formControl">
11-
@for (keyword of keywords(); track keyword) {
11+
@for (keyword of keywords(); track $index) {
1212
<mat-chip-row (removed)="removeKeyword(keyword)">
1313
{{keyword}}
1414
<button matChipRemove [attr.aria-label]="'remove ' + keyword">
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.example-button-container > button {
2+
margin: 0 12px;
3+
}
4+
5+
.example-form-field {
6+
width: 100%;
7+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<div class="example-button-container">
2+
<button matButton="elevated" (click)="keywordsFormModel.update(m => ({ ...m, enabled: false }))">
3+
Disable form control
4+
</button>
5+
<button matButton="elevated" (click)="keywordsFormModel.update(m => ({ ...m, enabled: true }))">
6+
Enable form control
7+
</button>
8+
</div>
9+
<p>
10+
<em>Enter video keywords</em>
11+
</p>
12+
<mat-form-field class="example-form-field">
13+
<mat-label>Video keywords</mat-label>
14+
<mat-chip-grid #chipGrid aria-label="Enter keywords" [formField]="keywordsForm.words">
15+
@for (keyword of keywordsForm.words().value(); track $index) {
16+
<mat-chip-row (removed)="removeKeyword(keyword)">
17+
{{ keyword }}
18+
<button matChipRemove [attr.aria-label]="'remove ' + keyword">
19+
<mat-icon>cancel</mat-icon>
20+
</button>
21+
</mat-chip-row>
22+
}
23+
</mat-chip-grid>
24+
<input
25+
placeholder="New keyword..."
26+
[matChipInputFor]="chipGrid"
27+
(matChipInputTokenEnd)="add($event)"
28+
/>
29+
</mat-form-field>
30+
31+
<p><strong>The following keywords are entered:</strong> {{ keywordsForm.words().value() }}</p>
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import {LiveAnnouncer} from '@angular/cdk/a11y';
2+
import {Component, inject, signal} from '@angular/core';
3+
import {disabled, form, FormField} from '@angular/forms/signals';
4+
import {MatButtonModule} from '@angular/material/button';
5+
import {MatChipInputEvent, MatChipsModule} from '@angular/material/chips';
6+
import {MatFormFieldModule} from '@angular/material/form-field';
7+
import {MatIconModule} from '@angular/material/icon';
8+
9+
/**
10+
* @title Chips with form field
11+
*/
12+
@Component({
13+
selector: 'chips-form-field-example',
14+
templateUrl: 'chips-form-field-example.html',
15+
styleUrl: 'chips-form-field-example.css',
16+
imports: [FormField, MatButtonModule, MatFormFieldModule, MatChipsModule, MatIconModule],
17+
})
18+
export class ChipsFormFieldExample {
19+
readonly keywordsFormModel = signal({
20+
words: ['angular', 'how-to', 'tutorial', 'accessibility'],
21+
enabled: true,
22+
});
23+
24+
readonly keywordsForm = form(this.keywordsFormModel, p => {
25+
disabled(p, {
26+
when: ({valueOf}) => !valueOf(p.enabled),
27+
});
28+
});
29+
30+
announcer = inject(LiveAnnouncer);
31+
32+
protected removeKeyword(keyword: string) {
33+
this.keywordsFormModel.update(keywords => {
34+
const index = keywords.words.indexOf(keyword);
35+
if (index < 0) {
36+
return keywords;
37+
}
38+
39+
keywords.words.splice(index, 1);
40+
this.announcer.announce(`removed ${keyword}`);
41+
return {...keywords};
42+
});
43+
}
44+
45+
protected add(event: MatChipInputEvent): void {
46+
const value = (event.value || '').trim();
47+
48+
// Add our keyword
49+
if (value) {
50+
this.keywordsFormModel.update(keywords => ({...keywords, words: [...keywords.words, value]}));
51+
}
52+
53+
// Clear the input value
54+
event.chipInput!.clear();
55+
}
56+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ <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 formControl.value; track keyword) {
6+
@for (keyword of formControl.value; track $index) {
77
<mat-chip-row (removed)="removeKeyword(keyword)">
88
{{keyword}}
99
<button matChipRemove [attr.aria-label]="'remove reactive form' + keyword">
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.example-form-field {
2+
width: 100%;
3+
}

0 commit comments

Comments
 (0)