Checkbox
Accessible checkbox with checked, indeterminate and disabled states.
import { Checkbox }from "@/components/ui"
States
Full source
The complete component, read from src/components/ui/checkbox.tsx.
checkbox.tsx
"use client";
import { Check as CheckIcon } from "lucide-react";
import { cn } from "@/lib/utils";
interface CheckboxProps {
checked?: boolean;
indeterminate?: boolean;
disabled?: boolean;
onChange?: () => void;
ariaLabel?: string;
}
export function Checkbox({ checked, indeterminate, disabled, onChange, ariaLabel }: CheckboxProps) {
const on = checked || indeterminate;
return (
<button
type="button"
disabled={disabled}
onClick={onChange}
role="checkbox"
aria-checked={indeterminate ? "mixed" : Boolean(checked)}
aria-label={ariaLabel}
className={cn(
"flex h-4 w-4 items-center justify-center rounded-sm border transition-colors",
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent",
"disabled:cursor-not-allowed disabled:opacity-50",
on ? "border-accent bg-accent" : "border-border bg-surface",
!on && disabled && "bg-bg-secondary"
)}
>
{indeterminate ? (
<span className="h-0.5 w-2 rounded-full bg-on-accent" />
) : checked ? (
<CheckIcon size={11} strokeWidth={3} className="text-on-accent" />
) : null}
</button>
);
}