<script setup lang="ts">
import {
ToolbarButton,
ToolbarLink,
ToolbarRoot,
ToolbarSeparator,
ToolbarToggleGroup,
ToolbarToggleItem,
} from 'akar';
import { ref } from 'vue';
import './styles.css';
const toggleStateSingle = ref('center');
const toggleStateMultiple = ref([]);
</script>
<template>
<div class="akar-demo akar-demo-Toolbar">
<ToolbarRoot
class="ToolbarRoot"
aria-label="Formatting options"
>
<ToolbarToggleGroup
v-model="toggleStateMultiple"
type="multiple"
aria-label="Text formatting"
>
<ToolbarToggleItem
class="ToolbarToggleItem"
value="bold"
aria-label="Bold"
>
<PIcon name="i-lucide-bold" />
</ToolbarToggleItem>
<ToolbarToggleItem
class="ToolbarToggleItem"
value="italic"
aria-label="Italic"
>
<PIcon name="i-lucide-italic" />
</ToolbarToggleItem>
<ToolbarToggleItem
class="ToolbarToggleItem"
value="strikethrough"
aria-label="Strike through"
>
<PIcon name="i-lucide-strikethrough" />
</ToolbarToggleItem>
</ToolbarToggleGroup>
<ToolbarSeparator class="ToolbarSeparator" />
<ToolbarToggleGroup
v-model="toggleStateSingle"
type="single"
aria-label="Text Alignment"
>
<ToolbarToggleItem
class="ToolbarToggleItem"
value="left"
aria-label="Left Aligned"
>
<PIcon name="i-lucide-align-left" />
</ToolbarToggleItem>
<ToolbarToggleItem
class="ToolbarToggleItem"
value="center"
aria-label="Center Aligned"
>
<PIcon name="i-lucide-align-center" />
</ToolbarToggleItem>
<ToolbarToggleItem
class="ToolbarToggleItem"
value="right"
aria-label="Right Aligned"
>
<PIcon name="i-lucide-align-right" />
</ToolbarToggleItem>
</ToolbarToggleGroup>
<ToolbarSeparator class="ToolbarSeparator" />
<ToolbarLink
class="ToolbarLink"
href="#"
target="_blank"
style="margin-right: 10"
>
Edited 2 hours ago
</ToolbarLink>
<ToolbarButton
class="ToolbarButton"
style="margin-left: auto"
>
Share
</ToolbarButton>
</ToolbarRoot>
</div>
</template>@import '../_colors/black-alpha.css';
@import '../_colors/mauve.css';
@import '../_colors/grass.css';
@scope (.akar-demo-Toolbar) {
/* reset */
a,
button {
all: unset;
}
.ToolbarRoot {
display: flex;
padding: 10px;
width: 100%;
min-width: max-content;
border-radius: 6px;
background-color: white;
box-shadow: 0 2px 10px var(--black-a7);
}
.ToolbarToggleItem,
.ToolbarLink,
.ToolbarButton {
flex: 0 0 auto;
color: var(--mauve-11);
height: 25px;
padding: 0 5px;
border-radius: 4px;
display: inline-flex;
font-size: 13px;
line-height: 1;
align-items: center;
justify-content: center;
}
.ToolbarToggleItem:hover,
.ToolbarLink:hover,
.ToolbarButton:hover {
background-color: var(--grass-3);
color: var(--grass-11);
}
.ToolbarToggleItem:focus,
.ToolbarLink:focus,
.ToolbarButton:focus {
position: relative;
box-shadow: 0 0 0 2px var(--grass-7);
}
.ToolbarToggleItem {
background-color: white;
margin-left: 2px;
}
.ToolbarToggleItem:first-child {
margin-left: 0;
}
.ToolbarToggleItem[data-state='on'] {
background-color: var(--grass-5);
color: var(--grass-11);
}
.ToolbarSeparator {
width: 1px;
background-color: var(--mauve-6);
margin: 0 10px;
}
.ToolbarLink {
background-color: transparent;
color: var(--mauve-11);
display: none;
justify-content: center;
align-items: center;
}
.ToolbarLink:hover {
background-color: transparent;
cursor: pointer;
}
@media (min-width: 520px) {
.ToolbarLink {
display: inline-flex;
}
}
.ToolbarButton {
padding-left: 10px;
padding-right: 10px;
color: white;
background-color: var(--grass-9);
}
.ToolbarButton:hover {
background-color: var(--grass-10);
color: white;
}
}Features
- Full keyboard navigation.
Installation
Install the component from your command line.
pnpm add akar
yarn add akar
npm install akar
bun add akar
Anatomy
Import the component.
<script setup lang="ts">
import {
ToolbarButton,
ToolbarLink,
ToolbarRoot,
ToolbarSeparator,
ToolbarToggleGroup,
ToolbarToggleItem,
} from 'akar';
</script>
<template>
<ToolbarRoot>
<ToolbarButton />
<ToolbarSeparator />
<ToolbarLink />
<ToolbarToggleGroup>
<ToolbarToggleItem />
</ToolbarToggleGroup>
</ToolbarRoot>
</template>
API Reference
Root
Contains all the toolbar component parts.
| Prop | Default | Type |
|---|---|---|
as | "div" | AsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange 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 | |
loop | booleanWhen | |
orientation | "horizontal" | "vertical" | "horizontal"The orientation of the toolbar |
| Data attribute | Value |
|---|---|
[data-orientation] | "vertical" | "horizontal" |
Button
A button item.
| Prop | Default | Type |
|---|---|---|
as | "button" | AsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange 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 attribute | Value |
|---|---|
[data-orientation] | "vertical" | "horizontal" |
Link
A link item.
| Prop | Default | Type |
|---|---|---|
as | "a" | AsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange 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.
| Prop | Default | Type |
|---|---|---|
as | "div" | AsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. | |
defaultValue | AcceptableValue | AcceptableValue[]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 | |
disabled | booleanWhen | |
loop | booleanWhen | |
modelValue | AcceptableValue | AcceptableValue[]The controlled value of the active item(s). Use this when you need to control the state of the items. Can be binded with | |
name | stringThe 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: | |
required | booleanWhen | |
rovingFocus | booleanWhen | |
type | "single" | "multiple"Determines whether a "single" or "multiple" items can be selected at a time. This prop will overwrite the inferred type from |
| Event | Payload |
|---|---|
update:modelValue | payload: AcceptableValue | AcceptableValue[]Event handler called when the value changes. |
| Data attribute | Value |
|---|---|
[data-orientation] | "vertical" | "horizontal" |
ToggleItem
An item in the group.
| Prop | Default | Type |
|---|---|---|
as | "div" | AsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. | |
disabled | booleanWhen | |
value* | AcceptableValueA string value for the toggle group item. All items within a toggle group should use a unique value. |
| Data attribute | Value |
|---|---|
[data-state] | "on" | "off" |
[data-disabled] | Present when disabled |
[data-orientation] | "vertical" | "horizontal" |
Separator
Used to visually separate items in the toolbar
| Prop | Default | Type |
|---|---|---|
as | "div" | AsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. |
| Data attribute | Value |
|---|---|
[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.
<script setup lang="ts">
import {
DropdownMenuContent,
DropdownMenuRoot,
DropdownMenuTrigger,
ToolbarButton,
ToolbarLink,
ToolbarRoot,
ToolbarSeparator,
ToolbarToggleGroup,
ToolbarToggleItem,
} from 'akar'
</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
| Key | Description |
|---|---|
| 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. |