Checkbox
A shadcn-style checkbox component built with Ark UI primitives.
import {
Checkbox,
CheckboxLabel,
CheckboxRoot,
} from "@/components/ui/checkbox";
const CheckboxDemo = () => (
<div className="w-full max-w-md grid place-items-center">
<CheckboxRoot>
<Checkbox />
<CheckboxLabel>Enable notifications</CheckboxLabel>
</CheckboxRoot>
</div>
);
export default CheckboxDemo;
Installation
npx shadcn@latest add @ark-cn/checkboxInstall the dependency required by this primitive:
npm install @ark-ui/react lucide-reactCopy the component source into your app:
TSXcomponents/ui/checkbox.tsx
"use client";
import { Checkbox as CheckboxPrimitive } from "@ark-ui/react/checkbox";
import { CheckIcon, MinusIcon } from "lucide-react";
import { cn } from "@/lib/utils";
export const CheckboxRoot = ({
children,
className,
...props
}: CheckboxPrimitive.RootProps) => {
return (
<CheckboxPrimitive.Root
data-slot="checkbox"
{...props}
className={cn("flex items-center gap-2", className)}
>
{children}
<CheckboxPrimitive.HiddenInput />
</CheckboxPrimitive.Root>
);
};
export const Checkbox = ({
className,
...props
}: CheckboxPrimitive.ControlProps) => {
return (
<CheckboxPrimitive.Control
className={cn(
"cursor-pointer peer relative flex size-4 shrink-0 items-center justify-center rounded border border-input transition-colors outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 data-invalid:border-destructive data-invalid:ring-3 data-invalid:ring-destructive/20 data-invalid:data-[state='checked']:border-primary dark:bg-input/30 dark:data-invalid:border-destructive/50 dark:data-invalid:ring-destructive/40 data-[state='checked']:border-primary data-[state='checked']:bg-primary data-[state='checked']:text-primary-foreground dark:data-[state='checked']:bg-primary",
className,
)}
{...props}
>
<CheckboxPrimitive.Context>
{({ checked, indeterminate }) => {
return (
<CheckboxPrimitive.Indicator
data-slot="checkbox-indicator"
className="grid place-content-center text-current transition-none [&>svg]:size-3.5"
indeterminate={indeterminate}
>
{checked ? <CheckIcon /> : indeterminate ? <MinusIcon /> : null}
</CheckboxPrimitive.Indicator>
);
}}
</CheckboxPrimitive.Context>
</CheckboxPrimitive.Control>
);
};
export const CheckboxLabel = ({
className,
...props
}: CheckboxPrimitive.LabelProps) => (
<CheckboxPrimitive.Label
data-slot="checkbox-label"
className={cn(
"text-sm font-medium text-foreground select-none data-disabled:opacity-50 data-invalid:text-destructive",
className,
)}
{...props}
/>
);
export const CheckboxGroup = ({
className,
...props
}: CheckboxPrimitive.GroupProps) => {
return <CheckboxPrimitive.Group className={cn(className)} {...props} />;
};
export const CheckboxContext = CheckboxPrimitive.Context;
Update import aliases to match your project setup.
Usage
import * as Checkbox from "@/components/ui/checkbox"Read exported parts in src/components/ui/checkbox.tsx and compose the primitive according to the Ark UI pattern for this component.
Examples
Basic
import {
Checkbox,
CheckboxLabel,
CheckboxRoot,
} from "@/components/ui/checkbox";
const CheckboxDemo = () => (
<div className="w-full max-w-md grid place-items-center">
<CheckboxRoot>
<Checkbox />
<CheckboxLabel>Enable notifications</CheckboxLabel>
</CheckboxRoot>
</div>
);
export default CheckboxDemo;
Description
import {
Checkbox,
CheckboxLabel,
CheckboxRoot,
} from "@/components/ui/checkbox";
const CheckboxDescriptionDemo = () => (
<CheckboxRoot className="items-start">
<Checkbox className="mt-0.5" />
<div className="space-y-1">
<CheckboxLabel>Email updates</CheckboxLabel>
<p className="text-muted-foreground text-xs">
Receive new release and changelog notifications.
</p>
</div>
</CheckboxRoot>
);
export default CheckboxDescriptionDemo;
Disabled
import {
Checkbox,
CheckboxLabel,
CheckboxRoot,
} from "@/components/ui/checkbox";
const CheckboxDisabledDemo = () => (
<CheckboxRoot disabled>
<Checkbox />
<CheckboxLabel>Disabled option</CheckboxLabel>
</CheckboxRoot>
);
export default CheckboxDisabledDemo;
Group
import {
Checkbox,
CheckboxGroup,
CheckboxLabel,
CheckboxRoot,
} from "@/components/ui/checkbox";
const checkboxItems = [
{
label: "Marketing alerts",
value: "marketing",
},
{
label: "Product alerts",
},
{
label: "Security alerts",
value: "security",
},
];
const CheckboxGroupDemo = () => {
return (
<CheckboxGroup className="space-y-2">
{checkboxItems.map((item) => (
<CheckboxRoot key={item.value} value={item.value}>
<Checkbox />
<CheckboxLabel className="capitalize">{item.label}</CheckboxLabel>
</CheckboxRoot>
))}
</CheckboxGroup>
);
};
export default CheckboxGroupDemo;
API reference
This component mirrors the upstream Ark UI primitive.
See the ARK UI documentation for the full API.
Accessibility
See the Ark UI documentation for clarification.