# Checkbox Field (/components/forms/checkbox-field)



Use `CheckboxField` when someone can choose an option independently of nearby controls. Pass `label`
to name the option, and `description` to clarify what it means.

apps/docs/src/examples/checkbox-field/basic.tsx

```tsx
import { CheckboxField } from '@luke-ui/react/checkbox-field';

export default () => {
	return <CheckboxField description="Receive updates by email." label="Email notifications" />;
};
```

## Labels [#labels]

Every `CheckboxField` has a visible `label`. The label sits inside a native `<label>`, so pass
textual content only. Place links and buttons next to the checkbox. Inline typography such as
`Strong` works inside the label. Set `slot={null}` on a `Text` you place there, as the
[Checkbox primitive](/components/primitives/checkbox#text-in-the-label) describes.

When another part of the layout draws the visible label, such as a table row or a settings row,
compose the [Checkbox primitive](/components/primitives/checkbox) and name the control with
`aria-labelledby`.

## States [#states]

Use `defaultSelected` for an uncontrolled initial value, or pair `isSelected` with `onChange` when
application state owns the selection. `isIndeterminate` communicates a mixed state, such as a parent
option whose child options are only partly selected.

apps/docs/src/examples/checkbox-field/states.tsx

```tsx
import { CheckboxField } from '@luke-ui/react/checkbox-field';
import { Comparison, ComparisonItem } from '#docs';

export default () => {
	return (
		<Comparison>
			<ComparisonItem label="Unchecked">
				<CheckboxField label="Example checkbox" />
			</ComparisonItem>
			<ComparisonItem label="Checked">
				<CheckboxField defaultSelected label="Example checkbox" />
			</ComparisonItem>
			<ComparisonItem label="Indeterminate">
				<CheckboxField isIndeterminate label="Example checkbox" />
			</ComparisonItem>
			<ComparisonItem label="Disabled">
				<CheckboxField isDisabled label="Example checkbox" />
			</ComparisonItem>
			<ComparisonItem label="Disabled and checked">
				<CheckboxField defaultSelected isDisabled label="Example checkbox" />
			</ComparisonItem>
			<ComparisonItem label="Invalid">
				<CheckboxField
					errorMessage="Select this example checkbox to continue."
					label="Example checkbox"
				/>
			</ComparisonItem>
		</Comparison>
	);
};
```

apps/docs/src/examples/checkbox-field/controlled.tsx

```tsx
import { CheckboxField } from '@luke-ui/react/checkbox-field';
import { Stack } from '@luke-ui/react/stack';
import { useState } from 'react';

export default () => {
	const [isSelected, setIsSelected] = useState(false);

	return (
		<Stack maxInlineSize="20rem">
			<CheckboxField
				isSelected={isSelected}
				label={isSelected ? 'Checked' : 'Unchecked'}
				onChange={setIsSelected}
			/>
		</Stack>
	);
};
```

## Size [#size]

Use `size` to change the checkbox control. It does not change the label typography. `medium` is the
default. Use `small` in compact layouts and `large` where a larger control improves scanning.

apps/docs/src/examples/checkbox-field/sizes.tsx

```tsx
import { CheckboxField } from '@luke-ui/react/checkbox-field';
import { Comparison, ComparisonItem } from '#docs';

export default () => {
	return (
		<Comparison>
			<ComparisonItem label="Small">
				<CheckboxField defaultSelected label="Example checkbox" size="small" />
			</ComparisonItem>
			<ComparisonItem label="Medium">
				<CheckboxField defaultSelected label="Example checkbox" size="medium" />
			</ComparisonItem>
			<ComparisonItem label="Large">
				<CheckboxField defaultSelected label="Example checkbox" size="large" />
			</ComparisonItem>
		</Comparison>
	);
};
```

## Validation [#validation]

Set `isRequired` to require the choice. `CheckboxField` shows its validation message after
validation fails. Pass `errorMessage` only for an error you already have, such as one from a form
library or your server. A non-empty message marks the checkbox invalid. Read
[Validation](/docs/validation) for where messages come from and how to write them.

apps/docs/src/examples/checkbox-field/validation.tsx

```tsx
import { Button } from '@luke-ui/react/button';
import { CheckboxField } from '@luke-ui/react/checkbox-field';
import { Cluster } from '@luke-ui/react/cluster';
import { Stack } from '@luke-ui/react/stack';
import type { SubmitEvent } from 'react';

export default () => {
	function handleSubmit(event: SubmitEvent<HTMLFormElement>) {
		event.preventDefault();
	}

	return (
		<form onSubmit={handleSubmit}>
			<Stack gap="sp16" maxInlineSize="20rem">
				<Stack minBlockSize="4.5rem">
					<CheckboxField isRequired label="I accept the terms of service" />
				</Stack>
				<Cluster>
					<Button type="submit">Create account</Button>
				</Cluster>
			</Stack>
		</form>
	);
};
```

## Required marker [#required-marker]

A required checkbox shows a marker after its `label`. Read
[Required fields](/components/forms/text-input-field#required-fields) for both `necessityIndicator`
values.

## Labels with Text [#labels-with-text]

Wrap a checkbox in block `Text` when its label needs a specific text size. The control follows the
inherited line height. It keeps its fixed visual square centred on the first line when the label
wraps. Outside `Text`, it uses the normal compact control size.

apps/docs/src/examples/checkbox-field/first-line-alignment.tsx

```tsx
import { CheckboxField } from '@luke-ui/react/checkbox-field';
import { Stack } from '@luke-ui/react/stack';
import { Text } from '@luke-ui/react/text';

export default () => {
	return (
		<Stack gap="sp16" maxInlineSize="18rem">
			<Text elementType="div" typography="caption">
				<CheckboxField label="A longer label keeps its control aligned when it wraps." />
			</Text>
			<Text elementType="div" typography="heading4">
				<CheckboxField label="Larger text keeps the same first-line alignment when it wraps." />
			</Text>
		</Stack>
	);
};
```

## IDs and refs [#ids-and-refs]

`id`, `className`, and `ref` target the root element. `inputId` and `inputRef` target the input.

## Form values [#form-values]

Pass `name` so the checkbox joins `FormData` when selected. Pass `value` to set the submitted value,
and `form` to associate a checkbox with a `<form>` it does not sit inside.

## Accessibility [#accessibility]

Disabled checkboxes cannot receive focus, and their value cannot change. Read-only checkboxes remain
focusable, so someone who uses a keyboard or assistive technology can still perceive their state.
Keyboard navigation shows a focus ring. Pointer focus does not.

## API [#api]

### CheckboxFieldProps

Props for `CheckboxField`.

`CheckboxFieldProps` also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.

| Prop                  | Type        | Description                                                                                                             |
| --------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------- |
| `aria-describedby?`   | `string`    | Identifies the element (or elements) that describes the object.                                                         |
| `aria-details?`       | `string`    | Identifies the element (or elements) that provide a detailed, extended description for the object.                      |
| `aria-errormessage?`  | `string`    | Identifies the element that provides an error message for the object.                                                   |
| `onKeyDown?`          | `function`  | Handler that is called when a key is pressed.                                                                           |
| `onKeyUp?`            | `function`  | Handler that is called when a key is released.                                                                          |
| `onFocus?`            | `function`  | Handler that is called when the element receives focus.                                                                 |
| `onBlur?`             | `function`  | Handler that is called when the element loses focus.                                                                    |
| `onFocusChange?`      | `function`  | Handler that is called when the element's focus status changes.                                                         |
| `onPress?`            | `function`  | Handler that is called when the press is released over the target.                                                      |
| `onPressStart?`       | `function`  | Handler that is called when a press interaction starts.                                                                 |
| `onPressEnd?`         | `function`  | Handler that is called when a press interaction ends, either over the target or when the pointer leaves the target.     |
| `onPressChange?`      | `function`  | Handler that is called when the press state changes.                                                                    |
| `onPressUp?`          | `function`  | Handler that is called when a press is released over the target, regardless of whether it started on the target or not. |
| `autoFocus?`          | `union`     | Whether the element should receive focus on render.                                                                     |
| `className?`          | `union`     | Class name for the root element.                                                                                        |
| `defaultSelected?`    | `union`     | Initial selection state for an uncontrolled checkbox.                                                                   |
| `form?`               | `string`    | The `<form>` element to associate the input with, by id.                                                                |
| `id?`                 | `string`    | Element id for the root element. Use `inputId` for the input.                                                           |
| `inputId?`            | `string`    | Element id for the input and the `for` of a `FieldLabel` in the root. Defaults to a generated id.                       |
| `inputRef?`           | `union`     | Forwarded to the underlying `<input type="checkbox">` element.                                                          |
| `isDisabled?`         | `union`     | Whether the checkbox is disabled.                                                                                       |
| `isIndeterminate?`    | `union`     | Whether the checkbox displays a mixed selection state.                                                                  |
| `isReadOnly?`         | `union`     | Whether the checkbox can be read but not changed.                                                                       |
| `isRequired?`         | `union`     | Whether the checkbox is required before the form can submit.                                                            |
| `isSelected?`         | `union`     | Whether the checkbox is selected.                                                                                       |
| `name?`               | `string`    | The name of the input, used when submitting an HTML form.                                                               |
| `onChange?`           | `function`  | Called when the selection changes.                                                                                      |
| `ref?`                | `union`     | Forwarded to the root element.                                                                                          |
| `size?`               | `union`     | Visual size of the checkbox control. Default: `'medium'`                                                                |
| `validate?`           | `function`  | Custom validation function run against the selection. Return a message, or `true`/`null` when valid.                    |
| `validationBehavior?` | `union`     | When native HTML form validation runs. Default: `'native'`                                                              |
| `value?`              | `string`    | The value submitted with an HTML form when the checkbox is selected.                                                    |
| `description?`        | `ReactNode` | Supporting text shown beneath the checkbox label.                                                                       |
| `errorMessage?`       | `ReactNode` | Validation message for a controlled error. A non-empty message marks the field invalid.                                 |
| `label`               | `union`     | Visible label. Pass non-empty, textual, non-interactive content. Place links and buttons outside the checkbox.          |
| `necessityIndicator?` | `union`     | How a required checkbox is marked. Default: `'icon'`                                                                    |
