Skip to content

ToggleGroup

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

vue
<script setup lang="ts">
import { ToggleGroupItem, ToggleGroupRoot } from 'radix-vue'
import { Icon } from '@iconify/vue'
import { ref } from 'vue'

const toggleStateSingle = ref('left')
const toggleStateMultiple = ref(['italic'])

const toggleGroupItemClasses
  = 'hover:bg-green3 text-mauve11 data-[state=on]:bg-green6 data-[state=on]:text-violet12 flex h-[35px] w-[35px] items-center justify-center bg-white text-base leading-4 first:rounded-l last:rounded-r focus:z-10 focus:shadow-[0_0_0_2px] focus:shadow-black focus:outline-none'
</script>

<template>
  <div>
    <ToggleGroupRoot v-model="toggleStateSingle" class="flex">
      <ToggleGroupItem value="left" aria-label="Toggle italic" :class="toggleGroupItemClasses">
        <Icon icon="radix-icons:text-align-left" class="w-[15px] h-[15px]" />
      </ToggleGroupItem>
      <ToggleGroupItem value="center" aria-label="Toggle italic" :class="toggleGroupItemClasses">
        <Icon icon="radix-icons:text-align-center" class="w-[15px] h-[15px]" />
      </ToggleGroupItem>
      <ToggleGroupItem value="right" aria-label="Toggle italic" :class="toggleGroupItemClasses">
        <Icon icon="radix-icons:text-align-right" class="w-[15px] h-[15px]" />
      </ToggleGroupItem>
    </ToggleGroupRoot>
    <br>
    <ToggleGroupRoot v-model="toggleStateMultiple" type="multiple" class="flex">
      <ToggleGroupItem value="bold" aria-label="Toggle italic" :class="toggleGroupItemClasses">
        <Icon icon="radix-icons:font-bold" class="w-[15px] h-[15px]" />
      </ToggleGroupItem>
      <ToggleGroupItem value="italic" aria-label="Toggle italic" :class="toggleGroupItemClasses">
        <Icon icon="radix-icons:font-italic" class="w-[15px] h-[15px]" />
      </ToggleGroupItem>
      <ToggleGroupItem value="strikethrough" aria-label="Toggle italic" :class="toggleGroupItemClasses">
        <Icon icon="radix-icons:strikethrough" class="w-[15px] h-[15px]" />
      </ToggleGroupItem>
    </ToggleGroupRoot>
  </div>
</template>

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
npm install radix-vue

Anatomy

Import the component.

vue
<script setup>
import { ToggleGroupItem, ToggleGroupRoot } from 'radix-vue'
</script>

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

API Reference

Root

Contains all the parts of a toggle group.

PropDefaultType
type*
enum

Determines whether a single or multiple items can be pressed at a time.

modelValue
string | string[]

The controlled value of the pressed item. Can be binded with v-model.

defaultValue
string | string[]

The value of the item to show as pressed when initially rendered. Use when you do not need to control the state of the items.

disabled
false
boolean

When true, prevents the user from interacting with the toggle group and all its items.

rovingFocus
true
boolean

When false, navigating through the items using arrow keys will be disabled.

orientation
undefined
enum

The orientation of the component, which determines how focus moves: horizontal for left/right arrows and vertical for up/down arrows.

dir
enum

The reading direction of the toggle group. If omitted, inherits globally from DirectionProvider or assumes LTR (left-to-right) reading mode.

loop
true
boolean

When true and rovingFocus is true, keyboard navigation will loop from last item to first, and vice versa.

as
div
string | Component

The element or component this component should render as. Can be overwrite by asChild

asChild
false
boolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

EmitType
@update:modelValue
(payload: string | string[]) => void
Data AttributeValue
[data-orientation]"vertical" | "horizontal"

Item

An item in the group.

PropDefaultType
as
button
string | Component

The element or component this component should render as. Can be overwrite by asChild

asChild
false
boolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

value*
string

A unique value for the item.

disabled
boolean

When true, prevents the user from interacting with the item.

Data AttributeValue
[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 { ref } from 'vue'
import { ToggleGroupItem, ToggleGroupRoot } from 'radix-vue'

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

<template>
  <ToggleGroupRoot v-model="value" type="single">
    <ToggleGroupItem value="left">
      <TextAlignLeftIcon />
    </ToggleGroupItem>
    <ToggleGroupItem value="center">
      <TextAlignCenterIcon />
    </ToggleGroupItem>
    <ToggleGroupItem value="right">
      <TextAlignRightIcon />
    </ToggleGroupItem>
  </ToggleGroupRoot>
</template>

Accessibility

Uses roving tabindex to manage focus movement among items.

Keyboard Interactions

KeyDescription
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.