dotUI
dotUI
beta
  1. Components
  2. Inputs
  3. Checkbox

Checkbox

Checkboxes allow users to select multiple items from a list of individual items, or to mark one individual item as selected.

<Checkbox>I accept the <Link href="/terms">terms and conditions</Link></Checkbox>

Installation

Install the following dependencies:

npm install react-aria-components

Copy and paste the following code into your project.

"use client";

import * as React from "react";
import {
  Checkbox as AriaCheckbox,
  composeRenderProps,
  type CheckboxProps as AriaCheckboxProps,
} from "react-aria-components";
import { tv, type VariantProps } from "tailwind-variants";
import { CheckIcon, MinusIcon } from "@/lib/icons";
import { focusRing, focusRingGroup } from "@/lib/utils/styles";

const checkboxStyles = tv({
  slots: {
    root: "group flex flex-row items-center gap-2 cursor-pointer invalid:text-fg-danger disabled:text-fg-disabled disabled:cursor-default",
    indicator: [
      "flex items-center justify-center size-4 shrink-0 rounded-sm border border-border-control cursor-pointer",
      "bg-transparent text-transparent group-selected:bg-bg-primary group-selected:text-fg-onPrimary transition-colors duration-75 group-selected:border-transparent",
      "group-indeterminate:bg-bg-primary group-indeterminate:text-fg-onPrimary",
      "group-read-only:cursor-default",
      "group-disabled:cursor-not-allowed group-disabled:border-border-disabled group-disabled:group-selected:text-fg-disabled group-disabled:group-selected:bg-bg-disabled group-disabled:group-indeterminate:bg-bg-disabled",
      "group-invalid:border-border-danger group-invalid:group-selected:bg-bg-danger-muted group-invalid:group-selected:text-fg-onMutedDanger",
    ],
  },
  variants: {
    variant: {
      default: {
        indicator: focusRingGroup(),
      },
      card: {
        root: [
          focusRing(),
          "border p-4 rounded-md flex-row-reverse gap-4 selected:bg-bg-muted disabled:selected:bg-bg-disabled transition-colors disabled:border-border-disabled",
        ],
      },
    },
  },
  defaultVariants: {
    variant: "default",
  },
});

interface CheckboxProps
  extends Omit<AriaCheckboxProps, "className">,
    VariantProps<typeof checkboxStyles> {
  className?: string;
}
const Checkbox = React.forwardRef<React.ElementRef<typeof AriaCheckbox>, CheckboxProps>(
  (localProps, ref) => {
    const contextProps = useCheckboxContext();
    const props = { ...contextProps, ...localProps };
    const { className, variant, ...restProps } = props;
    const { root, indicator } = checkboxStyles({ variant });
    return (
      <AriaCheckbox ref={ref} {...restProps} className={root({ className })}>
        {composeRenderProps(props.children, (children, { isIndeterminate }) => (
          <>
            <div className={indicator({ className: "" })}>
              {isIndeterminate ? (
                <MinusIcon className="size-2.5" />
              ) : (
                <CheckIcon className="size-3" />
              )}
            </div>
            <span>{children}</span>
          </>
        ))}
      </AriaCheckbox>
    );
  }
);
Checkbox.displayName = "Checkbox";

type CheckboxContextValue = VariantProps<typeof checkboxStyles>;
const CheckboxContext = React.createContext<CheckboxContextValue>({});
const useCheckboxContext = () => {
  return React.useContext(CheckboxContext);
};

export type { CheckboxProps };
export { Checkbox, CheckboxContext };

Update the import paths to match your project setup.

Usage

Use checkbox to allow users to select multiple items from a list of individual items, or to mark one individual item as selected.

Options

Variant

Use the variant prop to control the visual style of the checkbox.

<Checkbox variant="card">I accept the terms and conditions</Checkbox>

Indeterminate

A checkbox can be in an indeterminate state, controlled using the isIndeterminate prop.

<Checkbox isIndeterminate>Select all</Checkbox>

Disabled

Use the isDisabled prop to disable the checkbox.

<Checkbox isDisabled>I accept the terms and conditions</Checkbox>

Read only

The isReadOnly prop makes the selection immutable. Unlike isDisabled, the Checkbox remains focusable.

<Checkbox isReadOnly>I accept the terms and conditions</Checkbox>

Uncontrolled

The defaultSelected prop can be used to set the default state.

<Checkbox defaultSelected>I accept the terms and conditions</Checkbox>

Controlled

Use the isSelected and onChange props to control the value of the input.

const [checked, setChecked] = React.useState(false);
return (
  <Checkbox isSelected={checked} onChange={setChecked}>
    I accept the terms and conditions
  </Checkbox>
);

API Reference

PropTypeDefaultDescription
variant
"default" | "card"
"default"
The visual style of the checkbox group.
inputRef
MutableRefObject<HTMLInputElement>
-
A ref for the HTML input element.
isIndeterminate
boolean
-
Indeterminism is presentational only. The indeterminate visual representation remains regardless of user interaction.
defaultSelected
boolean
-
Whether the element should be selected (uncontrolled).
isSelected
boolean
-
Whether the element should be selected (controlled).
value
string
-
The value of the input element, used when submitting an HTML form.
isDisabled
boolean
-
Whether the input is disabled.
isReadOnly
boolean
-
Whether the input can be selected but not changed by the user.
isRequired
boolean
-
Whether user input is required on the input before form submission.
isInvalid
boolean
-
Whether the input value is invalid.
validate
(value: boolean) => ValidationError| true| null| undefined
-
A function that returns an error message if a given value is invalid. Validation errors are displayed to the user when the form is submitted if validationBehavior="native". For realtime validation, use the isInvalid prop instead.
autoFocus
boolean
-
Whether the element should receive focus on render.
name
string
-
The name of the input element, used when submitting an HTML
validationBehavior
'native' | 'aria'
'native'
Whether to use native HTML form validation to prevent form submission when the value is missing or invalid, or mark the field as required or invalid via ARIA.
children
ReactNode | (values: CheckboxRenderProps & {defaultChildren: ReactNode | undefined}) => ReactNode
-
The children of the component. A function may be provided to alter the children based on component state.
className
string
-
The CSS className for the element.
style
CSSProperties | (values: CheckboxRenderProps & {defaultStyle: CSSProperties}) => CSSProperties
-
The inline style for the element. A function may be provided to compute the style based on component state.
EventTypeDescription
onChange
(isSelected: boolean) => void
Handler that is called when the element's selection state changes.
onFocus
(e: FocusEvent<Target>) => void
Handler that is called when the element receives focus.
onBlur
(e: FocusEvent<Target>) => void
Handler that is called when the element loses focus.
onFocusChange
(isFocused: boolean) => void
Handler that is called when the element's focus status changes.
onKeyDown
(e: KeyboardEvent) => void
Handler that is called when a key is pressed.
onKeyUp
(e: KeyboardEvent) => void
Handler that is called when a key is released.
onHoverStart
(e: HoverEvent) => void
Handler that is called when a hover interaction starts.
onHoverEnd
(e: HoverEvent) => void
Handler that is called when a hover interaction ends.
onHoverChange
(isHovering: boolean) => void
Handler that is called when the hover state changes.
Data attributeDescription
[data-selected]
Whether the checkbox is selected.
[data-indeterminate]
Whether the checkbox is indeterminate.
[data-hovered]
Whether the checkbox is currently hovered with a mouse.
[data-pressed]
Whether the checkbox is currently in a pressed state.
[data-focused]
Whether the checkbox is focused, either via a mouse or keyboard.
[data-focus-visible]
Whether the checkbox is keyboard focused.
[data-disabled]
Whether the checkbox is disabled.
[data-readonly]
Whether the checkbox is read only.
[data-invalid]
Whether the checkbox invalid.
[data-required]
Whether the checkbox is required.

Accessibility

Keyboard interactions

KeyDescription
Space
Toggles the checkbox between selected and not selected

Built by mehdibha. The source code is available on GitHub.