Checkbox

July 6, 2026 · View on GitHub

Binary or tri-state toggle for independent options.

Contract

Checkbox represents a boolean choice that doesn't depend on siblings — "I agree", "Show advanced options", "Include attachments". In a group, each Checkbox is independent: toggling one doesn't affect others. The indeterminate state is for parent rows controlling a set of children (partially selected).

Anatomy

Container (square)
├─ check icon (SVG, opacity: 0 in unchecked)
├─ minus bar (rectangle, opacity: 0 unless indeterminate)
└─ (optional) label via ng-content
  • Container — fixed square, border, background, radius; colors driven by checked state
  • check icon — rendered always, opacity toggles on --checked
  • minus bar — horizontal rectangle, opacity toggles on --indeterminate
  • label — projected via ng-content, shown only when hasLabel is true

API

Inputs

NameTypeDefaultDescription
size'sm' | 'md' | 'lg''md'Component size
color'primary' | 'danger''primary'Color role (danger for "delete permanently" confirmations)
checkedbooleanfalseCurrent checked value
indeterminatebooleanfalseShows minus bar; takes precedence over checked visually
disabledbooleanfalseNon-interactive
forceStateKpState | nullnullForce visual state — Storybook only
hasLabelbooleantrueShow the projected label slot

Outputs

NamePayloadFires when
checkedChangebooleanUser toggles the state

Implements ControlValueAccessor — use [(ngModel)] or reactive-form bindings.

Content projection

  • ng-content — label text

Variants

DimensionValues
Sizesm (16px, stroke 1), md (20px, stroke 1.5), lg (24px, stroke 1.5)
Checkedunchecked, checked, indeterminate
Colorprimary, danger
Staterest, hover, active, focus, disabled, error

States

StateBehavior
restUnchecked: gray border. Checked: solid fill.
hoverBorder or fill darkens one step
activeBorder or fill darkens two steps
focus2px focus ring, offset 2px
disabledMuted fill and border; aria-disabled="true"; pointer-events: none
errorRed border; used together with FormField error

Accessibility

  • Role: checkbox
  • Keyboard: Space toggles; Tab to focus
  • Focus: 2px focus ring via outline, offset 2px
  • ARIA:
    • aria-checked="true" | "false" | "mixed" (mixed when indeterminate)
    • aria-disabled="true" when disabled
    • aria-label required when no visible label
  • Screen reader: announces label, role, and checked state (including "mixed")

Do / Don't

Do

  • Use for independent boolean choices ("Remember me", "Subscribe")
  • Use indeterminate on parent rows that represent a partially-selected set of children
  • Pair sm/md with form-body sizes; lg only for touch or marketing
  • Use danger color only when the checkbox confirms an irreversible destructive action

Don't

  • Don't use Checkbox for mutually-exclusive choices — use Radio
  • Don't use indeterminate as a third user-selectable value — it's a computed state
  • Don't remove aria-label on icon-only checkboxes (no visible text)
  • Don't toggle disabled purely from client-side validation — show inline error instead

References

Changelog

  • 0.1.0 — Initial component with 3 sizes × 3 checked states, primary/danger color, CVA integration