Checkbox
A control that toggles between checked, unchecked, and indeterminate states. Built on Radix Checkbox for full keyboard accessibility, with aria-invalid styling for form validation. For form-submitted boolean inputs, use Checkbox. For instant-action toggles (e.g., enable a feature), prefer Toggle.
Installation
npx shadcn@latest add @wuko/checkboxUsage
import { Checkbox } from "@/components/ui/checkbox";
export function Example() {
return (
<label className="flex items-center gap-2">
<Checkbox />
Accept terms and conditions
</label>
);
}Checked state
Use defaultChecked for uncontrolled checkboxes, or checked and onCheckedChange to control the state.
"use client";
import * as React from "react";
import { Checkbox } from "@/components/ui/checkbox";
export function Example() {
const [checked, setChecked] = React.useState(false);
return <Checkbox checked={checked} onCheckedChange={setChecked} />;
}Indeterminate
Set checked="indeterminate" for a third state — useful when a parent checkbox represents partial selection of its children (e.g., a header checkbox controlling some-but-not-all selected rows).
<Checkbox checked="indeterminate" />Invalid state
Set aria-invalid="true" to indicate a validation error. The border and focus ring turn red.
<label className="flex items-center gap-2">
<Checkbox aria-invalid="true" />
Accept terms and conditions
</label>Disabled
Use the disabled prop to prevent interaction. Pair with muted label styling for context.
<label className="flex items-center gap-2 opacity-50">
<Checkbox disabled />
Enable notifications
</label>Group
Use multiple labeled checkboxes under a shared heading for selection lists. Each maintains independent state.
Props
Forwards all props to the underlying Radix Checkbox. The most commonly used props are listed below.
| Prop | Type | Default | Description |
|---|---|---|---|
| checked | boolean | "indeterminate" | false | Controlled checked state. Use the literal string "indeterminate" for the third state. |
| defaultChecked | boolean | false | Initial checked state for uncontrolled use. Use checked + onCheckedChange for controlled state. |
| onCheckedChange | (checked: boolean | "indeterminate") => void | — | Fires when the checked state changes. |
| disabled | boolean | false | Disables interaction and reduces opacity. |
| required | boolean | false | Marks the checkbox as required for form submission. |
| aria-invalid | boolean | "true" | "false" | — | When true, applies the invalid state styling (red border, red focus ring). |
| name | string | — | The name attribute submitted with form data. |
| value | string | "on" | The value submitted with form data when checked. |
| className | string | — | Additional Tailwind classes merged with defaults. |
Accessibility
- Built on Radix Checkbox. Keyboard support: Tab to focus, Space to toggle. Screen readers announce checked, unchecked, and indeterminate states.
- Wrap each checkbox in a
<label>with associated text. Clicking the label toggles the checkbox and screen readers announce the label as the checkbox's name. - For invalid state, set
aria-invalid="true". The styling change is paired with the ARIA attribute so screen readers announce the validation state. - The
peerutility on the underlying Radix Root lets you style sibling elements based on checkbox state (e.g.,peer-disabled:opacity-50on a label). - For checkboxes in form submissions, set the
nameprop. The value (default"on") is submitted when checked.