8.0k New

Checkbox

A control that allows the user to toggle between checked and not checked.

Docs API Reference

Epicenter

Local-first, open source apps

Special Sponsor

By clicking this checkbox, you agree to the terms.

<script lang="ts">
  import * as Field from "$lib/components/ui/field/index.js";
  import { Checkbox } from "$lib/components/ui/checkbox/index.js";
  import { Label } from "$lib/components/ui/label/index.js";
</script>
 
<Field.Group class="max-w-sm">
  <Field.Field orientation="horizontal">
    <Checkbox id="terms-checkbox" name="terms-checkbox" />
    <Label for="terms-checkbox">Accept terms and conditions</Label>
  </Field.Field>
  <Field.Field orientation="horizontal">
    <Checkbox id="terms-checkbox-2" name="terms-checkbox-2" checked />
    <Field.Content>
      <Field.Label for="terms-checkbox-2"
        >Accept terms and conditions</Field.Label
      >
      <Field.Description
        >By clicking this checkbox, you agree to the terms.</Field.Description
      >
    </Field.Content>
  </Field.Field>
  <Field.Field orientation="horizontal" data-disabled>
    <Checkbox id="toggle-checkbox" name="toggle-checkbox" disabled />
    <Field.Label for="toggle-checkbox">Enable notifications</Field.Label>
  </Field.Field>
  <Field.Label>
    <Field.Field orientation="horizontal">
      <Checkbox id="toggle-checkbox-2" name="toggle-checkbox-2" />
      <Field.Content>
        <Field.Title>Enable notifications</Field.Title>
        <Field.Description
          >You can enable or disable notifications at any time.</Field.Description
        >
      </Field.Content>
    </Field.Field>
  </Field.Label>
</Field.Group>

Installation

pnpm dlx shadcn-svelte@latest add checkbox

Usage

<script lang="ts">
  import { Checkbox } from "$lib/components/ui/checkbox/index.js";
</script>
<Checkbox />

Checked State

Use bind:checked to control the checkbox state, or onCheckedChange to listen for changes.

<script lang="ts">
  import { Checkbox } from "$lib/components/ui/checkbox/index.js";
 
  let checked = $state(false);
</script>
 
<Checkbox bind:checked />

Invalid State

Set aria-invalid on the checkbox and data-invalid on the field wrapper to show the invalid styles.

<script lang="ts">
  import * as Field from "$lib/components/ui/field/index.js";
  import { Checkbox } from "$lib/components/ui/checkbox/index.js";
</script>
 
<Field.Group class="mx-auto w-56">
  <Field.Field orientation="horizontal" data-invalid>
    <Checkbox
      id="terms-checkbox-invalid"
      name="terms-checkbox-invalid"
      aria-invalid="true"
    />
    <Field.Label for="terms-checkbox-invalid"
      >Accept terms and conditions</Field.Label
    >
  </Field.Field>
</Field.Group>

Basic

Pair the checkbox with Field.Field and Field.Label for proper layout and labeling.

<script lang="ts">
  import * as Field from "$lib/components/ui/field/index.js";
  import { Checkbox } from "$lib/components/ui/checkbox/index.js";
</script>
 
<Field.Group class="mx-auto w-56">
  <Field.Field orientation="horizontal">
    <Checkbox id="terms-checkbox-basic" name="terms-checkbox-basic" />
    <Field.Label for="terms-checkbox-basic"
      >Accept terms and conditions</Field.Label
    >
  </Field.Field>
</Field.Group>

Description

Use Field.Content and Field.Description for helper text.

By clicking this checkbox, you agree to the terms and conditions.

<script lang="ts">
  import * as Field from "$lib/components/ui/field/index.js";
  import { Checkbox } from "$lib/components/ui/checkbox/index.js";
</script>
 
<Field.Group class="mx-auto w-72">
  <Field.Field orientation="horizontal">
    <Checkbox id="terms-checkbox-desc" name="terms-checkbox-desc" checked />
    <Field.Content>
      <Field.Label for="terms-checkbox-desc"
        >Accept terms and conditions</Field.Label
      >
      <Field.Description>
        By clicking this checkbox, you agree to the terms and conditions.
      </Field.Description>
    </Field.Content>
  </Field.Field>
</Field.Group>

Disabled

Use the disabled prop to prevent interaction and add the data-disabled attribute to the <Field.Field> component for disabled styles.

<script lang="ts">
  import * as Field from "$lib/components/ui/field/index.js";
  import { Checkbox } from "$lib/components/ui/checkbox/index.js";
</script>
 
<Field.Group class="mx-auto w-56">
  <Field.Field orientation="horizontal" data-disabled>
    <Checkbox
      id="toggle-checkbox-disabled"
      name="toggle-checkbox-disabled"
      disabled
    />
    <Field.Label for="toggle-checkbox-disabled"
      >Enable notifications</Field.Label
    >
  </Field.Field>
</Field.Group>

Group

Use multiple fields to create a checkbox list.

Show these items on the desktop:

Select the items you want to show on the desktop.

<script lang="ts">
  import * as Field from "$lib/components/ui/field/index.js";
  import { Checkbox } from "$lib/components/ui/checkbox/index.js";
</script>
 
<Field.Set>
  <Field.Legend variant="label">Show these items on the desktop:</Field.Legend>
  <Field.Description
    >Select the items you want to show on the desktop.</Field.Description
  >
  <Field.Group class="gap-3">
    <Field.Field orientation="horizontal">
      <Checkbox
        id="finder-pref-9k2-hard-disks-ljj-checkbox"
        name="finder-pref-9k2-hard-disks-ljj-checkbox"
        checked
      />
      <Field.Label
        for="finder-pref-9k2-hard-disks-ljj-checkbox"
        class="font-normal"
      >
        Hard disks
      </Field.Label>
    </Field.Field>
    <Field.Field orientation="horizontal">
      <Checkbox
        id="finder-pref-9k2-external-disks-1yg-checkbox"
        name="finder-pref-9k2-external-disks-1yg-checkbox"
        checked
      />
      <Field.Label
        for="finder-pref-9k2-external-disks-1yg-checkbox"
        class="font-normal"
      >
        External disks
      </Field.Label>
    </Field.Field>
    <Field.Field orientation="horizontal">
      <Checkbox
        id="finder-pref-9k2-cds-dvds-fzt-checkbox"
        name="finder-pref-9k2-cds-dvds-fzt-checkbox"
      />
      <Field.Label
        for="finder-pref-9k2-cds-dvds-fzt-checkbox"
        class="font-normal"
      >
        CDs, DVDs, and iPods
      </Field.Label>
    </Field.Field>
    <Field.Field orientation="horizontal">
      <Checkbox
        id="finder-pref-9k2-connected-servers-6l2-checkbox"
        name="finder-pref-9k2-connected-servers-6l2-checkbox"
      />
      <Field.Label
        for="finder-pref-9k2-connected-servers-6l2-checkbox"
        class="font-normal"
      >
        Connected servers
      </Field.Label>
    </Field.Field>
  </Field.Group>
</Field.Set>

Table

Name Email Role
Sarah Chen sarah.chen@example.com Admin
Marcus Rodriguez marcus.rodriguez@example.com User
Priya Patel priya.patel@example.com User
David Kim david.kim@example.com Editor
<script lang="ts">
  import { SvelteSet } from "svelte/reactivity";
  import * as Table from "$lib/components/ui/table/index.js";
  import { Checkbox } from "$lib/components/ui/checkbox/index.js";
 
  const tableData = [
    {
      id: "1",
      name: "Sarah Chen",
      email: "sarah.chen@example.com",
      role: "Admin"
    },
    {
      id: "2",
      name: "Marcus Rodriguez",
      email: "marcus.rodriguez@example.com",
      role: "User"
    },
    {
      id: "3",
      name: "Priya Patel",
      email: "priya.patel@example.com",
      role: "User"
    },
    {
      id: "4",
      name: "David Kim",
      email: "david.kim@example.com",
      role: "Editor"
    }
  ];
 
  const selectedRows = new SvelteSet<string>(["1"]);
  const selectAll = $derived(selectedRows.size === tableData.length);
 
  function handleSelectAll(checked: boolean) {
    if (checked) {
      for (const row of tableData) selectedRows.add(row.id);
    } else {
      selectedRows.clear();
    }
  }
 
  function handleSelectRow(id: string, checked: boolean) {
    if (checked) {
      selectedRows.add(id);
    } else {
      selectedRows.delete(id);
    }
  }
</script>
 
<Table.Root>
  <Table.Header>
    <Table.Row>
      <Table.Head class="w-8">
        <Checkbox
          id="select-all-checkbox"
          name="select-all-checkbox"
          checked={selectAll}
          onCheckedChange={handleSelectAll}
        />
      </Table.Head>
      <Table.Head>Name</Table.Head>
      <Table.Head>Email</Table.Head>
      <Table.Head>Role</Table.Head>
    </Table.Row>
  </Table.Header>
  <Table.Body>
    {#each tableData as row (row.id)}
      <Table.Row data-state={selectedRows.has(row.id) ? "selected" : undefined}>
        <Table.Cell>
          <Checkbox
            id="row-{row.id}-checkbox"
            name="row-{row.id}-checkbox"
            checked={selectedRows.has(row.id)}
            onCheckedChange={(checked) =>
              handleSelectRow(row.id, checked === true)}
          />
        </Table.Cell>
        <Table.Cell class="font-medium">{row.name}</Table.Cell>
        <Table.Cell>{row.email}</Table.Cell>
        <Table.Cell>{row.role}</Table.Cell>
      </Table.Row>
    {/each}
  </Table.Body>
</Table.Root>