Checkbox
An on or off choice that is saved with the rest of a form, with an indeterminate state for select all.
npx prodular-ui add checkboxWith labels
import { Checkbox } from "@/components/ui/checkbox"import { Field, FieldLabel } from "@/components/ui/field"
export default function CheckboxDefault() { return ( <div className="flex flex-col gap-3"> <Field orientation="horizontal"> <Checkbox defaultChecked /> <FieldLabel>Email me when a deal closes</FieldLabel> </Field> <Field orientation="horizontal"> <Checkbox /> <FieldLabel>Include archived projects</FieldLabel> </Field> <Field orientation="horizontal" disabled> <Checkbox defaultChecked /> <FieldLabel>Require two-factor sign-in</FieldLabel> </Field> </div> )}Group with select all
The parent checkbox turns indeterminate when only some are checked.
"use client"
import * as React from "react"
import { Checkbox } from "@/components/ui/checkbox"import { Field, FieldContent, FieldDescription, FieldGroup, FieldLabel, FieldLegend, FieldSet,} from "@/components/ui/field"
const scopes = [ { id: "read", label: "Read projects", description: "List projects, issues and comments." }, { id: "write", label: "Write issues", description: "Create and update issues on your behalf." }, { id: "admin", label: "Manage members", description: "Invite, remove and change roles." },]
export default function CheckboxGroup() { const [checked, setChecked] = React.useState<string[]>(["read"]) const all = checked.length === scopes.length const some = checked.length > 0 && !all
return ( <FieldSet className="w-full max-w-sm"> <FieldLegend variant="label">API key permissions</FieldLegend> <FieldGroup data-slot="checkbox-group" className="gap-4"> <Field orientation="horizontal" className="border-b pb-4"> <Checkbox checked={all} indeterminate={some} onCheckedChange={(value) => setChecked(value ? scopes.map((s) => s.id) : [])} /> <FieldLabel>Select all</FieldLabel> </Field> {scopes.map((scope) => ( <Field key={scope.id} orientation="horizontal"> <Checkbox checked={checked.includes(scope.id)} onCheckedChange={(value) => setChecked((prev) => (value ? [...prev, scope.id] : prev.filter((id) => id !== scope.id))) } /> <FieldContent> <FieldLabel>{scope.label}</FieldLabel> <FieldDescription>{scope.description}</FieldDescription> </FieldContent> </Field> ))} </FieldGroup> </FieldSet> )}Anatomy
<Field orientation="horizontal"> <Checkbox defaultChecked /> <FieldLabel>Email me when a deal closes</FieldLabel></Field>Guidance
Use it when
- Choices that are saved when the form is submitted.
- Several independent options from a list, such as permissions.
Avoid
- Settings that apply the moment they change. Use Switch.
- One choice from several. Use RadioGroup.
Rules for AI agents
Published in llms-full.txt, the registry and the MCP server, so coding agents follow them when they build with this component.
- Put Checkbox and its FieldLabel inside Field orientation="horizontal", checkbox first. The label is linked automatically.
- Use indeterminate (not checked) on a select-all checkbox when only some children are checked.
- Write the label as the positive statement (Email me when a deal closes), never a negation.
API
Checkbox
| Prop | Type | Default | Description |
|---|---|---|---|
| checked / defaultChecked | boolean | Controlled or initial state. | |
| indeterminate | boolean | false | Shows a dash. Use for partial selection. |
| onCheckedChange | (checked: boolean) => void | Called when toggled. | |
| disabled | boolean | Blocks interaction and dims the control. |
Installation
The Prodular UI CLI adds the source to components/ui with everything it depends on. In a project that already uses shadcn/ui, the shadcn CLI installs it from the Prodular registry too. See Installation for the first setup.
npx prodular-ui add checkbox# or, with the registry in components.jsonnpx shadcn@latest add @prodular/checkbox