Toolbar
Mixed-control rail on bits-ui Toolbar. Proper role=toolbar semantics with roving tabindex — arrow keys walk between children, separators are skipped, disabled items get skipped, Home/End jump to the ends.
Usage
<script lang="ts">
import * as Toolbar from '$lib/components/ui/toolbar';
import { Icon } from '$lib/components/ui/icon';
</script>
<Toolbar.Root aria-label="Text formatting">
<Toolbar.Group type="multiple">
<Toolbar.Toggle value="bold" aria-label="Bold"><Icon name="bold" /></Toolbar.Toggle>
<Toolbar.Toggle value="italic" aria-label="Italic"><Icon name="italic" /></Toolbar.Toggle>
<Toolbar.Toggle value="underline" aria-label="Underline"><Icon name="underline" /></Toolbar.Toggle>
</Toolbar.Group>
</Toolbar.Root>Mixed content
Toolbar groups toggle groups, buttons, links, and separators in one focus ring. Arrow keys move between items; separators are skipped.
<Toolbar.Root aria-label="Editor">
<Toolbar.Group type="multiple">
<Toolbar.Toggle value="bold" aria-label="Bold"><Icon name="bold" /></Toolbar.Toggle>
<Toolbar.Toggle value="italic" aria-label="Italic"><Icon name="italic" /></Toolbar.Toggle>
</Toolbar.Group>
<Toolbar.Separator />
<Toolbar.Group type="single" value="left">
<Toolbar.Toggle value="left" aria-label="Align left"><Icon name="align-left" /></Toolbar.Toggle>
<Toolbar.Toggle value="center" aria-label="Align center"><Icon name="align-center" /></Toolbar.Toggle>
<Toolbar.Toggle value="right" aria-label="Align right"><Icon name="align-right" /></Toolbar.Toggle>
</Toolbar.Group>
<Toolbar.Separator />
<Toolbar.Button>Publish</Toolbar.Button>
<Toolbar.Link href="/docs" target="_blank">
Docs <Icon name="external-link-line" class="size-3.5" size="0.875rem" />
</Toolbar.Link>
</Toolbar.Root>Vertical
Set orientation="vertical" to stack items. Up/Down arrows
walk the toolbar instead of Left/Right.
<script lang="ts">
import { Toolbar as ToolbarPrimitive } from 'bits-ui';
import { cn } from '$lib/utils.js';
let {
ref = $bindable(null),
class: className,
orientation = 'horizontal',
...restProps
}: ToolbarPrimitive.RootProps = $props();
</script>
<ToolbarPrimitive.Root
bind:ref
{orientation}
data-slot="toolbar"
data-substrate="3"
class={cn(
'flex items-center gap-1 rounded-lg border border-border bg-card p-1',
'data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch',
className
)}
{...restProps}
/>
With dropdown menu
Compose a DropdownMenu trigger inside Toolbar.Button via the child-snippet pattern for overflow actions.
<script lang="ts">
import { Toolbar as ToolbarPrimitive } from 'bits-ui';
import { cn } from '$lib/utils.js';
let {
ref = $bindable(null),
class: className,
orientation = 'horizontal',
...restProps
}: ToolbarPrimitive.RootProps = $props();
</script>
<ToolbarPrimitive.Root
bind:ref
{orientation}
data-slot="toolbar"
data-substrate="3"
class={cn(
'flex items-center gap-1 rounded-lg border border-border bg-card p-1',
'data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch',
className
)}
{...restProps}
/>
Toolbar.Root props
Inherits bits-ui Toolbar.Root props via spread. Sets role=toolbar on the rendered div.
| Prop | Type | Default | Description |
|---|---|---|---|
'horizontal' | 'vertical' | 'horizontal' | Axis of roving focus. Horizontal uses Left/Right arrows; vertical uses Up/Down. | |
boolean | true | Whether arrow navigation wraps at the ends. | |
string | — | Required. Names the toolbar landmark for assistive tech. | |
string | — | Merged onto the root via tailwind-merge. |
Toolbar.Group props
Toggle group scoped inside a toolbar. type is required.
| Prop | Type | Default | Description |
|---|---|---|---|
'single' | 'multiple' | — | Single picks one value at a time; multiple lets users stack toggles. | |
string | string[] (bindable) | — | String for single, array for multiple. Two-way bindable. | |
boolean | false | Disables every toggle in the group. |
Toolbar.Toggle props
A GroupItem inside a Toolbar.Group. Inherits the Toggle primitive's styling via `variant` + `size`.
| Prop | Type | Default | Description |
|---|---|---|---|
string | — | Required. Identifies the toggle within its group. | |
'default' | 'outline' | 'default' | Inherited from Toggle. Outline keeps a border in the resting state. | |
'sm' | 'default' | 'lg' | 'sm' | Toolbar toggles default to sm so they tuck into the rail height. |
Toolbar.Button props
Generic toolbar button. Inherits Button's variant/size.
| Prop | Type | Default | Description |
|---|---|---|---|
'default' | 'outline' | 'secondary' | 'ghost' | 'destructive' | 'link' | 'ghost' | Visual style, inherited from Button. | |
'xs' | 'sm' | 'default' | 'lg' | 'icon' | 'icon-xs' | 'icon-sm' | 'icon-lg' | 'sm' | Toolbar buttons default to sm. |