Accessible, unstyled WAI-ARIA toolbar with native actions and roving focus.
|
|
| Package |
@vizejs/ui/toolbar |
| Maturity |
stable |
| Own the source |
vize lib pull toolbar |
| Requires |
context |
| Aliases |
toolbar, action toolbar, editor toolbar, command toolbar |
| Covers |
WAI-ARIA Toolbar, React Aria Toolbar, Radix Toolbar |
Usage
import { Toolbar, ToolbarItem } from "@vizejs/ui/toolbar";
Or copy the source into your project with vize lib pull toolbar (see Source Distribution).
API
Source: src/families/actions/toolbar/toolbar.vue
Props
| Prop |
Type |
Default |
Description |
as |
PrimitiveAs |
"div" |
Native element, custom element, or component to render. |
disabled |
boolean |
false |
Disable every item and remove the toolbar from roving focus. |
orientation |
ToolbarOrientation |
"horizontal" |
Directional layout hint used by arrow-key roving focus. |
dir |
ToolbarDirection |
"ltr" |
Reading direction used to map horizontal arrow-key navigation. |
loop |
boolean |
true |
Whether arrow-key navigation wraps at the first and last enabled item. |
rovingFocus |
boolean |
true |
Whether items participate in a single-tabstop roving focus model. |
ariaLabel |
string |
undefined |
Accessible name when no visible label or aria-labelledby supplies one. |
ariaLabelledby |
string |
undefined |
Space-separated ids that label the toolbar. |
ariaDescribedby |
string |
undefined |
Space-separated ids that describe the toolbar. |
Events
| Event |
Payload |
Description |
press |
[value: string, nativeEvent: MouseEvent] |
Fired after an enabled item is activated by pointer or keyboard. |
Slots
| Slot |
Slot props |
Description |
default |
ToolbarSlotState |
Renders grouped action controls with toolbar navigation state. |
Exposed
| Member |
Type |
Description |
disabled |
boolean |
Whether the toolbar suppresses every item activation. |
orientation |
ToolbarOrientation |
Directional layout hint used by arrow-key roving focus. |
dir |
ToolbarDirection |
Reading direction used by horizontal arrow-key roving focus. |
rovingFocus |
boolean |
Whether items participate in a single-tabstop roving focus model. |
state |
ToolbarState |
Stable state token for styling and tests. |
style |
ToolbarStyle |
Inline native style object applied to the host. |
activeValue |
string | null |
Currently active item value, or null before an item is focusable. |
element |
PrimitiveElement | null |
Rendered root element or component instance. |
focus |
(options?: FocusOptions) => void |
Move focus to the active or first enabled item. |
focusValue |
(value: string, options?: FocusOptions) => boolean |
Move focus to an enabled item by value and report whether it was found. |
Source: src/families/actions/toolbar/toolbar-item.vue
Props
| Prop |
Type |
Default |
Description |
as |
PrimitiveAs |
"button" |
Native element, custom element, or component to render. |
native |
boolean |
auto |
Whether the rendered target already implements native button semantics. |
type |
"button" | "reset" | "submit" |
"button" |
Native button submission behavior. |
value (required) |
string |
required |
Stable item value emitted by item and toolbar press events. |
disabled |
boolean |
false |
Disable this item while preserving the rest of the toolbar. |
ariaLabel |
string |
undefined |
Accessible name when no visible label or aria-labelledby supplies one. |
ariaLabelledby |
string |
undefined |
Space-separated ids that label this item. |
ariaDescribedby |
string |
undefined |
Space-separated ids that describe this item. |
Events
| Event |
Payload |
Description |
press |
[value: string, nativeEvent: MouseEvent] |
Fired after user activation reaches this enabled item. |
Slots
| Slot |
Slot props |
Description |
default |
ToolbarItemSlotState |
Renders item contents with current availability and navigation state. |
Exposed
| Member |
Type |
Description |
value |
string |
Item value used by the toolbar navigation and press contract. |
disabled |
boolean |
Whether this item or its toolbar suppresses activation. |
orientation |
ToolbarOrientation |
Directional layout hint inherited from the toolbar. |
dir |
ToolbarDirection |
Reading direction inherited from the toolbar. |
state |
ToolbarItemState |
Stable state token for styling and tests. |
element |
PrimitiveElement | null |
Rendered item element or component instance. |
focus |
(options?: FocusOptions) => void |
Move focus to the rendered item. |
Behavior
Every row is proven by a mounted-DOM, SSR/hydration, renderer, type, size, or
tree-shaking gate. A row without a passing test is a bug in the family contract.
| ID |
Component |
Scenario |
Behavior |
Assertion |
| T1 |
toolbar.vue |
semantic root |
renders role="toolbar" with labeling, orientation, direction, part, data, and style hooks |
renders accessible toolbar semantics without adding visual CSS |
| T2 |
toolbar-item.vue |
vertical roving |
one-tabstop arrow-key focus follows orientation and skips disabled native buttons |
roving focus follows vertical orientation and skips disabled items |
| T3 |
toolbar.vue |
native tab order |
rovingFocus=false preserves native tab order and lets arrow keys pass through |
roving focus can be disabled to preserve the native tab order |
| T4 |
toolbar-item.vue |
rtl navigation |
horizontal arrow-key focus maps next and previous through the toolbar dir contract |
horizontal roving focus respects rtl direction |
| T5 |
toolbar-item.vue |
activation |
enabled items emit item and toolbar press events in dispatch order |
pointer and keyboard activation emit value-carrying events |
| T6 |
both |
disabled |
disabled toolbars and items suppress activation and leave tab order safely |
disabled toolbars and items suppress activation |
| T7 |
toolbar-item.vue |
custom element |
non-native items receive role="button" and synthesize Enter/Space keyboard clicks |
custom items expose button semantics and keyboard activation |
| T8 |
both |
public instance |
root and items expose focus methods and immutable state snapshots |
exposes focus, focusValue, activeValue, and live state |
| T9 |
toolbar-item.vue |
duplicate value |
mount and reactive value changes reject duplicate item values |
rejects duplicate item values before roving focus becomes ambiguous |
| T10 |
toolbar-item.vue |
provider boundary |
items fail loudly when rendered outside a matching toolbar provider |
items require a matching toolbar provider |
| T11 |
both |
SSR/hydration |
server markup is deterministic and hydrates without replacing the root or drifting tabindex |
toolbar-ssr.test.ts, runtime-conformance.test.ts |
| T12 |
public types |
invalid contract |
TypeScript rejects unsupported orientation, direction, native button type, and item values |
src/families/actions/toolbar/toolbar.types.test-d.ts |
| T13 |
root/subpath |
consumer bundle |
root and subpath consumers retain only Toolbar, emit no CSS, and stay within gzip budget |
scripts/check-tree-shaking.mjs |
Contract
Toolbar is a headless compound primitive for clustered actions such as editor
controls, document commands, and inspector panels. It owns no selection model and
emits no visual CSS. Consumers style through data-vize-ui, data-state,
data-disabled, data-orientation, data-roving-focus, data-value, part,
and --vize-ui-toolbar-orientation.
The root always renders role="toolbar". Items are native <button type="button"> controls by default, and non-native targets receive explicit
button semantics plus Enter/Space activation. Roving focus is enabled by default
so the toolbar has a single tab stop; consumers can set rovingFocus=false when
native per-control tab stops are required.
Items require a unique string value so item-level and toolbar-level press
events, activeValue, roving tabindex, and focusValue() stay stable across
polymorphic rendering, slot changes, and DOM reordering. Duplicate values throw
VIZE_UI_TOOLBAR_VALUE_DUPLICATE during registration or reactive value changes
before more than one item can own the active tab stop.