> ## Documentation Index
> Fetch the complete documentation index at: https://anvil.servicetitan.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Checkbox - Web (AI Kit)

> Checkboxes let users select one or more options from a set.

> [!NOTE]
>
> For development, import `Checkbox` from
> `@servicetitan/anvil2-ai-kit`. For design, find it in the
> [AI Kit Web Component Library file](https://www.figma.com/design/QEIsArLktLeJAaFvcpw3PO/AI-Kit-Web-Component-Library).

ai-kit-checkbox

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-checkbox?file=src/App.tsx)

```tsx lines theme={null}
import { Checkbox } from "@servicetitan/anvil2-ai-kit";

function App() {
  return <Checkbox label="Notify customer" />;
}

export default App;
```

## Options

The Checkbox supports selection, an indeterminate mixed state, and either a visible label or an indicator-only presentation.

### Selection

ai-kit-checkbox-selection

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-checkbox-selection?file=src/App.tsx)

```tsx lines theme={null}
import { Checkbox } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
      <Checkbox label="Unselected" />
      <Checkbox label="Selected" defaultSelected />
    </div>
  );
}

export default App;
```

The checkbox toggles between unselected and selected. Use `isSelected` for controlled selection or `defaultSelected` for uncontrolled.

### Indeterminate

ai-kit-checkbox-indeterminate

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-checkbox-indeterminate?file=src/App.tsx)

```tsx lines theme={null}
import { useState } from "react";
import { Checkbox } from "@servicetitan/anvil2-ai-kit";

function App() {
  const [completed, setCompleted] = useState(true);
  const [cancelled, setCancelled] = useState(false);
  const allSelected = completed && cancelled;
  const someSelected = completed || cancelled;

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
      <Checkbox
        label="Select all"
        isSelected={allSelected}
        isIndeterminate={someSelected && !allSelected}
        onChange={(isSelected) => {
          setCompleted(isSelected);
          setCancelled(isSelected);
        }}
      />
      <div
        style={{
          display: "flex",
          flexDirection: "column",
          gap: 8,
          paddingLeft: 24,
        }}
      >
        <Checkbox
          label="Include completed jobs"
          isSelected={completed}
          onChange={setCompleted}
        />
        <Checkbox
          label="Include cancelled jobs"
          isSelected={cancelled}
          onChange={setCancelled}
        />
      </div>
    </div>
  );
}

export default App;
```

`isIndeterminate` renders a minus indicator for a select-all row whose children are only partially selected. It's a display-only override — pair it with your own logic to derive the mixed state from the children's selection, as shown above.

### Label

ai-kit-checkbox-label

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-checkbox-label?file=src/App.tsx)

```tsx lines theme={null}
import { Checkbox } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
      {/* With visible label */}
      <Checkbox label="Notify customer" />

      {/* Indicator only, named via aria-label */}
      <Checkbox aria-label="Notify customer" />
    </div>
  );
}

export default App;
```

A visible `label` doubles as the accessible name. Omit `label` and supply `aria-label` or `aria-labelledby` instead for an indicator-only checkbox — common in dense table rows.

## Behavior

The Checkbox responds to selection, focus, and disabled states.

### Visual States

ai-kit-checkbox-visual-states

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-checkbox-visual-states?file=src/App.tsx)

```tsx lines theme={null}
import { Checkbox } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
      {/* Rest */}
      <Checkbox label="Notify customer" />

      {/* Selected */}
      <Checkbox label="Notify customer" defaultSelected />

      {/* Indeterminate */}
      <Checkbox label="Notify customer" isIndeterminate />

      {/* Focus */}
      <Checkbox label="Notify customer" />

      {/* Disabled */}
      <Checkbox label="Notify customer" isDisabled />

      {/* Disabled + selected */}
      <Checkbox label="Notify customer" isDisabled defaultSelected />
    </div>
  );
}

export default App;
```

Selecting the checkbox fills the indicator; keyboard focus draws a ring scoped to the square indicator, not the full label width. `isDisabled` dims the control and blocks interaction in either selection state.

## Usage Guidelines

### When to Use

Use the Checkbox when:

* **Selecting options from a set** – Users choose one or more independent options.
* **Selecting all in a group** – A select-all row controls child options. Show the indeterminate state when only some children are selected.
* **Selecting rows in dense layouts** – Table rows or other compact layouts have no room for a visible label. Use an indicator-only Checkbox with an accessible name.

### When not to use

Avoid using the Checkbox for:

* **Picking options from a list that opens from a trigger** – Use the [Menu](https://anvil.servicetitan.com/docs/components/menu/ai-kit.md) with single or multiple selection instead.
* **Toggling a button-style setting, such as bold or list view** – Use the [Button Toggle](https://anvil.servicetitan.com/docs/components/button-toggle/ai-kit.md) instead.

## Keyboard Interaction

Users can navigate and toggle the Checkbox using standard keyboard controls.

| Key | Description |
| - | - |
| Tab | Moves focus to the next checkbox |
| Space | Toggles the focused checkbox |

## Code

**Implementation**

ai-kit-checkbox

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-checkbox?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Checkbox } from "@servicetitan/anvil2-ai-kit";

function App() {
  return <Checkbox label="Notify customer" />;
}

export default App;
```

## Common Examples

To use the `Checkbox`, import it from `@servicetitan/anvil2-ai-kit` and pass a visible `label`, or omit `label` and supply exactly one of `aria-label` or `aria-labelledby`.

```tsx theme={null}
import { Checkbox } from "@servicetitan/anvil2-ai-kit";

function ExampleComponent() {
  return <Checkbox label="Notify customer" />;
}
```

### Selection

Use `isSelected` with `onChange` for controlled selection, or `defaultSelected` for uncontrolled.

ai-kit-checkbox-selection

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-checkbox-selection?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Checkbox } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
      <Checkbox label="Unselected" />
      <Checkbox label="Selected" defaultSelected />
    </div>
  );
}

export default App;
```

### Indeterminate

`isIndeterminate` is a display-only mixed state for select-all rows. Derive it from child selection in your own logic.

ai-kit-checkbox-indeterminate

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-checkbox-indeterminate?file=src/App.tsx)

```tsx lines expandable theme={null}
import { useState } from "react";
import { Checkbox } from "@servicetitan/anvil2-ai-kit";

function App() {
  const [completed, setCompleted] = useState(true);
  const [cancelled, setCancelled] = useState(false);
  const allSelected = completed && cancelled;
  const someSelected = completed || cancelled;

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
      <Checkbox
        label="Select all"
        isSelected={allSelected}
        isIndeterminate={someSelected && !allSelected}
        onChange={(isSelected) => {
          setCompleted(isSelected);
          setCancelled(isSelected);
        }}
      />
      <div
        style={{
          display: "flex",
          flexDirection: "column",
          gap: 8,
          paddingLeft: 24,
        }}
      >
        <Checkbox
          label="Include completed jobs"
          isSelected={completed}
          onChange={setCompleted}
        />
        <Checkbox
          label="Include cancelled jobs"
          isSelected={cancelled}
          onChange={setCancelled}
        />
      </div>
    </div>
  );
}

export default App;
```

### Label and indicator-only

A visible `label` is the accessible name. For dense rows, omit `label` and name the control with `aria-label` or `aria-labelledby`. Never pass both naming attributes.

ai-kit-checkbox-label

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-checkbox-label?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Checkbox } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
      {/* With visible label */}
      <Checkbox label="Notify customer" />

      {/* Indicator only, named via aria-label */}
      <Checkbox aria-label="Notify customer" />
    </div>
  );
}

export default App;
```

### Disabled

`isDisabled` dims the control and blocks interaction in either selection state.

ai-kit-checkbox-visual-states

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-checkbox-visual-states?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Checkbox } from "@servicetitan/anvil2-ai-kit";

function App() {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
      {/* Rest */}
      <Checkbox label="Notify customer" />

      {/* Selected */}
      <Checkbox label="Notify customer" defaultSelected />

      {/* Indeterminate */}
      <Checkbox label="Notify customer" isIndeterminate />

      {/* Focus */}
      <Checkbox label="Notify customer" />

      {/* Disabled */}
      <Checkbox label="Notify customer" isDisabled />

      {/* Disabled + selected */}
      <Checkbox label="Notify customer" isDisabled defaultSelected />
    </div>
  );
}

export default App;
```

## React Accessibility

* Supply a visible `label`, or exactly one of `aria-label` or `aria-labelledby`.
* Keyboard focus draws a ring on the square indicator, not the full label width.
* Users toggle a focused checkbox with Space.

**Checkbox Props**

```tsx theme={null}
<Checkbox
  label="Notify customer"
  isSelected={false}
  onChange={(isSelected) => {}}
/>
```

## `Checkbox` Props

The `Checkbox` accepts the following props. Pass a `label`, or omit `label` and pass exactly one of `aria-label` or `aria-labelledby`.

**aria-label** `string`

Accessible name when there is no visible `label`. Mutually exclusive with
`aria-labelledby`.

**aria-labelledby** `string`

id(s) of the element(s) that name an indicator-only checkbox. Mutually
exclusive with `aria-label`.

**className** `string`

Class merged onto the root label.

**defaultSelected** `boolean`

Whether the checkbox starts checked when uncontrolled.

**isDisabled** `boolean`

Whether the checkbox is disabled.

**isIndeterminate** `boolean`

Mixed selection state for select-all controls. Display only; it does not
replace `isSelected`.

**isSelected** `boolean`

Whether the checkbox is checked when controlled.

**label** `string`

Visible label and accessible name. Omit for indicator-only checkboxes.

**onChange** `(isSelected: boolean) =\> void`

Called when the checked state changes.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.