elements
Demos UI Feed Discuss Install
Style System
  • Style
  • Themes
  • Behaviors
Forms
  • Button
  • ButtonGroup
  • Checkbox
  • ColorPicker
  • Combobox
  • Field
  • FileUpload
  • Input
  • InputGroup
  • InputOTP
  • Label
  • NativeSelect
  • NumberInput
  • PasswordInput
  • RadioGroup
  • Select
  • Slider
  • Switch
  • TagsInput
  • Textarea
  • Toggle
  • ToggleGroup
Overlays
  • AlertDialog
  • Command
  • ContextMenu
  • Dialog
  • Drawer
  • DropdownMenu
  • HoverCard
  • Menubar
  • NavigationMenu
  • Popover
  • Sheet
  • Toast
  • Tooltip
Display
  • Accordion
  • Alert
  • AspectRatio
  • Avatar
  • Badge
  • Breadcrumb
  • Card
  • Collapsible
  • Empty
  • Item
  • Kbd
  • Pagination
  • Progress
  • Separator
  • Skeleton
  • Spinner
  • Table
  • Tabs
  • Tree
Layout
  • Carousel
  • Resizable
  • ScrollArea
  • Sidebar
Dates
  • Calendar
  • DatePicker
  • DateRangePicker
  • TimePicker
Data
  • AreaChart
  • BarChart
  • Chart
  • DataTable
  • Kanban
  • LineChart
  • PieChart
  • RadarChart
  • RadialChart
  • VirtualList
Chat
  • Attachment
  • Message
  • MessageList
  • PromptInput
Elements UI / Forms / Checkbox

Checkbox

A native checkbox drawn by the theme, with an indeterminate (mixed) state.

Basic

A label wrapping the checkbox toggles it. checked is two-way.

checked: false
Code
<Label>
  <Checkbox checked={state.terms} />
  Accept terms and conditions
</Label>

Usage

import { Checkbox, CheckboxGroup } from "@elements/ui/checkbox";

<Label><Checkbox checked={form.terms} /> Accept terms and conditions</Label>

// Select all: checked when every row is, mixed when only some are.
<Checkbox checked={rows.every((r) => r.on)}
          indeterminate={rows.some((r) => r.on) && !rows.every((r) => r.on)}
          onCheckedChange={(on) => rows.forEach((r) => r.on = on)}
          attrs={{ "aria-label": "Select all" }} />

Examples

With a description

onCheckedChange fires for the user's changes, not for state set in code.

You can enable or disable notifications at any time.

changes: 0, last: none
Code
<div class="option">
  <Checkbox checked={state.notify} attrs={{ id: "notify", "aria-describedby": "notify-hint" }}
            onCheckedChange={(on) => log(on)} />
  <div>
    <Label htmlFor="notify">Enable notifications</Label>
    <p class="hint" id="notify-hint">You can enable or disable notifications at any time.</p>
  </div>
</div>

Group with select all

The parent is checked when all are, mixed when some are. Clicking it checks all, then clears all, then brings back the earlier mix.

Code
// state.all = { get checked() {...every}, set checked(on) {...set each},
//               get mixed() {...some but not every}, set mixed(_) {} }
// From mixed, a press checks all and remembers the mix; the press after
// clearing all brings the mix back (APG mixed-state checkbox).
<Checkbox checked={state.all.checked} indeterminate={state.all.mixed} attrs={{ id: "all" }} />
<Label htmlFor="all">Show on desktop</Label>

<Label e:for={d of state.disks}>
  <Checkbox checked={d.on} name="disks" value={d.id} /> {d.label}
</Label>

CheckboxGroup with a parent

The group owns a string[] value. The parent box checks all, clears all, shows mixed and brings back the last mix, with no code on the page.

value: none
Code
<CheckboxGroup value={state.apples} allValues={["a", "b", "c"]} attrs={{ "aria-labelledby": "apples" }}>
  <Label attrs={{ id: "apples" }}><Checkbox parent /> Apples</Label>
  <div class="nested">
    <Label><Checkbox value="a" /> Fuji</Label>
    <Label><Checkbox value="b" /> Gala</Label>
    <Label><Checkbox value="c" /> Granny Smith</Label>
  </div>
</CheckboxGroup>

CheckboxGroup with a starting value

The boxes in the group show the group's starting value in the server HTML, before script runs.

Nested parent checkbox

A group inside a group: the inner parent stands for one value of the outer group, and the outer parent shows mixed while the inner group is partly checked.

permissions: none; manage: none

Table

Row selection with a select-all header in the mixed state.

NameEmailRole
Sarah Chensarah.chen@example.comAdmin
Marc Rodriguezmarcus.rodriguez@example.comUser
Priya Patelpriya.patel@example.comUser
David Kimdavid.kim@example.comEditor
Code
<th><Checkbox checked={state.allRows.checked} indeterminate={state.allRows.mixed}
              attrs={{ "aria-label": "Select all" }} /></th>
...
<td><Checkbox checked={row.selected} attrs={{ "aria-label": `Select ${row.name}` }} /></td>

Disabled and invalid

States change color, never size.

Code
<Checkbox disabled />
<Checkbox disabled checked />
<Checkbox invalid />

Read only

Focusable and announced, but a click, Space or a label press leaves it as it is.

Code
<Label><Checkbox checked readOnly /> Two-factor sign in (set by your organization)</Label>

Required in a form

The browser will not submit until it is checked. uncheckedValue submits a value while a box is unchecked.

submitted: 0 changes: 0
Code
<form onsubmit={() => signup(state)}>
  <Label><Checkbox checked={state.agree} required name="agree" /> I agree to the terms</Label>
  <Label><Checkbox name="newsletter" value="yes" uncheckedValue="no" /> Send me the newsletter</Label>
  <Button type="submit" variant="primary">Create account</Button>
  <Button type="reset">Reset</Button>
</form>

<Label><Checkbox name="remember" checked uncheckedValue="no" attrs={{ form: "signup" }} /> Remember me</Label>

Cancel a change

onCheckedChange runs before the box changes and gets details second; details.cancel() keeps it as it was.

checked: false, attempts: 0, last: none
Code
<Checkbox checked={guard.value} onCheckedChange={(checked, details) => {
  if (!guard.allowed) details.cancel();
}} />

Right to left

The box sits at the inline start, before its label.

Reference Checkbox in the manual Every part, attribute, slot, key and data attribute.
Prev ButtonGroupNext ColorPicker
Product
Manual Pricing Compare
Company
History Contact
Legal
Privacy Policy Acceptable Use Terms License Agreement
© Elements Dev Corporation 2026