Overview
Get Started
import { Checkbox } from "@/components/ui/checkbox";
import { CheckboxGroup } from "@/components/ui/checkbox-group";
import { Label } from "@/components/ui/label";
export function CheckboxGroupDemo() {
return (
<CheckboxGroup aria-label="Select frameworks" defaultValue={["next"]}>
<Label>
<Checkbox value="next" />
Next.js
</Label>
<Label>
<Checkbox value="solid" />
Solid Start
</Label>
<Label>
<Checkbox value="angular" />
Angular
</Label>
</CheckboxGroup>
);
}Installation
import { CheckboxGroup as CheckboxGroupPrimitive } from "@base-ui/react/checkbox-group";
import { cn } from "@/lib/cn";
function CheckboxGroup({
className,
...props
}: React.ComponentProps<typeof CheckboxGroupPrimitive>) {
return (
<CheckboxGroupPrimitive
className={cn("flex flex-col items-start gap-3", className)}
{...props}
/>
);
}
export { CheckboxGroup };Usage
import { Checkbox } from "@/components/ui/checkbox";
import { CheckboxGroup } from "@/components/ui/checkbox-group";
import { Label } from "@/components/ui/label";<CheckboxGroup>
<Label>
<Checkbox defaultChecked />
Next.js
</Label>
<Label>
<Checkbox />
Vite
</Label>
<Label>
<Checkbox />
Astro
</Label>
</CheckboxGroup>Examples
Labeling checkbox group
Label the group with aria-labelledby and a sibling label element:
import { Checkbox } from "@/components/ui/checkbox";
import { CheckboxGroup } from "@/components/ui/checkbox-group";
import { Label } from "@/components/ui/label";
export function CheckboxGroupDemo() {
return (
<div className="flex flex-col items-start gap-4">
<Label id="frameworks-label">Select frameworks</Label>
<CheckboxGroup aria-labelledby="frameworks-label" defaultValue={["next"]}>
<Label>
<Checkbox value="next" />
Next.js
</Label>
<Label>
<Checkbox value="solid" />
Solid Start
</Label>
<Label>
<Checkbox value="angular" />
Angular
</Label>
</CheckboxGroup>
</div>
);
}Disabled
import { Checkbox } from "@/components/ui/checkbox";
import { CheckboxGroup } from "@/components/ui/checkbox-group";
import { Label } from "@/components/ui/label";
export function CheckboxGroupDemo() {
return (
<div className="flex flex-col items-start gap-4">
<Label id="frameworks-label">Select frameworks</Label>
<CheckboxGroup aria-labelledby="frameworks-label" defaultValue={["next"]} disabled>
<Label>
<Checkbox value="next" />
Next.js
</Label>
<Label>
<Checkbox value="solid" />
Solid Start
</Label>
<Label>
<Checkbox value="angular" />
Angular
</Label>
</CheckboxGroup>
</div>
);
}With disabled item
import { Checkbox } from "@/components/ui/checkbox";
import { CheckboxGroup } from "@/components/ui/checkbox-group";
import { Label } from "@/components/ui/label";
export function CheckboxGroupDemo() {
return (
<div className="flex flex-col items-start gap-4">
<Label id="frameworks-label">Select frameworks</Label>
<CheckboxGroup aria-labelledby="frameworks-label" defaultValue={["next"]}>
<div className="flex items-center gap-2">
<Checkbox id="next-checkbox" value="next" className="peer" />
<Label htmlFor="next-checkbox" className="peer-data-disabled:opacity-50">
Next.js
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox id="solid-checkbox" value="solid" disabled className="peer" />
<Label htmlFor="solid-checkbox" className="peer-data-disabled:opacity-50">
Solid Start
</Label>
</div>
<div className="flex items-center gap-2">
<Checkbox id="angular-checkbox" value="angular" className="peer" />
<Label htmlFor="angular-checkbox" className="peer-data-disabled:opacity-50">
Angular
</Label>
</div>
</CheckboxGroup>
</div>
);
}Controlled
["solid"]"use client";
import { useState } from "react";
import { Checkbox } from "@/components/ui/checkbox";
import { CheckboxGroup } from "@/components/ui/checkbox-group";
import { Label } from "@/components/ui/label";
const frameworks = [
{ id: "next", name: "Next.js" },
{ id: "solid", name: "Solid Start" },
{ id: "angular", name: "Angular" },
];
export function CheckboxGroupDemo() {
const [value, setValue] = useState<string[]>(["solid"]);
return (
<div className="flex w-full max-w-sm flex-col items-center gap-4">
<CheckboxGroup aria-labelledby="frameworks" onValueChange={setValue} value={value}>
<Label id="frameworks">Select Frameworks</Label>
{frameworks.map((framework) => (
<Label className="ms-4" key={framework.id}>
<Checkbox value={framework.id} />
{framework.name}
</Label>
))}
</CheckboxGroup>
<pre className="rounded-lg bg-muted px-3 py-2 text-sm">
<code>{JSON.stringify(value)}</code>
</pre>
</div>
);
}Parent checkbox
"use client";
import { useState } from "react";
import { Checkbox } from "@/components/ui/checkbox";
import { CheckboxGroup } from "@/components/ui/checkbox-group";
import { Label } from "@/components/ui/label";
const frameworks = [
{ id: "next", name: "Next.js" },
{ id: "solid", name: "Solid Start" },
{ id: "angular", name: "Angular" },
];
export function CheckboxGroupDemo() {
const [value, setValue] = useState<string[]>([]);
return (
<CheckboxGroup
allValues={frameworks.map((framework) => framework.id)}
aria-labelledby="frameworks-caption"
onValueChange={setValue}
value={value}
>
<Label id="frameworks-caption">
<Checkbox name="frameworks" parent />
Frameworks
</Label>
{frameworks.map((framework) => (
<Label className="ms-4" key={framework.id}>
<Checkbox value={framework.id} />
{framework.name}
</Label>
))}
</CheckboxGroup>
);
}Nested parent checkbox
"use client";
import { useState } from "react";
import { Checkbox } from "@/components/ui/checkbox";
import { CheckboxGroup } from "@/components/ui/checkbox-group";
import { Label } from "@/components/ui/label";
const mainPermissions = [
{ id: "view-dashboard", name: "View Dashboard" },
{ id: "manage-users", name: "Manage Users" },
{ id: "access-reports", name: "Access Reports" },
];
const userManagementPermissions = [
{ id: "create-user", name: "Create User" },
{ id: "edit-user", name: "Edit User" },
{ id: "delete-user", name: "Delete User" },
{ id: "assign-roles", name: "Assign Roles" },
];
export function CheckboxGroupDemo() {
const [mainValue, setMainValue] = useState<string[]>([]);
const [managementValue, setManagementValue] = useState<string[]>([]);
const managementIsPartial =
managementValue.length > 0 && managementValue.length !== userManagementPermissions.length;
return (
<CheckboxGroup
allValues={mainPermissions.map((p) => p.id)}
aria-labelledby="user-permissions"
onValueChange={(value) => {
if (value.includes("manage-users")) {
setManagementValue(userManagementPermissions.map((p) => p.id));
} else if (managementValue.length === userManagementPermissions.length) {
setManagementValue([]);
}
setMainValue(value);
}}
value={mainValue}
>
<Label id="user-permissions">
<Checkbox indeterminate={managementIsPartial} parent />
User Permissions
</Label>
{mainPermissions
.filter((p) => p.id !== "manage-users")
.map((p) => (
<Label className="ms-4" key={p.id}>
<Checkbox value={p.id} />
{p.name}
</Label>
))}
<CheckboxGroup
allValues={userManagementPermissions.map((p) => p.id)}
aria-labelledby="manage-users"
className="ms-4"
onValueChange={(value) => {
if (value.length === userManagementPermissions.length) {
setMainValue((prev) => Array.from(new Set([...prev, "manage-users"])));
} else {
setMainValue((prev) => prev.filter((v) => v !== "manage-users"));
}
setManagementValue(value);
}}
value={managementValue}
>
<Label id="manage-users">
<Checkbox parent />
Manage Users
</Label>
{userManagementPermissions.map((p) => (
<Label className="ms-4" key={p.id}>
<Checkbox value={p.id} />
{p.name}
</Label>
))}
</CheckboxGroup>
</CheckboxGroup>
);
}