# Toggle Group

**A set of toggle buttons where one or several can be pressed.**

**Reference:** [View Source](https://github.com/jramke/fluid-primitives/tree/main/Resources/Private/Primitives/ToggleGroup) · [Zag.js Docs](https://zagjs.com/components/react/toggle-group)

**ToggleGroupExamples.html**

```html
<ui:toggleGroup.root defaultValue="{0: 'center'}" aria-label="Text alignment">
    <ui:toggleGroup.item value="left">Left</ui:toggleGroup.item>
    <ui:toggleGroup.item value="center">Center</ui:toggleGroup.item>
    <ui:toggleGroup.item value="right">Right</ui:toggleGroup.item>
</ui:toggleGroup.root>

```

## Features

- Single or multiple selection
- Roving focus: the group is one tab stop and the arrow keys move between the items, with <kbd>Home</kbd> and <kbd>End</kbd> to jump to the first and last item
- Supports horizontal and vertical orientations
- Optionally prevents the pressed item from being deselected
- Supports disabled items and a disabled group

## Anatomy

```html
<primitives:toggleGroup.root>
    <primitives:toggleGroup.item />
</primitives:toggleGroup.root>
```

## Installation

```bash
typo3 ui:add toggle-group
```

Or copy the files manually from GitHub (https://github.com/jramke/fluid-primitives/tree/main/Resources/Private/Registry/ToggleGroup) into your project.

Read more about installing [Components and Primitives](/docs/core-concepts/primitives.md).

## Examples

### Multiple

Allow several items to be pressed at the same time.

**ToggleGroupExamples.html**

```html
<ui:toggleGroup.root multiple="{true}" defaultValue="{0: 'bold'}" aria-label="Text formatting">
    <ui:toggleGroup.item value="bold" aria-label="Bold" class="font-bold">B</ui:toggleGroup.item>
    <ui:toggleGroup.item value="italic" aria-label="Italic" class="italic">I</ui:toggleGroup.item>
    <ui:toggleGroup.item value="underline" aria-label="Underline" class="underline">U</ui:toggleGroup.item>
</ui:toggleGroup.root>

```

### Vertical Orientation

Stack the items vertically. The arrow keys follow the orientation.

**ToggleGroupExamples.html**

```html
<ui:toggleGroup.root orientation="{f:constant(name: 'Jramke\FluidPrimitives\Enum\Orientation::Vertical')}" defaultValue="{0: 'medium'}" aria-label="Size">
    <ui:toggleGroup.item value="small">Small</ui:toggleGroup.item>
    <ui:toggleGroup.item value="medium">Medium</ui:toggleGroup.item>
    <ui:toggleGroup.item value="large">Large</ui:toggleGroup.item>
</ui:toggleGroup.root>

```

### Disabled

Disable the whole group, or single items. A disabled group always wins over an item, an item can not opt out of it.

**ToggleGroupExamples.html**

```html
<div class="flex flex-col items-start gap-4">
    <ui:toggleGroup.root defaultValue="{0: 'left'}" aria-label="Text alignment of the disabled group" disabled="{true}">
        <ui:toggleGroup.item value="left">Left</ui:toggleGroup.item>
        <ui:toggleGroup.item value="center">Center</ui:toggleGroup.item>
        <ui:toggleGroup.item value="right">Right</ui:toggleGroup.item>
    </ui:toggleGroup.root>
    <ui:toggleGroup.root defaultValue="{0: 'left'}" aria-label="Text alignment with a disabled item">
        <ui:toggleGroup.item value="left">Left</ui:toggleGroup.item>
        <ui:toggleGroup.item value="center" disabled="{true}">Center</ui:toggleGroup.item>
        <ui:toggleGroup.item value="right">Right</ui:toggleGroup.item>
    </ui:toggleGroup.root>
</div>

```

### Not Deselectable

Keep one item always pressed. This has no effect with `multiple`.

**ToggleGroupExamples.html**

```html
<ui:toggleGroup.root deselectable="{false}" defaultValue="{0: 'month'}" aria-label="Billing period">
    <ui:toggleGroup.item value="month">Monthly</ui:toggleGroup.item>
    <ui:toggleGroup.item value="year">Yearly</ui:toggleGroup.item>
</ui:toggleGroup.root>

```

## API Reference

### toggleGroup.root

Provides the shared state and wraps the items. Renders a `<div>` element with `role="group"`.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `defaultValue` | `string[]` | No | `-` | The initial value of the pressed items when rendered. Use when you don't need to control the value of the toggle group. |
| `disabled` | `boolean` | No | `-` | Whether all items of the toggle group are disabled. |
| `multiple` | `boolean` | No | `false` | Whether multiple items can be pressed at the same time. |
| `deselectable` | `boolean` | No | `true` | Whether the pressed item can be deselected again. Ignored when `multiple` is `true`. |
| `loopFocus` | `boolean` | No | `true` | Whether the keyboard navigation loops from the last item to the first, and vice versa. |
| `rovingFocus` | `boolean` | No | `true` | Whether the items use a roving tabindex, so the whole group is a single tab stop and the arrow keys move the focus. |
| `orientation` | `Enum\Orientation` | No | `Horizontal` | The orientation of the toggle group. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `rootId` | `string` | No | `-` | The root ID of the component, used for hydration and identification. |
| `ids` | `array` | No | `[]` | The IDs of of the component parts for composition. |
| `autoMount` | `boolean` | No | `true` | Whether the client initializes the component on its own. Set it to false to mount it yourself with `mount()` |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-toggle-group-root` | <uid> |
| `data-disabled` | Present when disabled |
| `data-multiple` |  |
| `data-orientation` | The orientation of the toggle-group |

### toggleGroup.item

A toggle button of the group. Renders a `<button>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `value` | `string` | Yes | `-` | The value of the toggle group item. |
| `disabled` | `boolean` | No | `-` | Whether the item is disabled. An item of a disabled group is always disabled. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-toggle-group-item` | <uid> |
| `data-pressed` | Present when pressed |
| `data-disabled` | Present when disabled |
| `data-orientation` | The orientation of the item |

### Machine JavaScript API

| Name | Type | Description |
| --- | --- | --- |
| `value` | `string[]` | The value of the toggle group. |
| `setValue` | `(value: string[]) => void` | Sets the value of the toggle group. |
| `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of the toggle item. |
| `getRootState` | `() => RootState` | Returns the state of the toggle group |

### Accessibility

| Key | Description |
| --- | --- |
| `Tab`  | Moves focus to either the pressed item or the first item in the group. |
| `Space`  | Activates/deactivates the item. |
| `Enter`  | Activates/deactivates the item. |
| `ArrowDown`  | Moves focus to the next item in the group. |
| `ArrowRight`  | Moves focus to the next item in the group. |
| `ArrowUp`  | Moves focus to the previous item in the group. |
| `ArrowLeft`  | Moves focus to the previous item in the group. |
| `Home`  | Moves focus to the first item. |
| `End`  | Moves focus to the last item. |
