Skip to content

ToggleGroup

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

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

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

const toggleGroupItemClasses
  = 'hover:bg-indigo3 text-mauve12 data-[state=on]:bg-indigo6 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"
      type="single"
      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.

sh
sh
$ npm add @oku-ui/primitives

Anatomy

Import the component.

vue
vue
<script setup>
import { ToggleGroupItem, ToggleGroupRoot } from '@oku-ui/primitives'
</script>

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

API Reference

Root

Contains all the parts of a toggle group.

PropDefaultType
defaultValue
string | string[]
dir
'ltr' | 'rtl'
disabled
boolean

Whether the group is disabled from user interaction.

loop
boolean
orientation
'horizontal' | 'vertical'
rovingFocus
boolean

Whether the group should maintain roving focus of its buttons.

type
'single' | 'multiple'
value
string | string[]
EmitPayload
update:value
[value: string | string[]]
Data AttributeValue
[data-orientation]"vertical" | "horizontal"

Item

An item in the group.

PropDefaultType
as
'div'
object | AsTag
disabled
boolean
value*
string

A string value for the toggle group item. All items within a toggle group should use a unique value.

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
vue
<script setup>
import { ref } from 'vue'
import { ToggleGroupItem, ToggleGroupRoot } from '@oku-ui/primitives'

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