ComponentUpdated in v15

Checkbox

A checkbox for one boolean, or a group of them for an array.

Installation

Import the class, and @use the entry point in your global styles: without it the component renders unstyled.

import { Component } from '@angular/core';
import { WrCheckbox, WrCheckboxGroup } from 'ngwr/checkbox';

@Component({ imports: [WrCheckbox, WrCheckboxGroup] })
export class MyComponent {}

Standalone

Bind the boolean with [(checked)] or any Angular form.

Value: true
<wr-checkbox [(checked)]="agree">I agree</wr-checkbox>

Inside a group

Give each box a checkboxValue, not value; the group's value is the array of checked ones.

Value: [autosave]
<wr-checkbox-group [(value)]="features">
  <wr-checkbox checkboxValue="autosave">Autosave</wr-checkbox>
  <wr-checkbox checkboxValue="notifications">Notifications</wr-checkbox>
  <wr-checkbox checkboxValue="darkmode">Dark mode</wr-checkbox>
</wr-checkbox-group>

Indeterminate

[indeterminate] shows a dash for a partly checked parent. You set it and clear it.

<wr-checkbox [checked]="allChecked()" (checkedChange)="toggleAll()" [indeterminate]="someChecked()">
  Select all
</wr-checkbox>
@for (p of permItems; track p) {
  <wr-checkbox [checked]="perms().includes(p)" (checkedChange)="togglePerm(p)">{{ p }}</wr-checkbox>
}

Sizes

sm, md (default) or lg.

<wr-checkbox size="sm" [(checked)]="agree">Small</wr-checkbox>
<wr-checkbox size="lg" [(checked)]="agree">Large</wr-checkbox>

Disabled and read-only

Disabled leaves the tab order and submits nothing; read-only keeps its tab stop and submits, but refuses the toggle.

<wr-checkbox [disabled]="true">Disabled</wr-checkbox>
<wr-checkbox [readonly]="true">Read-only</wr-checkbox>

Use it in a form

A single checkbox binds a boolean and the group an array; Forms lists what reactive forms ignore.

<!-- Signal Forms -->
<wr-checkbox [formField]="form.agree">I agree</wr-checkbox>

<!-- Reactive forms -->
<form [formGroup]="form">
  <wr-checkbox formControlName="agree">I agree to the terms</wr-checkbox>
  <wr-checkbox-group formControlName="features">
    <wr-checkbox checkboxValue="autosave">Autosave</wr-checkbox>
    <wr-checkbox checkboxValue="notifications">Notifications</wr-checkbox>
  </wr-checkbox-group>
</form>

<!-- Template-driven -->
<wr-checkbox [(ngModel)]="agree" name="agree">I agree</wr-checkbox>
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';

import { WrCheckbox, WrCheckboxGroup } from 'ngwr/checkbox';

@Component({
  imports: [ReactiveFormsModule, WrCheckbox, WrCheckboxGroup],
  templateUrl: './my.html',
})
export class MyComponent {
  protected readonly form = new FormGroup({
    agree: new FormControl(false, { nonNullable: true, validators: [Validators.requiredTrue] }),
    features: new FormControl<string[]>(['autosave'], { nonNullable: true }),
  });
}
agree: false · features: [autosave] · form valid: false

Checkbox API

NameDescriptionTypeDefault
idStable id used to associate the native input with its label. Lands on the inner <input>; the host never keeps it.stringRandomly generated
checkboxValueThis checkbox's identity when inside a <wr-checkbox-group> — the value added to / removed from the group's array. Ignored in standalone mode. (Named checkboxValue, not value, because FormCheckboxControl reserves value.)unknownnull
ariaLabelAccessible name for a checkbox used WITHOUT projected text — a selection cell in a table, say. The wrapping <label> names the control whenever content is projected; with none, the native input has no name, and an aria-label put on the host lands on a <wr-checkbox> element that no screen reader ever announces.string | nullnull
ariaLabelledbyIds of the elements that name this checkbox, space-separated, for a box whose name is already on screen somewhere else — a table row's label cell, say, joined to an action word. Lands on the inner <input> as aria-labelledby, which wins over ariaLabel and over projected text. The ids have to resolve in the same document; one that matches nothing is skipped, and with none left the box falls back to ariaLabel.string | nullnull
checkedChecked state — the form value. Bound by [formField], two-way via [(checked)], or [(ngModel)]. Ignored inside a <wr-checkbox-group>, where the group's array is the source of truth.booleanfalse
(touch)Emitted on blur so a bound field can mark itself touched.void—
disabledDisable the checkbox. Bound automatically from the field's disabled state when used with [formField].booleanfalse
readonlyRefuse edits while staying focusable and submittable. Bound automatically from the field's readonly state when used with [formField]. A native <input type="checkbox"> ignores the readonly attribute, so this cancels the click's activation behaviour instead — which covers Space too, since a checkbox turns Space into a click — and mirrors the state as aria-readonly, which role checkbox supports.booleanfalse
sizeControl size — shares the --wr-control-* contract.WrCheckboxSize'md'
iconOptional icon name rendered inside the box when checked, in place of the default checkmark. Use any registered NGWR icon.WrIconName | nullnull
indeterminateShow the indeterminate ("mixed") state — a dash instead of a check. Visual only and controlled: set it yourself for a parent "select all" whose children are partly checked, and clear it on the next toggle. Takes visual precedence over checked; the native input reports aria-checked="mixed". A click the host does not answer still toggles checked underneath, and the dash and the mixed state both stay until the binding turns false.booleanfalse

Checkbox Group API

NameDescriptionTypeDefault
disabledDisable every child checkbox. Bound automatically from the field's disabled state when used with [formField].booleanfalse
readonlyRefuse edits on every child while they stay focusable and the value still submits. Bound automatically from the field's readonly state when used with [formField]. No aria-readonly on the host: role group does not support it (the state is not global), so each child box mirrors its own instead.booleanfalse
valueThe checked items' values. Bound by [formField], or two-way via [(value)].unknown[][]
(touch)Emitted when a child toggles so a bound field can mark itself touched.void—

CSS variables

Set these on the component's selector or a wrapper, not on :root: the defaults are declared on ngwr/checkbox's own element.

VariableDefaultDeclared on
--wr-checkbox-bgvar(--wr-color-surface).wr-checkbox +2 variant overrides
--wr-checkbox-bordervar(--wr-border-base).wr-checkbox +3 variant overrides
--wr-checkbox-colorvar(--wr-color-on-surface).wr-checkbox +1 variant override
--wr-checkbox-font-familyvar(--wr-font-family-base).wr-checkbox
--wr-checkbox-font-sizevar(--wr-text-sm).wr-checkbox +2 variant overrides
--wr-checkbox-group-gapvar(--wr-space-sm).wr-checkbox-group
--wr-checkbox-label-gapvar(--wr-space-sm).wr-checkbox
--wr-checkbox-line-heightvar(--wr-control-line-height-md).wr-checkbox +2 variant overrides
--wr-checkbox-marktransparent.wr-checkbox +2 variant overrides
--wr-checkbox-radiusvar(--wr-control-radius-md).wr-checkbox +2 variant overrides
--wr-checkbox-size1.125rem.wr-checkbox +2 variant overrides

Dependencies

See also