Checkbox

WAI-ARIA supports two types of checkbox widgets: dual-state checkboxes toggle between two choices -- checked and not checked -- and tri-state checkboxes, which allow an additional third state known as partially checked.

Uncontrolled

"use client";
import * as Checkbox from "@lora-ui/checkbox";
export default function Uncontrolled() {
function onCheckedChange(checked, indeterminate) {
console.log(checked, indeterminate);
}
return (
<div className="flex items-start">
<div className="mt-[2px] flex">
<Checkbox.Root
id="uncontrolled-checkbox-1"
defaultChecked
onCheckedChange={onCheckedChange}
className="border-box group relative flex h-[18px] w-[18px] items-center justify-center rounded border border-[#d0d5dd] p-[2px] outline-offset-2 has-[:checked]:bg-[#7f56d9] has-[:checked]:has-[:disabled]:bg-[#f2f4f7] has-[:indeterminate]:bg-[#7f56d9] has-[:indeterminate]:has-[:disabled]:bg-[#f2f4f7] dark:border-[#333741] dark:has-[:checked]:bg-[#7f56d9] dark:has-[:checked]:has-[:disabled]:bg-[#1f242f] dark:has-[:indeterminate]:bg-[#7f56d9] dark:has-[:indeterminate]:has-[:disabled]:bg-[#1f242f]"
>
<Checkbox.Indicator className="invisible group-has-[:checked]:visible group-has-[:indeterminate]:visible group-has-[:checked]:group-has-[:disabled]:text-[#98a2b3] group-has-[:checked]:text-white dark:group-has-[:checked]:group-has-[:disabled]:text-[#85888e]">
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z"
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
/>
</svg>
</Checkbox.Indicator>
</Checkbox.Root>
<label htmlFor="uncontrolled-checkbox-1">
<p className="ml-2 text-sm font-medium text-[#344054] dark:text-[#cecfd2]">
Remember me
</p>
<p className="ml-2 text-sm font-normal text-[#475467] dark:text-[#94969c]">
Save my login details for next time.
</p>
</label>
</div>
</div>
);
}

Controlled

"use client";
import * as Checkbox from "@lora-ui/checkbox";
import React from "react";
export default function Controlled() {
const [indeterminate1, setIndeterminate1] = React.useState(true);
const [checked1, setChecked1] = React.useState(false);
const [checked, setChecked] = React.useState(true);
function changeIndeterminateHandler() {
console.log("indeterminate", indeterminate1, "checked", checked1);
setIndeterminate1(!indeterminate1);
setChecked1(false);
}
function changeCheckedHandler() {
console.log("checked", checked);
setChecked(!checked);
}
return (
<>
<div className="mt-1 flex">
<Checkbox.Root
id="controlled-checkbox-1"
name="controlled-checkbox"
checked={checked}
onCheckedChange={changeCheckedHandler}
className="border-box group relative flex h-[18px] w-[18px] items-center justify-center rounded border border-[#d0d5dd] p-[2px] outline-offset-2 has-[:disabled]:pointer-events-none has-[:checked]:bg-[#7f56d9] has-[:checked]:has-[:disabled]:bg-[#f2f4f7] has-[:indeterminate]:bg-[#7f56d9] has-[:indeterminate]:has-[:disabled]:bg-[#f2f4f7] dark:border-[#333741] dark:has-[:checked]:bg-[#7f56d9] dark:has-[:checked]:has-[:disabled]:bg-[#1f242f] dark:has-[:indeterminate]:bg-[#7f56d9] dark:has-[:indeterminate]:has-[:disabled]:bg-[#1f242f]"
>
<Checkbox.Indicator className="invisible absolute group-has-[:checked]:visible group-has-[:indeterminate]:hidden group-has-[:checked]:group-has-[:disabled]:text-[#98a2b3] group-has-[:checked]:text-white dark:group-has-[:checked]:group-has-[:disabled]:text-[#85888e]">
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z"
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
/>
</svg>
</Checkbox.Indicator>
<Checkbox.Indicator className="invisible absolute group-has-[:indeterminate]:visible group-has-[:checked]:hidden group-has-[:checked]:group-has-[:disabled]:text-[#98a2b3] group-has-[:checked]:text-white dark:group-has-[:checked]:group-has-[:disabled]:text-[#85888e]">
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M2.25 7.5C2.25 7.22386 2.47386 7 2.75 7H12.25C12.5261 7 12.75 7.22386 12.75 7.5C12.75 7.77614 12.5261 8 12.25 8H2.75C2.47386 8 2.25 7.77614 2.25 7.5Z"
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
/>
</svg>
</Checkbox.Indicator>
</Checkbox.Root>
<label htmlFor="controlled-checkbox-1">
<p className="ml-2 text-sm font-medium text-[#344054] dark:text-[#cecfd2]">
Remember me
</p>
<p className="ml-2 text-sm font-normal text-[#475467] dark:text-[#94969c]">
Save my login details for next time.
</p>
</label>
</div>
<div className="mt-1 flex">
<Checkbox.Root
id="controlled-checkbox-2"
name="controlled-checkbox"
checked={checked1}
indeterminate={indeterminate1}
onCheckedChange={changeIndeterminateHandler}
className="border-box group relative flex h-[18px] w-[18px] items-center justify-center rounded border border-[#d0d5dd] p-[2px] outline-offset-2 has-[:disabled]:pointer-events-none has-[:checked]:bg-[#7f56d9] has-[:checked]:has-[:disabled]:bg-[#f2f4f7] has-[:indeterminate]:bg-[#7f56d9] has-[:indeterminate]:has-[:disabled]:bg-[#f2f4f7] dark:border-[#333741] dark:has-[:checked]:bg-[#7f56d9] dark:has-[:checked]:has-[:disabled]:bg-[#1f242f] dark:has-[:indeterminate]:bg-[#7f56d9] dark:has-[:indeterminate]:has-[:disabled]:bg-[#1f242f]"
>
<Checkbox.Indicator className="invisible absolute group-has-[:checked]:visible group-has-[:indeterminate]:hidden group-has-[:checked]:group-has-[:disabled]:text-[#98a2b3] group-has-[:checked]:text-white group-has-[:indeterminate]:group-has-[:disabled]:text-[#98a2b3] dark:group-has-[:checked]:group-has-[:disabled]:text-[#85888e]">
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z"
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
/>
</svg>
</Checkbox.Indicator>
<Checkbox.Indicator className="group-has-[:checked]:group-has-[:disabled] invisible absolute group-has-[:indeterminate]:visible group-has-[:checked]:hidden group-has-[:checked]:group-has-[:disabled]:text-[#98a2b3] group-has-[:checked]:text-white group-has-[:indeterminate]:group-has-[:disabled]:text-[#98a2b3] group-has-[:indeterminate]:text-white dark:group-has-[:checked]:group-has-[:disabled]:text-[#85888e]">
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M2.25 7.5C2.25 7.22386 2.47386 7 2.75 7H12.25C12.5261 7 12.75 7.22386 12.75 7.5C12.75 7.77614 12.5261 8 12.25 8H2.75C2.47386 8 2.25 7.77614 2.25 7.5Z"
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
/>
</svg>
</Checkbox.Indicator>
</Checkbox.Root>
<label htmlFor="controlled-checkbox-2">
<p className="ml-2 text-sm font-medium text-[#344054] dark:text-[#cecfd2]">
Remember me
</p>
<p className="ml-2 text-sm font-normal text-[#475467] dark:text-[#94969c]">
Save my login details for next time.
</p>
</label>
</div>
<div className="mt-1 flex">
<Checkbox.Root
id="controlled-checkbox-3"
indeterminate
checked={false}
disabled
className="border-box group relative flex h-[18px] w-[18px] items-center justify-center rounded border border-[#d0d5dd] p-[2px] outline-offset-2 has-[:disabled]:pointer-events-none has-[:checked]:bg-[#7f56d9] has-[:checked]:has-[:disabled]:bg-[#f2f4f7] has-[:indeterminate]:bg-[#7f56d9] has-[:indeterminate]:has-[:disabled]:bg-[#f2f4f7] dark:border-[#333741] dark:has-[:checked]:bg-[#7f56d9] dark:has-[:checked]:has-[:disabled]:bg-[#1f242f] dark:has-[:indeterminate]:bg-[#7f56d9] dark:has-[:indeterminate]:has-[:disabled]:bg-[#1f242f]"
>
<Checkbox.Indicator className="invisible absolute group-has-[:checked]:visible group-has-[:indeterminate]:hidden group-has-[:checked]:group-has-[:disabled]:text-[#98a2b3] group-has-[:checked]:text-white group-has-[:indeterminate]:group-has-[:disabled]:text-[#98a2b3] dark:group-has-[:checked]:group-has-[:disabled]:text-[#85888e]">
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z"
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
/>
</svg>
</Checkbox.Indicator>
<Checkbox.Indicator className="group-has-[:checked]:group-has-[:disabled] invisible absolute group-has-[:indeterminate]:visible group-has-[:checked]:hidden group-has-[:checked]:group-has-[:disabled]:text-[#98a2b3] group-has-[:checked]:text-white group-has-[:indeterminate]:group-has-[:disabled]:text-[#98a2b3] group-has-[:indeterminate]:text-white dark:group-has-[:checked]:group-has-[:disabled]:text-[#85888e]">
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M2.25 7.5C2.25 7.22386 2.47386 7 2.75 7H12.25C12.5261 7 12.75 7.22386 12.75 7.5C12.75 7.77614 12.5261 8 12.25 8H2.75C2.47386 8 2.25 7.77614 2.25 7.5Z"
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
/>
</svg>
</Checkbox.Indicator>
</Checkbox.Root>
<label htmlFor="controlled-checkbox-3">
<p className="ml-2 text-sm font-medium text-[#344054] dark:text-[#cecfd2]">
Remember me
</p>
<p className="ml-2 text-sm font-normal text-[#475467] dark:text-[#94969c]">
Save my login details for next time.
</p>
</label>
</div>
</>
);
}

Installation

Install the component from your command line.

npm install @lora-ui/checkbox

API Reference

Root

PropTypeDefaultExplanation
isDisabledBooleanfalse
isCheckedBooleanfalse
isIndeterminateBooleanfalse
isControlledBooleantrue
onCheckedChangeFunction(checked?) => {}'if checkbox is controlled, onCheckedChange is a function to update checked state, otherwise onCheckedChange accept inner checked state from checkbox'

Indicator

PropTypeDefaultExplanation

Keyboard

CommandDescription
Tab
Move focus to the next focusable element
Shift+Tab
Move focus to the previous focusable element
Space
Toggles checkbox between checked and unchecked states.

Other

All relevant ARIA attributes are automatically managed.