laif-ds
Version:
Design System di Laif con componenti React basati su principi di Atomic Design
151 lines (121 loc) • 4.15 kB
Markdown
# Checkbox
## Overview
Accessible checkbox with support for checked, unchecked, and indeterminate states. Keyboard focus styles and disabled state included.
## Props
### Checkbox (Root)
| Prop | Type | Default | Description |
| ----------------- | ---------------------------- | ----------- | -------------------------------------------- |
| `checked` | `boolean \| "indeterminate"` | `false` | Current state of the checkbox. |
| `disabled` | `boolean` | `false` | Disables interactions. |
| `onCheckedChange` | `(checked: boolean) => void` | `undefined` | Called when the state changes. |
| `id` | `string` | `undefined` | Useful when paired with a label's `htmlFor`. |
| `className` | `string` | `""` | Additional classes for size/layout. |
## Behavior
- **Indeterminate**: Use `checked="indeterminate"` to display a dash indicator.
- **Focus & invalid**: Visual feedback for focus and invalid states is included.
- **Labeling**: Pair with `Label` and `htmlFor` for accessible labeling.
## Examples
### Default
```tsx
import { Checkbox } from "laif-ds";
import { Label } from "laif-ds";
export function DefaultCheckbox() {
return (
<div className="flex items-center gap-2">
<Checkbox id="terms" />
<Label htmlFor="terms">Accept terms and conditions</Label>
</div>
);
}
```
### Indeterminate
```tsx
import { Checkbox } from "laif-ds";
import { Label } from "laif-ds";
export function IndeterminateCheckbox() {
return (
<div className="flex items-center gap-2">
<Checkbox id="partial" checked="indeterminate" />
<Label htmlFor="partial">Partially selected options</Label>
</div>
);
}
```
### Disabled
```tsx
import { Checkbox } from "laif-ds";
import { Label } from "laif-ds";
export function DisabledCheckbox() {
return (
<div className="flex items-center gap-2">
<Checkbox id="disabled" disabled />
<Label htmlFor="disabled">Accept terms and conditions</Label>
</div>
);
}
```
### Select All Pattern
```tsx
import * as React from "react";
import { Checkbox } from "laif-ds";
import { Label } from "laif-ds";
export function SelectAllExample() {
const [items, setItems] = React.useState([
{ id: "item1", label: "Item 1", checked: false },
{ id: "item2", label: "Item 2", checked: true },
{ id: "item3", label: "Item 3", checked: false },
]);
const checkedCount = items.filter((i) => i.checked).length;
const selectAllState =
checkedCount === 0
? false
: checkedCount === items.length
? true
: ("indeterminate" as const);
const handleSelectAll = () => {
const newChecked = selectAllState !== true;
setItems(items.map((i) => ({ ...i, checked: newChecked })));
};
return (
<div className="space-y-4">
<div className="flex items-center gap-2 border-b pb-2">
<Checkbox
id="select-all"
checked={selectAllState}
onCheckedChange={handleSelectAll}
/>
<Label htmlFor="select-all">
Select All ({checkedCount}/{items.length})
</Label>
</div>
<div className="space-y-2 pl-6">
{items.map((item) => (
<div key={item.id} className="flex items-center gap-2">
<Checkbox
id={item.id}
checked={item.checked}
onCheckedChange={(checked) =>
setItems(
items.map((i) =>
i.id === item.id
? { ...i, checked: checked as boolean }
: i,
),
)
}
/>
<Label htmlFor={item.id}>{item.label}</Label>
</div>
))}
</div>
</div>
);
}
```
## Notes
- **Indicator**: A check icon is shown when `checked=true`, a dash for indeterminate.
- **Disabled**: Applies reduced opacity and disables pointer events.