# Checkbox

URL: https://ark-ui.com/docs/components/checkbox
Source: https://raw.githubusercontent.com/chakra-ui/ark/refs/heads/main/website/src/content/pages/components/checkbox.mdx

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

---

<ComponentPreview id="Checkbox" />

## Anatomy

<Anatomy id="checkbox" />

```tsx
<Checkbox.Root>
  <Checkbox.Control>
    <Checkbox.Indicator />
  </Checkbox.Control>
  <Checkbox.Label />
  <Checkbox.HiddenInput />
</Checkbox.Root>
```

## Examples

**Example: basic**

```ripple
import { Checkbox } from 'ark-ripple/checkbox';
import { Check } from 'lucide-ripple';
import styles from 'styles/checkbox.module.css';

export component Basic() {
  <Checkbox.Root class={styles.Root}>
    <Checkbox.Control class={styles.Control}>
      <Checkbox.Indicator class={styles.Indicator}>
        <Check />
      </Checkbox.Indicator>
    </Checkbox.Control>
    <Checkbox.Label class={styles.Label}>{'Checkbox'}</Checkbox.Label>
    <Checkbox.HiddenInput />
  </Checkbox.Root>
}

```

### Default Checked

Use the `defaultChecked` prop to set the initial checked state in an uncontrolled manner. The checkbox will manage its
own state internally.

**Example: default-checked**

```ripple
import { Checkbox } from 'ark-ripple/checkbox';
import styles from 'styles/checkbox.module.css';
import { Check } from 'lucide-ripple';

export component DefaultChecked() {
  <Checkbox.Root class={styles.Root} defaultChecked>
    <Checkbox.Control class={styles.Control}>
      <Checkbox.Indicator class={styles.Indicator}>
        <Check />
      </Checkbox.Indicator>
    </Checkbox.Control>
    <Checkbox.Label class={styles.Label}>{'Checkbox'}</Checkbox.Label>
    <Checkbox.HiddenInput />
  </Checkbox.Root>
}

```

### Controlled

Use the `checked` and `onCheckedChange` props to programatically control the checkbox's state.

**Example: controlled**

```ripple
import { Checkbox } from 'ark-ripple/checkbox';
import styles from 'styles/checkbox.module.css';
import { track } from 'ripple';
import { Check } from 'lucide-ripple';

export component Controlled() {
  let checked = track(true);

  <Checkbox.Root
    class={styles.Root}
    {checked}
    onCheckedChange={(e) => {
      @checked = e.checked;
    }}
  >
    <Checkbox.Control class={styles.Control}>
      <Checkbox.Indicator class={styles.Indicator}>
        <Check />
      </Checkbox.Indicator>
    </Checkbox.Control>
    <Checkbox.Label class={styles.Label}>{'Checkbox'}</Checkbox.Label>
    <Checkbox.HiddenInput />
  </Checkbox.Root>
}

```

### Root Provider

An alternative way to control the checkbox is to use the `RootProvider` component and the `useCheckbox` hook. This way
you can access the state and methods from outside the component.

**Example: root-provider**

```ripple
import { Checkbox, useCheckbox } from 'ark-ripple/checkbox';
import styles from 'styles/checkbox.module.css';
import button from 'styles/button.module.css';
import { Check } from 'lucide-ripple';

export component RootProvider() {
  const checkbox = useCheckbox();

  <div class="vstack">
    <Checkbox.RootProvider class={styles.Root} value={checkbox}>
      <Checkbox.Control class={styles.Control}>
        <Checkbox.Indicator class={styles.Indicator}>
          <Check />
        </Checkbox.Indicator>
      </Checkbox.Control>
      <Checkbox.Label class={styles.Label}>{'Checkbox'}</Checkbox.Label>
      <Checkbox.HiddenInput />
    </Checkbox.RootProvider>
    if (@checkbox.checked) {
      <button
        type="button"
        onClick={() => {
          @checkbox.setChecked(false);
        }}
        class={button.Root}
      >
        {'Uncheck'}
      </button>
    } else {
      <button
        type="button"
        onClick={() => {
          @checkbox.setChecked(true);
        }}
        class={button.Root}
      >
        {'Check'}
      </button>
    }
  </div>
}

```

### Disabled

Use the `disabled` prop to make the checkbox non-interactive.

**Example: disabled**

```ripple
import { Checkbox } from 'ark-ripple/checkbox';
import styles from 'styles/checkbox.module.css';
import { Check } from 'lucide-ripple';

export component Disabled() {
  <Checkbox.Root class={styles.Root} disabled>
    <Checkbox.Control class={styles.Control}>
      <Checkbox.Indicator class={styles.Indicator}>
        <Check />
      </Checkbox.Indicator>
    </Checkbox.Control>
    <Checkbox.Label class={styles.Label}>{'Checkbox'}</Checkbox.Label>
    <Checkbox.HiddenInput />
  </Checkbox.Root>
}

```

### Indeterminate

Use the `indeterminate` prop to create a checkbox in an indeterminate state (partially checked).

**Example: indeterminate**

```ripple
import { Checkbox } from 'ark-ripple/checkbox';
import styles from 'styles/checkbox.module.css';
import { Check, Minus } from 'lucide-ripple';

export component Indeterminate() {
  <Checkbox.Root class={styles.Root} checked="indeterminate">
    <Checkbox.Control class={styles.Control}>
      <Checkbox.Indicator class={styles.Indicator}>
        <Check />
      </Checkbox.Indicator>
      <Checkbox.Indicator class={styles.Indicator} indeterminate>
        <Minus />
      </Checkbox.Indicator>
    </Checkbox.Control>
    <Checkbox.Label class={styles.Label}>{'Checkbox'}</Checkbox.Label>
    <Checkbox.HiddenInput />
  </Checkbox.Root>
}

```

### Field

The checkbox integrates smoothly with the `Field` component to handle form state, helper text, and error text for proper
accessibility.

**Example: with-field**

```ripple
import { Checkbox } from 'ark-ripple/checkbox';
import { Field } from 'ark-ripple/field';
import { Check, Minus } from 'lucide-ripple';
import styles from 'styles/checkbox.module.css';
import field from 'styles/field.module.css';

export component WithField() {
  <Field.Root class={field.Root} data-inline>
    <Checkbox.Root class={styles.Root}>
      <Checkbox.Control class={styles.Control}>
        <Checkbox.Indicator class={styles.Indicator}>
          <Check />
        </Checkbox.Indicator>
        <Checkbox.Indicator class={styles.Indicator} indeterminate>
          <Minus />
        </Checkbox.Indicator>
      </Checkbox.Control>
      <Checkbox.Label class={styles.Label}>{'Label'}</Checkbox.Label>
      <Checkbox.HiddenInput />
    </Checkbox.Root>
    <Field.HelperText class={field.HelperText}>{'Additional Info'}</Field.HelperText>
    <Field.ErrorText class={field.ErrorText}>{'Error Info'}</Field.ErrorText>
  </Field.Root>
}

```

### Form

Pass the `name` and `value` props to the `Checkbox.Root` component to make the checkbox part of a form. The checkbox's
value will be submitted with the form when the user submits it.

**Example: with-form**

```ripple
import { Checkbox } from 'ark-ripple/checkbox';
import styles from 'styles/checkbox.module.css';
import button from 'styles/button.module.css';
import { Check } from 'lucide-ripple';

export component WithForm() {
  <form
    style={{ display: 'flex', flexDirection: 'column', gap: '1rem', alignItems: 'flex-start' }}
    onSubmit={(e) => {
      e.preventDefault();
      console.log('terms:', new FormData(e.currentTarget).get('terms'));
    }}
  >
    <Checkbox.Root class={styles.Root} name="terms" value="accepted">
      <Checkbox.Control class={styles.Control}>
        <Checkbox.Indicator class={styles.Indicator}>
          <Check />
        </Checkbox.Indicator>
      </Checkbox.Control>
      <Checkbox.Label class={styles.Label}>{'I agree to the terms and conditions'}</Checkbox.Label>
      <Checkbox.HiddenInput />
    </Checkbox.Root>
    <button class={button.Root} data-variant="solid" type="submit">{'Submit'}</button>
  </form>
}

```

### Context

Access the checkbox's state and methods with `Checkbox.Context` or the `useCheckboxContext` hook.

**Example: context**

```ripple
import { Checkbox } from 'ark-ripple/checkbox';
import styles from 'styles/checkbox.module.css';
import { Check } from 'lucide-ripple';

export component Context() {
  <Checkbox.Root class={styles.Root}>
    <Checkbox.Control class={styles.Control}>
      <Checkbox.Indicator class={styles.Indicator}>
        <Check />
      </Checkbox.Indicator>
    </Checkbox.Control>
    <Checkbox.Context>
      component children({ context }) {
        <Checkbox.Label class={styles.Label}>
          {'Checked: '}
          {String(@context.checked)}
        </Checkbox.Label>
      }
    </Checkbox.Context>
    <Checkbox.HiddenInput />
  </Checkbox.Root>
}

```

## Checkbox Group

Use the `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.

```tsx
<Checkbox.Group>
  <Checkbox.Root>
    <Checkbox.Control>
      <Checkbox.Indicator />
    </Checkbox.Control>
    <Checkbox.Label />
    <Checkbox.HiddenInput />
  </Checkbox.Root>
</Checkbox.Group>
```

**Example: group**

```ripple
import { Checkbox } from 'ark-ripple/checkbox';
import styles from 'styles/checkbox.module.css';
import { Check } from 'lucide-ripple';

export component Group() {
  <Checkbox.Group class={styles.Group} defaultValue={['react']} name="framework">
    for (const item of items; key item.value) {
      <Checkbox.Root class={styles.Root} value={item.value}>
        <Checkbox.Control class={styles.Control}>
          <Checkbox.Indicator class={styles.Indicator}>
            <Check />
          </Checkbox.Indicator>
        </Checkbox.Control>
        <Checkbox.Label class={styles.Label}>{item.label}</Checkbox.Label>
        <Checkbox.HiddenInput />
      </Checkbox.Root>
    }
  </Checkbox.Group>
}

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

```

### Controlled

Use the `value` and `onValueChange` props to programmatically control the checkbox group's state. This example
demonstrates how to manage selected checkboxes in an array and display the current selection.

**Example: group-controlled**

```ripple
import { Checkbox } from 'ark-ripple/checkbox';
import styles from 'styles/checkbox.module.css';
import { track } from 'ripple';
import { Check } from 'lucide-ripple';

export component GroupControlled() {
  let value = track(['react']);

  <div class="vstack">
    <output>
      {'value: '}
      {JSON.stringify(@value)}
    </output>
    <Checkbox.Group
      class={styles.Group}
      {value}
      name="framework"
      onValueChange={(v) => {
        @value = v;
        console.log(v);
      }}
    >
      for (const item of items; key item.value) {
        <Checkbox.Root class={styles.Root} value={item.value}>
          <Checkbox.Control class={styles.Control}>
            <Checkbox.Indicator class={styles.Indicator}>
              <Check />
            </Checkbox.Indicator>
          </Checkbox.Control>
          <Checkbox.Label class={styles.Label}>{item.label}</Checkbox.Label>
          <Checkbox.HiddenInput />
        </Checkbox.Root>
      }
    </Checkbox.Group>
  </div>
}

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

```

### Root Provider

Use the `useCheckboxGroup` hook to create the checkbox group store and pass it to the `Checkbox.GroupProvider`
component. This provides maximum control over the group programmatically, similar to how `RootProvider` works for
individual checkboxes.

**Example: group-provider**

```ripple
import { Checkbox, useCheckboxGroup } from 'ark-ripple/checkbox';
import styles from 'styles/checkbox.module.css';
import { Check } from 'lucide-ripple';

export component GroupProvider() {
  const group = useCheckboxGroup(
    {
      defaultValue: ['react'],
      name: 'framework',
    },
  );

  <Checkbox.GroupProvider class={styles.Group} value={group}>
    for (const item of items; key item.value) {
      <Checkbox.Root class={styles.Root} value={item.value}>
        <Checkbox.Control class={styles.Control}>
          <Checkbox.Indicator class={styles.Indicator}>
            <Check />
          </Checkbox.Indicator>
        </Checkbox.Control>
        <Checkbox.Label class={styles.Label}>{item.label}</Checkbox.Label>
        <Checkbox.HiddenInput />
      </Checkbox.Root>
    }
  </Checkbox.GroupProvider>
}

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

```

### Invalid

Use the `invalid` prop on `Checkbox.Group` to mark the entire group as invalid for validation purposes. This applies the
invalid state to all checkboxes within the group.

**Example: group-with-invalid**

```ripple
import { Checkbox } from 'ark-ripple/checkbox';
import styles from 'styles/checkbox.module.css';
import { Check } from 'lucide-ripple';

export component GroupWithInvalid() {
  <Checkbox.Group class={styles.Group} invalid>
    for (const item of items; key item.value) {
      <Checkbox.Root class={styles.Root} value={item.value}>
        <Checkbox.Control class={styles.Control}>
          <Checkbox.Indicator class={styles.Indicator}>
            <Check />
          </Checkbox.Indicator>
        </Checkbox.Control>
        <Checkbox.Label class={styles.Label}>{item.label}</Checkbox.Label>
        <Checkbox.HiddenInput />
      </Checkbox.Root>
    }
  </Checkbox.Group>
}

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

```

### Max Selected

Use the `maxSelectedValues` prop to limit the number of checkboxes that can be selected at once. Once the maximum is
reached, remaining checkboxes become disabled.

**Example: group-with-max-selected**

```ripple
import { Checkbox } from 'ark-ripple/checkbox';
import styles from 'styles/checkbox.module.css';
import { Check } from 'lucide-ripple';

export component GroupWithMaxSelected() {
  <Checkbox.Group
    class={styles.Group}
    defaultValue={['react']}
    maxSelectedValues={2}
    name="framework"
  >
    for (const item of items; key item.value) {
      <Checkbox.Root class={styles.Root} value={item.value}>
        <Checkbox.Control class={styles.Control}>
          <Checkbox.Indicator class={styles.Indicator}>
            <Check />
          </Checkbox.Indicator>
        </Checkbox.Control>
        <Checkbox.Label class={styles.Label}>{item.label}</Checkbox.Label>
        <Checkbox.HiddenInput />
      </Checkbox.Root>
    }
  </Checkbox.Group>
}

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

```

### Select All

Implement a "select all" checkbox that controls all checkboxes within a group. The parent checkbox automatically shows
an indeterminate state when some (but not all) items are selected, and becomes fully checked when all items are
selected.

**Example: group-with-select-all**

```ripple
import { Checkbox } from 'ark-ripple/checkbox';
import { Check, Minus } from 'lucide-ripple';
import { track, trackSplit } from 'ripple';
import styles from 'styles/checkbox.module.css';

component CheckboxItem(props: Checkbox.RootProps & { children?: any }) {
  <Checkbox.Root class={styles.Root} {...props}>
    <Checkbox.Control class={styles.Control}>
      <Checkbox.Indicator class={styles.Indicator}>
        <Check />
      </Checkbox.Indicator>
      <Checkbox.Indicator class={styles.Indicator} indeterminate>
        <Minus />
      </Checkbox.Indicator>
    </Checkbox.Control>
    <Checkbox.Label class={styles.Label}>
      <props.children />
    </Checkbox.Label>
    <Checkbox.HiddenInput />
  </Checkbox.Root>
}

export component GroupWithSelectAll() {
  let value = track<string[]>([]);

  const handleSelectAll = (checked: boolean) => {
    @value = checked ? items.map((item) => item.value) : [];
  };

  const allSelected = track(() => @value.length === items.length);
  const indeterminate = track(() => @value.length > 0 && @value.length < items.length);

  <div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}>
    <output>
      {'Selected: '}
      {JSON.stringify(@value)}
    </output>

    <CheckboxItem
      value="all"
      checked={@indeterminate ? 'indeterminate' : @allSelected}
      onCheckedChange={(e) => {
        handleSelectAll(!!e.checked);
      }}
    >
      {'JSX Frameworks'}
    </CheckboxItem>

    <Checkbox.Group
      class={styles.Group}
      style={{ marginInlineStart: '1rem' }}
      {value}
      name="framework"
      onValueChange={(v) => {
        @value = v;
      }}
    >
      for (const item of items; key item.value) {
        <CheckboxItem value={item.value}>{item.label}</CheckboxItem>
      }
    </Checkbox.Group>
  </div>
}

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

```

### Form

Use the `Checkbox.Group` component within a form to handle multiple checkbox values with form submission. The `name`
prop ensures all selected values are collected as an array when the form is submitted using `FormData.getAll()`.

**Example: group-with-form**

```ripple
import { Checkbox } from 'ark-ripple/checkbox';
import styles from 'styles/checkbox.module.css';
import button from 'styles/button.module.css';
import { Check } from 'lucide-ripple';

export component GroupWithForm() {
  <form
    class="vstack"
    onSubmit={(e) => {
      e.preventDefault();
      console.log(new FormData(e.currentTarget).getAll('framework'));
    }}
  >
    <Checkbox.Group class={styles.Group} defaultValue={['react']} name="framework">
      for (const item of items; key item.value) {
        <Checkbox.Root class={styles.Root} value={item.value}>
          <Checkbox.Control class={styles.Control}>
            <Checkbox.Indicator class={styles.Indicator}>
              <Check />
            </Checkbox.Indicator>
          </Checkbox.Control>
          <Checkbox.Label class={styles.Label}>{item.label}</Checkbox.Label>
          <Checkbox.HiddenInput />
        </Checkbox.Root>
      }
    </Checkbox.Group>
    <button class={button.Root} type="submit">{'Submit'}</button>
  </form>
}

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

```

### Fieldset

Use the `Fieldset` component with `Checkbox.Group` to provide semantic grouping with legend, helper text, and error text
support.

**Example: group-with-fieldset**

```ripple
import { Checkbox } from 'ark-ripple/checkbox';
import { Fieldset } from 'ark-ripple/fieldset';
import { Check } from 'lucide-ripple';
import styles from 'styles/checkbox.module.css';
import fieldset from 'styles/fieldset.module.css';

export component GroupWithFieldset() {
  <Fieldset.Root class={fieldset.Root}>
    <Fieldset.Legend class={fieldset.Legend}>{'Select frameworks'}</Fieldset.Legend>
    <Fieldset.HelperText class={fieldset.HelperText}>
      {'Choose your preferred frameworks'}
    </Fieldset.HelperText>
    <Checkbox.Group class={styles.Group} defaultValue={['react']} name="framework">
      for (const item of items; key item.value) {
        <Checkbox.Root class={styles.Root} value={item.value}>
          <Checkbox.Control class={styles.Control}>
            <Checkbox.Indicator class={styles.Indicator}>
              <Check />
            </Checkbox.Indicator>
          </Checkbox.Control>
          <Checkbox.Label class={styles.Label}>{item.label}</Checkbox.Label>
          <Checkbox.HiddenInput />
        </Checkbox.Root>
      }
    </Checkbox.Group>
  </Fieldset.Root>
}

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

```

## Guides

### asChild Behavior

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.

## API Reference

### Props

**Component API Reference**

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `checked` | `CheckedState` | No | The controlled checked state of the checkbox |
| `defaultChecked` | `CheckedState` | No | The initial checked state of the checkbox when rendered.
Use when you don't need to control the checked state of the checkbox. |
| `disabled` | `boolean` | No | Whether the checkbox is disabled |
| `form` | `string` | No | The id of the form that the checkbox belongs to. |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{ root: string; hiddenInput: string; control: string; label: string }>` | No | The ids of the elements in the checkbox. Useful for composition. |
| `invalid` | `boolean` | No | Whether the checkbox is invalid |
| `name` | `string` | No | The name of the input field in a checkbox.
Useful for form submission. |
| `onCheckedChange` | `(details: CheckedChangeDetails) => void` | No | The callback invoked when the checked state changes. |
| `readOnly` | `boolean` | No | Whether the checkbox is read-only |
| `required` | `boolean` | No | Whether the checkbox is required |
| `value` | `string` | No | The value of checkbox input. Useful for form submission. |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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 |
| `[data-required]` | Present when required |


**Control Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Control Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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 |
| `[data-required]` | Present when required |


**Group Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `defaultValue` | `string[]` | No | The initial value of `value` when uncontrolled |
| `disabled` | `boolean` | No | If `true`, the checkbox group is disabled |
| `invalid` | `boolean` | No | If `true`, the checkbox group is invalid |
| `maxSelectedValues` | `number` | No | The maximum number of selected values |
| `name` | `string` | No | The name of the input fields in the checkbox group
(Useful for form submission). |
| `onValueChange` | `(value: string[]) => void` | No | The callback to call when the value changes |
| `readOnly` | `boolean` | No | If `true`, the checkbox group is read-only |
| `value` | `string[]` | No | The controlled value of the checkbox group |


**GroupProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseCheckboxGroupContext` | Yes |  |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**HiddenInput Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Indicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `indeterminate` | `boolean` | No |  |


**Indicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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 |
| `[data-required]` | Present when required |


**Label Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Label Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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 |
| `[data-required]` | Present when required |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseCheckboxReturn` | Yes |  |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


### Context

**API:**

| Property | Type | Description |
|----------|------|-------------|
| `checked` | `boolean` | Whether the checkbox is checked |
| `disabled` | `boolean` | Whether the checkbox is disabled |
| `indeterminate` | `boolean` | Whether the checkbox is indeterminate |
| `focused` | `boolean` | Whether the checkbox is focused |
| `checkedState` | `CheckedState` | The checked state of the checkbox |
| `setChecked` | `(checked: CheckedState) => void` | Function to set the checked state of the checkbox |
| `toggleChecked` | `VoidFunction` | Function to toggle the checked state of the checkbox |


## Accessibility

Complies with the [Checkbox WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/).

### Keyboard Support

<KeyBindingsTable id="checkbox" />