Checkbox
Labelled checkbox with a full-height 44px click row.
import { Checkbox } from '@elirobinson/react/components/atoms/Checkbox';Styles: @elirobinson/react/styles/atoms/Checkbox.css — already included when you import @elirobinson/react/styles.css.
Show code
import { Checkbox } from '@elirobinson/react/components/atoms/Checkbox';
export default function Basic() {
return <Checkbox label="Email me weekly coaching tips" />;
}When to use it
Reach for Checkbox when the choice is independent and part of a form that gets
submitted — pick any number of options, in any combination. Reach for Switch instead
when flipping it takes effect immediately, with no submit step (a notification
preference, a feature flag). Reach for RadioGroup when only one of several options can
be true at once.
States
Show code
import { Checkbox } from '@elirobinson/react/components/atoms/Checkbox';
export default function States() {
return (
<div className="demo-col">
<Checkbox label="Unchecked" />
<Checkbox label="Checked by default" defaultChecked />
<Checkbox label="Disabled" disabled />
<Checkbox label="Disabled and checked" disabled defaultChecked />
</div>
);
}Controlled
Checkbox forwards every native input prop, so checked and onChange work exactly
like a plain <input type="checkbox">.
1 of 4 modules in this session.
Show code
import { useState } from 'react';
import { Checkbox } from '@elirobinson/react/components/atoms/Checkbox';
const MODULES = ['Warm-up drills', 'Passing circuit', 'Small-sided game', 'Cooldown stretch'];
export default function Controlled() {
const [selected, setSelected] = useState<string[]>(['Warm-up drills']);
const toggle = (module: string) => {
setSelected((current) =>
current.includes(module) ? current.filter((item) => item !== module) : [...current, module],
);
};
return (
<div className="demo-col">
{MODULES.map((module) => (
<Checkbox
key={module}
label={module}
checked={selected.includes(module)}
onChange={() => toggle(module)}
/>
))}
<p>
{selected.length} of {MODULES.length} modules in this session.
</p>
</div>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
labelrequired | string | — | — |
Also accepts all Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> props.
Accessibility
- Renders a native
<input type="checkbox">paired with a<label>—labelis required and is the input's only accessible name. - The id is auto-generated with
useIdwhen you don't pass one, sohtmlForalways resolves. - Keyboard:
Tabfocuses,Spacetoggles — nativeinputbehavior, nothing reimplemented. - The row reserves a 44px minimum height for rhythm alongside other controls, but the actual hit target is the 18×18 box and the label text — clicking the empty vertical space around them doesn't toggle it.
- The ref forwards to the underlying
<input>.
Do
- Use Checkbox for independent yes/no choices inside a form that submits together.
- Always pass a real, specific label — it’s required, and it’s the input’s only accessible name.
- Group related checkboxes visually (a card, a list) so “N selected” context is clear.
- Let defaultChecked or checked drive pre-selected state — don’t manage a shadow copy elsewhere.
Don't
- Use Checkbox when only one answer can be true — that’s RadioGroup.
- Use Checkbox for a setting that takes effect the instant it’s flipped — that’s Switch.
- Expect the full 44px row to be clickable — only the box and the label text respond.
- Omit the label prop and lean on placeholder or nearby text — there’s no other accessible name path.