Checkbox
A single opt-in — terms acceptance, a marketing consent. Carries its own label, so it does not go inside a Field.
import Checkbox from '@/components/ui/Checkbox';Source: src/components/ui/Checkbox.tsx
Examples
States
The `required` prop INTERCEPTS the native attribute rather than passing it on. The native gate fires before the form’s own submit handler and would pre-empt the inline error, so the component marks itself and validates in the same pass as everything else.
A label with a link in it
The label takes rich content, which matters for the commonest case of all: a consent sentence containing a link to the terms.
label is a ReactNode, so a TextLink inside it works — and the link stays clickable without toggling the box.
Props
<Checkbox> props
| Prop | Type | Default | Description |
|---|---|---|---|
labelrequired | React.ReactNode | — | Plain text or rich content (e.g. a sentence with TextLinks in it). |
error | string | — | Validation message shown in red below the label, matching Input's `error`. |
required | boolean | false | Marks the box as required: an asterisk after the label and `aria-required` on the input. Same contract as Field's `required` — it INTERCEPTS the native attribute rather than passing it on, because that gate fires before the form's own submit handler and pre-empts the inline `error` below. A checkbox can't use Field (it carries its own label), so it marks itself. |
Also accepts everything in InputHTMLAttributes<HTMLInputElement> — so native attributes (id, onClick, aria-*, data-*) pass straight through.
Accessibility
- Real <input type="checkbox">, so Space toggles it and the label is clickable.
- aria-invalid and aria-describedby are wired when `error` is set; `required` also sets aria-required.
Usage
Do
- Use one for a single yes/no. For several independent options, use several checkboxes.
Don’t
- Don’t wrap it in a Field — it labels itself, which is why it has its own `required`.
- Don’t use a checkbox for a setting that takes effect immediately; that is a Toggle.