A group of toggle buttons with shared state, supporting single or multiple selection.
npm install @data-slot/toggle-groupA group of toggle buttons with shared state, supporting single or multiple selection.
``bash`
bun add @data-slot/toggle-group
`html
$3
`javascript
import { create, createToggleGroup } from "@data-slot/toggle-group";// Auto-discover and bind all toggle-group elements
const controllers = create();
// Or target a specific element
const group = createToggleGroup(element, {
defaultValue: "center",
multiple: false,
orientation: "horizontal",
loop: true,
onValueChange: (value) => console.log(value),
});
// Programmatic control
group.setValue("left");
group.toggle("bold");
console.log(group.value); // ["left"]
// Cleanup
group.destroy();
`Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
|
defaultValue | string \| string[] | [] | Initial selected value(s). For multiple values, use array or space-separated string. |
| multiple | boolean | false | Allow multiple selections. |
| orientation | "horizontal" \| "vertical" | "horizontal" | Orientation for keyboard navigation. |
| loop | boolean | true | Wrap keyboard focus at ends. |
| disabled | boolean | false | Disable the entire group. |
| onValueChange | (value: string[]) => void | - | Callback when selection changes. |Data Attributes
$3
| Attribute | Description |
|-----------|-------------|
|
data-slot="toggle-group" | Required. Identifies the root element. |
| data-default-value | Initial selected value(s). Space-separated for multiple values. |
| data-multiple | Enable multiple selection mode. |
| data-orientation | "horizontal" or "vertical" for keyboard navigation. |
| data-disabled | Disable the entire group. |$3
| Attribute | Description |
|-----------|-------------|
|
data-slot="toggle-group-item" | Required. Identifies an item. |
| data-value | Required. The value associated with this item. |
| data-disabled | Disable this specific item. |$3
| Attribute | Values | Description |
|-----------|--------|-------------|
|
aria-pressed | "true" \| "false" | Whether item is pressed. |
| data-state | "on" \| "off" | Visual state for styling. |
| data-value (on root) | Space-separated values | Current selection. |Events
$3
`javascript
// Listen for changes
root.addEventListener("toggle-group:change", (e) => {
console.log(e.detail.value); // string[]
});
`$3
| Event | Detail | Description |
|-------|--------|-------------|
|
toggle-group:set | { value: string \| string[] } | Set selection programmatically |`javascript
// Set selection from outside
root.dispatchEvent(new CustomEvent("toggle-group:set", {
detail: { value: "bold" }
}));// Set multiple values
root.dispatchEvent(new CustomEvent("toggle-group:set", {
detail: { value: ["bold", "italic"] }
}));
`Note: Blocked when group is disabled.
$3
The following shapes are deprecated and will be removed in v1.0:
`javascript
// Deprecated: bare string
root.dispatchEvent(new CustomEvent("toggle-group:set", {
detail: "bold"
}));// Deprecated: bare array
root.dispatchEvent(new CustomEvent("toggle-group:set", {
detail: ["bold", "italic"]
}));
`Use
{ value: ... } instead.Keyboard Navigation
| Key | Action |
|-----|--------|
|
ArrowRight / ArrowDown | Move to next item (based on orientation) |
| ArrowLeft / ArrowUp | Move to previous item (based on orientation) |
| Home | Move to first item |
| End | Move to last item |
| Enter / Space | Toggle current item |Styling
`css
/ Style pressed items /
[data-slot="toggle-group-item"][data-state="on"] {
background: #333;
color: white;
}/ Style disabled items /
[data-slot="toggle-group-item"][aria-disabled="true"] {
opacity: 0.5;
cursor: not-allowed;
}
`Accessibility
- Root has
role="group"
- Items have aria-pressed attribute
- Disabled items have aria-disabled="true" and native disabled
- Supports roving tabindex for keyboard navigation
- Add aria-label or aria-labelledby` to root for context