# Checkbox Documentation

Allow users to switch between checked, unchecked, and indeterminate states.

This is a documentation section that potentially contains examples, demos, and other useful information related to a specific part of Bits UI. When helping users with this documentation, you can ignore the classnames applied to the demos unless they are relevant to the user's issue.

```svelte
<script lang="ts">
  import { Checkbox, Label } from "bits-ui";
  import Check from "phosphor-svelte/lib/Check";
  import Minus from "phosphor-svelte/lib/Minus";
</script>
<div class="flex items-center space-x-3">
  <Checkbox.Root
    id="terms"
    aria-labelledby="terms-label"
    class="border-muted bg-foreground data-[state=unchecked]:border-border-input data-[state=unchecked]:bg-background data-[state=unchecked]:hover:border-dark-40 peer inline-flex size-[25px] items-center justify-center rounded-md border transition-all duration-150 ease-in-out active:scale-[0.98]"
    name="hello"
    indeterminate
  >
    {#snippet children({ checked, indeterminate })}
      <div class="text-background inline-flex items-center justify-center">
        {#if indeterminate}
          <Minus class="size-[15px]" weight="bold" />
        {:else if checked}
          <Check class="size-[15px]" weight="bold" />
        {/if}
      </div>
    {/snippet}
  </Checkbox.Root>
  <Label.Root
    id="terms-label"
    for="terms"
    class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
  >
    Accept terms and conditions
  </Label.Root>
</div>
```

## Overview

The Checkbox component provides a flexible and accessible way to create checkbox inputs in your Svelte applications. It supports three states: checked, unchecked, and indeterminate, allowing for complex form interactions and data representations.

## Key Features

- **Tri-State Support**: Handles checked, unchecked, and indeterminate states, providing versatility in form design.  
- **Accessibility**: Built with WAI-ARIA guidelines in mind, ensuring keyboard navigation and screen reader support.  
- **Flexible State Management**: Supports both controlled and uncontrolled state, allowing for full control over the checkbox's checked state. ## Architecture

The Checkbox component is composed of the following parts:

- **Root**: The main component that manages the state and behavior of the checkbox. ## Structure

Here's an overview of how the Checkbox component is structured in code:

```svelte
<script lang="ts">
 import { Checkbox } from "bits-ui";
</script>
<Checkbox.Root>
 {#snippet children({ checked, indeterminate })}
  {#if indeterminate}
   -
  {:else if checked}
   
  {:else}
   
  {/if}
 {/snippet}
</Checkbox.Root>
```

## Reusable Components

It's recommended to use the `Checkbox` primitive to create your own custom checkbox component that can be used throughout your application. In the example below, we're using the `Checkbox` and [`Label`](/docs/components/label) components to create a custom checkbox component.

MyCheckbox.svelte

```svelte
<script lang="ts">
 import { Checkbox, Label, useId, type WithoutChildrenOrChild } from "bits-ui";
 let {
  id = useId(),
  checked = $bindable(false),
  ref = $bindable(null),
  labelRef = $bindable(null),
  ...restProps
 }: WithoutChildrenOrChild<Checkbox.RootProps> & {
  labelText: string;
  labelRef?: HTMLLabelElement | null;
 } = $props();
</script>
<Checkbox.Root bind:checked bind:ref {...restProps}>
 {#snippet children({ checked, indeterminate })}
  {#if indeterminate}
   -
  {:else if checked}
   
  {:else}
   
  {/if}
 {/snippet}
</Checkbox.Root>
<Label.Root for={id} bind:ref={labelRef}>
 {labelText}
</Label.Root>
```

You can then use the `MyCheckbox` component in your application like so:

+page.svelte

```svelte
<script lang="ts">
 import MyCheckbox from "$lib/components/MyCheckbox.svelte";
</script>
<MyCheckbox labelText="Enable notifications" />
```

## Managing Checked State

This section covers how to manage the `checked` state of the Checkbox.

### Two-Way Binding

Use `bind:checked` for simple, automatic state synchronization:

```svelte
<script lang="ts">
 import { Checkbox } from "bits-ui";
 let myChecked = $state(false);
</script>
<button onclick={() => (myChecked = false)}> uncheck </button>
<Checkbox.Root bind:checked={myChecked} />
```

### Fully Controlled

Use a [Function Binding](https://svelte.dev/docs/svelte/bind#Function-bindings) for complete control over the state's reads and writes.

```svelte
<script lang="ts">
 import { Checkbox } from "bits-ui";
 let myChecked = $state(false);
 function getChecked() {
  return myChecked;
 }
 function setChecked(newChecked: boolean) {
  myChecked = newChecked;
 }
</script>
<Checkbox.Root bind:checked={getChecked, setChecked}>
</Checkbox.Root>
```

## Managing Indeterminate State

This section covers how to manage the `indeterminate` state of the Checkbox.

### Two-Way Binding

Use `bind:indeterminate` for simple, automatic state synchronization:

```svelte
<script lang="ts">
 import MyCheckbox from "$lib/components/MyCheckbox.svelte";
 let myIndeterminate = $state(true);
</script>
<button onclick={() => (myIndeterminate = false)}> clear indeterminate </button>
<MyCheckbox bind:indeterminate={myIndeterminate} />
```

### Fully Controlled

Use a [Function Binding](https://svelte.dev/docs/svelte/bind#Function-bindings) for complete control over the state's reads and writes.

```svelte
<script lang="ts">
 import { Checkbox } from "bits-ui";
 let myIndeterminate = $state(true);
 function getIndeterminate() {
  return myIndeterminate;
 }
 function setIndeterminate(newIndeterminate: boolean) {
  myIndeterminate = newIndeterminate;
 }
</script>
<Checkbox.Root bind:indeterminate={getIndeterminate, setIndeterminate}>
</Checkbox.Root>
```

## Disabled State

You can disable the checkbox by setting the `disabled` prop to `true`.

```svelte
<MyCheckbox disabled labelText="Enable notifications" />
```

## HTML Forms

If you set the `name` prop, a hidden checkbox input will be rendered to submit the value of the checkbox with a form.

By default, the checkbox will be submitted with default checkbox value of `'on'` if the `checked` prop is `true`.

```svelte
<MyCheckbox name="notifications" labelText="Enable notifications" />
```

### Custom Input Value

If you'd prefer to submit a different value, you can use the `value` prop to set the value of the hidden input.

For example, if you wanted to submit a string value, you could do the following:

```svelte
<MyCheckbox value="hello" name="notifications" labelText="Enable notifications" />
```

### Required

If you want to make the checkbox required, you can use the `required` prop.

```svelte
<Checkbox.Root required>
</Checkbox.Root>
```

This will apply the `required` attribute to the hidden input element, ensuring that proper form submission is enforced.

## Checkbox Groups

You can use the `Checkbox.Group` component to create a checkbox group.

```svelte
<script lang="ts">
 import { Checkbox } from "bits-ui";
</script>
<Checkbox.Group name="notifications">
 <Checkbox.GroupLabel>Notifications</Checkbox.GroupLabel>
 <Checkbox.Root value="marketing" />
 <Checkbox.Root value="promotions" />
 <Checkbox.Root value="news" />
</Checkbox.Group>
```

```svelte
<script lang="ts">
  import { Checkbox, Label, useId } from "bits-ui";
  import Check from "phosphor-svelte/lib/Check";
  import Minus from "phosphor-svelte/lib/Minus";
  let myValue = $state<string[]>(["marketing", "news"]);
</script>
<Checkbox.Group
  class="flex flex-col gap-3"
  bind:value={myValue}
  name="notifications"
>
  <Checkbox.GroupLabel class="text-foreground-alt text-sm font-medium">
    Notifications
  </Checkbox.GroupLabel>
  <div class="flex flex-col gap-4">
    {@render MyCheckbox({ label: "Marketing", value: "marketing" })}
    {@render MyCheckbox({ label: "Promotions", value: "promotions" })}
    {@render MyCheckbox({ label: "News", value: "news" })}
    {@render MyCheckbox({ label: "Updates", value: "updates" })}
  </div>
</Checkbox.Group>
{#snippet MyCheckbox({ value, label }: { value: string; label: string })}
  {@const id = useId()}
  <div class="flex items-center">
    <Checkbox.Root
      {id}
      aria-labelledby="{id}-label"
      class="border-muted bg-foreground data-[state=unchecked]:border-border-input data-[state=unchecked]:bg-background data-[state=unchecked]:hover:border-dark-40 peer inline-flex size-[25px] items-center justify-center rounded-md border transition-all duration-150 ease-in-out active:scale-[0.98]"
      name="hello"
      {value}
    >
      {#snippet children({ checked, indeterminate })}
        <div class="text-background inline-flex items-center justify-center">
          {#if indeterminate}
            <Minus class="size-[15px]" weight="bold" />
          {:else if checked}
            <Check class="size-[15px]" weight="bold" />
          {/if}
        </div>
      {/snippet}
    </Checkbox.Root>
    <Label.Root
      id="{id}-label"
      for={id}
      class="pl-3 text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
    >
      {label}
    </Label.Root>
  </div>
{/snippet}
```

### Managing Value State

This section covers how to manage the `value` state of a Checkbox Group.

#### Two-Way Binding

Use `bind:value` for simple, automatic state synchronization:

```svelte
<script lang="ts">
 import { Checkbox } from "bits-ui";
 let myValue = $state<string[]>([]);
</script>
<button
 onclick={() => {
  myValue = ["item-1", "item-2"];
 }}
>
 Open Items 1 and 2
</button>
<Checkbox.Group name="myItems" bind:value={myValue}>
 <Checkbox.GroupLabel>Items</Checkbox.GroupLabel>
 <Checkbox.Root value="item-1" />
 <Checkbox.Root value="item-2" />
 <Checkbox.Root value="item-3" />
</Checkbox.Group>
```

#### Fully Controlled

Use a [Function Binding](https://svelte.dev/docs/svelte/bind#Function-bindings) for complete control over the state's reads and writes.

```svelte
<script lang="ts">
 import { Checkbox } from "bits-ui";
 let myValue = $state<string[]>([]);
 function getValue() {
  return myValue;
 }
 function setValue(newValue: string[]) {
  myValue = newValue;
 }
</script>
<Checkbox.Group bind:value={getValue, setValue}>
</Checkbox.Group>
```

### HTML Forms

To render hidden `<input />` elements for the various checkboxes within a group, pass a `name` to `Checkbox.Group`. All descendent checkboxes will then render hidden inputs with the same name.

```svelte
<Checkbox.Group name="notifications">
</Checkbox.Group>
```

When a `Checkbox.Group` component is used, its descendent `Checkbox.Root` components will use certain properties from the group, such as the `name`, `required`, and `disabled`.

## API Reference

### Checkbox.Root

The button component used to toggle the state of the checkbox.

| Property                                                                                        | Type                                                                                                                                                                                                                            | Description                                                                                                                                                                                                     |
| ---------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `checked` $bindable | `boolean`                                                                                                                                                                                             | The checkbox button's checked state.`Default: false`                                                                                                                              |
| `onCheckedChange`                                             | `function`- (checked: boolean) => void                               | A callback that is fired when the checkbox button's checked state changes.`Default:  undefined`                                                                                |
| `indeterminate` $bindable                        | `boolean`                                                                                                                                                                                             | Whether the checkbox is an indeterminate state or not.`Default: false`                                                                                                            |
| `onIndeterminateChange`                                       | `function`- (indeterminate: boolean) => void                         | A callback that is fired when the indeterminate state changes.`Default:  undefined`                                                                                            |
| `disabled`                                                    | `boolean`                                                                                                                                                                                             | Whether or not the checkbox button is disabled. This prevents the user from interacting with it.`Default: false`                                                                  |
| `required`                                                    | `boolean`                                                                                                                                                                                             | Whether or not the checkbox is required.`Default: false`                                                                                                                          |
| `name`                                                        | `string`                                                                                                                                                                                              | The name of the checkbox. If provided a hidden input will be render to use for form submission. If not provided, the hidden input will not be rendered.`Default:  undefined`   |
| `value`                                                       | `string`                                                                                                                                                                                              | The value of the checkbox. This is what is submitted with the form when the checkbox is checked.`Default:  undefined`                                                          |
| `ref` $bindable                                  | `HTMLButtonElement`                                                                                                                                                                                   | The underlying DOM element being rendered. You can bind to this to get a reference to the element.`Default:  undefined`                                                        |
| `children`                                                    | `Snippet`- Snippet                                                   | The children content to render.`Default:  undefined`                                                                                                                           |
| `child`                                                       | `Snippet`- type SnippetProps = { props: Record\<string, unknown>; }; | Use render delegation to render your own element. See [Child Snippet](/docs/child-snippet) docs for more information.`Default:  undefined` | | Data Attribute                             | Value                                                                                                                                                                                                  | Description                                                                                     |
| ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `data-state` | `enum`- 'checked' \| 'unchecked' \| 'indeterminate' | The checkbox's state of checked, unchecked, or indeterminate.            |
| `data-disabled`                                   | `''`                                                                                                                                                                                          | Present when the checkbox is disabled.                                   |
| `data-checkbox-root`                              | `''`                                                                                                                                                                                          | Present on the root element. |

### Checkbox.Group

A group that synchronizes its value state with its descendant checkboxes.

| Property                                                                                      | Type                                                                                                                                                                                                                            | Description                                                                                                                                                                                                                                      |
| -------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `value` $bindable | `string[]`                                                                                                                                                                                            | The value of the group. This is an array of the values of the checked checkboxes within the group.`Default: []`                                                                                                    |
| `onValueChange`                                             | `function`- (value: string\[]) => void                               | A callback that is fired when the checkbox group's value state changes.`Default:  undefined`                                                                                                                    |
| `disabled`                                                  | `boolean`                                                                                                                                                                                             | Whether or not the checkbox group is disabled. If `true`, all checkboxes within the group will be disabled. To disable a specific checkbox in the group, pass the `disabled` prop to the checkbox.`Default: false` |
| `required`                                                  | `boolean`                                                                                                                                                                                             | Whether or not the checkbox group is required for form submission.`Default: false`                                                                                                                                 |
| `name`                                                      | `string`                                                                                                                                                                                              | The name of the checkbox group. If provided a hidden input will be rendered to use for form submission.`Default:  undefined`                                                                                    |
| `ref` $bindable                                | `HTMLDivElement`                                                                                                                                                                                      | The underlying DOM element being rendered. You can bind to this to get a reference to the element.`Default:  undefined`                                                                                         |
| `children`                                                  | `Snippet`                                                                                                                                                                                             | The children content to render.`Default:  undefined`                                                                                                                                                            |
| `child`                                                     | `Snippet`- type SnippetProps = { props: Record\<string, unknown>; }; | Use render delegation to render your own element. See [Child Snippet](/docs/child-snippet) docs for more information.`Default:  undefined`                                  | | Data Attribute                                | Value         | Description                                                                                      |
| -------------------------------------------------------------------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `data-disabled` | `''` | Present when the checkbox group is disabled.                              |
| `data-checkbox-group`                                | `''` | Present on the group element. |

### Checkbox.GroupLabel

An accessible label for the checkbox group.

| Property                                                                                    | Type                                                                                                                                                                                                                            | Description                                                                                                                                                                                                     |
| ------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ref` $bindable | `HTMLLabelElement`                                                                                                                                                                                    | The underlying DOM element being rendered. You can bind to this to get a reference to the element.`Default:  undefined`                                                        |
| `children`                                                | `Snippet`                                                                                                                                                                                             | The children content to render.`Default:  undefined`                                                                                                                           |
| `child`                                                   | `Snippet`- type SnippetProps = { props: Record\<string, unknown>; }; | Use render delegation to render your own element. See [Child Snippet](/docs/child-snippet) docs for more information.`Default:  undefined` | | Data Attribute                                | Value         | Description                                                                                      |
| -------------------------------------------------------------------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `data-disabled` | `''` | Present when the checkbox group is disabled.                              |
| `data-checkbox-group-label`                          | `''` | Present on the label element. |