Forms & Inputs
Checkbox
A form-associated checkbox. Works inside a native <form>, supports the indeterminate state, and offers card / toggle tile variants for selection UIs.
Preview
Section titled “Preview”<nana-checkbox>Accept terms and conditions</nana-checkbox> Installation
Section titled “Installation”The checkbox ships for all three targets. Pick the tab for your project — the CLI detects which you are on and serves the matching implementation.
npx @nana-tec/ui add checkboxLands as src/components/ui/checkbox/checkbox.tsx, styled with Tailwind classes that
resolve to the design tokens. Requires Tailwind v4.
npx @nana-tec/ui add checkboxLands in src/lib/components/ui/checkbox/ as Checkbox.svelte, styled with Tailwind
classes that resolve to the design tokens. Requires Tailwind v4.
Install the package for a versioned dependency:
npm install @nana-tec/ui-componentsOr copy the source in and own it:
npx @nana-tec/ui add checkboximport { Checkbox } from "@/components/ui/checkbox";
export function Example() { const [accepted, setAccepted] = useState(false);
return ( <Checkbox label="Accept terms" description="You can withdraw consent at any time." checked={accepted} onChange={(event) => setAccepted(event.target.checked)} /> );}indeterminate is applied to the underlying input as a DOM property, so a
partially-selected parent works without extra wiring. Every native <input>
attribute passes through, and it forwards a ref.
<script lang="ts"> import { Checkbox } from '$lib/components/ui/checkbox';
let accepted = $state(false);</script>
<Checkbox label="Accept terms" description="You can withdraw consent at any time." bind:checked={accepted}/>checked is $bindable, so bind:checked is the idiomatic way to drive it.
Set indeterminate for a partially-selected parent.
import "@nana-tec/ui-components/checkbox";<nana-checkbox>Accept terms and conditions</nana-checkbox>Classes you pass to the React and Svelte components are merged with
tailwind-merge, so an override wins rather than fighting. See
Using Tailwind.
<nana-checkbox size="sm">Small</nana-checkbox>
<nana-checkbox size="md">Medium</nana-checkbox>
<nana-checkbox size="lg">Large</nana-checkbox> States
Section titled “States”<nana-checkbox checked>Checked</nana-checkbox>
<nana-checkbox indeterminate>Indeterminate</nana-checkbox>
<nana-checkbox disabled>Disabled</nana-checkbox>
<nana-checkbox checked disabled>Checked & disabled</nana-checkbox> The React and Svelte props, read from the components’ own types:
Checkbox
| Prop | Type | Default |
|---|---|---|
size | CheckboxSize | 'md' |
indeterminate | boolean | false |
label | ReactNode | |
description | ReactNode | |
children | ReactNode |
Also accepts Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type' | 'children'>.
Checkbox
| Prop | Type | Default |
|---|---|---|
size | CheckboxSize | 'md' |
indeterminate | boolean | false |
checkedbind: | boolean | false |
label | string | |
description | string | |
children | Snippet |
Also accepts Omit<HTMLInputAttributes, 'class' | 'size' | 'type' | 'checked'>.
The attribute names, events and CSS hooks below are the Web Components reference.
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
checked | checked | boolean | false | Checked state |
description | description | string | undefined | — | Secondary descriptive text |
disabled | disabled | boolean | false | Disable the control |
indeterminate | indeterminate | boolean | false | Indeterminate (mixed) state — for "some children selected" |
invalid | invalid | boolean | false | Invalid styling + state |
label | label | string | undefined | — | Convenience label text (slot wins if both are present) |
loading | loading | boolean | false | Replace the box with a spinner |
name | name | string | '' | Form field name |
required | required | boolean | false | Mark as required for form validation |
size | size | CheckboxSize | 'md' | Control size |
value | value | string | 'on' | Submitted value when checked (default "on") |
variant | variant | CheckboxVariant | 'default' | Visual style |
Events
| Event | Description |
|---|---|
nana-change | Fired on toggle (detail.checked, detail.indeterminate) |
Slots
| Slot | Description |
|---|---|
(default) | The label (overrides the label attribute) |
description | Secondary descriptive text |
CSS parts
| Part | Description |
|---|---|
::part(control) | The clickable row |
::part(box) | The check box |
::part(label) | The label text |
CSS custom properties
| Property | Description |
|---|---|
--nana-checkbox-accent | Checked background / border colour |
--nana-checkbox-radius | Box corner radius |
--nana-checkbox-bg | Box fill when unchecked |
--nana-checkbox-border | Box border colour |
--nana-checkbox-check-color | Colour of the check mark itself |
Events
Section titled “Events”| Event | Type | Description |
|---|---|---|
nana-change | CustomEvent | Fired on toggle (detail.checked, detail.indeterminate) |
| Slot | Description |
|---|---|
(default) | The label (overrides the label attribute) |
description | Secondary descriptive text |
CSS Variables
Section titled “CSS Variables”| Variable | Description |
|---|---|
--nana-checkbox-accent | Checked background / border colour |
--nana-checkbox-radius | Box corner radius |
CSS Parts
Section titled “CSS Parts”| Part | Description |
|---|---|
control | The clickable row |
box | The check box |
label | The label text |
Accessibility
Section titled “Accessibility”- Keyboard accessible
- Screen-reader labels
- Focus-visible states
- ARIA roles and states
- WCAG 2.2 AA contrast