Toolbar

Displays frequently used actions or tools in a compact, easily accessible bar.

	<script lang="ts">
  import { Separator, Toolbar } from "bits-ui";
  import Sparkle from "phosphor-svelte/lib/Sparkle";
  import TextAlignCenter from "phosphor-svelte/lib/TextAlignCenter";
  import TextAlignLeft from "phosphor-svelte/lib/TextAlignLeft";
  import TextAlignRight from "phosphor-svelte/lib/TextAlignRight";
  import TextB from "phosphor-svelte/lib/TextB";
  import TextItalic from "phosphor-svelte/lib/TextItalic";
  import TextStrikethrough from "phosphor-svelte/lib/TextStrikethrough";
 
  let text = $state(["bold"]);
  let align = $state("");
</script>
 
<Toolbar.Root
  class="flex h-12 min-w-max items-center justify-center rounded-10px border border-border bg-background-alt px-[4px] py-1 shadow-mini"
>
  <Toolbar.Group
    bind:value={text}
    type="multiple"
    class="flex items-center gap-x-0.5"
  >
    <Toolbar.GroupItem
      aria-label="toggle bold"
      value="bold"
      class="inline-flex size-10 items-center justify-center rounded-9px bg-background-alt text-foreground/60 transition-all hover:bg-muted active:scale-98 active:bg-dark-10 data-[state=on]:bg-muted data-[state=on]:text-foreground/80 active:data-[state=on]:bg-dark-10"
    >
      <TextB class="size-6" />
    </Toolbar.GroupItem>
    <Toolbar.GroupItem
      aria-label="toggle italic"
      value="italic"
      class="inline-flex size-10 items-center justify-center rounded-9px bg-background-alt text-foreground/60 transition-all hover:bg-muted active:scale-98 active:bg-dark-10 data-[state=on]:bg-muted data-[state=on]:text-foreground/80 active:data-[state=on]:bg-dark-10"
    >
      <TextItalic class="size-6" />
    </Toolbar.GroupItem>
    <Toolbar.GroupItem
      aria-label="toggle strikethrough"
      value="strikethrough"
      class="inline-flex size-10 items-center justify-center rounded-9px bg-background-alt text-foreground/60 transition-all hover:bg-muted active:scale-98 active:bg-dark-10 data-[state=on]:bg-muted data-[state=on]:text-foreground/80 active:data-[state=on]:bg-dark-10"
    >
      <TextStrikethrough class="size-6" />
    </Toolbar.GroupItem>
  </Toolbar.Group>
 
  <Separator.Root class="-my-1 mx-1 w-[1px] self-stretch bg-dark-10" />
 
  <Toolbar.Group
    bind:value={align}
    type="single"
    class="flex items-center gap-x-0.5"
  >
    <Toolbar.GroupItem
      aria-label="align left"
      value="left"
      class="inline-flex size-10 items-center justify-center rounded-9px bg-background-alt text-foreground/60 transition-all hover:bg-muted active:scale-98 active:bg-dark-10 data-[state=on]:bg-muted data-[state=on]:text-foreground/80 active:data-[state=on]:bg-dark-10"
    >
      <TextAlignLeft class="size-6" />
    </Toolbar.GroupItem>
    <Toolbar.GroupItem
      aria-label="align center"
      value="center"
      class="inline-flex size-10 items-center justify-center rounded-9px bg-background-alt text-foreground/60 transition-all hover:bg-muted active:scale-98 active:bg-dark-10 data-[state=on]:bg-muted data-[state=on]:text-foreground/80 active:data-[state=on]:bg-dark-10"
    >
      <TextAlignCenter class="size-6" />
    </Toolbar.GroupItem>
    <Toolbar.GroupItem
      aria-label="align right"
      value="right"
      class="inline-flex size-10 items-center justify-center rounded-9px bg-background-alt text-foreground/60 transition-all hover:bg-muted active:scale-98 active:bg-dark-10 data-[state=on]:bg-muted data-[state=on]:text-foreground/80 active:data-[state=on]:bg-dark-10"
    >
      <TextAlignRight class="size-6" />
    </Toolbar.GroupItem>
  </Toolbar.Group>
 
  <Separator.Root class="-my-1 mx-1 w-[1px] self-stretch bg-dark-10" />
 
  <div class="flex items-center">
    <Toolbar.Button
      class="inline-flex items-center justify-center rounded-9px px-3 py-2 text-sm  font-medium text-foreground/80 transition-all hover:bg-muted active:scale-98 active:bg-dark-10"
    >
      <Sparkle class="mr-2 size-6" />
      <span> Ask AI </span>
    </Toolbar.Button>
  </div>
</Toolbar.Root>

Structure

	<script lang="ts">
	import { Toolbar } from "bits-ui";
</script>
 
<Toolbar.Root>
	<Toolbar.Group>
		<Toolbar.GroupItem />
	</Toolbar.Group>
	<Toolbar.Link />
	<Toolbar.Button />
</Toolbar.Root>

Managing Value State

Bits UI offers several approaches to manage and synchronize the component's value state, catering to different levels of control and integration needs.

1. Two-Way Binding

For seamless state synchronization, use Svelte's bind:value directive. This method automatically keeps your local state in sync with the component's internal state.

	<script lang="ts">
	import { Toolbar } from "bits-ui";
	let myValue = $state("");
</script>
 
<button onclick={() => (myValue = "item-1")}> Press item 1 </button>
 
<Toolbar.Root>
	<Toolbar.Group type="single" bind:value={myValue}>
		<!-- ... -->
	</Toolbar.Group>
</Toolbar.Root>

Key Benefits

  • Simplifies state management
  • Automatically updates myValue when the internal state changes (e.g., via clicking on an item)
  • Allows external control (e.g., toggling an item via a separate button)

2. Change Handler

For more granular control or to perform additional logic on state changes, use the onValueChange prop. This approach is useful when you need to execute custom logic alongside state updates.

	<script lang="ts">
	import { Toolbar } from "bits-ui";
	let myValue = $state("");
</script>
 
<Toolbar.Root>
	<Toolbar.Group
		type="single"
		value={myValue}
		onValueChange={(v) => {
			myValue = v;
			// additional logic here.
		}}
	>
		<!-- ... -->
	</Toolbar.Group>
</Toolbar.Root>

Use Cases

  • Implementing custom behaviors on value change
  • Integrating with external state management solutions
  • Triggering side effects (e.g., logging, data fetching)

3. Fully Controlled

For complete control over the component's value state, use the controlledValue prop. This approach requires you to manually manage the value state, giving you full control over when and how the component responds to value change events.

To implement controlled state:

  1. Set the controlledValue prop to true on the Toolbar.Group component.
  2. Provide a value prop to Toolbar.Group, which should be a variable holding the current state.
  3. Implement an onValueChange handler to update the state when the internal state changes.
	<script lang="ts">
	import { Toolbar } from "bits-ui";
	let myValue = $state("");
</script>
 
<Toolbar.Root>
	<Toolbar.Group
		type="single"
		controlledValue
		value={myValue}
		onValueChange={(v) => {
			myValue = v;
			// additional logic here.
		}}
	>
		<!-- ... -->
	</Toolbar.Group>
</Toolbar.Root>

When to Use

  • Implementing complex logic
  • Coordinating multiple UI elements
  • Debugging state-related issues

API Reference

Toolbar.Root

The root component which contains the toolbar.

Property Type Description
loop
boolean

Whether or not the toolbar should loop when navigating.

Default: true
orientation
enum

The orientation of the toolbar.

Default: horizontal
ref $bindable
HTMLDivElement

The underlying DOM element being rendered. You can bind to this to get a reference to the element.

Default: undefined
children
Snippet

The children content to render.

Default: undefined
child
Snippet

Use render delegation to render your own element. See Child Snippet docs for more information.

Default: undefined
Data Attribute Value Description
data-orientation
enum

The orientation of the component.

data-toolbar-root
''

Present on the root element.

Toolbar.Button

A button in the toolbar.

Property Type Description
disabled
boolean

Whether or not the button is disabled.

Default: false
ref $bindable
HTMLButtonElement

The underlying DOM element being rendered. You can bind to this to get a reference to the element.

Default: undefined
children
Snippet

The children content to render.

Default: undefined
child
Snippet

Use render delegation to render your own element. See Child Snippet docs for more information.

Default: undefined
Data Attribute Value Description
data-toolbar-button
''

Present on the button element.

Toolbar.Link

A link in the toolbar.

Property Type Description
ref $bindable
HTMLAnchorElement

The underlying DOM element being rendered. You can bind to this to get a reference to the element.

Default: undefined
children
Snippet

The children content to render.

Default: undefined
child
Snippet

Use render delegation to render your own element. See Child Snippet docs for more information.

Default: undefined
Data Attribute Value Description
data-toolbar-link
''

Present on the link element.

Toolbar.Group

A group of toggle items in the toolbar.

Property Type Description
type required
enum

The type of toggle group.

Default: 'single'
value $bindable
union

The value of the toggle group. If the type is multiple, this will be an array of strings, otherwise it will be a string.

Default: undefined
onValueChange
function

A callback function called when the value changes.

Default: undefined
controlledValue
boolean

Whether or not the value is controlled or not. If true, the component will not update the value state internally, instead it will call onValueChange when it would have otherwise, and it is up to you to update the value prop that is passed to the component. See Controlled State for more information.

Default: false
disabled
boolean

Whether or not the switch is disabled.

Default: false
ref $bindable
HTMLDivElement

The underlying DOM element being rendered. You can bind to this to get a reference to the element.

Default: undefined
children
Snippet

The children content to render.

Default: undefined
child
Snippet

Use render delegation to render your own element. See Child Snippet docs for more information.

Default: undefined
Data Attribute Value Description
data-toolbar-group
''

Present on the group element.

Toolbar.GroupItem

A toggle item in the toolbar toggle group.

Property Type Description
value required
string

The value of the toolbar toggle group item. When the toolbar toggle group item is selected, toolbar the toggle group's value will be set to this value if in single mode, or this value will be pushed to the toggle group's array value if in multiple mode.

Default: undefined
disabled
boolean

Whether or not the item is disabled.

Default: false
ref $bindable
HTMLButtonElement

The underlying DOM element being rendered. You can bind to this to get a reference to the element.

Default: undefined
children
Snippet

The children content to render.

Default: undefined
child
Snippet

Use render delegation to render your own element. See Child Snippet docs for more information.

Default: undefined
Data Attribute Value Description
data-state
enum

Whether the toolbar toggle item is in the on or off state.

data-value
''

The value of the toolbar toggle item.

data-disabled
''

Present when the toolbar toggle item is disabled.

data-toolbar-item
''

Present on the toolbar toggle item.