Installation
$Terminal
npx shadcn@latest add https://sdk-components.thesqd.com/r/checkbox.jsonUsage
Pair the Checkbox with a Label and connect them by id for accessibility.
TSImport
import { Checkbox, CheckboxGroup } from "@/components/ui/checkbox";TSExample
import { Checkbox } from "@/components/ui/checkbox";
export function Example() {
return (
<Checkbox
label="Accept terms and conditions"
caption="By clicking this checkbox, you agree to the terms and conditions."
/>
);
}Composition
Anatomy of the Checkbox primitive.
Checkbox (single checkbox — pass label/caption as props)
├── label={<ReactNode>} (auto-emits a <Label htmlFor={id}>)
├── caption={<ReactNode>} (helper text stacked under the label)
├── variant="disclaimer" (disclaimer layout: label → caption → left-aligned "I agree" → error)
├── strikeWhenChecked (line-through label when checked — todo affordance)
├── size="sm" | "default" | "lg" (box size; disclaimer defaults to "lg")
├── required / error (red asterisk + error message; required only renders in disclaimer)
└── ...rest (checked / defaultChecked / onCheckedChange / disabled / id / className)
CheckboxGroup (list-shape — one Checkbox per option)
├── options={[{ value, label, caption?, disabled? }]}
├── value / defaultValue / onValueChange (controlled or uncontrolled string[])
├── variant="vertical" | "horizontal" | "badge" (default: "vertical")
├── label / caption / required / error
└── size / disabled / itemClassName
Pass any custom layout by mapping <Checkbox> yourself; CheckboxGroup is a
convenience for the three common shapes.Basic
Single checkbox with an associated label.
Sizes
Three sizes via the `size` prop — `sm` (size-4), `default` (size-5, the original), and `lg` (size-6). Disclaimer variant ships at `lg` automatically.
Horizontal group
Multiple checkboxes laid out inline with wrapping.
With description
Label + helper text stacked beside the checkbox.
By clicking this checkbox, you agree to the terms and conditions.
Todo list item
Checked label strikes through via a `peer` selector.
Badge chips
Whole-badge toggle — the checkbox only renders when selected.
With “Other”
Pass `otherOption` and the group renders a trailing checkbox that reveals an inline text input when checked — same pattern as RadioGroup.
Selected: 1
Disclaimer
Bold label (+ required asterisk), description paragraph, left-aligned "I agree" checkbox, and optional error message.
By checking this box you confirm you have read and agree to our Terms of Service and Privacy Policy.
API Reference
Props exposed by the Checkbox + CheckboxGroup primitives.
Checkbox
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | — | Auto-emits a <Label htmlFor={id}> beside the checkbox. Omit for a bare checkbox. |
caption | ReactNode | — | Helper text stacked beneath the label. Switches the layout to start-aligned. |
checked | boolean | — | Controlled checked state. |
defaultChecked | boolean | false | Uncontrolled initial checked state. |
onCheckedChange | (checked: boolean) => void | — | Fires when the checked state changes. |
disabled | boolean | false | Disables interaction and dims the control. |
className | string | — | Override or extend the resolved Checkbox classes. |
variant | "disclaimer" | — | When set to "disclaimer", renders a structured layout: bold label → description → left-aligned "I agree" checkbox → error. |
size | "sm" | "default" | "lg" | "default" ("lg" in disclaimer variant) | Box size: sm (size-4), default (size-5, the original), lg (size-6). Disclaimer variant defaults to lg so the confirmation reads as deliberate. |
required | boolean | — | Adds a red asterisk after the label. Only visible in the disclaimer variant. |
error | string | — | Error message shown below the "I agree" row. Only used in the disclaimer variant. |
strikeWhenChecked | boolean | false | Adds `line-through` to the label when the checkbox is checked. |
CheckboxGroup
| Prop | Type | Default | Description |
|---|---|---|---|
options | CheckboxGroupOption[] | — | One option per checkbox. See the next table for the option shape. |
value | string[] | — | Controlled list of selected `option.value`s. |
defaultValue | string[] | — | Initial selection when uncontrolled. |
onValueChange | (value: string[]) => void | — | Fires whenever the selection set changes. |
variant | "vertical" | "horizontal" | "badge" | "vertical" | Layout variant. `badge` wraps each option in a Badge chip and only renders the checkbox when selected. |
label | ReactNode | — | Group label rendered above the options. |
caption | ReactNode | — | Helper text rendered below the options. |
required | boolean | — | Adds a red asterisk after the group label. |
error | string | — | Error message rendered in place of the description. |
size | "sm" | "default" | "lg" | — | Forwarded to every Checkbox in the group. |
disabled | boolean | — | Disables every option in the group. |
CheckboxGroupOption
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Stable identifier stored in `value` / `defaultValue`. |
label | ReactNode | — | Visible label. |
caption | ReactNode | — | Helper text under the label (vertical/horizontal variants only). |
disabled | boolean | — | Disable just this option. |