On this page

Forms

Checkbox Group

A labelled group of checkboxes for choosing multiple options.

Use CheckboxGroup when someone can choose more than one option from a related set. It provides a shared label, description, and validation message for its CheckboxField children.

Checkbox Group: Basic
Days availableChoose any days that apply.
import { CheckboxField } from '@luke-ui/react/checkbox-field';
import { CheckboxGroup } from '@luke-ui/react/checkbox-group';

export default () => {
	return (
		<CheckboxGroup description="Choose any days that apply." label="Days available">
			<CheckboxField label="Monday" value="monday" />
			<CheckboxField label="Tuesday" value="tuesday" />
			<CheckboxField label="Wednesday" value="wednesday" />
		</CheckboxGroup>
	);
};

Selection

Pass defaultValue to set the initial selection, or pass value with onChange to control it. Pass a unique value to each CheckboxField. The group value is an array of the selected values.

Checkbox Group: Controlled
Days available

Days selected: 1

import { CheckboxField } from '@luke-ui/react/checkbox-field';
import { CheckboxGroup } from '@luke-ui/react/checkbox-group';
import { Stack } from '@luke-ui/react/stack';
import { Text } from '@luke-ui/react/text';
import { useState } from 'react';

export default () => {
	const [days, setDays] = useState(['monday']);

	return (
		<Stack gap="space.16">
			<CheckboxGroup label="Days available" onChange={setDays} value={days}>
				<CheckboxField label="Monday" value="monday" />
				<CheckboxField label="Tuesday" value="tuesday" />
				<CheckboxField label="Wednesday" value="wednesday" />
			</CheckboxGroup>
			<Text color="secondary" elementType="p" role="status">
				{`Days selected: ${days.length}`}
			</Text>
		</Stack>
	);
};

Layout

The group is vertical by default. Set orientation="horizontal" to arrange options in a row that wraps when it runs out of space.

Checkbox Group: Layout
Vertical
Days available
Horizontal
Days available
import { CheckboxField } from '@luke-ui/react/checkbox-field';
import { CheckboxGroup } from '@luke-ui/react/checkbox-group';
import { Comparison, ComparisonItem } from '#docs';

export default () => {
	return (
		<Comparison>
			<ComparisonItem label="Vertical">
				<CheckboxGroup label="Days available">
					<CheckboxField label="Monday" value="monday" />
					<CheckboxField label="Tuesday" value="tuesday" />
					<CheckboxField label="Wednesday" value="wednesday" />
				</CheckboxGroup>
			</ComparisonItem>
			<ComparisonItem label="Horizontal">
				<CheckboxGroup label="Days available" orientation="horizontal">
					<CheckboxField label="Monday" value="monday" />
					<CheckboxField label="Tuesday" value="tuesday" />
					<CheckboxField label="Wednesday" value="wednesday" />
				</CheckboxGroup>
			</ComparisonItem>
		</Comparison>
	);
};

Size

Set size to provide a default size for its checkbox fields. A child's size takes precedence over the group size. When neither sets a size, the group inherits Form.controlSize or uses medium. The size changes the control without changing the label typography.

Checkbox Group: Size
Small
Days available
Medium
Days available
Small group with a medium option
Days available
import { CheckboxField } from '@luke-ui/react/checkbox-field';
import { CheckboxGroup } from '@luke-ui/react/checkbox-group';
import { Comparison, ComparisonItem } from '#docs';

export default () => {
	return (
		<Comparison>
			<ComparisonItem label="Small">
				<CheckboxGroup label="Days available" size="small">
					<CheckboxField label="Monday" value="monday" />
					<CheckboxField label="Tuesday" value="tuesday" />
				</CheckboxGroup>
			</ComparisonItem>
			<ComparisonItem label="Medium">
				<CheckboxGroup label="Days available" size="medium">
					<CheckboxField label="Monday" value="monday" />
					<CheckboxField label="Tuesday" value="tuesday" />
				</CheckboxGroup>
			</ComparisonItem>
			<ComparisonItem label="Small group with a medium option">
				<CheckboxGroup label="Days available" size="small">
					<CheckboxField label="Monday" value="monday" />
					<CheckboxField label="Tuesday" size="medium" value="tuesday" />
				</CheckboxGroup>
			</ComparisonItem>
		</Comparison>
	);
};

Validation

Set isRequired to require at least one selection, or pass validate to check the selected values. Set isRequired or pass validate on a CheckboxField when that option needs its own rule. The group shows these native validation messages below its options.

Pass errorMessage to CheckboxGroup for a controlled error from a form library or server. A non-empty message marks the group invalid and takes precedence over native validation messages. The description stays visible while the group is invalid. Read Validation for where messages come from and how to write them.

By default, a required group shows a marker after its label. Read Required fields for the necessityIndicator values.

Submit without selecting a day to see the validation message.

Checkbox Group: Validation
Days availableChoose at least one day.
import { Button } from '@luke-ui/react/button';
import { CheckboxField } from '@luke-ui/react/checkbox-field';
import { CheckboxGroup } from '@luke-ui/react/checkbox-group';
import { Stack } from '@luke-ui/react/stack';
import type { SubmitEvent } from 'react';

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

export default () => {
	return (
		<form onSubmit={handleSubmit}>
			<Stack gap="space.16">
				<CheckboxGroup
					description="Choose at least one day."
					isRequired
					label="Days available"
					name="days"
				>
					<CheckboxField label="Monday" value="monday" />
					<CheckboxField label="Tuesday" value="tuesday" />
					<CheckboxField label="Wednesday" value="wednesday" />
				</CheckboxGroup>
				<Button type="submit">Submit</Button>
			</Stack>
		</form>
	);
};

Select email updates and submit without accepting the terms to see the group error for the required option.

Checkbox Group: Required option
Consent
import { Button } from '@luke-ui/react/button';
import { CheckboxField } from '@luke-ui/react/checkbox-field';
import { CheckboxGroup } from '@luke-ui/react/checkbox-group';
import { Stack } from '@luke-ui/react/stack';
import type { SubmitEvent } from 'react';

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

export default () => {
	return (
		<form onSubmit={handleSubmit}>
			<Stack gap="space.16">
				<CheckboxGroup label="Consent" name="consent">
					<CheckboxField isRequired label="I accept the terms" value="terms" />
					<CheckboxField label="Email me updates" value="updates" />
				</CheckboxGroup>
				<Button type="submit">Submit</Button>
			</Stack>
		</form>
	);
};

Form values

Pass name to include the selected values in form submission. Pass form to associate the group with a <form> it does not sit inside.

Accessibility

Use a visible label to name the group. When another part of the layout names it, pass aria-labelledby. Pass aria-label when there is no visible group label. Each CheckboxField keeps its own visible label and optional description.

Set isDisabled on the group to disable every option. An individual option cannot override a disabled group with isDisabled={false}.

API

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

NameTypeDefault
description
ReactNode—

Supporting text shown below the group label. Optional helper text shown below the control.

errorMessage
ReactNode—

Validation message for a controlled error. A non-empty message marks the group invalid.

label
Exclude<ReactNode, boolean |⁠ null |⁠ undefined>—

Visible label. Pass non-empty, textual, non-interactive content. Place links and buttons outside it, and associate external label content with aria-labelledby instead.

necessityIndicator
—

Controls how the group label identifies required or optional values. Controls how the label identifies required or optional values. Inherits from Form, or uses 'required-asterisk' when unset.

orientation
'vertical' |⁠ 'horizontal''vertical'

Controls whether options stack or wrap in rows.

size
—

Default control size for its options. An option's explicit size takes precedence.