forms
Checkbox
Native checkbox with custom check and indeterminate indicators, label, description, error, and attribute forwarding.
Examples
Basic checkbox
Create a tax invoice draft when ORD status becomes Paid.
<x-ui.checkbox
name="e_invoice"
value="1"
label="Issue e-Faktur automatically"
description="Create a tax invoice draft when ORD status becomes Paid."
class="max-w-md"
/>
<div class="w-full max-w-md">
<div class="flex items-start gap-3">
<div class="relative -ml-1.5 inline-flex size-10 shrink-0 items-center justify-center">
<input
id="e-invoice-basic"
type="checkbox"
name="e_invoice"
value="1"
aria-describedby="e-invoice-basic-description"
class="peer absolute inset-0 z-10 size-full cursor-pointer opacity-0"
>
<span class="pointer-events-none flex size-4 items-center justify-center rounded-control border border-border-strong bg-surface-raised text-on-brand shadow-2xs peer-checked:border-brand peer-checked:bg-brand peer-checked:[&_svg]:opacity-100 peer-focus-visible:outline-none peer-focus-visible:ring-2 peer-focus-visible:ring-ring peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-surface" aria-hidden="true">
<svg class="size-3 shrink-0 opacity-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75"><path stroke-linecap="round" stroke-linejoin="round" d="M5 12.5 9.5 17 19 7" /></svg>
</span>
</div>
<div class="min-w-0 flex-1 pt-2">
<label for="e-invoice-basic" class="block text-sm font-medium text-fg">Issue e-Faktur automatically</label>
<p id="e-invoice-basic-description" class="mt-0.5 text-sm text-fg-muted leading-relaxed">Create a tax invoice draft when ORD status becomes Paid.</p>
</div>
</div>
</div>
Indeterminate
3 of 12 orders on this page are selected for bulk packing.
<x-ui.checkbox
name="select_all"
label="Select all open orders"
description="3 of 12 orders on this page are selected for bulk packing."
indeterminate
class="max-w-md"
/>
<div class="w-full max-w-md">
<div class="flex items-start gap-3">
<div class="relative -ml-1.5 inline-flex size-10 shrink-0 items-center justify-center">
<input
id="select-all-orders"
type="checkbox"
name="select_all"
class="peer absolute inset-0 z-10 size-full cursor-pointer opacity-0"
x-data
x-init="$el.indeterminate = true"
>
<span class="pointer-events-none flex size-4 items-center justify-center rounded-control border border-border-strong bg-surface-raised text-on-brand shadow-2xs peer-indeterminate:border-brand peer-indeterminate:bg-brand peer-indeterminate:[&_svg]:opacity-100 peer-focus-visible:outline-none peer-focus-visible:ring-2 peer-focus-visible:ring-ring peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-surface" aria-hidden="true">
<svg class="size-3 shrink-0 opacity-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.25"><path stroke-linecap="round" d="M6 12h12" /></svg>
</span>
</div>
<div class="min-w-0 flex-1 pt-2">
<label for="select-all-orders" class="block text-sm font-medium text-fg">Select all open orders</label>
<p class="mt-0.5 text-sm text-fg-muted leading-relaxed">3 of 12 orders on this page are selected for bulk packing.</p>
</div>
</div>
</div>
Validation error
Finance requires confirmation before voiding a posted invoice.
<x-ui.checkbox
name="terms"
value="1"
label="Confirm void of INV-2026-104"
error="Finance requires confirmation before voiding a posted invoice."
class="max-w-md"
/>
<div class="w-full max-w-md">
<div class="flex items-start gap-3">
<div class="relative -ml-1.5 inline-flex size-10 shrink-0 items-center justify-center">
<input
id="terms-error"
type="checkbox"
name="terms"
value="1"
aria-invalid="true"
aria-describedby="terms-error-error"
class="peer absolute inset-0 z-10 size-full cursor-pointer opacity-0"
>
<span class="pointer-events-none flex size-4 items-center justify-center rounded-control border border-danger bg-surface-raised text-on-brand shadow-2xs peer-checked:border-brand peer-checked:bg-brand peer-checked:[&_svg]:opacity-100 peer-focus-visible:outline-none peer-focus-visible:ring-2 peer-focus-visible:ring-ring peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-surface" aria-hidden="true">
<svg class="size-3 shrink-0 opacity-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75"><path stroke-linecap="round" stroke-linejoin="round" d="M5 12.5 9.5 17 19 7" /></svg>
</span>
</div>
<div class="min-w-0 flex-1 pt-2">
<label for="terms-error" class="block text-sm font-medium text-fg">Confirm void of INV-2026-104</label>
</div>
</div>
<p id="terms-error-error" class="mt-1.5 flex items-start gap-1.5 text-xs text-danger">
<svg class="mt-0.5 size-3.5 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v4m0 4h.01M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0Z" /></svg>
<span>Finance requires confirmation before voiding a posted invoice.</span>
</p>
</div>
Props API
| Prop | Type | Default | Description |
|---|---|---|---|
label
Type
string|null
Default
null
|
string|null
|
null
|
Visible label linked via for/id. |
description
Type
string|null
Default
null
|
string|null
|
null
|
Supporting text referenced by aria-describedby. |
error
Type
string|null
Default
null
|
string|null
|
null
|
Validation message. Sets aria-invalid and contributes to aria-describedby. |
indeterminate
Type
bool
Default
false
|
bool
|
false
|
Sets the native indeterminate state via Alpine x-init. |
Accessibility notes
Architected with WCAG 2.2 AA patterns in mind. These notes document the exact keyboard and ARIA behavior for this component.
- Uses a native checkbox under a custom painted indicator so Space toggles the control when focused.
- Label for and input id are linked. Description and error contribute to aria-describedby.
- Error state sets aria-invalid="true" on the checkbox.
- Indeterminate is a visual/API state only. It is not a third submitted value. Clicking clears indeterminate and checks or unchecks normally.
- Pass-through attributes (name, value, required, disabled, checked, x-model, wire:model) land on the input.
- Keyboard: Tab focuses the control. Space toggles checked.
Built by Praesepe
Architecture & custom software partner
Praesepe uses these exact UI primitives to ship SME dashboards, inventory systems, invoicing desks, and internal tools faster, without rebuilding a design system for every client.
- Same Blade + Tailwind 4 + Alpine 3 stack you see in this docs site
- Opinionated for Indonesian SME ops: invoices, stock, roles, approvals
- Architected with WCAG 2.2 AA patterns in mind for keyboard and ARIA