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.

Checked: false

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
dotUI
beta

Accessible, mobile friendly, modern UI components.

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