ComponentStandalone

Checkbox

Two-state checkbox. Standalone (boolean) or inside <wr-checkbox-group> (array of values).

Installation

import { WrCheckbox, WrCheckboxGroup } from 'ngwr/checkbox';
import { FormsModule } from '@angular/forms';

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

Standalone

Signal-forms native — bind the boolean checked model via [(checked)], [formField], or classic [(ngModel)].

Value: true
<!-- signal-forms native: [(checked)], [formField], or classic [(ngModel)] -->
<wr-checkbox [(checked)]="agree">I agree</wr-checkbox>

Inside a group

The group manages an array of values. Each child contributes its value when checked.

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

A parent [indeterminate] shows the mixed state (a dash) when only some children are checked — the classic 'select all'. It's visual and controlled: you set it, and clear it on the next toggle.

<!-- A parent "select all": mixed when only some children are checked. -->
<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>
}

Disabled

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

Use it in a form

Signal forms is the native path — [formField] binds the checked model directly. Reactive forms and [(ngModel)] go through Angular 22's forms bridge, which binds a signal-forms control with no ControlValueAccessor involved: the library ships none, and formControlName still works. That bridge is not an accessor, and the guide is what it carries and what it drops — updateOn, required, and a { emitEvent: false } write that never repaints. Mind which model each half binds, too: a single checkbox is a boolean, the group is the array of checkboxValues.

<!-- Signal forms — the native path. -->
<wr-checkbox [formField]="form.agree">I agree</wr-checkbox>

<!-- Reactive forms. A single <wr-checkbox> is a FormCheckboxControl, so the
     control it binds holds a BOOLEAN — the checkbox's `checked` model, not
     `checkboxValue` (which is group identity and stays out of forms). -->
<form [formGroup]="form">
  <wr-checkbox formControlName="agree">I agree to the terms</wr-checkbox>

  <!-- A <wr-checkbox-group> is a FormValueControl<unknown[]>, so ITS control
       holds the array of checked `checkboxValue`s. -->
  <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 — the same bridge. -->
<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
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. Unset falls back to the checkbox.size app default from provideWrConfig().WrCheckboxSize | null'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".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

Custom properties ngwr/checkbox publishes. Each default below is declared on the component's own selector, so a :root override is shadowed by it — set them on that selector, on a wrapper you scope yourself, or inline on the element. Unlike the BEM class names, these are the supported way to restyle the component.

VariableDefaultDeclared on
--wr-checkbox-bgvar(--wr-color-surface).wr-checkbox +2 variant overrides
--wr-checkbox-bordervar(--wr-color-outline).wr-checkbox +3 variant overrides
--wr-checkbox-colorvar(--wr-color-on-surface).wr-checkbox +1 variant override
--wr-checkbox-font-sizevar(--wr-text-sm).wr-checkbox +2 variant overrides
--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