Components
Checkbox

Checkbox

A control element that allows for multiple selections within a set.

You can explore the checkbox component in the following curated examples.

Anatomy

To set up the checkbox correctly, you'll need to understand its anatomy and how we name its parts.

Each part includes a data-part attribute to help identify them in the DOM.

Design impact on the asChild property

The Checkbox.Root element of the checkbox is a label element. This is because the checkbox is a form control and should be associated with a label to provide context and meaning to the user. Otherwise, the HTML and accessibility structure will be invalid.

If you need to use the asChild property, make sure that the label element is the direct child of the Checkbox.Root component.

Examples

Learn how to use the Checkbox component in your project. Let's take a look at the most basic example:

import { Checkbox } from '@ark-ui/react/checkbox'
import { CheckIcon } from 'lucide-react'

export const Basic = () => (
  <Checkbox.Root>
    <Checkbox.Label>Checkbox</Checkbox.Label>
    <Checkbox.Control>
      <Checkbox.Indicator>
        <CheckIcon />
      </Checkbox.Indicator>
    </Checkbox.Control>
    <Checkbox.HiddenInput />
  </Checkbox.Root>
)

Controlled Checkbox

To create a controlled Checkbox component, manage the state of the checked status using the checked prop and update it when the onCheckedChange event handler is called:

import { Checkbox } from '@ark-ui/react/checkbox'
import { CheckIcon } from 'lucide-react'
import { useState } from 'react'

export const Controlled = () => {
  const [checked, setChecked] = useState<Checkbox.CheckedState>(true)

  return (
    <Checkbox.Root checked={checked} onCheckedChange={(e) => setChecked(e.checked)}>
      <Checkbox.Label>Checkbox</Checkbox.Label>
      <Checkbox.Control>
        <Checkbox.Indicator>
          <CheckIcon />
        </Checkbox.Indicator>
      </Checkbox.Control>
      <Checkbox.HiddenInput />
    </Checkbox.Root>
  )
}

Indeterminate Checkbox

In some cases, you may need a checkbox to represent a state that is neither checked nor unchecked, known as the indeterminate state. This can be achieved by setting the checked prop to indeterminate:

import { Checkbox } from '@ark-ui/react/checkbox'
import { CheckIcon, MinusIcon } from 'lucide-react'

export const Indeterminate = () => (
  <Checkbox.Root checked="indeterminate">
    <Checkbox.Label>Checkbox</Checkbox.Label>
    <Checkbox.Control>
      <Checkbox.Indicator>
        <CheckIcon />
      </Checkbox.Indicator>
      <Checkbox.Indicator indeterminate>
        <MinusIcon />
      </Checkbox.Indicator>
    </Checkbox.Control>
    <Checkbox.HiddenInput />
  </Checkbox.Root>
)

Checkbox Group

Ark provides a Checkbox.Group component to manage a group of checkboxes. The Checkbox.Group component manages the state of the checkboxes and provides a way to access the checked values:

import { Checkbox } from '@ark-ui/react/checkbox'
import { CheckIcon } from 'lucide-react'

const items = [
  { label: 'React', value: 'react' },
  { label: 'Solid', value: 'solid' },
  { label: 'Vue', value: 'vue' },
]

export const Group = () => (
  <Checkbox.Group defaultValue={['react']} name="framework" onValueChange={console.log}>
    {items.map((item) => (
      <Checkbox.Root value={item.value} key={item.value}>
        <Checkbox.Label>{item.label}</Checkbox.Label>
        <Checkbox.Control>
          <Checkbox.Indicator>
            <CheckIcon />
          </Checkbox.Indicator>
        </Checkbox.Control>
        <Checkbox.HiddenInput />
      </Checkbox.Root>
    ))}
  </Checkbox.Group>
)

Render Prop Usage

For cases where you need more flexibility in rendering, the Checkbox component offers the use of a render prop. The render prop function gives you access to the checkbox's API, allowing you to customize the checkbox control's rendering:

import { Checkbox } from '@ark-ui/react/checkbox'
import { CheckIcon } from 'lucide-react'

export const RenderProp = () => (
  <Checkbox.Root>
    <Checkbox.Control>
      <Checkbox.Indicator>
        <CheckIcon />
      </Checkbox.Indicator>
    </Checkbox.Control>
    <Checkbox.Context>
      {(checkbox) => <Checkbox.Label>Checkbox {checkbox.checked.toString()}</Checkbox.Label>}
    </Checkbox.Context>
    <Checkbox.HiddenInput />
  </Checkbox.Root>
)

Using the Field Component

The Field component helps manage form-related state and accessibility attributes of a checkbox. It includes handling ARIA labels, helper text, and error text to ensure proper accessibility.

import { Checkbox } from '@ark-ui/react/checkbox'
import { Field } from '@ark-ui/react/field'
import { CheckIcon, MinusIcon } from 'lucide-react'

export const WithField = (props: Field.RootProps) => (
  <Field.Root {...props}>
    <Checkbox.Root>
      <Checkbox.Label>Label</Checkbox.Label>
      <Checkbox.Control>
        <Checkbox.Indicator>
          <CheckIcon />
        </Checkbox.Indicator>
        <Checkbox.Indicator indeterminate>
          <MinusIcon />
        </Checkbox.Indicator>
      </Checkbox.Control>
      <Checkbox.HiddenInput />
    </Checkbox.Root>
    <Field.HelperText>Additional Info</Field.HelperText>
    <Field.ErrorText>Error Info</Field.ErrorText>
  </Field.Root>
)

Using the Root Provider

The RootProvider component provides a context for the checkbox. It accepts the value of the useCheckbox hook. You can leverage it to access the component state and methods from outside the checkbox.

import { Checkbox, useCheckbox } from '@ark-ui/react/checkbox'
import { CheckIcon } from 'lucide-react'

export const RootProvider = () => {
  const checkbox = useCheckbox()

  return (
    <>
      <span>{checkbox.checked ? 'Checked' : 'UnChecked'}</span>

      <Checkbox.RootProvider value={checkbox}>
        <Checkbox.Label>Checkbox</Checkbox.Label>
        <Checkbox.Control>
          <Checkbox.Indicator>
            <CheckIcon />
          </Checkbox.Indicator>
        </Checkbox.Control>
        <Checkbox.HiddenInput />
      </Checkbox.RootProvider>
    </>
  )
}

If you're using the RootProvider component, you don't need to use the Root component.

API Reference

Root

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
checked
CheckedState

The checked state of the checkbox

defaultChecked
CheckedState

The checked state of the checkbox when it is first rendered. Use this when you do not need to control the state of the checkbox.

disabled
boolean

Whether the checkbox is disabled

form
string

The id of the form that the checkbox belongs to.

id
string

The unique identifier of the machine.

ids
Partial<{ root: string hiddenInput: string control: string label: string }>

The ids of the elements in the checkbox. Useful for composition.

invalid
boolean

Whether the checkbox is invalid

name
string

The name of the input field in a checkbox. Useful for form submission.

onCheckedChange
(details: CheckedChangeDetails) => void

The callback invoked when the checked state changes.

readOnly
boolean

Whether the checkbox is read-only

required
boolean

Whether the checkbox is required

value'on'
string

The value of checkbox input. Useful for form submission.

Data AttributeValue
[data-active]Present when active or pressed
[data-focus]Present when focused
[data-focus-visible]Present when focused with keyboard
[data-readonly]Present when read-only
[data-hover]Present when hovered
[data-disabled]Present when disabled
[data-state]"indeterminate" | "checked" | "unchecked"
[data-invalid]Present when invalid

Control

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-active]Present when active or pressed
[data-focus]Present when focused
[data-focus-visible]Present when focused with keyboard
[data-readonly]Present when read-only
[data-hover]Present when hovered
[data-disabled]Present when disabled
[data-state]"indeterminate" | "checked" | "unchecked"
[data-invalid]Present when invalid

Group

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
defaultValue
string[]

The initial value of `value` when uncontrolled

disabled
boolean

If `true`, the checkbox group is disabled

invalid
boolean

If `true`, the checkbox group is invalid

name
string

The name of the input fields in the checkbox group (Useful for form submission).

onValueChange
(value: string[]) => void

The callback to call when the value changes

readOnly
boolean

If `true`, the checkbox group is read-only

value
string[]

The controlled value of the checkbox group

HiddenInput

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Indicator

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
indeterminate
boolean

Data AttributeValue
[data-active]Present when active or pressed
[data-focus]Present when focused
[data-focus-visible]Present when focused with keyboard
[data-readonly]Present when read-only
[data-hover]Present when hovered
[data-disabled]Present when disabled
[data-state]"indeterminate" | "checked" | "unchecked"
[data-invalid]Present when invalid

Label

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-active]Present when active or pressed
[data-focus]Present when focused
[data-focus-visible]Present when focused with keyboard
[data-readonly]Present when read-only
[data-hover]Present when hovered
[data-disabled]Present when disabled
[data-state]"indeterminate" | "checked" | "unchecked"
[data-invalid]Present when invalid

RootProvider

PropDefaultType
value
UseCheckboxReturn

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Accessibility

Complies with the Checkbox WAI-ARIA design pattern.

Keyboard Support

KeyDescription
Space
Toggle the checkbox