Components Forms
Checkbox
StableA native checkbox with label, description and an indeterminate state.
Use Checkbox for independent yes/no choices that are applied on submit, such as accepting terms or opting into notifications. Use Switch for settings that take effect immediately, and CheckboxGroup for several related options under one label.
Overview
import { Checkbox } from '@bindshq/stance-react';
export function Basic() {
return <Checkbox label="Send a copy of the signed document to all parties" defaultChecked />;
}Light, dark and high contrast
Every Stance component is designed and tested in all three appearance modes.
Import
import { Checkbox } from '@bindshq/stance-react';Platforms
Checkbox has native counterparts. They share Stance tokens and intent, and use each platform’s own controls and conventions. The live previews on this page are the web implementation.
import { Checkbox } from '@bindshq/stance-react';Playground
<Checkbox />Examples
import { Checkbox } from '@bindshq/stance-react';
export function WithDescription() {
return (
<Checkbox
label="Require signer authentication"
description="Signers confirm a one-time code sent to their email before signing."
/>
);
}Indeterminate (select all)
The parent reflects a partial selection of its children.
import * as React from 'react';
import { Checkbox } from '@bindshq/stance-react';
const documents = ['Mutual NDA', 'Master services agreement', 'Data processing addendum'];
export function Indeterminate() {
const [selected, setSelected] = React.useState<string[]>(['Mutual NDA']);
const all = selected.length === documents.length;
const some = selected.length > 0 && !all;
return (
<div style={{ display: 'grid', gap: 10 }}>
<Checkbox
label="Select all documents"
checked={all ? true : some ? 'indeterminate' : false}
onCheckedChange={(c) => setSelected(c ? documents : [])}
/>
<div style={{ display: 'grid', gap: 10, paddingLeft: 28 }}>
{documents.map((d) => (
<Checkbox
key={d}
label={d}
checked={selected.includes(d)}
onCheckedChange={(c) => setSelected((s) => (c ? [...s, d] : s.filter((x) => x !== d)))}
/>
))}
</div>
</div>
);
}You must accept the terms to continue
import { Checkbox, FormField } from '@bindshq/stance-react';
export function States() {
return (
<div style={{ display: 'grid', gap: 12 }}>
<Checkbox size="sm" label="Small" defaultChecked />
<Checkbox label="Disabled" disabled />
<Checkbox label="Disabled and checked" disabled defaultChecked />
<FormField label="Accept the terms of service" error="You must accept the terms to continue">
<Checkbox />
</FormField>
</div>
);
}API reference
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | 'indeterminate' | None | Controlled state. |
defaultChecked | boolean | false | Initial state when uncontrolled. |
onCheckedChange | (checked: boolean) => void | None | Called with the new state. |
label | ReactNode | None | Visible label. Without it, provide aria-label. |
description | ReactNode | None | Help text under the label, linked via aria-describedby. |
size | 'sm' | 'md' | 'md' | Box size. |
invalid | boolean | None | Marks the checkbox invalid. |
value | string | None | Form value; identifies the item inside a CheckboxGroup. |
...props | InputHTMLAttributes | None | Native input attributes; the ref targets the <input>. |
Accessibility
- A real <input type="checkbox"> is styled, so native semantics, form submission and keyboard behaviour are preserved.
- The indeterminate state is set on the element and exposed as "mixed".
- The whole label is clickable, and an enlarged invisible hit area keeps small boxes above the 24px target size.
- The checkmark is drawn in the accent foreground colour and remains visible in Windows forced colours.
Keyboard
| Keys | Action |
|---|---|
| Space | Toggles the checkbox. |
Usage guidelines
Do
- Phrase labels positively: “Email me when a document is signed”.
Don’t
- Use a checkbox for an action that happens immediately; use Switch.