Checkbox
Input for selecting one or multiple options.
import { Checkbox } from "ui-lab-components";
export function Example() {
return <Checkbox label="Accept terms and conditions" />;
}Basic States
The default checkbox states: unchecked, checked, disabled, and disabled checked.
import { Checkbox, Flex } from 'ui-lab-components';
export const metadata = {
title: 'Basic States',
description: 'The default checkbox states: unchecked, checked, disabled, and disabled checked.',
};
export default function Example() {
return (
<Flex direction="column" gap="md" style={{ width: 280 }}>
<Checkbox id="basic-unchecked" label="Unchecked" />
<Checkbox id="basic-checked" label="Checked" defaultChecked />
<Checkbox id="basic-disabled" label="Disabled" disabled />
<Checkbox id="basic-disabled-checked" label="Disabled checked" disabled defaultChecked />
</Flex>
);
}
Helper and Error Text
A labeled checkbox can include supporting text and an invalid state for form feedback.
Get a short product update when a new version ships.
You must accept the terms before continuing.
import { Checkbox, Flex } from 'ui-lab-components';
export const metadata = {
title: 'Helper and Error Text',
description: 'A labeled checkbox can include supporting text and an invalid state for form feedback.',
};
export default function Example() {
return (
<Flex direction="column" gap="lg" style={{ width: 320 }}>
<Checkbox
id="helper-release-notes"
label="Release notes"
helper="Get a short product update when a new version ships."
defaultChecked
/>
<Checkbox
id="helper-terms"
label="Accept terms"
helper="You must accept the terms before continuing."
helperTextError
aria-invalid="true"
/>
</Flex>
);
}
Controlled
Use checked and onChange when checkbox state is owned by the surrounding interface.
Notifications are enabled.
"use client";
import { useState } from 'react';
import { Button, Checkbox, Flex } from 'ui-lab-components';
export const metadata = {
title: 'Controlled',
description: 'Use checked and onChange when checkbox state is owned by the surrounding interface.',
};
export default function Example() {
const [checked, setChecked] = useState(true);
return (
<Flex direction="column" gap="md" style={{ width: 300 }}>
<Checkbox
id="controlled-email"
label="Email notifications"
helper={checked ? 'Notifications are enabled.' : 'Notifications are paused.'}
checked={checked}
onChange={(event) => setChecked(event.currentTarget.checked)}
/>
<Button variant="secondary" onClick={() => setChecked((value) => !value)}>
{checked ? 'Turn off' : 'Turn on'}
</Button>
</Flex>
);
}
Checkbox Group
Use a small group when a user can select any number of related options.
Subscriptions
Choose the emails this workspace receives.
"use client";
import { useState } from 'react';
import { Checkbox, Flex } from 'ui-lab-components';
export const metadata = {
title: 'Checkbox Group',
description: 'Use a small group when a user can select any number of related options.',
};
const subscriptionOptions = [
'Product updates',
'Security alerts',
'Billing reminders',
];
export default function Example() {
const [selected, setSelected] = useState<Set<string>>(
new Set(['Product updates', 'Security alerts'])
);
const toggleOption = (option: string) => {
setSelected((current) => {
const next = new Set(current);
next.has(option) ? next.delete(option) : next.add(option);
return next;
});
};
return (
<Flex direction="column" gap="md" style={{ width: 300 }}>
<div>
<p className="text-sm font-medium text-foreground-100">Subscriptions</p>
<p className="text-xs text-foreground-400">Choose the emails this workspace receives.</p>
</div>
<Flex direction="column" gap="sm">
{subscriptionOptions.map((option) => (
<Checkbox
key={option}
id={`subscription-${option.toLowerCase().replace(/ /g, '-')}`}
label={option}
checked={selected.has(option)}
onChange={() => toggleOption(option)}
/>
))}
</Flex>
</Flex>
);
}
Indeterminate
A parent checkbox can show partial selection when only some child options are checked.
"use client";
import { useState } from 'react';
import { Checkbox, Divider, Flex } from 'ui-lab-components';
export const metadata = {
title: 'Indeterminate',
description: 'A parent checkbox can show partial selection when only some child options are checked.',
};
const tableColumns = ['Name', 'Email', 'Role', 'Last active'];
export default function Example() {
const [visibleColumns, setVisibleColumns] = useState<Set<string>>(
new Set(['Name', 'Email'])
);
const allSelected = visibleColumns.size === tableColumns.length;
const isIndeterminate = visibleColumns.size > 0 && !allSelected;
const toggleAll = () => {
setVisibleColumns(allSelected ? new Set() : new Set(tableColumns));
};
const toggleColumn = (column: string) => {
setVisibleColumns((current) => {
const next = new Set(current);
next.has(column) ? next.delete(column) : next.add(column);
return next;
});
};
return (
<Flex direction="column" gap="sm" style={{ width: 280 }}>
<Checkbox
id="columns-all"
label="Show all columns"
checked={allSelected}
isIndeterminate={isIndeterminate}
onChange={toggleAll}
/>
<Divider />
<Flex direction="column" gap="sm" styles={{ root: 'pl-8' }}>
{tableColumns.map((column) => (
<Checkbox
key={column}
id={`column-${column.toLowerCase().replace(/ /g, '-')}`}
label={column}
checked={visibleColumns.has(column)}
onChange={() => toggleColumn(column)}
/>
))}
</Flex>
</Flex>
);
}
Consent Form
A required checkbox can gate a form action while optional choices remain independent.
Required to create a workspace.
"use client";
import { useState } from 'react';
import { Button, Checkbox, Flex } from 'ui-lab-components';
export const metadata = {
title: 'Consent Form',
description: 'A required checkbox can gate a form action while optional choices remain independent.',
};
export default function Example() {
const [accepted, setAccepted] = useState(false);
const [updates, setUpdates] = useState(false);
return (
<Flex direction="column" gap="md" style={{ width: 320 }}>
<Checkbox
id="consent-terms"
label="I agree to the terms"
helper="Required to create a workspace."
checked={accepted}
onChange={(event) => setAccepted(event.currentTarget.checked)}
/>
<Checkbox
id="consent-updates"
label="Send product updates"
checked={updates}
onChange={(event) => setUpdates(event.currentTarget.checked)}
/>
<Button variant="primary" isDisabled={!accepted} styles={{ root: 'w-full' }}>
Continue
</Button>
</Flex>
);
}