# Checkbox

_Box Kite 2.2.6 · a markdown copy of https://www.box-kite.dev/checkbox/_

Use Checkbox component to turn an option on or off.

**Import**

```jsx
import Checkbox from '@box-kite/react/components/checkbox';
```

**Basic Checkbox**

```jsx
<Checkbox label="Accept the terms" name="terms" defaultChecked />
```

## The label is the component's job

`label` renders the text inside a `<label>` that wraps the input. The association is implicit, so there is no `htmlFor`/`id` pair to generate or keep in sync, and the whole row is a click target — which is what a checkbox row is expected to be. A checkbox with no label is the most common accessibility failure there is, so this is not left to the consumer.

Style that `<label>` with `labelProps`; every other Box prop still styles the box itself. Leave `label` out and nothing wraps the input at all — the markup is exactly what it was before.

```jsx
<Checkbox label="Accept the terms" name="terms" labelProps={{ gap: 3, fontSize: 14 }} />
```

**Indeterminate**

```jsx
<Checkbox label="Select all rows" name="rows" indeterminate />
```

## The mixed state is announced, not just drawn

`indeterminate` is a DOM property, not an attribute — set it and the browser draws the dash, but the accessibility tree still says checked or not checked. The component adds `aria-checked="mixed"` alongside it, which is what a screen reader reads out. A parent checkbox over a partly-selected list is the case this exists for.

`indeterminate` is a pseudo-class style prop as well as a state, so the tuple form carries both: `indeterminate={[mixed, { opacity: 0.6 }]}` is the state first and what `:indeterminate` should look like second.

**Disabled Checkbox**

```jsx
<Checkbox label="Accept the terms" disabled defaultChecked />
```

**Clean Checkbox**

```jsx
<Checkbox clean defaultChecked />
```

## On or off, rather than checked?

A setting that takes effect immediately is a switch, not a checkbox. `Switch` is the same input underneath with `role="switch"` and a track-and-thumb style — see its page.

## Checkbox props

Everything below is this component’s own. All 235 of Box’s style props work on it too, and those are on [/box](https://www.box-kite.dev/box.md) rather than repeated here.

| Prop | Type | Default | What it does |
| --- | --- | --- | --- |
| `name` | `string` | — | What the checkbox submits under. Needed for a form; a controlled checkbox can do without one. |
| `props` | `CheckboxTagProps` | — | Attributes for the `<input>` itself — `type` is the component's, and so is `aria-checked`. |
| `onInput` | `(e: React.ChangeEvent<HTMLInputElement>) => void` | — | Fires on every click or keystroke. On a checkbox this is the same moment as `onChange`. |
| `onChange` | `(e: React.ChangeEvent<HTMLInputElement>) => void` | — | Fires when the box is ticked or cleared. `e.target.checked` is the new state. |
| `value` | `string \| number` | — | The value the form submits when it is checked. Defaults to `"on"`, as HTML does. |
| `autoFocus` | `boolean` | — | Focus it on mount. One per page at most — a stolen focus is a lost place in the document. |
| `readOnly` | `boolean` | — | Rendered and read, but not toggleable. Unlike `disabled` it stays in the tab order and submits. |
| `defaultChecked` | `boolean` | — | The state it starts in when the checkbox is uncontrolled. Pass `checked` instead to control it. |
| `label` | `React.ReactNode` | — | The text beside the checkbox — rendered inside a `<label>` that wraps the input, so the association is the component's job. Without it a consumer has to wire `htmlFor`/`id` by hand, and a checkbox with no label is the single most common accessibility failure there is. |
| `labelProps` | `BoxProps<'label'>` | — | Styles for the wrapping `<label>`: the row's layout, not the box's own appearance. |

## Checkbox keyboard

| Key | Result |
| --- | --- |
| `Tab` | Focuses the checkbox. It is one tab stop, whether or not it carries a label. |
| `Space` | Ticks and clears it. The platform supplies this one. |

## Checkbox accessibility

Implements [the WAI-ARIA APG pattern](https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/).

- A real `<input type="checkbox">`, so focus, the checked state, the disabled state and form submission are the platform's rather than this component's.
- `label` renders the `<label>` wrapping the input, which is what names it — without one a checkbox is the commonest accessibility failure there is.
- `indeterminate` sets the DOM property *and* `aria-checked="mixed"`: the browser draws from the first, a screen reader reads the second, and a checkbox with only the property is read as unchecked.

Swept with axe on every release, in 2 states: `Checkbox`, `Checkbox (indeterminate)`. No violations, with contrast and landmark rules left to a human. Screen-reader results are not published yet.

## Checkbox style tree

Every part the component draws is a node with a name, so a default can be restyled with `Box.components()` instead of a selector — and a variant is a name too.

`checkbox`variants: datagrid

---

_Every page: https://www.box-kite.dev/llms.txt · every prop, measured: https://www.box-kite.dev/props.md_

