Checkbox
A control that allows the user to toggle between checked and unchecked states.
Installation
Install the component Checkbox in your project using the CLI.
Checkbox.tsx
pnpm dlx behsseui@latest add CheckboxInstall the component manually.
Create a ui folder at the root of the project, then a component folder inside it, and finally a Checkbox.tsx file in that folder.
Copy and paste the following code into your project.
ui/components/Checkbox.tsx
1"use client"23import { useState, useId, forwardRef } from "react"4import { cn } from "@/lib/utils"5import Check from "@/ui/icons/Check"67interface CheckboxProps {8 checked?: boolean9 defaultChecked?: boolean10 onCheckedChange?: (checked: boolean) => void11 disabled?: boolean12 id?: string13 name?: string14 value?: string15 className?: string16 label?: string17}1819const Checkbox = forwardRef<HTMLButtonElement, CheckboxProps>(20 (21 {22 checked: controlledChecked,23 defaultChecked = false,24 onCheckedChange,25 disabled = false,26 id: providedId,27 name,28 value,29 className,30 label,31 },32 ref33 ) => {34 const generatedId = useId()35 const id = providedId ?? generatedId3637 // Internal state for uncontrolled mode38 const [internalChecked, setInternalChecked] = useState(defaultChecked)3940 // Determine if controlled or uncontrolled41 const isControlled = controlledChecked !== undefined42 const isChecked = isControlled ? controlledChecked : internalChecked4344 const handleClick = () => {45 if (disabled) return4647 const newChecked = !isChecked4849 // Update internal state (for uncontrolled mode)50 if (!isControlled) {51 setInternalChecked(newChecked)52 }5354 // Call onCheckedChange callback if provided55 onCheckedChange?.(newChecked)56 }5758 const handleKeyDown = (e: React.KeyboardEvent) => {59 if (e.key === " " || e.key === "Enter") {60 e.preventDefault()61 handleClick()62 }63 }6465 return (66 <div className={cn("flex items-center gap-2", className)}>67 <button68 ref={ref}69 type="button"70 role="checkbox"71 aria-checked={isChecked}72 aria-disabled={disabled}73 id={id}74 data-state={isChecked ? "checked" : "unchecked"}75 data-disabled={disabled ? "" : undefined}76 disabled={disabled}77 onClick={handleClick}78 onKeyDown={handleKeyDown}79 className={cn(80 "peer h-4 w-4 shrink-0 rounded-[3px] border border-primary",81 "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",82 "transition-colors",83 isChecked && "bg-primary text-primary-foreground",84 disabled && "cursor-not-allowed opacity-50"85 )}86 >87 {isChecked && (88 <Check className="h-3.5 w-3.5 text-primary-foreground" />89 )}90 </button>91 {/* Hidden input for form submission */}92 <input93 type="checkbox"94 name={name}95 value={value}96 checked={isChecked}97 disabled={disabled}98 onChange={() => {}}99 className="sr-only"100 tabIndex={-1}101 aria-hidden="true"102 />103 {label && (104 <label105 htmlFor={id}106 className={cn(107 "text-sm font-medium leading-none cursor-pointer",108 "peer-disabled:cursor-not-allowed peer-disabled:opacity-70"109 )}110 >111 {label}112 </label>113 )}114 </div>115 )116 }117)118119Checkbox.displayName = "Checkbox"120121export { Checkbox }122Usages
Different variants and use cases for the Checkbox component.
Default
A basic checkbox without a label.
Default.tsx
<Checkbox />With Label
A checkbox with an associated label.
With Label.tsx
<Checkbox label="Accept terms and conditions" />Checked
A checkbox that starts in a checked state.
Checked.tsx
<Checkbox defaultChecked label="I agree" />Disabled
A disabled checkbox that cannot be interacted with.
Disabled.tsx
<Checkbox disabled label="Disabled" />Disabled Checked
A disabled checkbox in a checked state.
Disabled Checked.tsx
<Checkbox disabled defaultChecked label="Disabled checked" />Group
Multiple checkboxes grouped together allowing users to select multiple options.
Group.tsx
<div className="flex flex-col gap-3">
<Checkbox label="Option 1" />
<Checkbox label="Option 2" />
<Checkbox label="Option 3" />
</div>