Skip to content

Toolbar

A container for grouping a set of controls, such as buttons, Toolbar groups or dropdown menus.
vue
<script setup lang="ts">
import {
  ToolbarButton,
  ToolbarLink,
  ToolbarRoot,
  ToolbarSeparator,
  ToolbarToggleGroup,
  ToolbarToggleItem,
} from 'radix-vue'
import { Icon } from '@iconify/vue'
import { ref } from 'vue'

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

<template>
  <ToolbarRoot
    class="flex p-[10px] w-full max-w-[610px] !min-w-max rounded-md bg-white shadow-[0_2px_10px] shadow-blackA7"
    aria-label="Formatting options"
  >
    <ToolbarToggleGroup
      v-model="toggleStateMultiple"
      type="multiple"
      aria-label="Text formatting"
    >
      <ToolbarToggleItem
        class="flex-shrink-0 flex-grow-0 basis-auto text-mauve11 h-[25px] px-[5px] rounded inline-flex text-[13px] leading-none items-center justify-center bg-white ml-0.5 outline-none hover:bg-green3 hover:text-grass11 focus:relative focus:shadow-[0_0_0_2px] focus:shadow-green7 first:ml-0 data-[state=on]:bg-green5 data-[state=on]:text-grass11"
        value="bold"
        aria-label="Bold"
      >
        <Icon
          class="w-[15px] h-[15px]"
          icon="radix-icons:font-bold"
        />
      </ToolbarToggleItem>
      <ToolbarToggleItem
        class="flex-shrink-0 flex-grow-0 basis-auto text-mauve11 h-[25px] px-[5px] rounded inline-flex text-[13px] leading-none items-center justify-center bg-white ml-0.5 outline-none hover:bg-green3 hover:text-grass11 focus:relative focus:shadow-[0_0_0_2px] focus:shadow-green7 first:ml-0 data-[state=on]:bg-green5 data-[state=on]:text-grass11"
        value="italic"
        aria-label="Italic"
      >
        <Icon
          class="w-[15px] h-[15px]"
          icon="radix-icons:font-italic"
        />
      </ToolbarToggleItem>
      <ToolbarToggleItem
        class="flex-shrink-0 flex-grow-0 basis-auto text-mauve11 h-[25px] px-[5px] rounded inline-flex text-[13px] leading-none items-center justify-center bg-white ml-0.5 outline-none hover:bg-green3 hover:text-grass11 focus:relative focus:shadow-[0_0_0_2px] focus:shadow-green7 first:ml-0 data-[state=on]:bg-green5 data-[state=on]:text-grass11"
        value="strikethrough"
        aria-label="Strike through"
      >
        <Icon
          class="w-[15px] h-[15px]"
          icon="radix-icons:strikethrough"
        />
      </ToolbarToggleItem>
    </ToolbarToggleGroup>
    <ToolbarSeparator class="w-[1px] bg-mauve6 mx-[10px]" />
    <ToolbarToggleGroup
      v-model="toggleStateSingle"
      type="single"
      aria-label="Text Alignment"
    >
      <ToolbarToggleItem
        class="flex-shrink-0 flex-grow-0 basis-auto text-mauve11 h-[25px] px-[5px] rounded inline-flex text-[13px] leading-none items-center justify-center bg-white ml-0.5 outline-none hover:bg-green3 hover:text-grass11 focus:relative focus:shadow-[0_0_0_2px] focus:shadow-green7 first:ml-0 data-[state=on]:bg-green5 data-[state=on]:text-grass11"
        value="left"
        aria-label="Left Aligned"
      >
        <Icon
          class="w-[15px] h-[15px]"
          icon="radix-icons:text-align-left"
        />
      </ToolbarToggleItem>
      <ToolbarToggleItem
        class="flex-shrink-0 flex-grow-0 basis-auto text-mauve11 h-[25px] px-[5px] rounded inline-flex text-[13px] leading-none items-center justify-center bg-white ml-0.5 outline-none hover:bg-green3 hover:text-grass11 focus:relative focus:shadow-[0_0_0_2px] focus:shadow-green7 first:ml-0 data-[state=on]:bg-green5 data-[state=on]:text-grass11"
        value="center"
        aria-label="Center Aligned"
      >
        <Icon
          class="w-[15px] h-[15px]"
          icon="radix-icons:text-align-center"
        />
      </ToolbarToggleItem>
      <ToolbarToggleItem
        class="flex-shrink-0 flex-grow-0 basis-auto text-mauve11 h-[25px] px-[5px] rounded inline-flex text-[13px] leading-none items-center justify-center bg-white ml-0.5 outline-none hover:bg-green3 hover:text-grass11 focus:relative focus:shadow-[0_0_0_2px] focus:shadow-green7 first:ml-0 data-[state=on]:bg-green5 data-[state=on]:text-grass11"
        value="right"
        aria-label="Right Aligned"
      >
        <Icon
          class="w-[15px] h-[15px]"
          icon="radix-icons:text-align-right"
        />
      </ToolbarToggleItem>
    </ToolbarToggleGroup>
    <ToolbarSeparator class="w-[1px] bg-mauve6 mx-[10px]" />
    <ToolbarLink
      class="bg-transparent !font-normal !text-mauve11 inline-flex justify-center items-center hover:bg-transparent hover:cursor-pointer flex-shrink-0 flex-grow-0 basis-auto h-[25px] px-[5px] rounded text-[13px] leading-none bg-white ml-0.5 outline-none hover:bg-green3 hover:text-grass11 focus:relative focus:shadow-[0_0_0_2px] focus:shadow-green7 first:ml-0 data-[state=on]:bg-green5 data-[state=on]:text-grass11"
      href="#"
      target="_blank"
      style="margin-right: 10"
    >
      Edited 2 hours ago
    </ToolbarLink>
    <ToolbarButton
      class="px-[10px] text-white bg-green9 flex-shrink-0 flex-grow-0 basis-auto h-[25px] rounded inline-flex text-[13px] leading-none items-center justify-center outline-none hover:bg-green10 focus:relative focus:shadow-[0_0_0_2px] focus:shadow-green7"
      style="margin-left: auto"
    >
      Share
    </ToolbarButton>
  </ToolbarRoot>
</template>

Features

  • Full keyboard navigation.

Installation

Install the component from your command line.

sh
$ npm add radix-vue

Anatomy

Import the component.

vue
<script setup lang="ts">
import {
  ToolbarButton,
  ToolbarLink,
  ToolbarRoot,
  ToolbarSeparator,
  ToolbarToggleGroup,
  ToolbarToggleItem,
} from 'radix-vue'
</script>

<template>
  <ToolbarRoot>
    <ToolbarButton />
    <ToolbarSeparator />
    <ToolbarLink />
    <ToolbarToggleGroup>
      <ToolbarToggleItem />
    </ToolbarToggleGroup>
  </ToolbarRoot>
</template>

API Reference

Root

Contains all the toolbar component parts.

PropDefaultType
as
'div'
AsTag | Component

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

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

dir
'ltr' | 'rtl'

The reading direction of the combobox when applicable.
If omitted, inherits globally from ConfigProvider or assumes LTR (left-to-right) reading mode.

loop
boolean

When true, keyboard navigation will loop from last tab to first, and vice versa.

orientation
'horizontal'
'vertical' | 'horizontal'

The orientation of the toolbar

Data AttributeValue
[data-orientation]"vertical" | "horizontal"

Button

A button item.

PropDefaultType
as
'button'
AsTag | Component

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

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

disabled
boolean
Data AttributeValue
[data-orientation]"vertical" | "horizontal"

A link item.

PropDefaultType
as
'a'
AsTag | Component

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

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

ToggleGroup

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

PropDefaultType
as
'div'
AsTag | Component

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

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

defaultValue
string | string[]

The default active value of the item(s).

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.
If omitted, inherits globally from ConfigProvider or assumes LTR (left-to-right) reading mode.

disabled
boolean

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

loop
boolean

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

modelValue
string | string[]

The controlled value of the active item(s).

Use this when you need to control the state of the items. Can be binded with v-model

orientation
'vertical' | 'horizontal'

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

rovingFocus
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 pressed at a time.

This prop will be ignored if any of v-model or defaultValue is defined, as the type will be inferred from the value.

EmitPayload
update:modelValue
[payload: string | string[]]

Event handler called when the value changes.

Data AttributeValue
[data-orientation]"vertical" | "horizontal"

ToggleItem

An item in the group.

PropDefaultType
as
'div'
AsTag | Component

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

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

defaultValue
boolean

The pressed state of the toggle when it is initially rendered. Use when you do not need to control its open state.

disabled
boolean

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

pressed
boolean

The controlled pressed state of the toggle. Can be bind as v-model.

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"

Separator

Used to visually separate items in the toolbar

PropDefaultType
as
'div'
AsTag | Component

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

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

Data AttributeValue
[data-orientation]"vertical" | "horizontal"

Examples

Use with other primitives

All our primitives which expose a Trigger part, such as Dialog, AlertDialog, Popover, DropdownMenu can be composed within a toolbar by using the asChild prop.

Here is an example using our DropdownMenu primitive.

vue
<script setup lang="ts">
import {
  DropdownMenuContent,
  DropdownMenuRoot,
  DropdownMenuTrigger,
  ToolbarButton,
  ToolbarLink,
  ToolbarRoot,
  ToolbarSeparator,
  ToolbarToggleGroup,
  ToolbarToggleItem,
} from 'radix-vue'
</script>

<template>
  <ToolbarRoot>
    <ToolbarButton>Action 1</ToolbarButton>
    <ToolbarSeparator />
    <DropdownMenuRoot>
      <ToolbarButton as-child>
        <DropdownMenuTrigger>Trigger</DropdownMenuTrigger>
      </ToolbarButton>
      <DropdownMenuContent></DropdownMenuContent>
    </DropdownMenuRoot>
  </ToolbarRoot>
</template>

Accessibility

Uses roving tabindex to manage focus movement among items.

Keyboard Interactions

KeyDescription
Tab
Moves focus to the first item in the group.
Space
Activates/deactivates the item.
Enter
Activates/deactivates the item.
ArrowDown
Moves focus to the next item depending on orientation.
ArrowRight
Moves focus to the next item depending on orientation.
ArrowUp
Moves focus to the previous item depending on orientation .
ArrowLeft
Moves focus to the previous item depending on orientation .
Home
Moves focus to the first item.
End
Moves focus to the last item.