A checkbox component for binary choices and multiple selections. Supports indeterminate state and provides proper accessibility with label association. Supports three appearances: checkbox (default square indicator), button (Panel-powered with full emphasis and feedback), and switch (horizontal toggle with sliding knob).
---
import Checkbox from "../Checkbox.astro";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "md", direction: "column" })}>
<Checkbox id="checkbox-unchecked">Unchecked</Checkbox>
<Checkbox id="checkbox-checked" checked>Checked</Checkbox>
<Checkbox id="checkbox-indeterminate" indeterminate>Indeterminate</Checkbox>
<Checkbox id="checkbox-disabled" disabled>Disabled</Checkbox>
</div>Three sizes are available across all appearances.
---
import Checkbox from "../Checkbox.astro";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "xl", direction: "column" })}>
<div>
<h3>checkbox appearance</h3>
<div class={stack({ gap: "sm", direction: "row", align: "center" })}>
<Checkbox id="astro-csize-sm" size="sm">Small</Checkbox>
<Checkbox id="astro-csize-md" size="md" checked>Medium</Checkbox>
<Checkbox id="astro-csize-lg" size="lg">Large</Checkbox>
</div>
</div>
<div>
<h3>button appearance</h3>
<div class={stack({ gap: "sm", direction: "row", align: "center" })}>
<Checkbox id="astro-csbtn-sm" appearance="button" size="sm"
>Small</Checkbox
>
<Checkbox id="astro-csbtn-md" appearance="button" size="md" checked
>Medium</Checkbox
>
<Checkbox id="astro-csbtn-lg" appearance="button" size="lg"
>Large</Checkbox
>
</div>
</div>
</div>appearance="button" composes with Panel — use feedback (primary, success, danger, warning, neutral) to control the surface.
---
import Checkbox from "../Checkbox.astro";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "xl", direction: "column" })}>
<div>
<h3>Primary (default)</h3>
<div class={stack({ gap: "sm", direction: "row" })}>
<Checkbox id="astro-cbtn-p1" appearance="button" checked
>Option 1</Checkbox
>
<Checkbox id="astro-cbtn-p2" appearance="button">Option 2</Checkbox>
<Checkbox id="astro-cbtn-p3" appearance="button">Option 3</Checkbox>
</div>
</div>
<div>
<h3>Danger</h3>
<div class={stack({ gap: "sm", direction: "row" })}>
<Checkbox id="astro-cbtn-d1" appearance="button" feedback="danger" checked
>Option 1</Checkbox
>
<Checkbox id="astro-cbtn-d2" appearance="button" feedback="danger"
>Option 2</Checkbox
>
</div>
</div>
<div>
<h3>Warning</h3>
<div class={stack({ gap: "sm", direction: "row" })}>
<Checkbox
id="astro-cbtn-w1"
appearance="button"
feedback="warning"
checked>Option 1</Checkbox
>
<Checkbox id="astro-cbtn-w2" appearance="button" feedback="warning"
>Option 2</Checkbox
>
</div>
</div>
<div>
<h3>Success</h3>
<div class={stack({ gap: "sm", direction: "row" })}>
<Checkbox
id="astro-cbtn-s1"
appearance="button"
feedback="success"
checked>Option 1</Checkbox
>
<Checkbox id="astro-cbtn-s2" appearance="button" feedback="success"
>Option 2</Checkbox
>
</div>
</div>
</div>appearance="switch" renders a horizontal toggle with a sliding knob — ideal for instant on/off settings. It still uses <input type="checkbox"> under the hood, so standard form semantics and checked/disabled behavior are unchanged.
---
import Checkbox from "../Checkbox.astro";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "xl", direction: "column" })}>
<div>
<h3>Primary (default)</h3>
<div class={stack({ gap: "sm", direction: "row" })}>
<Checkbox id="astro-csw-p1" appearance="switch" checked>Wi-Fi</Checkbox>
<Checkbox id="astro-csw-p2" appearance="switch">Bluetooth</Checkbox>
</div>
</div>
<div>
<h3>Success</h3>
<div class={stack({ gap: "sm", direction: "row" })}>
<Checkbox id="astro-csw-s1" appearance="switch" feedback="success" checked
>Notifications</Checkbox
>
<Checkbox id="astro-csw-s2" appearance="switch" feedback="success"
>Sync</Checkbox
>
</div>
</div>
<div>
<h3>Warning</h3>
<div class={stack({ gap: "sm", direction: "row" })}>
<Checkbox id="astro-csw-w1" appearance="switch" feedback="warning" checked
>Beta features</Checkbox
>
<Checkbox id="astro-csw-w2" appearance="switch" feedback="warning"
>Experimental</Checkbox
>
</div>
</div>
<div>
<h3>Danger</h3>
<div class={stack({ gap: "sm", direction: "row" })}>
<Checkbox id="astro-csw-d1" appearance="switch" feedback="danger" checked
>Delete on save</Checkbox
>
<Checkbox id="astro-csw-d2" appearance="switch" feedback="danger"
>Purge cache</Checkbox
>
</div>
</div>
<div>
<h3>Sizes</h3>
<div class={stack({ gap: "sm", direction: "row" })}>
<Checkbox id="astro-csw-sm" appearance="switch" size="sm" checked
>Small</Checkbox
>
<Checkbox id="astro-csw-md" appearance="switch" size="md" checked
>Medium</Checkbox
>
<Checkbox id="astro-csw-lg" appearance="switch" size="lg" checked
>Large</Checkbox
>
</div>
</div>
<div>
<h3>Disabled</h3>
<div class={stack({ gap: "sm", direction: "row" })}>
<Checkbox id="astro-csw-dis1" appearance="switch" disabled
>Unchecked</Checkbox
>
<Checkbox id="astro-csw-dis2" appearance="switch" disabled checked
>Checked</Checkbox
>
</div>
</div>
</div>Badges inside checkbox components scale with the component’s size via fontSize: 1rem.
---
import Checkbox from "../Checkbox.astro";
import PindobaBadge from "@pindoba/astro-badge";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "xl", direction: "column" })}>
<div>
<h3>checkbox appearance</h3>
<div class={stack({ gap: "sm", direction: "row", align: "center" })}>
<Checkbox id="astro-badge-cb-sm" size="sm" checked>
Small <PindobaBadge feedback="primary" size="sm">3</PindobaBadge>
</Checkbox>
<Checkbox id="astro-badge-cb-md" size="md" checked>
Medium <PindobaBadge feedback="primary" size="sm">3</PindobaBadge>
</Checkbox>
<Checkbox id="astro-badge-cb-lg" size="lg" checked>
Large <PindobaBadge feedback="primary" size="sm">3</PindobaBadge>
</Checkbox>
</div>
</div>
<div>
<h3>button appearance</h3>
<div class={stack({ gap: "sm", direction: "row", align: "center" })}>
<Checkbox id="astro-badge-cbtn-sm" appearance="button" size="sm" checked>
Small <PindobaBadge feedback="primary" size="sm">3</PindobaBadge>
</Checkbox>
<Checkbox id="astro-badge-cbtn-md" appearance="button" size="md" checked>
Medium <PindobaBadge feedback="primary" size="sm">3</PindobaBadge>
</Checkbox>
<Checkbox id="astro-badge-cbtn-lg" appearance="button" size="lg" checked>
Large <PindobaBadge feedback="primary" size="sm">3</PindobaBadge>
</Checkbox>
</div>
</div>
</div>Use the leading and trailing slots to position icons, stamps, or badges at the start and end of the label. With emphasis="adaptive", badges and stamps follow the parent’s color in both unchecked and checked states. The trailing slot pins to the end of the row, which pairs well with fullWidth.
---
import Checkbox from "../Checkbox.astro";
import Badge from "@pindoba/astro-badge";
import Stamp from "@pindoba/astro-stamp";
import { Icon } from "astro-icon/components";
import { stack } from "@pindoba/styled-system/patterns";
const sizes = ["sm", "md", "lg"] as const;
---
<div class={stack({ gap: "lg", direction: "column" })}>
<div>
<h3>button appearance — both slots</h3>
<div class={stack({ gap: "sm", direction: "column" })}>
{
sizes.map((size) => (
<Checkbox
id={`astro-lt-cbtn-${size}`}
appearance="button"
size={size}
fullWidth
checked={size === "md"}
>
<Stamp
slot="leading"
emphasis="adaptive"
size="xs"
shape="circle"
iconFill
>
<Icon name="lucide:bell" />
</Stamp>
Notifications
<Badge slot="trailing" emphasis="adaptive" size="sm">
12
</Badge>
</Checkbox>
))
}
</div>
</div>
<div>
<h3>button appearance — leading only</h3>
<div class={stack({ gap: "sm", direction: "column" })}>
{
sizes.map((size) => (
<Checkbox
id={`astro-lt-cbtn-leading-${size}`}
appearance="button"
size={size}
fullWidth
checked={size === "md"}
>
<Stamp
slot="leading"
emphasis="adaptive"
size="xs"
shape="circle"
iconFill
>
<Icon name="lucide:bell" />
</Stamp>
Notifications
</Checkbox>
))
}
</div>
</div>
<div>
<h3>button appearance — trailing only</h3>
<div class={stack({ gap: "sm", direction: "column" })}>
{
sizes.map((size) => (
<Checkbox
id={`astro-lt-cbtn-trailing-${size}`}
appearance="button"
size={size}
fullWidth
checked={size === "md"}
>
Notifications
<Badge slot="trailing" emphasis="adaptive" size="sm">
12
</Badge>
</Checkbox>
))
}
</div>
</div>
<div>
<h3>checkbox appearance</h3>
<div class={stack({ gap: "sm", direction: "column" })}>
{
sizes.map((size) => (
<Checkbox
id={`astro-lt-cb-${size}`}
size={size}
checked={size === "md"}
>
Tasks
<Badge slot="trailing" emphasis="adaptive" size="sm">
5
</Badge>
</Checkbox>
))
}
</div>
</div>
</div>The passThrough prop provides per-slot escape hatches: style accepts a Panda CSS SystemStyleObject merged with the base styles, and props forwards arbitrary HTML attributes onto the element.
---
import Checkbox from "../Checkbox.astro";
import { stack } from "@pindoba/styled-system/patterns";
---
<div class={stack({ gap: "xl", direction: "column" })}>
<div>
<h3>Custom input style via passThrough</h3>
<Checkbox
id="checkbox-custom-style"
passThrough={{
input: {
style: { borderRadius: "full" },
},
}}
>
Rounded checkbox
</Checkbox>
</div>
<div>
<h3>Custom props via passThrough</h3>
<Checkbox
id="checkbox-custom-props"
passThrough={{
root: {
props: { "data-testid": "my-checkbox" },
},
input: {
props: { "aria-label": "Accept terms and conditions" },
},
}}
>
Accept terms
</Checkbox>
</div>
</div>| prop | type | default | req | description |
|---|---|---|---|---|
| appearance | "checkbox""button""switch" | "checkbox" | Visual style of the checkbox. checkbox: Default square indicator. button: Styled as a button using Panel composition. switch: Horizontal toggle with sliding knob. | |
| feedback | "primary""neutral""success""danger""warning" | "primary" | Color scheme applied via colorPalette. For checkbox appearance this sets the indicator accent color. For button appearance this sets the Panel feedback color. | |
| size | "sm""md""lg" | "md" | Size of the component. | |
| fullWidth | boolean | false | Expand the checkbox to fill its container width. | |
| id | string | - | Unique identifier for the checkbox input, required for proper label association. | |
| checked | boolean | undefined | Controls the checked state of the checkbox. | |
| indeterminate | boolean | undefined | Controls the indeterminate (partially checked) state of the checkbox. | |
| disabled | boolean | undefined | Disables the checkbox. | |
| passThrough | { root?: { style?: SystemStyleObject; props?: HTMLLabelAttributes }; input?: { style?: SystemStyleObject; props?: HTMLInputAttributes } } | undefined | Per-slot style and attribute overrides. | |
| children | Snippet | undefined | Label content rendered next to the checkbox. | |
| ...rest | Omit<HTMLInputAttributes, 'type'> | - | Standard HTML input attributes (excluding type). |