---
title: "Toggle Group"
description: "A set of two-state buttons that can be toggled on or off."
canonical_url: "https://vinicunca.dev/akar/components/toggle-group"
---
# Toggle Group

> A set of two-state buttons that can be toggled on or off.

## ToggleGroup

```vue [index.vue]
<script setup lang="ts">
import { ToggleGroupItem, ToggleGroupRoot } from 'akar'
import { ref } from 'vue'
import './styles.css'

const toggleStateSingle = ref('left')
const toggleStateMultiple = ref(['italic'])
</script>

<template>
  <div class="akar-demo akar-demo-ToggleGroup">
    <div>
        <ToggleGroupRoot
          v-model="toggleStateSingle"
          type="single"
          class="ToggleGroup"
        >
          <ToggleGroupItem
            value="left"
            aria-label="Toggle italic"
            class="ToggleGroupItem"
          >
            <PIcon name="i-lucide-align-left" />
          </ToggleGroupItem>
          <ToggleGroupItem
            value="center"
            aria-label="Toggle italic"
            class="ToggleGroupItem"
          >
            <PIcon name="i-lucide-align-center" />
          </ToggleGroupItem>
          <ToggleGroupItem
            value="right"
            aria-label="Toggle italic"
            class="ToggleGroupItem"
          >
            <PIcon name="i-lucide-align-right" />
          </ToggleGroupItem>
        </ToggleGroupRoot>
        <br>
        <ToggleGroupRoot
          v-model="toggleStateMultiple"
          type="multiple"
          class="ToggleGroup"
        >
          <ToggleGroupItem
            value="bold"
            aria-label="Toggle italic"
            class="ToggleGroupItem"
          >
            <PIcon name="i-lucide-bold" />
          </ToggleGroupItem>
          <ToggleGroupItem
            value="italic"
            aria-label="Toggle italic"
            class="ToggleGroupItem"
          >
            <PIcon name="i-lucide-italic" />
          </ToggleGroupItem>
          <ToggleGroupItem
            value="strikethrough"
            aria-label="Toggle italic"
            class="ToggleGroupItem"
          >
            <PIcon name="i-lucide-strikethrough" />
          </ToggleGroupItem>
        </ToggleGroupRoot>
      </div>
  </div>
</template>
```

```css [styles.css]
@import '../_colors/black-alpha.css';
@import '../_colors/mauve.css';
@import '../_colors/grass.css';

@scope (.akar-demo-ToggleGroup) {
/* reset */
button {
  all: unset;
}

.ToggleGroup {
  display: inline-flex;
  background-color: var(--mauve-6);
  border-radius: 4px;
  box-shadow: 0 2px 10px var(--black-a7);
}

.ToggleGroupItem {
  background-color: white;
  color: var(--mauve-11);
  height: 35px;
  width: 35px;
  display: flex;
  font-size: 15px;
  line-height: 1;
  align-items: center;
  justify-content: center;
  margin-left: 1px;
}
.ToggleGroupItem:first-child {
  margin-left: 0;
  border-top-left-radius: 4px;
  border-bottom-left-radius: 4px;
}
.ToggleGroupItem:last-child {
  border-top-right-radius: 4px;
  border-bottom-right-radius: 4px;
}
.ToggleGroupItem:hover {
  background-color: var(--grass-3);
}
.ToggleGroupItem[data-state='on'] {
  background-color: var(--grass-5);
  color: var(--grass-11);
}
.ToggleGroupItem:focus {
  position: relative;
  box-shadow: 0 0 0 2px black;
}
}
```

## Features

- Full keyboard navigation.
- Supports horizontal/vertical orientation.
- Support single and multiple pressed buttons.
- Can be controlled or uncontrolled.

## Installation

Install the component from your command line.

```bash [pnpm]
pnpm add akar
```

```bash [yarn]
yarn add akar
```

```bash [npm]
npm install akar
```

```bash [bun]
bun add akar
```

## Anatomy

Import the component.

```vue
<script setup>
import { ToggleGroupItem, ToggleGroupRoot } from 'akar';
</script>

<template>
  <ToggleGroupRoot>
    <ToggleGroupItem />
  </ToggleGroupRoot>
</template>
```

## API Reference

### Root

Contains all the parts of a toggle group.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"div"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |
| `defaultValue` |  | `AcceptableValue \| AcceptableValue[]` | The default active value of the item(s).<br><br>Use when you do not need to control the state of the item(s). |
| `dir` |  | `"ltr" \| "rtl"` | The reading direction of the combobox when applicable.<br><br>If omitted, inherits globally from `ConfigProvider` or assumes LTR (left-to-right) reading mode. |
| `disabled` | `false` | `boolean` | When `true`, prevents the user from interacting with the toggle group and all its items. |
| `loop` | `true` | `boolean` | When `loop` and `rovingFocus` is `true`, keyboard navigation will loop from last item to first, and vice versa. |
| `modelValue` |  | `AcceptableValue \| AcceptableValue[]` | The controlled value of the active item(s).<br><br>Use this when you need to control the state of the items. Can be binded with `v-model` |
| `name` |  | `string` | The name of the field. Submitted with its owning form as part of a name/value pair. |
| `orientation` |  | `"vertical" \| "horizontal"` | The orientation of the component, which determines how focus moves: `horizontal` for left/right arrows and `vertical` for up/down arrows. |
| `required` |  | `boolean` | When `true`, indicates that the user must set the value before the owning form can be submitted. |
| `rovingFocus` | `true` | `boolean` | When `false`, navigating through the items using arrow keys will be disabled. |
| `type` |  | `"single" \| "multiple"` | Determines whether a "single" or "multiple" items can be selected at a time.<br><br>This prop will overwrite the inferred type from `modelValue` and `defaultValue`. |

**Events**

| Event | Payload | Description |
| --- | --- | --- |
| `update:modelValue` | `payload: AcceptableValue \| AcceptableValue[]` | Event handler called when the value changes. |

**Slots**

| Slot | Payload | Description |
| --- | --- | --- |
| `modelValue` | `AcceptableValue \| AcceptableValue[]` | Current toggle values |

[ToggleGroupRoot.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/ToggleGroup/ToggleGroupRoot.vue)

| Data attribute | Value |
| --- | --- |
| `[data-orientation]` | "vertical" \\| "horizontal" |

### Item

An item in the group.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"button"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |
| `disabled` |  | `boolean` | When `true`, prevents the user from interacting with the toggle. |
| `value*` |  | `AcceptableValue` | A string value for the toggle group item. All items within a toggle group should use a unique value. |

**Slots**

| Slot | Payload | Description |
| --- | --- | --- |
| `modelValue` | `boolean` | Current value |
| `state` | `"on" \| "off"` | Current state |
| `pressed` | `boolean` | Current pressed state |
| `disabled` | `boolean` | Current disabled state |

[ToggleGroupItem.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/ToggleGroup/ToggleGroupItem.vue)

| Data attribute | Value |
| --- | --- |
| `[data-state]` | "on" \\| "off" |
| `[data-disabled]` | Present when disabled |
| `[data-orientation]` | "vertical" \\| "horizontal" |

## Examples

### Ensuring there is always a value

You can control the component to ensure a value.

```vue
<script setup>
import { ToggleGroupItem, ToggleGroupRoot } from 'akar'
import { ref } from 'vue'

const value = ref('left')
</script>

<template>
  <ToggleGroupRoot
    :model-value="value"
    @update:model-value="(val) => {
      if (val) value = val
    }"
  >
    <ToggleGroupItem value="left">
      <TextAlignLeftIcon />
    </ToggleGroupItem>
    <ToggleGroupItem value="center">
      <TextAlignCenterIcon />
    </ToggleGroupItem>
    <ToggleGroupItem value="right">
      <TextAlignRightIcon />
    </ToggleGroupItem>
  </ToggleGroupRoot>
</template>
```

## Accessibility

Uses [roving tabindex](https://www.w3.org/TR/wai-aria-practices-1.2/examples/radio/radio.html) to manage focus movement among items.

### Keyboard Interactions

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

---

- [ARIA](https://www.w3.org/WAI/ARIA/apg/patterns/button)
- [GitHub](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/ToggleGroup)
- [npm](https://www.npmjs.com/package/akar)


## Sitemap

See the full [sitemap](https://vinicunca.dev/sitemap.md) for all pages.
