Noctis

Checkbox

A square box that toggles a boolean. The checked box fills with the accent and draws a check in; the mixed state shows a minus. Built on Base UI's Checkbox, so Space toggles it, the hidden input integrates with forms, focus shows a visible ring, and the draw-in respects prefers-reduced-motion.

Basic

Pair a Checkbox.Label with a Checkbox.Root inside a Checkbox.Field: the label becomes the accessible name, clicking it toggles the box, and the whole row reads as one control. Checkbox.Root mounts its check glyph by default, so the common case needs no explicit Indicator. Drive it with checked / onCheckedChange, or omit them and pass defaultChecked to let it own its state.

Sizes

size sets the box and glyph metrics — sm, md (the default), or lg. Set it on the Checkbox.Field to size the box and scale its label together; the box inherits the field's size unless it sets its own.

States

A checked box fills with the accent and draws the check in; an unchecked box rests as a bordered field box whose border turns to the field hover signal on hover. Read-only keeps the value visible but not editable; invalid paints the danger border; disabled dims through opacity and turns off its pointer affordance — disabled is never a recolour, and the component dims itself (no need to dim the row).

Validation

A required acknowledgement validates at submit, not on blur. When invalid, the box shows the danger border and an error message is wired through aria-describedby — colour is never the only signal.

Read-only

Read-only differs from disabled: it stays full-opacity and in the accessibility tree (the value is still announced), it simply can't be edited. Disabled dims the control and removes it from interaction.

Indeterminate & groups

A CheckboxGroup shares one ticked-value list across its children. Give the group allValues and add a parent checkbox to drive a "select all" affordance: the parent ticks when every child is on, clears when none are, and shows the mixed (indeterminate) minus glyph in between. Echo the mixed state with a partial count so it stays legible.

1 of 3 selected

Orientation

A group stacks vertically by default; orientation="horizontal" lays it out in a row — useful for a compact filter bar.

Checkbox card

A selectable card is a recipe, not a new part: a bordered Surface rendered as a <label> so the whole card is the toggle target, with the checkbox in the corner as the accessible control. Selecting it tints the border to the accent and washes the fill.

Keyboard

KeyAction
TabMove focus to the box.
SpaceToggle the focused box between checked and unchecked (a parent select-all cycles the group).

A checkbox is a single tab stop — there is no arrow navigation. Arrow keys move between options in a RadioGroup, where only one option can be chosen.

Accessibility

  • Role & state. Checkbox.Root renders role="checkbox" with aria-checked reporting true / false / mixed, backed by a hidden <input> for forms.
  • Names. A Checkbox.Label inside a Checkbox.Field supplies the accessible name. For a label-less box (e.g. a table-row select), pass an explicit aria-label.
  • Invalid. Set aria-invalid and wire the message through aria-describedby (a Field.Error-style line). The danger border is a reinforcement, never the only signal.
  • Read-only. Read-only boxes stay focusable and announced — they are reflected visually but never removed from the accessibility tree.
  • Motion. The check draws in along the inline axis (inline-start in both LTR and RTL); under prefers-reduced-motion: reduce it appears instantly, meaning preserved.
  • Touch & contrast. Every size carries a transparent hit area so the tap target clears the 24px minimum, and a forced-colors fallback keeps the check perceivable in Windows High Contrast.

Anatomy

Compose the checkbox from its parts. Checkbox.Root is a Base UI Checkbox, so toggling, the hidden form input, and the state attributes come for free.

  • Checkbox.Root — the box; owns the checked state (checked / onCheckedChange, or uncontrolled defaultChecked), the indeterminate flag, the shared size, and form props (name, value, required, readOnly). Mounts a default Indicator when given no children.
  • Checkbox.Indicator — the glyph holder; draws the check in when ticked and the minus when indeterminate. Render it explicitly only to customise it.
  • Checkbox.Field — the labelled row; links a Checkbox.Label to the box (clicking the label toggles it), holds the box↔label gap, and cascades its size.
  • Checkbox.Label — the visible accessible name; mirrors the field's disabled and invalid state.
  • CheckboxGroup — shares one selected-value list across a set of checkboxes (value / onValueChange, or uncontrolled defaultValue); pass allValues to drive a parent checkbox, and orientation to lay the group out in a row.

Every rendered part carries a data-slot (noctis-checkbox on the box, noctis-checkbox-indicator on the glyph holder, noctis-checkbox-field / noctis-checkbox-label on the labelled row, noctis-checkbox-group on the group) for host-side styling — pair it with the Base UI state attributes (data-checked, data-unchecked, data-indeterminate, data-disabled, data-readonly, data-invalid) and the group's data-orientation.

On surfaces

The same control re-tuned across the elevation scopes — the root canvas, an elevated panel, a menu, and a sunken well. It stays legible on every layer.

root
elevated
menu
sunken

Design tokens

Generated from the component's declaration — the same graph that mints the CSS, so a variable name or its resolution default can't drift. The minted tokens are the public override seam: set one on any ancestor and every checkbox in that region retunes — e.g. .dense { --noctis-checkbox-group-gap: 0.375rem; } tightens a group beneath it. Knobs that aren't minted are reached through the part's data-slot. See Customization for the full override ladder and Tokens for the whole graph.

Token

API reference

Generated from the component's types — every prop, type, default, and description comes straight from the source. Each part gets its own table; the Root forwards the Base UI Checkbox props it owns toggling through. Expand a row for the full type and description.

Checkbox.Root

Prop

Checkbox.Indicator

Prop

Checkbox.Field

Prop

Checkbox.Label

Prop

AttributeDescription
data-slotThe styling/testing hook — the slot name the precompiled CSS keys off.
data-sizeStamps the size axis (`sm` / `md` / `lg`) on the box, re-pointing the size internals.
data-checkedPresent on the box and indicator while the checkbox is ticked.
data-uncheckedPresent on the box and indicator while the checkbox is not ticked.
data-indeterminatePresent while the checkbox is in the mixed (indeterminate) state.
data-disabledPresent while the checkbox is disabled.
data-readonlyPresent while the checkbox is read-only — valid and announced, but not editable.
data-invalidPresent while the checkbox is in an invalid state (also honours `aria-invalid`).
data-orientationStamps the group's layout axis (`vertical` / `horizontal`) on `noctis-checkbox-group`.