<Checkbox
name="playground-notifications"
label="Email notifications"
size="md"
/>Features
- Works on its own or in a group with a shared label.
- Supports controlled and uncontrolled state.
- Shows helper text under the label.
- Shows mixed selection with
indeterminate. - Extends the click area to a container with
stretched. - Supports responsive sizes, disabled and error states.
Initial State
Use defaultChecked to set the initial state of an uncontrolled checkbox.
import { Checkbox, Stack } from "@vortexlabs/vortex";
<Stack gap={4}>
<Checkbox name="weekly-digest" label="Weekly digest" defaultChecked />
<Checkbox name="product-news" label="Product news" />
</Stack>Sizes
Checkbox comes in sm and md; the default is md. Pass a breakpoint object to change size by screen width.
<Stack gap={4}>
<Checkbox name="compact-alerts" size="sm" label="Compact alerts" />
<Checkbox name="standard-alerts" size="md" label="Standard alerts" />
<Checkbox name="responsive-alerts" size={{ xs: "sm", md: "md" }} label="Responsive alerts" />
</Stack>Labels and Helper Text
Use helperText for supporting information. When the design omits visible text, supply ariaLabel instead of label.
<Stack gap={4}>
<Checkbox name="activity-email" label="Activity emails" helperText="Receive an email when someone mentions you." />
<Checkbox name="select-project" ariaLabel="Select the Website project" />
</Stack>Controlled State
Pass checked and update it in onChange. A standalone checkbox needs a name for onChange to fire.
"use client";
import { Checkbox, Stack, Text } from "@vortexlabs/vortex";
import { useState } from "react";
export const CheckboxControlledExample = () => {
const [checked, setChecked] = useState(false);
return (
<Stack gap={3}>
<Checkbox
name="archive"
label="Include archived projects"
checked={checked}
onChange={({ checked }) => setChecked(checked)}
/>
<Text size="body-sm-desktop">
{checked ? "Showing all projects" : "Showing active projects"}
</Text>
</Stack>
);
};Disabled and Error States
Set disabled to prevent changes, or error to flag a problem. Both also work on Checkbox.Group.
<Stack gap={4}>
<Checkbox name="locked-notifications" label="Required notifications" defaultChecked disabled />
<Checkbox name="terms" label="I accept the terms" error helperText="Accept the terms before continuing." />
</Stack>Composition
Use Checkbox.Group for related options that share one array of values. Inside it, use Checkbox.Item instead of Checkbox; rendering either in the wrong place throws an error.
Checkbox.Group
Render each option as a Checkbox.Item and name the group with Checkbox.GroupLabel.
<Checkbox.Group name="notifications" defaultValue={["releases"]}>
<Stack gap={4}>
<Stack gap={1}>
<Checkbox.GroupLabel>
<Text size="body-md-desktop" weight="medium">Email notifications</Text>
</Checkbox.GroupLabel>
<Checkbox.GroupDescription>
<Text size="body-sm-desktop" color="subtle">Choose the updates you want to receive.</Text>
</Checkbox.GroupDescription>
</Stack>
<Stack gap={3}>
<Checkbox.Item value="releases" label="Product releases" />
<Checkbox.Item value="tips" label="Tips and tutorials" />
<Checkbox.Item value="events" label="Events" />
</Stack>
</Stack>
</Checkbox.Group>Mixed Selection
Set indeterminate on a parent checkbox when only some of its options are selected.
"use client";
import { Checkbox, Stack, Text } from "@vortexlabs/vortex";
import { useState } from "react";
export const CheckboxMixedExample = () => {
const [selected, setSelected] = useState<string[]>(["design"]);
const allSelected = selected.length === 2;
return (
<Stack gap={4}>
<Checkbox
name="all-teams"
label="All teams"
checked={allSelected}
indeterminate={selected.length > 0 && !allSelected}
onChange={({ checked }) =>
setSelected(checked ? ["design", "engineering"] : [])
}
/>
<Checkbox.Group
name="teams"
value={selected}
onChange={({ value }) => setSelected(value)}
ariaLabel="Teams"
>
<Stack gap={3} paddingInline={6}>
<Checkbox.Item value="design" label="Design" />
<Checkbox.Item value="engineering" label="Engineering" />
</Stack>
</Checkbox.Group>
<Text size="body-sm-desktop">
{selected.length} {selected.length === 1 ? "team" : "teams"} selected
</Text>
</Stack>
);
};Stretched Click Area
Set stretched to make the whole container clickable, such as a card. Place the item directly inside it; other links or buttons in the container need position: relative; z-index: 1.
<Checkbox.Group name="channels" defaultValue={["email"]} ariaLabel="Notification channels">
<Stack direction="row" gap={3}>
<Stack padding={4} borderRadius="md" borderColor="default">
<Checkbox.Item stretched value="email" label="Email" helperText="Daily summary" />
</Stack>
<Stack padding={4} borderRadius="md" borderColor="default">
<Checkbox.Item stretched value="sms" label="SMS" helperText="Urgent alerts only" />
</Stack>
</Stack>
</Checkbox.Group>Accessibility
Space while a checkbox is focused toggles it.label or ariaLabel, and name each group with Checkbox.GroupLabel.