Aboard Nexus
Forms

Checkbox

Select an independent option or represent a mixed selection.

Checkbox represents an independently selectable option. A mixed state summarizes a group where only some items are selected.

'use client'import { useState } from 'react'import { Checkbox } from '@aboard/ui/core/checkbox'export default function CheckboxExample() {const [checked, setChecked] = useState(false)const [indeterminate, setIndeterminate] = useState(false)const disabled = falsereturn (<label className="flex items-center gap-2 text-sm">  <Checkbox checked={checked} disabled={disabled} indeterminate={indeterminate}    onCheckedChange={(checked) => { setChecked(checked); setIndeterminate(false) }} />    {"Enable notifications"}  </label>  )  }
checked
Disabled
Indeterminate

When to use

Use checkboxes for independent choices, selection lists, or acknowledgement before submission. Use radio buttons for one mutually exclusive choice and a switch for a setting applied immediately. A checked acknowledgement is not authorization for a privileged operation.

Import and examples

These snippets assume Tailwind scans packages/ui/src/core, the full packages/ui/src/styles/reui/style-nova.css is loaded alongside shadcn/tailwind.css and tw-animate-css, and the application provides the semantic theme tokens. Render them inside a style-nova ancestor (for example, <div className="style-nova">). Copying the JSX alone does not reproduce Nova styling.

import { Checkbox } from '@aboard/ui/core/checkbox'
import { Field, FieldDescription, FieldLabel } from '@aboard/ui/core/field'

export function NotificationOption() {
  return (
    <Field>
      <div className="flex items-center gap-2">
        <Checkbox id="notifications" name="notifications" defaultChecked
          aria-describedby="notifications-help" />
        <FieldLabel htmlFor="notifications">Include task notifications</FieldLabel>
      </div>
      <FieldDescription id="notifications-help">
        Include task updates in the next summary.
      </FieldDescription>
    </Field>
  )
}

Derive select-all state from the child selection. Mixed state is a separate boolean prop, not checked="indeterminate".

'use client'

import { useState } from 'react'
import { Checkbox } from '@aboard/ui/core/checkbox'

const items = ['Design notes', 'Review checklist']

export function DocumentSelection() {
  const [selected, setSelected] = useState<string[]>([items[0]])
  return (
    <fieldset className="flex flex-col gap-3">
      <legend>Documents to include</legend>
      <label className="flex items-center gap-2">
        <Checkbox checked={selected.length === items.length}
          indeterminate={selected.length > 0 && selected.length < items.length}
          onCheckedChange={(checked) => setSelected(checked ? [...items] : [])} />
        Select all documents
      </label>
      {items.map((item) => (
        <label key={item} className="flex items-center gap-2">
          <Checkbox checked={selected.includes(item)}
            onCheckedChange={(checked) => setSelected((current) =>
              checked ? [...current, item] : current.filter((value) => value !== item))} />
          {item}
        </label>
      ))}
    </fieldset>
  )
}

Props and defaults

The wrapper accepts Base UI 1.7.0 Checkbox.Root.Props. Derive the wrapper type with React.ComponentProps<typeof Checkbox>.

PropTypeDefault and behavior
checkedbooleanundefined; controlled when supplied.
defaultCheckedbooleanfalse; initial uncontrolled selection.
onCheckedChange(checked: boolean, eventDetails) => voidNo handler; update controlled state here.
indeterminatebooleanfalse; mixed state independent of checked.
disabledbooleanfalse; ignores user interaction.
readOnlybooleanfalse; prevents toggling.
requiredbooleanfalse; must be checked for native form validity.
id / namestringUnset; label target and form field name.
valuestringChecked form value defaults to native "on".
uncheckedValuestringUnset; unchecked controls normally submit no value.
inputRefReact.Ref<HTMLInputElement>Unset; access to the hidden input.

Do not mix checked and defaultChecked. The wrapper owns the indicator, so place label text outside Checkbox, not in its children. The upstream parent prop requires Checkbox Group; it does not automatically manage a group in this wrapper. The example manages selection explicitly.

Composition and accessibility

Associate a visible label through htmlFor and id, or wrap the checkbox in a native label. Use fieldset and legend for related choices, aria-describedby for helper/error text, and aria-invalid for known invalid state. Base UI supplies the interactive checkbox and a hidden input for form participation.

Tab focuses available controls; Space toggles the focused checkbox. Preserve the focus ring and a generous label hit target. Disabled and read-only have different interaction semantics; neither is a permission check. The wrapper renders a Check icon when checked and a Minus icon when indeterminate. The Minus indicator is an Aboard extension: pinned ReUI uses Check for both states, so this is not an exact upstream copy. Both icons are hidden from assistive technology; the checkbox state, not the glyph, carries its accessible meaning.

State evidence and limits

The registered preview exposes checked, disabled, and indeterminate, each initially false. Its generated example includes those values and a controlled change handler. Toggling the live checkbox updates checked state and clears indeterminate; the separate controls can still change the sample while its checkbox is disabled. readOnly, required, and form submission values are package APIs, not controls in this Preview.

Source evidence is packages/ui/src/core/checkbox.tsx and apps/site/components/component-preview/interactive-samples.tsx. @aboard/ui is version 0.1.0 and pins @base-ui/react to 1.7.0; the props above follow that installed version. The recorded adaptation source is ReUI Checkbox, pinned to commit 8a2c701eaf95729f238274d5ce2555a5a8bd23e7. Local package imports and the Lucide indicator adaptation, including the mixed-state Minus extension, remain explicit Aboard differences.

These source-backed descriptions do not claim completed browser tests or verified state/code parity. The examples use local state, not saved preferences or real document operations.

For Agents

aboard.ui.component.forms.checkbox identifies this documentation capability. Trusted application code can import the installed React component. This does not prove a declarative Checkbox descriptor schema, renderer, or persisted binding exists. Specify the label, initial state, group ownership, and submission intent for handoff; verify the actual contribution contract before emitting a descriptor. Documentation and contract are partial; declarative runtime, security, and tests remain uncertain. The Preview cannot grant consent or execute a Workspace mutation.

How is this guide?

On this page