Github

Checkbox

A control that allows the user to toggle between checked and not checked.

By clicking this checkbox, you agree to the terms.

import { Checkbox } from "@/components/ui/checkbox";
import {
	Field,
	FieldContent,
	FieldDescription,
	FieldGroup,
	FieldLabel,
	FieldTitle,
} from "@/components/ui/field";

export function CheckboxDemo() {
	return (
		<FieldGroup className="w-full max-w-sm">
			<Field orientation="horizontal">
				<Checkbox
					id="checkbox-demo-terms-2"
					name="checkbox-demo-terms-2"
					defaultChecked
				/>
				<FieldContent>
					<FieldLabel htmlFor="checkbox-demo-terms-2">
						Accept terms and conditions
					</FieldLabel>
					<FieldDescription>
						By clicking this checkbox, you agree to the terms.
					</FieldDescription>
				</FieldContent>
			</Field>
			<Field orientation="horizontal" data-disabled>
				<Checkbox
					id="checkbox-demo-notify-off"
					name="checkbox-demo-notify-off"
					disabled
				/>
				<FieldLabel htmlFor="checkbox-demo-notify-off">
					Enable notifications
				</FieldLabel>
			</Field>
			<FieldLabel>
				<Field orientation="horizontal">
					<Checkbox
						id="checkbox-demo-notify-on"
						name="checkbox-demo-notify-on"
					/>
					<FieldContent>
						<FieldTitle>Enable notifications</FieldTitle>
						<FieldDescription>
							You can enable or disable notifications at any time.
						</FieldDescription>
					</FieldContent>
				</Field>
			</FieldLabel>
		</FieldGroup>
	);
}

Installation

pnpm dlx shadcn@latest add https://herocn.dev/r/checkbox.json

Usage

import { Checkbox } from "@/components/ui/checkbox"
<Checkbox />

Composition

The checkbox is implemented as a single root control with a built-in check indicator:

Checkbox (Root)
└── Indicator (check icon, always mounted)

Pair it with Field and FieldLabel (or Label) so the control has an accessible name and correct layout.

Checked state

Use defaultChecked for uncontrolled checkboxes, or checked and onCheckedChange for controlled 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={(value) => setChecked(value)} />
  )
}

Examples

Basic

Pair the checkbox with Field, FieldGroup, and FieldLabel for proper layout and labeling.

import { Checkbox } from "@/components/ui/checkbox";
import { Field, FieldGroup, FieldLabel } from "@/components/ui/field";

export function CheckboxBasic() {
	return (
		<FieldGroup className="mx-auto w-full max-w-xs">
			<Field orientation="horizontal">
				<Checkbox id="checkbox-basic-terms" name="checkbox-basic-terms" />
				<FieldLabel htmlFor="checkbox-basic-terms">
					Accept terms and conditions
				</FieldLabel>
			</Field>
		</FieldGroup>
	);
}

Variants

Use the variant prop for a softer, shadow-free secondary style (for example on tinted or secondary surfaces).

import { Checkbox } from "@/components/ui/checkbox";
import { Field, FieldGroup, FieldLabel } from "@/components/ui/field";

export function CheckboxVariants() {
	return (
		<FieldGroup className="mx-auto w-full max-w-xs gap-4">
			<Field orientation="horizontal">
				<Checkbox id="checkbox-variant-default" />
				<FieldLabel htmlFor="checkbox-variant-default" className="font-normal">
					Default
				</FieldLabel>
			</Field>
			<Field orientation="horizontal">
				<Checkbox id="checkbox-variant-secondary" variant="secondary" />
				<FieldLabel
					htmlFor="checkbox-variant-secondary"
					className="font-normal"
				>
					Secondary
				</FieldLabel>
			</Field>
		</FieldGroup>
	);
}

Description

Use FieldContent and FieldDescription for helper text beside the control.

By clicking this checkbox, you agree to the terms and conditions.

import { Checkbox } from "@/components/ui/checkbox";
import {
	Field,
	FieldContent,
	FieldDescription,
	FieldGroup,
	FieldLabel,
} from "@/components/ui/field";

export function CheckboxDescription() {
	return (
		<FieldGroup className="mx-auto w-full max-w-xs">
			<Field orientation="horizontal">
				<Checkbox
					id="checkbox-desc-terms"
					name="checkbox-desc-terms"
					defaultChecked
				/>
				<FieldContent>
					<FieldLabel htmlFor="checkbox-desc-terms">
						Accept terms and conditions
					</FieldLabel>
					<FieldDescription>
						By clicking this checkbox, you agree to the terms and conditions.
					</FieldDescription>
				</FieldContent>
			</Field>
		</FieldGroup>
	);
}

Disabled

Pass disabled to the checkbox. Add data-disabled on the surrounding Field so disabled field styles apply consistently.

import { Checkbox } from "@/components/ui/checkbox";
import { Field, FieldGroup, FieldLabel } from "@/components/ui/field";

export function CheckboxDisabled() {
	return (
		<FieldGroup className="mx-auto w-full max-w-xs">
			<Field orientation="horizontal" data-disabled>
				<Checkbox
					id="checkbox-disabled-notify"
					name="checkbox-disabled-notify"
					disabled
				/>
				<FieldLabel htmlFor="checkbox-disabled-notify">
					Enable notifications
				</FieldLabel>
			</Field>
		</FieldGroup>
	);
}

Invalid

Set aria-invalid on the checkbox and data-invalid on the Field wrapper to show invalid styles.

import { Checkbox } from "@/components/ui/checkbox";
import { Field, FieldGroup, FieldLabel } from "@/components/ui/field";

export function CheckboxInvalid() {
	return (
		<FieldGroup className="mx-auto w-full max-w-xs">
			<Field orientation="horizontal" data-invalid>
				<Checkbox
					id="checkbox-invalid-terms"
					name="checkbox-invalid-terms"
					aria-invalid
				/>
				<FieldLabel htmlFor="checkbox-invalid-terms">
					Accept terms and conditions
				</FieldLabel>
			</Field>
		</FieldGroup>
	);
}

Group

Use FieldSet, FieldLegend, and multiple horizontal Field rows for a checkbox list.

Show these items on the desktop

Select the items you want to show on the desktop.

Your Desktop & Documents folders are being synced with iCloud Drive. You can access them from other devices.

import { Checkbox } from "@/components/ui/checkbox";
import {
	Field,
	FieldContent,
	FieldDescription,
	FieldGroup,
	FieldLabel,
	FieldLegend,
	FieldSeparator,
	FieldSet,
} from "@/components/ui/field";

export function FieldCheckbox() {
	return (
		<FieldGroup className="w-full max-w-xs">
			<FieldSet>
				<FieldLegend variant="label">
					Show these items on the desktop
				</FieldLegend>
				<FieldDescription>
					Select the items you want to show on the desktop.
				</FieldDescription>
				<FieldGroup className="gap-3">
					<Field orientation="horizontal">
						<Checkbox id="finder-pref-9k2-hard-disks-ljj" defaultChecked />
						<FieldLabel
							htmlFor="finder-pref-9k2-hard-disks-ljj"
							className="font-normal"
						>
							Hard disks
						</FieldLabel>
					</Field>
					<Field orientation="horizontal">
						<Checkbox id="finder-pref-9k2-external-disks-1yg" />
						<FieldLabel
							htmlFor="finder-pref-9k2-external-disks-1yg"
							className="font-normal"
						>
							External disks
						</FieldLabel>
					</Field>
					<Field orientation="horizontal">
						<Checkbox id="finder-pref-9k2-cds-dvds-fzt" />
						<FieldLabel
							htmlFor="finder-pref-9k2-cds-dvds-fzt"
							className="font-normal"
						>
							CDs, DVDs, and iPods
						</FieldLabel>
					</Field>
					<Field orientation="horizontal">
						<Checkbox id="finder-pref-9k2-connected-servers-6l2" />
						<FieldLabel
							htmlFor="finder-pref-9k2-connected-servers-6l2"
							className="font-normal"
						>
							Connected servers
						</FieldLabel>
					</Field>
				</FieldGroup>
			</FieldSet>
			<FieldSeparator />
			<Field orientation="horizontal">
				<Checkbox id="finder-pref-9k2-sync-folders-nep" defaultChecked />
				<FieldContent>
					<FieldLabel htmlFor="finder-pref-9k2-sync-folders-nep">
						Sync Desktop & Documents folders
					</FieldLabel>
					<FieldDescription>
						Your Desktop & Documents folders are being synced with iCloud Drive.
						You can access them from other devices.
					</FieldDescription>
				</FieldContent>
			</Field>
		</FieldGroup>
	);
}

In surface

Use variant="secondary" when placing checkboxes inside a Surface or card so the control matches the panel background.

Folders stay available on your other devices when iCloud is on.

import { Checkbox } from "@/components/ui/checkbox";
import {
	Field,
	FieldContent,
	FieldDescription,
	FieldGroup,
	FieldLabel,
} from "@/components/ui/field";
import { Surface } from "@/components/ui/surface";

export function CheckboxInSurface() {
	return (
		<Surface className="flex w-full max-w-sm flex-col gap-4 rounded-3xl p-6">
			<FieldGroup className="gap-3">
				<Field orientation="horizontal">
					<Checkbox
						id="checkbox-surface-sync"
						name="checkbox-surface-sync"
						variant="secondary"
						defaultChecked
					/>
					<FieldContent>
						<FieldLabel htmlFor="checkbox-surface-sync">
							Sync Desktop & Documents
						</FieldLabel>
						<FieldDescription>
							Folders stay available on your other devices when iCloud is on.
						</FieldDescription>
					</FieldContent>
				</Field>
				<Field orientation="horizontal">
					<Checkbox
						id="checkbox-surface-analytics"
						name="checkbox-surface-analytics"
						variant="secondary"
					/>
					<FieldLabel
						htmlFor="checkbox-surface-analytics"
						className="font-normal"
					>
						Share analytics
					</FieldLabel>
				</Field>
			</FieldGroup>
		</Surface>
	);
}

RTL

Checkbox layout follows inline direction; use the same Field patterns as in LTR. See the RTL guide for app-wide configuration.

بالنقر على هذا المربع، فإنك توافق على الشروط.

"use client";

import {
	type Translations,
	useTranslation,
} from "@/components/language-selector";
import { Checkbox } from "@/components/ui/checkbox";
import {
	Field,
	FieldContent,
	FieldDescription,
	FieldGroup,
	FieldLabel,
	FieldTitle,
} from "@/components/ui/field";
import { Label } from "@/components/ui/label";

const translations: Translations = {
	en: {
		dir: "ltr",
		values: {
			acceptTerms: "Accept terms and conditions",
			acceptTermsDescription:
				"By clicking this checkbox, you agree to the terms.",
			enableNotifications: "Enable notifications",
			enableNotificationsDescription:
				"You can enable or disable notifications at any time.",
		},
	},
	ar: {
		dir: "rtl",
		values: {
			acceptTerms: "قبول الشروط والأحكام",
			acceptTermsDescription: "بالنقر على هذا المربع، فإنك توافق على الشروط.",
			enableNotifications: "تفعيل الإشعارات",
			enableNotificationsDescription:
				"يمكنك تفعيل أو إلغاء تفعيل الإشعارات في أي وقت.",
		},
	},
	he: {
		dir: "rtl",
		values: {
			acceptTerms: "קבל תנאים והגבלות",
			acceptTermsDescription:
				"על ידי לחיצה על תיבת הסימון הזו, אתה מסכים לתנאים.",
			enableNotifications: "הפעל התראות",
			enableNotificationsDescription:
				"אתה יכול להפעיל או להשבית התראות בכל עת.",
		},
	},
};

export function CheckboxRtl() {
	const { dir, language, t } = useTranslation(translations, "ar");

	return (
		<FieldGroup lang={language} dir={dir} className="w-full">
			<Field orientation="horizontal">
				<Checkbox id="checkbox-rtl-terms" name="checkbox-rtl-terms" />
				<Label htmlFor="checkbox-rtl-terms">{t.acceptTerms}</Label>
			</Field>
			<Field orientation="horizontal">
				<Checkbox
					id="checkbox-rtl-terms-2"
					name="checkbox-rtl-terms-2"
					defaultChecked
				/>
				<FieldContent>
					<FieldLabel htmlFor="checkbox-rtl-terms-2">
						{t.acceptTerms}
					</FieldLabel>
					<FieldDescription>{t.acceptTermsDescription}</FieldDescription>
				</FieldContent>
			</Field>
			<Field orientation="horizontal" data-disabled>
				<Checkbox
					id="checkbox-rtl-notify-off"
					name="checkbox-rtl-notify-off"
					disabled
				/>
				<FieldLabel htmlFor="checkbox-rtl-notify-off">
					{t.enableNotifications}
				</FieldLabel>
			</Field>
			<FieldLabel>
				<Field orientation="horizontal">
					<Checkbox id="checkbox-rtl-notify-on" name="checkbox-rtl-notify-on" />
					<FieldContent>
						<FieldTitle>{t.enableNotifications}</FieldTitle>
						<FieldDescription>
							{t.enableNotificationsDescription}
						</FieldDescription>
					</FieldContent>
				</Field>
			</FieldLabel>
		</FieldGroup>
	);
}

API Reference

Checkbox

The Checkbox component forwards props to @base-ui/react Checkbox and supports the following additional prop:

PropTypeDefault
variant"default" | "secondary"
"default"

For the full prop surface, see the Base UI Checkbox API.