Installation
Theme
Mode

Forms & input

Checkbox, Radio & Toggle

The three selection primitives, unified. Checkboxes for many-of, radios for one-of, toggles for instant on/off — shared states, sizing, and keyboard behavior, built on Base UI.

$npx shadcn@latest add @orbit/checkbox @orbit/radio-group @orbit/switch

When to use

Pick by selection logic, not by looks.

Live — click to toggle
Checkbox — many-of. Each option is independent.
Radio — one-of. Choosing clears the rest. Never fewer than two.
Toggle — instant on/off. Applies immediately, no Save.

Sizes

Two sizes, matched to the rest of the form family: md 18px control (default) · sm 16px control.

md · 18px control
sm · 16px control

States

Each kind shares the same vocabulary: unselected, selected, focus ring, disabled — plus indeterminate for checkboxes. Tab through any demo to see the 3px themed focus ring.

Checkbox — including the indeterminate dash
Radio
Toggle

Groups

Common patterns: a radio group with descriptions, a checkbox group with select-all, and a toggle settings list.

Radio — group label and descriptions
Visibility
Checkbox — select-all with indeterminate parent
1 / 4
Toggle — settings list

Props

Checkbox

PropTypeDefaultDescription
labelReactNodeRow label. When present, the control is wrapped in a <label> so the whole row is a hit target.
descriptionReactNodeSecondary line under the label.
size"sm" | "md""md"Control size: 16px or 18px box.
checked / defaultCheckedbooleanfalseControlled / uncontrolled checked state.
onCheckedChange(checked, details) => voidCalled when the checkbox is ticked or unticked.
indeterminatebooleanfalseMixed state — renders the dash. Clears to a normal toggle on interaction; keep it in sync with child rows.
disabledbooleanfalseBlocks interaction and mutes the row.
…restCheckbox.Root propsEverything else (name, value, required, inputRef, …) is forwarded to Base UI Checkbox.Root, including ref.

RadioGroup / RadioGroupItem

PropTypeDefaultDescription
labelReactNodeGroup: heading rendered above the options (wired via aria-labelledby). Item: row label.
descriptionReactNodeSecondary line — under the group heading, or under an item's label.
size"sm" | "md""md"Group only. Control size, inherited by every item.
orientation"vertical" | "horizontal""vertical"Group only. Stack options or flow them in a row.
value / defaultValuestringGroup only. Controlled / uncontrolled selected value.
onValueChange(value, details) => voidGroup only. Called when the selection changes.
value (item)stringItem only, required. The value this radio represents.
disabledbooleanfalseOn the group, disables every item; on an item, just that row.
…restRadioGroup / Radio.Root propsForwarded to Base UI RadioGroup and Radio.Root respectively, including ref.

Switch

PropTypeDefaultDescription
labelReactNodeRow label. When present, the track sits on the trailing edge of the row — set w-full for a settings-row layout.
descriptionReactNodeSecondary line under the label.
size"sm" | "md""md"Track size: 30×18 or 34×20.
checked / defaultCheckedbooleanfalseControlled / uncontrolled on state.
onCheckedChange(checked, details) => voidCalled when the switch flips.
disabledbooleanfalseBlocks interaction and mutes the row.
…restSwitch.Root propsEverything else (name, value, required, inputRef, …) is forwarded to Base UI Switch.Root, including ref.

Usage

Do

Match the control to the logic

Checkbox for many-of, radio for one-of, toggle for an instant on/off setting.

Don’t

Use a toggle inside a form

Toggles apply instantly; if a choice needs Save, use a checkbox instead.

Do

Make the whole row a target

Label and control are one hit area — generous and easy to tap.

Don’t

Offer a single radio

Radios need at least two choices; a lone option should be a checkbox.

Keyboard & accessibility

Base UI provides the semantics: checkbox / radio / switch roles, aria-checked (including mixed), roving focus within radio groups, and label-bound rows. The 3px focus ring uses the themed --ring token.

TabMove to the control / group
SpaceToggle checkbox & switch
↑ ↓Move within a radio group
rolecheckbox / radio / switch
aria-checkedReflects on / mixed
labelBound to each control
Tab to see the focus ring