Skip to main content
In progress

Checkbox

A Checkbox lets users select one or more options from a limited set, while a Checkbox Group combines related checkboxes under a shared label with optional helper text and validation.

Select colors
Code example
import { Checkbox, CheckboxGroup } from '@yleisradio/yds-components-react';

<CheckboxGroup
id="colors"
name="colors"
label="Select colors"
selectedValue={["red", "blue"]}
onValueChange={() => {}}
>
<Checkbox value="red" label="Red" name="colors" />
<Checkbox value="green" label="Green" name="colors" />
<Checkbox value="blue" label="Blue" name="colors" />
<Checkbox value="yellow" label="Yellow" name="colors" />
</CheckboxGroup>

Why to use

Checkboxes enable independent, multi-select decisions in forms and filters. A Checkbox Group clarifies context with a shared label, optional description, and unified validation, while each Checkbox represents a separate, non-exclusive choice.

When to use

Use Checkboxes when the user may choose any number of options (including none). Prefer a Checkbox Group when the options belong together and should share a label, helper text, or validation.

Do
  • Use for multi-select choices from a short list (typically less than 8 options).
  • Group related checkboxes under a clear, descriptive group label.
  • Add description text when extra context is needed.
  • Stack options vertically for readability.
  • Use indeterminate state to indicate a mixed/partial selection for parent items.
  • Keep labels short and specific.
Don’t
  • Don’t use Checkboxes for single mandatory choice — use Radio.
  • Don’t use Checkboxes for immediate toggles — use Switch.
  • Don’t trigger instant side effects on check/uncheck; apply changes on submit (or use Switch for immediate effects).
  • Don’t mix Primary and Secondary variants in the same interface; use one style consistently.
  • Don’t rely only on color to convey state or errors.

Anatomy

Checkbox anatomy

  1. Group label – Describes the set of related options.
  2. Description – Optional helper text below the label.
  3. Checkbox control – Square selector; multiple can be checked.
  4. Option label – Text linked to each checkbox option.

Key Checkbox Props

Use the following props to customize the Checkbox component to fit your needs.

variant

ValueExampleDescription
primaryDefault style for most use cases.
secondaryUses highlight color for the control.
Code example
<Checkbox name="demo" value="primary" label="Primary" variant="primary" defaultChecked />
<Checkbox name="demo" value="secondary" label="Secondary" variant="secondary" defaultChecked />

isDisabled

Non-interactive, dimmed styling.

TypeExampleDescription
booleanTemporarily prevents user interaction.
Code example
<Checkbox name="demo" value="x" label="Disabled" isDisabled />

hideLabel

TypeExampleDescription
booleanVisually hides label but keeps it accessible.
Code example
<Checkbox name="demo" value="hidden" label="Hidden label" hideLabel />

controlAlign

ValueExampleDescription
startPositions the control before the label text.
endPositions the control after the label text.
Code example
<Checkbox name="align" value="start" label="Start aligned" controlAlign="start" />
<Checkbox name="align" value="end" label="End aligned" controlAlign="end" />

error

Applies error styling to the individual checkbox.

TypeExampleDescription
booleanMarks checkbox with error styling.
Code example
<Checkbox name="demo" value="err" label="Error" error />

checked / defaultChecked

Standard HTML checked control for controlled or uncontrolled usage.

PropExampleDescription
defaultCheckedSets initial checked state.
checkedControlled state—must provide onChange handler.
Code example
// Uncontrolled
<Checkbox name="demo" value="one" label="Uncontrolled default" defaultChecked />

// Controlled
const [isChecked, setChecked] = useState(true);
<Checkbox
name="demo"
value="two"
label="Controlled"
checked={isChecked}
onChange={(e) => setChecked(e.currentTarget.checked)}
/>

Key CheckboxGroup Props

Use the following props to customize the CheckboxGroup component to fit your needs.

label

TypeExampleDescription
string
Fruits
Text label describing the purpose of the group.
Code example
<CheckboxGroup id="fruits" name="fruits" label="Fruits" selectedValue={[]} onValueChange={() => {}}>
<Checkbox value="apple" label="Apple" name="fruits" />
<Checkbox value="pear" label="Pear" name="fruits" />
</CheckboxGroup>

description

Helper guidance placed below group label.

TypeExampleDescription
string
Fruits
Select any that apply
Provides additional context or instructions for the group.
Code example
<CheckboxGroup
id="fruits"
name="fruits"
label="Fruits"
description="Select any that apply"
selectedValue={[]}
onValueChange={() => {}}
>
<Checkbox value="apple" label="Apple" name="fruits" />
<Checkbox value="pear" label="Pear" name="fruits" />
</CheckboxGroup>

selectedValue

Array of currently selected checkbox values (controlled state).

TypeExampleDescription
string[]
Controlled selection values.
Code example
<CheckboxGroup
id="colors2"
name="colors2"
label="Colours"
selectedValue={['green']}
onValueChange={(next) => {}}
>
<Checkbox value="red" label="Red" name="colors2" />
<Checkbox value="green" label="Green" name="colors2" />
<Checkbox value="blue" label="Blue" name="colors2" />
</CheckboxGroup>

errorMessage

TypeExampleDescription
string
Fruits
Shows an error message and applies error styles to the group.
Code example
<CheckboxGroup
id="fruits"
name="fruits"
label="Fruits"
errorMessage="Select at least one"
selectedValue={[]}
onValueChange={() => {}}
>
<Checkbox value="apple" label="Apple" name="fruits" />
<Checkbox value="pear" label="Pear" name="fruits" />
</CheckboxGroup>

labelOptions

Pass-through props to underlying FormGroupLabel (e.g., optionalLabel, isHidden).

TypeExampleDescription
FormGroupLabelProps
Vegetables (Optional)
Customizes group label display.
Code example
<CheckboxGroup
id="fruits"
name="fruits"
label="Fruits"
labelOptions={{ optionalLabel: '(Optional)' }}
selectedValue={[]}
onValueChange={() => {}}
>
<Checkbox value="apple" label="Apple" name="fruits" />
<Checkbox value="pear" label="Pear" name="fruits" />
</CheckboxGroup>

Behavior

  • Each checkbox is independent; multiple can be selected or none.
  • Use a Checkbox Group to bind related options under one label/description and to show a single error message.
  • Indeterminate visually represents a partial/unknown selection for parent items (not submitted as a value).
  • Avoid immediate side effects on check/uncheck; apply changes on submit (use Switch for instant toggles).
  • Disabled items remain visible but non-interactive.

Accessibility

Implementation examples

With description

Preferred learning methods
Select any methods that help you study effectively
Code example
<CheckboxGroup
id="learning"
name="learning"
label="Preferred learning methods"
description="Select any methods that help you study effectively"
selectedValue={["online", "group"]}
onValueChange={() => {}}
>
<Checkbox value="online" label="Online self-paced" name="learning" />
<Checkbox value="classroom" label="Classroom" name="learning" />
<Checkbox value="hybrid" label="Hybrid" name="learning" />
<Checkbox value="group" label="Group discussions" name="learning" />
<Checkbox value="independent" label="Independent study" name="learning" />
</CheckboxGroup>

With error message

Preferred learning methods
Select any methods that help you study effectively
Code example
<CheckboxGroup
id="learning-error"
name="learning-error"
label="Preferred learning methods"
description="Select any methods that help you study effectively"
errorMessage="Please select at least one method"
selectedValue={[]}
onValueChange={() => {}}
>
<Checkbox value="online" label="Online self-paced" name="learning-error" />
<Checkbox value="classroom" label="Classroom" name="learning-error" />
<Checkbox value="hybrid" label="Hybrid" name="learning-error" />
<Checkbox value="group" label="Group discussions" name="learning-error" />
<Checkbox value="independent" label="Independent study" name="learning-error" />
</CheckboxGroup>

Indeterminate state

Indeterminate state indicates a partial selection (e.g., parent with some children selected). It does not submit a value—purely visual and must be set via ref. Rarely used.

Intedeterminate state
Code example
import { useEffect, useRef, useState } from 'react';
import { Checkbox, CheckboxGroup } from '@yleisradio/yds-components-react';

export const IndeterminateCheckbox = () => {
const ref = useRef<HTMLInputElement | null>(null);
const [childValues, setChildValues] = useState<string[]>(['a']);

const allValues = ['a', 'b', 'c'];
const isAll = childValues.length === allValues.length;
const isNone = childValues.length === 0;

useEffect(() => {
if (ref.current) {
ref.current.indeterminate = !isAll && !isNone;
}
}, [isAll, isNone]);

return (
<CheckboxGroup
id="indeterminate-state"
name="indeterminate-state"
label="Intedeterminate state"
selectedValue={[]}
onValueChange={() => {}}
>
<Checkbox
name="parent"
value="parent"
label="Select all"
ref={ref}
checked={isAll}
onChange={() => {
setChildValues(isAll ? [] : allValues);
}}
/>
{allValues.map((v) => (
<Checkbox
key={v}
name="children"
value={v}
label={`Child ${v.toUpperCase()}`}
checked={childValues.includes(v)}
onChange={(e) => {
setChildValues((prev) =>
e.target?.checked ? prev.concat([v]) : prev.filter((x) => x !== v)
);
}}
/>
))}
</CheckboxGroup>
);
};

API Reference

Props

Checkbox

The Checkbox component accepts all standard HTML <input> attributes in addition to the following props:

PropTypeRequiredDefaultDescription
isDisabledbooleanNofalse
variant'primary' | 'secondary'No'primary'
valuestringNo
namestringYes
labelReactNodeYes
errorbooleanNofalse
hideLabelbooleanNofalse
useUnderlaybooleanNofalse
controlAlignInputControlAlignNo'start'

CheckboxGroup

The CheckboxGroup component accepts the following props:

PropTypeRequiredDefaultDescription
idstringYes
namestringYes
selectedValuestring[]Yes
errorMessagestringNo
labelstringNo
labelOptionsFormGroupLabelPropsNo
descriptionstringNo
childrenReactNodeYes
onValueChange(value: string[]) => voidYes

Type Definitions

Checkbox

export type InputControlAlign = 'start' | 'end';

export interface CheckboxDSProps {
isDisabled?: boolean;
variant?: 'primary' | 'secondary';
value?: string;
name: string;
label: ReactNode;
error?: boolean;
hideLabel?: boolean;
useUnderlay?: boolean;
controlAlign?: InputControlAlign;
}

export type CheckboxProps = InputHTMLAttributes<HTMLInputElement> & CheckboxDSProps;

CheckboxGroup

export interface CheckboxGroupDSProps {
id: string;
name: string;
selectedValue: string[];
errorMessage?: string;
label?: string;
labelOptions?: FormGroupLabelProps;
description?: string;
children: ReactNode;
onValueChange: (value: string[]) => void;
}

export type CheckboxGroupProps = CheckboxGroupDSProps;
  • Radio: For single mandatory choice.
  • Switch For immediate on/off toggles.
  • TagFilter: For removable selection chips.