Checkbox
Overviewimport { Checkbox } from '@nili/ui';This is the library’s own overview page, rendered live. Switch the language or the theme in the header and it follows.
States
A real checkbox input, so checked, defaultChecked, disabled and required all behave as the browser intends.
import { Checkbox } from "@nili/ui"
export function Example() {
return (
<>
<Checkbox label={t('states.unchecked')} />
<Checkbox label={t('states.checked')} defaultChecked />
<Checkbox label={t('states.indeterminate')} indeterminate />
<Checkbox label={t('states.invalid')} invalid />
<Checkbox label={t('states.disabled')} disabled />
<Checkbox
label={t('states.disabledChecked')}
disabled
defaultChecked
/>
</>
)
}The label row
sublabel is muted text inline after the label; badge is the trailing slot; description is the second line; linkButton is the action under it. All four are Figma toggles, as props.
import { Checkbox, Badge, LinkButton } from "@nili/ui"
export function Example() {
return (
<Checkbox
defaultChecked
label="Email notifications"
sublabel="(recommended)"
badge={<Badge size="small" color="green" appearance="lighter">Free</Badge>}
description="We will only email you about things you asked for."
linkButton={<LinkButton href="#" size="sm">Manage preferences</LinkButton>}
/>
)
}Label position
Figma calls this “Flip”. It is logical, so start is left in English and right in Persian.
import { Checkbox } from "@nili/ui"
export function Example() {
return (
<>
<Checkbox label={t('position.end')} labelPosition="end" />
<Checkbox label={t('position.start')} labelPosition="start" />
</>
)
}Indeterminate — select all
indeterminate is not a DOM attribute; it has to be assigned to the element, which is why this component always attaches a ref internally. The usual use is a parent checkbox over a list.
import { Checkbox } from "@nili/ui"
export function Example() {
const [items, setItems] = useState([true, false, false])
const all = items.every(Boolean)
const some = items.some(Boolean) && !all
return (
<>
<Checkbox
label="Select all"
checked={all}
indeterminate={some}
onChange={(e) => setItems(items.map(() => e.target.checked))}
/>
{items.map((checked, index) => (
<Checkbox
key={index}
label={`Item ${index + 1}`}
checked={checked}
onChange={(e) =>
setItems((current) =>
current.map((v, i) => (i === index ? e.target.checked : v)),
)
}
/>
))}
</>
)
}Without a label
Omit label for a bare control — a table's row-select column, for instance. Give it an aria-label, since there is nothing else to name it.
import { Checkbox } from "@nili/ui"
export function Example() {
return <Checkbox aria-label={t('bare.selectRow')} />
}Checkbox
extends Omit< ComponentPropsWithoutRef<'input'>, 'type' | 'size' >
Other props
| Prop | Type | Default | Notes |
|---|---|---|---|
| disabled | boolean | — | |
| required | boolean | — | |
| readOnly | boolean | — | |
| checked | boolean | — | |
| defaultChecked | boolean | — | |
| placeholder | string | — | |
| value | string | — | |
| defaultValue | string | — | |
| name | string | — | |
| maxLength | number | — | |
| autoComplete | string | — | |
| aria-label | string | — | |
| label | ReactNode | — | |
| description | ReactNode | — | Secondary line under the label. Figma's "Description" toggle. |
| sublabel | ReactNode | — | Muted text inline after the label — Figma's "Sublabel". |
| badge | ReactNode | — | Trailing slot on the label row — Figma's "Badge". |
| linkButton | ReactNode | — | Action under the description — Figma's "Link Button". |
| labelPosition | start | end | end | Which side the label sits on. Figma calls this "Flip". Logical, so `start` is left in English and right in Persian. |
| indeterminate | boolean | false | Tri-state. Not a DOM attribute — it has to be assigned to the element, which is why this component always attaches a ref internally. |
| invalid | boolean | false | |
| rootClassName | string | — | Wrapper class. Use `className` for the control itself. |
CheckboxControl
internalVariant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| invalid | 'true' | 'false' | false |
CheckboxDescription
internalVariant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| disabled | 'true' | 'false' | false |
CheckboxIndicator
internalCheckboxLabel
internalVariant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| disabled | 'true' | 'false' | false |
CheckboxRoot
internalVariant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| labelPosition | end | start | end | |
| align | center | start | center |