Toolbar
Move through a compact set of related actions and invoke the active tool.
Usage
Horizontal toolbar
Group inline text formatting actions in their natural horizontal order.
Group inline text formatting actions in their natural horizontal order.
<!-- Toolbar / Formatting -->
<script setup lang="ts">
import { ToolbarRoot, ToolbarItem, ToolbarSeparator } from '@sectile/vue/toolbar'
import { ref } from 'vue'
const items = ['bold', 'italic', 'link']
const lastAction = ref('')
</script>
<template>
<ToolbarRoot :items="items" label="Text formatting" @invoke="lastAction = $event">
<ToolbarItem value="bold"><strong>B</strong><span class="sr-only">Bold</span></ToolbarItem>
<ToolbarItem value="italic"><em>I</em><span class="sr-only">Italic</span></ToolbarItem>
<ToolbarSeparator />
<ToolbarItem value="link">Link</ToolbarItem>
</ToolbarRoot>
<p v-if="lastAction" role="status">{{ lastAction }} applied</p>
</template>Vertical toolbar
Stack canvas tools vertically beside an editing surface.
Stack canvas tools vertically beside an editing surface.
<!-- Toolbar / Vertical -->
<script setup lang="ts">
import { ToolbarRoot, ToolbarItem, ToolbarSeparator } from '@sectile/vue/toolbar'
import { ref } from 'vue'
const items = ['select', 'comment', 'upload']
const activeTool = ref('select')
</script>
<template>
<ToolbarRoot :items="items" orientation="vertical" label="Canvas tools" @invoke="activeTool = $event">
<ToolbarItem value="select">Select</ToolbarItem>
<ToolbarItem value="comment">Comment</ToolbarItem>
<ToolbarSeparator />
<ToolbarItem value="upload">Upload</ToolbarItem>
</ToolbarRoot>
<p role="status">Active tool: {{ activeTool }}</p>
</template>Controlled focus
Let the parent coordinate the active toolbar item without changing keyboard rules.
Let the parent coordinate the active toolbar item without changing keyboard rules.
<!-- Toolbar / Controlled Focus -->
<script setup lang="ts">
import { ToolbarRoot, ToolbarItem } from '@sectile/vue/toolbar'
import { ref } from 'vue'
const items = ['select', 'comment', 'upload']
const activeTool = ref('select')
</script>
<template>
<ToolbarRoot v-model="activeTool" :items="items" label="Canvas tools">
<ToolbarItem v-for="item in items" :key="item" :value="item">
{{ item }}
</ToolbarItem>
</ToolbarRoot>
<button type="button" @click="activeTool = 'comment'">Focus comment</button>
</template>API
Vue package: @sectile/vue/toolbar
ToolbarRootToolbarItemToolbarSeparator
Props
ToolbarRootProps
as- Type
PrimitiveAsDefault'div'Element or component rendered for this part.
asChild- Type
booleanDefaultfalseWhether to merge this part into its single child instead of rendering a wrapper.
defaultValue- Type
string | nullDefaultnullInitial value used when the component owns its state.
disabled- Type
booleanDefaultfalseWhether interaction is unavailable.
disabledItems- Type
readonly string[]Default[]Item values excluded from focus and selection.
items- Type
readonly string[]DefaultRequiredOrdered item values managed by the component.
label- Type
stringDefaultundefinedAccessible name announced for the control.
modelValue- Type
string | nullDefaultundefinedCurrent value when state is controlled by the parent.
orientation- Type
'horizontal' | 'vertical'Default'horizontal'Axis used for layout and keyboard movement.
policies- Type
ToolbarPolicies<string>DefaultundefinedBehavior policies that customize validation, movement, or selection.
ToolbarItemProps
as- Type
PrimitiveAsDefault'button'Element or component rendered for this part.
asChild- Type
booleanDefaultfalseWhether to merge this part into its single child instead of rendering a wrapper.
disabled- Type
booleanDefaultfalseWhether interaction is unavailable.
value- Type
stringDefaultRequiredCurrent value exposed by this contract.
ToolbarPartProps
as- Type
PrimitiveAsDefaultVaries by partElement or component rendered for this part.
asChild- Type
booleanDefaultfalseWhether to merge this part into its single child instead of rendering a wrapper.
Slots
ToolbarRootSlotProps
disabled- Type
booleanWhether interaction is unavailable.
highlightedValue- Type
string | nullValue currently highlighted for interaction.
orientation- Type
'horizontal' | 'vertical'Current layout and movement axis.
ToolbarItemSlotProps
disabled- Type
booleanWhether interaction is unavailable.
highlighted- Type
booleanWhether this item is highlighted for interaction.
value- Type
stringCurrent value exposed by this contract.
Events
ToolbarRoot
invoke- Payload
stringEmitted when the current action is invoked.
update:modelValue- Payload
string | nullEmitted when the component requests a new controlled value.
Other types
ToolbarValueChangeHandler
type ToolbarValueChangeHandler = (value: string | null) => voidToolbarInvokeHandler
type ToolbarInvokeHandler = (value: string) => voidParts
Shared scope: [data-scope="toolbar"]. Combine it with a part selector to keep styles local to this component.
| Part | Selector | Role | Extra attributes |
|---|---|---|---|
root | [data-part="root"] | Defines the component boundary and owns its composed parts. | — |
item | [data-part="item"] | Represents one selectable or actionable item. | — |
separator | [data-part="separator"] | Separates related groups without becoming an action. | — |
Keyboard interaction
| Key | Behavior |
|---|---|
| Arrow keys | Move between toolbar items in the configured orientation. |
| Home / End | Move to the first or last enabled item. |
| Enter / Space | Invoke the focused tool. |
Accessibility
The labeled toolbar uses one roving tab stop and keeps separators out of the focus order.
See the corresponding WAI-ARIA pattern for the host accessibility contract.
