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.
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.
Use checked and onCheckedChange to control the state. onCheckedChange also receives event details.
Two-factor authentication is off.
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.
Five sizes are available: xs, sm, md, lg, and xl. The label and description type scale with the tile.
disabled stops interaction and dims the whole row; readOnly keeps focus behavior but prevents changing the checked state.
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.
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | — | Visible label rendered inside the control. It becomes the accessible name unless aria-label or aria-labelledby is provided. |
description | ReactNode | — | 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. |
checked | boolean | — | Controlled checked state. |
defaultChecked | boolean | false | Initial checked state when uncontrolled. |
indeterminate | boolean | false | Mixed state; sets aria-checked="mixed" when true. |
onCheckedChange | (checked: boolean, details) => void | — | Called when the checked state changes. |
disabled | boolean | false | Disables interaction. |
readOnly | boolean | false | Prevents changes while remaining focusable. |
required | boolean | false | Requires the checkbox to be checked for form submission. |
name | string | — | Form field name. |
form | string | — | ID of the form that owns the hidden input. |
value | string | — | Value submitted with the form when checked. |
uncheckedValue | string | — | Value submitted with the form when unchecked. |
parent | boolean | false | Whether this checkbox controls a group of child checkboxes inside a CheckboxGroup. |
id | string | — | ID of the hidden input, or of the root element when nativeButton is true. |
inputRef | Ref<HTMLInputElement> | — | Ref to the hidden native input. |
nativeButton | boolean | false | Whether the rendered element is a native <button>. |
render | ReactElement | ((props, state) => ReactElement) | — | Replaces the root element. |
ref | Ref<HTMLElement> | — | Ref forwarded to the root element. |
className | string | — | Tailwind classes merged into the checkbox root. |
style | CSSProperties | — | 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. |
| Attribute | Description |
|---|---|
data-checked | Present when the checkbox is checked. |
data-unchecked | Present when the checkbox is not checked. |
data-indeterminate | Present when the checkbox is in an indeterminate state. |
data-disabled | Present when the checkbox is disabled. |
data-readonly | Present when the checkbox is read-only. |
data-required | Present when the checkbox is required. |
data-valid | Present when the checkbox is valid and wrapped in Field. |
data-invalid | Present when the checkbox is invalid and wrapped in Field. |
data-touched | Present after the checkbox is touched while wrapped in Field. |
data-dirty | Present after the checkbox value changes while wrapped in Field. |
data-filled | Present when the checkbox is checked while wrapped in Field. |
data-focused | Present when the checkbox is focused while wrapped in Field. |
data-starting-style | Present when the indicator begins animating in. |
data-ending-style | Present when the indicator is animating out. |
data-slot | Marks internal parts (root, box, fill, glass, overlay, indicator, indicator-icon, wrapper, label, description) for styling. |
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.