Components

Checkbox

A React checkbox with a Liquid Glass tile, animated check, and indeterminate state.

Checkbox renders the glass tile, check or dash indicator, optional label and description, and a hidden native checkbox for form submission.

The tile keeps the glass surface when unchecked; when checked it fills with --ui-ink and reveals the mark with a scale animation. The indeterminate mixed state is supported.

Basic example

label and description render to the right of the tile, and the entire row is clickable. When checked is omitted the component is uncontrolled; use defaultChecked for the initial state.

Product updatesReceive an email when a new release ships.Security alertsGet notified about sign-ins from new devices.Research invitesOccasional invitations to product interviews.

Controlled usage

Use checked and onCheckedChange to control the state. onCheckedChange also receives event details.

Enable two-factor authenticationRequire a verification code when signing in.

Two-factor authentication is off.

Indeterminate state

indeterminate renders a mixed state with a dash mark. It is commonly used for a "select all" parent: set indeterminate when some children are selected and checked when all of them are.

Email notificationsChoose the channels you want to hear about.
CommentsReplies and mentions on your projects.ReleasesNew versions published by your team.BillingInvoices, receipts, and payment failures.

Sizes

Five sizes are available: xs, sm, md, lg, and xl. The label and description type scale with the tile.

Size xsSize smSize mdSize lgSize xl

Disabled and read-only

disabled stops interaction and dims the whole row; readOnly keeps focus behavior but prevents changing the checked state.

DisabledThe checked value is visible but cannot change.Read-onlyFocus and selection work, but the value cannot change.

Accessibility

Checkbox renders a focusable element with role="checkbox" and aria-checked (a <span> by default), plus a hidden native checkbox for form submission. The visible label names it and description is linked with aria-describedby; explicit ARIA names take precedence.

Space toggles the focused control. indeterminate sets aria-checked="mixed". Use required when a checked state is mandatory, and see the accessibility guide for form patterns.

API reference

PropTypeDefaultDescription
labelReactNode—Visible label rendered inside the control. It becomes the accessible name unless aria-label or aria-labelledby is provided.
descriptionReactNode—Supporting copy under the label, linked with aria-describedby when the control has a name.
size"xs" | "sm" | "md" | "lg" | "xl""md"Tile, icon, and text size.
checkedboolean—Controlled checked state.
defaultCheckedbooleanfalseInitial checked state when uncontrolled.
indeterminatebooleanfalseMixed state; sets aria-checked="mixed" when true.
onCheckedChange(checked: boolean, details) => void—Called when the checked state changes.
disabledbooleanfalseDisables interaction.
readOnlybooleanfalsePrevents changes while remaining focusable.
requiredbooleanfalseRequires the checkbox to be checked for form submission.
namestring—Form field name.
formstring—ID of the form that owns the hidden input.
valuestring—Value submitted with the form when checked.
uncheckedValuestring—Value submitted with the form when unchecked.
parentbooleanfalseWhether this checkbox controls a group of child checkboxes inside a CheckboxGroup.
idstring—ID of the hidden input, or of the root element when nativeButton is true.
inputRefRef<HTMLInputElement>—Ref to the hidden native input.
nativeButtonbooleanfalseWhether the rendered element is a native <button>.
renderReactElement | ((props, state) => ReactElement)—Replaces the root element.
refRef<HTMLElement>—Ref forwarded to the root element.
classNamestring—Tailwind classes merged into the checkbox root.
styleCSSProperties—Inline styles merged into the same element as className.
ui{ root?: ClassValue; box?: ClassValue; fill?: ClassValue; glass?: ClassValue; overlay?: ClassValue; indicator?: ClassValue; indicatorIcon?: ClassValue; wrapper?: ClassValue; label?: ClassValue; description?: ClassValue }—Tailwind classes for internal slots, keyed by data-slot.
AttributeDescription
data-checkedPresent when the checkbox is checked.
data-uncheckedPresent when the checkbox is not checked.
data-indeterminatePresent when the checkbox is in an indeterminate state.
data-disabledPresent when the checkbox is disabled.
data-readonlyPresent when the checkbox is read-only.
data-requiredPresent when the checkbox is required.
data-validPresent when the checkbox is valid and wrapped in Field.
data-invalidPresent when the checkbox is invalid and wrapped in Field.
data-touchedPresent after the checkbox is touched while wrapped in Field.
data-dirtyPresent after the checkbox value changes while wrapped in Field.
data-filledPresent when the checkbox is checked while wrapped in Field.
data-focusedPresent when the checkbox is focused while wrapped in Field.
data-starting-stylePresent when the indicator begins animating in.
data-ending-stylePresent when the indicator is animating out.
data-slotMarks internal parts (root, box, fill, glass, overlay, indicator, indicator-icon, wrapper, label, description) for styling.

Theming

The component uses the shared glass material. Tune shared --ui-glass-* tokens on a parent, use className for layout, and use ui for internal slots keyed by data-slot. Component-specific values live in src/theme/checkbox.ts. See the theming guide for token layers and presets.

  • Switch — For settings that take effect immediately.
  • Radio Group — For choosing one option from a small set.
  • Toggle — For a one-off pressed action.