Skip to content

Commit d783233

Browse files
authored
docs(material/checkbox): Update checkbox docs & examples (#29234)
1 parent ec4e974 commit d783233

File tree

11 files changed

+93
-72
lines changed

11 files changed

+93
-72
lines changed

src/components-examples/material/checkbox/checkbox-configurable/checkbox-configurable-example.html

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@ <h2 class="example-h2">Result</h2>
2727

2828
<section class="example-section">
2929
<mat-checkbox
30-
class="example-margin"
31-
[(ngModel)]="checked"
32-
[(indeterminate)]="indeterminate"
33-
[labelPosition]="labelPosition"
34-
[disabled]="disabled">
30+
class="example-margin"
31+
[(ngModel)]="checked"
32+
[(indeterminate)]="indeterminate"
33+
[labelPosition]="labelPosition()"
34+
[disabled]="disabled()"
35+
>
3536
I'm a checkbox
3637
</mat-checkbox>
3738
</section>
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import {Component} from '@angular/core';
2-
import {MatRadioModule} from '@angular/material/radio';
1+
import {ChangeDetectionStrategy, Component, model} from '@angular/core';
32
import {FormsModule} from '@angular/forms';
4-
import {MatCheckboxModule} from '@angular/material/checkbox';
53
import {MatCardModule} from '@angular/material/card';
4+
import {MatCheckboxModule} from '@angular/material/checkbox';
5+
import {MatRadioModule} from '@angular/material/radio';
66

77
/**
88
* @title Configurable checkbox
@@ -13,10 +13,11 @@ import {MatCardModule} from '@angular/material/card';
1313
styleUrl: 'checkbox-configurable-example.css',
1414
standalone: true,
1515
imports: [MatCardModule, MatCheckboxModule, FormsModule, MatRadioModule],
16+
changeDetection: ChangeDetectionStrategy.OnPush,
1617
})
1718
export class CheckboxConfigurableExample {
18-
checked = false;
19-
indeterminate = false;
20-
labelPosition: 'before' | 'after' = 'after';
21-
disabled = false;
19+
readonly checked = model(false);
20+
readonly indeterminate = model(false);
21+
readonly labelPosition = model<'before' | 'after'>('after');
22+
readonly disabled = model(false);
2223
}
Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
<mat-checkbox
2-
required
3-
[checked]="true"
4-
name="first-name"
5-
value="first-value"
6-
aria-label="First checkbox">
2+
required
3+
[checked]="true"
4+
name="first-name"
5+
value="first-value"
6+
aria-label="First checkbox"
7+
>
78
First
89
</mat-checkbox>
9-
<mat-checkbox indeterminate="true" [disabled]="disabled" aria-label="Second checkbox">
10+
<mat-checkbox indeterminate="true" [disabled]="disabled()" aria-label="Second checkbox">
1011
Second
1112
</mat-checkbox>

src/components-examples/material/checkbox/checkbox-harness/checkbox-harness-example.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ describe('CheckboxHarnessExample', () => {
3838
});
3939

4040
it('should toggle checkbox', async () => {
41-
fixture.componentInstance.disabled = false;
41+
fixture.componentRef.setInput('disabled', false);
4242
fixture.changeDetectorRef.markForCheck();
4343
const [checkedCheckbox, uncheckedCheckbox] = await loader.getAllHarnesses(MatCheckboxHarness);
4444
await checkedCheckbox.toggle();

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Component} from '@angular/core';
1+
import {ChangeDetectionStrategy, Component, input} from '@angular/core';
22
import {MatCheckboxModule} from '@angular/material/checkbox';
33

44
/**
@@ -9,7 +9,8 @@ import {MatCheckboxModule} from '@angular/material/checkbox';
99
templateUrl: 'checkbox-harness-example.html',
1010
standalone: true,
1111
imports: [MatCheckboxModule],
12+
changeDetection: ChangeDetectionStrategy.OnPush,
1213
})
1314
export class CheckboxHarnessExample {
14-
disabled = true;
15+
readonly disabled = input(true);
1516
}

src/components-examples/material/checkbox/checkbox-overview/checkbox-overview-example.html

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,20 @@
55

66
<section class="example-section">
77
<span class="example-list-section">
8-
<mat-checkbox class="example-margin"
9-
[checked]="allComplete"
10-
[color]="task.color"
11-
[indeterminate]="someComplete()"
12-
(change)="setAll($event.checked)">
13-
{{task.name}}
8+
<mat-checkbox
9+
class="example-margin"
10+
[checked]="task().completed"
11+
[indeterminate]="partiallyComplete()"
12+
(change)="update($event.checked)"
13+
>
14+
{{task().name}}
1415
</mat-checkbox>
1516
</span>
1617
<span class="example-list-section">
1718
<ul>
18-
@for (subtask of task.subtasks; track subtask) {
19+
@for (subtask of task().subtasks; track subtask; let i = $index) {
1920
<li>
20-
<mat-checkbox [(ngModel)]="subtask.completed"
21-
[color]="subtask.color"
22-
(ngModelChange)="updateAllComplete()">
21+
<mat-checkbox [checked]="subtask.completed" (change)="update($event.checked, i)">
2322
{{subtask.name}}
2423
</mat-checkbox>
2524
</li>
Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import {Component} from '@angular/core';
2-
import {ThemePalette} from '@angular/material/core';
1+
import {ChangeDetectionStrategy, Component, computed, signal} from '@angular/core';
32
import {FormsModule} from '@angular/forms';
43
import {MatCheckboxModule} from '@angular/material/checkbox';
54

65
export interface Task {
76
name: string;
87
completed: boolean;
9-
color: ThemePalette;
108
subtasks?: Task[];
119
}
1210

@@ -19,37 +17,37 @@ export interface Task {
1917
styleUrl: 'checkbox-overview-example.css',
2018
standalone: true,
2119
imports: [MatCheckboxModule, FormsModule],
20+
changeDetection: ChangeDetectionStrategy.OnPush,
2221
})
2322
export class CheckboxOverviewExample {
24-
task: Task = {
25-
name: 'Indeterminate',
23+
readonly task = signal<Task>({
24+
name: 'Parent task',
2625
completed: false,
27-
color: 'primary',
2826
subtasks: [
29-
{name: 'Primary', completed: false, color: 'primary'},
30-
{name: 'Accent', completed: false, color: 'accent'},
31-
{name: 'Warn', completed: false, color: 'warn'},
27+
{name: 'Child task 1', completed: false},
28+
{name: 'Child task 2', completed: false},
29+
{name: 'Child task 3', completed: false},
3230
],
33-
};
31+
});
3432

35-
allComplete: boolean = false;
36-
37-
updateAllComplete() {
38-
this.allComplete = this.task.subtasks != null && this.task.subtasks.every(t => t.completed);
39-
}
40-
41-
someComplete(): boolean {
42-
if (this.task.subtasks == null) {
33+
readonly partiallyComplete = computed(() => {
34+
const task = this.task();
35+
if (!task.subtasks) {
4336
return false;
4437
}
45-
return this.task.subtasks.filter(t => t.completed).length > 0 && !this.allComplete;
46-
}
38+
return task.subtasks.some(t => t.completed) && !task.subtasks.every(t => t.completed);
39+
});
4740

48-
setAll(completed: boolean) {
49-
this.allComplete = completed;
50-
if (this.task.subtasks == null) {
51-
return;
52-
}
53-
this.task.subtasks.forEach(t => (t.completed = completed));
41+
update(completed: boolean, index?: number) {
42+
this.task.update(task => {
43+
if (index === undefined) {
44+
task.completed = completed;
45+
task.subtasks?.forEach(t => (t.completed = completed));
46+
} else {
47+
task.subtasks![index].completed = completed;
48+
task.completed = task.subtasks?.every(t => t.completed) ?? true;
49+
}
50+
return {...task};
51+
});
5452
}
5553
}
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import {Component} from '@angular/core';
2-
import {FormBuilder, FormsModule, ReactiveFormsModule} from '@angular/forms';
31
import {JsonPipe} from '@angular/common';
2+
import {ChangeDetectionStrategy, Component, inject} from '@angular/core';
3+
import {FormBuilder, FormsModule, ReactiveFormsModule} from '@angular/forms';
44
import {MatCheckboxModule} from '@angular/material/checkbox';
55

66
/** @title Checkboxes with reactive forms */
@@ -10,13 +10,14 @@ import {MatCheckboxModule} from '@angular/material/checkbox';
1010
styleUrl: 'checkbox-reactive-forms-example.css',
1111
standalone: true,
1212
imports: [FormsModule, ReactiveFormsModule, MatCheckboxModule, JsonPipe],
13+
changeDetection: ChangeDetectionStrategy.OnPush,
1314
})
1415
export class CheckboxReactiveFormsExample {
15-
toppings = this._formBuilder.group({
16+
private readonly _formBuilder = inject(FormBuilder);
17+
18+
readonly toppings = this._formBuilder.group({
1619
pepperoni: false,
1720
extracheese: false,
1821
mushroom: false,
1922
});
20-
21-
constructor(private _formBuilder: FormBuilder) {}
2223
}

src/material/checkbox/checkbox-config.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ import {ThemePalette} from '@angular/material/core';
1010

1111
/** Default `mat-checkbox` options that can be overridden. */
1212
export interface MatCheckboxDefaultOptions {
13-
/** Default theme color palette to be used for checkboxes. */
13+
/**
14+
* Default theme color palette to be used for checkboxes. This API is supported in M2 themes
15+
* only, it has no effect in M3 themes. For information on applying color variants in M3, see
16+
* https://material.angular.io/guide/theming#using-component-color-variants
17+
*/
1418
color?: ThemePalette;
1519
/** Default checkbox click action for checkboxes. */
1620
clickAction?: MatCheckboxClickAction;

src/material/checkbox/checkbox.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ enhanced with Material Design styling and animations.
44
<!-- example(checkbox-overview) -->
55

66
### Checkbox label
7+
78
The checkbox label is provided as the content to the `<mat-checkbox>` element. The label can be
89
positioned before or after the checkbox by setting the `labelPosition` property to `'before'` or
910
`'after'`.
@@ -14,16 +15,19 @@ If you don't want the label to appear next to the checkbox, you can use
1415
specify an appropriate label.
1516

1617
### Use with `@angular/forms`
18+
1719
`<mat-checkbox>` is compatible with `@angular/forms` and supports both `FormsModule`
1820
and `ReactiveFormsModule`.
1921

2022
### Indeterminate state
23+
2124
`<mat-checkbox>` supports an `indeterminate` state, similar to the native `<input type="checkbox">`.
2225
While the `indeterminate` property of the checkbox is true, it will render as indeterminate
2326
regardless of the `checked` value. Any interaction with the checkbox by a user (i.e., clicking) will
2427
remove the indeterminate state.
2528

2629
### Click action config
30+
2731
When user clicks on the `mat-checkbox`, the default behavior is toggle `checked` value and set
2832
`indeterminate` to `false`. This behavior can be customized by
2933
[providing a new value](https://angular.io/guide/dependency-injection)
@@ -38,22 +42,29 @@ providers: [
3842
The possible values are:
3943

4044
#### `noop`
45+
4146
Do not change the `checked` value or `indeterminate` value. Developers have the power to
4247
implement customized click actions.
4348

4449
#### `check`
50+
4551
Toggle `checked` value of the checkbox, ignore `indeterminate` value. If the
4652
checkbox is in `indeterminate` state, the checkbox will display as an `indeterminate` checkbox
4753
regardless the `checked` value.
4854

4955
#### `check-indeterminate`
56+
5057
Default behavior of `mat-checkbox`. Always set `indeterminate` to `false`
5158
when user click on the `mat-checkbox`.
5259
This matches the behavior of native `<input type="checkbox">`.
5360

5461
### Theming
55-
The color of a `<mat-checkbox>` can be changed by using the `color` property. By default, checkboxes
56-
use the theme's accent color. This can be changed to `'primary'` or `'warn'`.
62+
63+
The color of a `<mat-checkbox>` can be changed by specifying a `$color-variant` when applying the
64+
`mat.checkbox-theme` or `mat.checkbox-color` mixins (see the
65+
[theming guide](/guide/theming#using-component-color-variants) to learn more.) By default,
66+
checkboxes use the theme's primary palette. This can be changed to `'secondary'`, `'tertiary'`,
67+
or `'error'`.
5768

5869
### Accessibility
5970

src/material/checkbox/checkbox.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,28 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
import {FocusableOption} from '@angular/cdk/a11y';
910
import {
11+
ANIMATION_MODULE_TYPE,
1012
AfterViewInit,
1113
Attribute,
12-
booleanAttribute,
1314
ChangeDetectionStrategy,
1415
ChangeDetectorRef,
1516
Component,
1617
ElementRef,
1718
EventEmitter,
18-
forwardRef,
1919
Inject,
2020
Input,
2121
NgZone,
22-
numberAttribute,
2322
OnChanges,
2423
Optional,
2524
Output,
2625
SimpleChanges,
2726
ViewChild,
2827
ViewEncapsulation,
29-
ANIMATION_MODULE_TYPE,
28+
booleanAttribute,
29+
forwardRef,
30+
numberAttribute,
3031
} from '@angular/core';
3132
import {
3233
AbstractControl,
@@ -36,8 +37,7 @@ import {
3637
ValidationErrors,
3738
Validator,
3839
} from '@angular/forms';
39-
import {_MatInternalFormField, MatRipple} from '@angular/material/core';
40-
import {FocusableOption} from '@angular/cdk/a11y';
40+
import {MatRipple, _MatInternalFormField} from '@angular/material/core';
4141
import {
4242
MAT_CHECKBOX_DEFAULT_OPTIONS,
4343
MAT_CHECKBOX_DEFAULT_OPTIONS_FACTORY,
@@ -202,7 +202,11 @@ export class MatCheckbox
202202

203203
// TODO(crisbeto): this should be a ThemePalette, but some internal apps were abusing
204204
// the lack of type checking previously and assigning random strings.
205-
/** Palette color of the checkbox. */
205+
/**
206+
* Palette color of the checkbox. This API is supported in M2 themes only, it has no effect in M3
207+
* themes. For information on applying color variants in M3, see
208+
* https://material.angular.io/guide/theming#using-component-color-variants
209+
*/
206210
@Input() color: string | undefined;
207211

208212
/**

0 commit comments

Comments
 (0)