gnome-ui
Components

Toolbar

A container for grouping a set of controls, such as buttons, toggle groups, or menus, often used for text editors or application toolbars.

Toolbar component
import * as React from 'react';
import { Toolbar } from 'gnome-ui/toolbar';
import { Toggle } from 'gnome-ui/toggle';
import { ToggleGroup } from 'gnome-ui/toggle-group';
import { Bold, Italic, Strikethrough, AlignLeft, AlignCenter, AlignRight, Link, Image } from 'lucide-react';

export function ToolbarDefault() {
  const [format, setFormat] = React.useState<string[]>([]);
  const [align, setAlign] = React.useState<string[]>(['left']);

  return (
    <Toolbar.Root className="flex w-full max-w-2xl flex-wrap items-center gap-2 rounded-xl border border-border bg-card p-2 shadow-sm">
      <Toolbar.Group className="flex items-center gap-1">
        <ToggleGroup multiple value={format} onValueChange={setFormat} className="flex gap-1">
          <Toggle value="bold" className="inline-flex h-9 w-9 items-center justify-center rounded-xl border border-transparent text-sm font-medium text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 data-[pressed]:bg-primary data-[pressed]:text-primary-foreground" aria-label="Bold">
            <Icons.Bold className="size-4" />
          </Toggle>
          <Toggle value="italic" className="inline-flex h-9 w-9 items-center justify-center rounded-xl border border-transparent text-sm font-medium text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 data-[pressed]:bg-primary data-[pressed]:text-primary-foreground" aria-label="Italic">
            <Icons.Italic className="size-4" />
          </Toggle>
          <Toggle value="strikethrough" className="inline-flex h-9 w-9 items-center justify-center rounded-xl border border-transparent text-sm font-medium text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 data-[pressed]:bg-primary data-[pressed]:text-primary-foreground" aria-label="Strikethrough">
            <Icons.Strikethrough className="size-4" />
          </Toggle>
        </ToggleGroup>
      </Toolbar.Group>

      <Toolbar.Separator className="mx-2 h-5 w-px bg-border" />

      <Toolbar.Group className="flex items-center gap-1">
        <ToggleGroup value={align} onValueChange={setAlign} className="flex gap-1">
          <Toggle value="left" className="inline-flex h-9 w-9 items-center justify-center rounded-xl border border-transparent text-sm font-medium text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 data-[pressed]:bg-primary data-[pressed]:text-primary-foreground" aria-label="Align Left">
            <Icons.AlignLeft className="size-4" />
          </Toggle>
          <Toggle value="center" className="inline-flex h-9 w-9 items-center justify-center rounded-xl border border-transparent text-sm font-medium text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 data-[pressed]:bg-primary data-[pressed]:text-primary-foreground" aria-label="Align Center">
            <Icons.AlignCenter className="size-4" />
          </Toggle>
          <Toggle value="right" className="inline-flex h-9 w-9 items-center justify-center rounded-xl border border-transparent text-sm font-medium text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 data-[pressed]:bg-primary data-[pressed]:text-primary-foreground" aria-label="Align Right">
            <Icons.AlignRight className="size-4" />
          </Toggle>
        </ToggleGroup>
      </Toolbar.Group>

      <Toolbar.Separator className="mx-2 h-5 w-px bg-border" />

      <Toolbar.Group className="flex items-center gap-1">
        <Toolbar.Button className="inline-flex h-9 w-9 items-center justify-center rounded-xl border border-transparent text-sm font-medium text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 data-[pressed]:bg-primary data-[pressed]:text-primary-foreground" aria-label="Add Link">
          <Icons.Link className="size-4" />
        </Toolbar.Button>
        <Toolbar.Button className="inline-flex h-9 w-9 items-center justify-center rounded-xl border border-transparent text-sm font-medium text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 data-[pressed]:bg-primary data-[pressed]:text-primary-foreground" aria-label="Add Image">
          <Icons.Image className="size-4" />
        </Toolbar.Button>
      </Toolbar.Group>
    </Toolbar.Root>
  );
}

Anatomy

import { Toolbar } from 'gnome-ui/toolbar';

<Toolbar.Root>
  <Toolbar.Group>
    <Toolbar.Button />
    <Toolbar.Button />
  </Toolbar.Group>
  <Toolbar.Separator />
  <Toolbar.Link />
</Toolbar.Root>

Examples

Vertical Orientation

Set orientation="vertical" to create a side toolbar.

Toolbar component
import * as React from 'react';
import { Toolbar } from 'gnome-ui/toolbar';
import { Bold, Italic, AlignLeft } from 'lucide-react';

export function ToolbarVertical() {
  return (
    <Toolbar.Root orientation="vertical" className="flex h-fit w-14 flex-col items-center gap-2 rounded-xl border border-border bg-card py-2 shadow-sm">
      <Toolbar.Button className="inline-flex h-9 w-9 items-center justify-center rounded-xl border border-transparent text-sm font-medium text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 data-[pressed]:bg-primary data-[pressed]:text-primary-foreground" aria-label="Bold">
        <Icons.Bold className="size-4" />
      </Toolbar.Button>
      <Toolbar.Button className="inline-flex h-9 w-9 items-center justify-center rounded-xl border border-transparent text-sm font-medium text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 data-[pressed]:bg-primary data-[pressed]:text-primary-foreground" aria-label="Italic">
        <Icons.Italic className="size-4" />
      </Toolbar.Button>
      <Toolbar.Separator className="my-1 h-px w-5 bg-border" />
      <Toolbar.Button className="inline-flex h-9 w-9 items-center justify-center rounded-xl border border-transparent text-sm font-medium text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 data-[pressed]:bg-primary data-[pressed]:text-primary-foreground" aria-label="Align Left">
        <Icons.AlignLeft className="size-4" />
      </Toolbar.Button>
    </Toolbar.Root>
  );
}

With Input

Toolbars can contain inputs for search or other controls, fully integrated with the toolbar's keyboard navigation.

Toolbar component
import * as React from 'react';
import { Toolbar } from 'gnome-ui/toolbar';

export function ToolbarWithInput() {
  return (
    <Toolbar.Root className="flex w-full max-w-md items-center gap-2 rounded-xl border border-border bg-card p-2 shadow-sm">
      <Toolbar.Input 
        className="flex h-9 w-full rounded-xl border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring placeholder:text-muted-foreground" 
        placeholder="Search tool..." 
      />
      <Toolbar.Button className="inline-flex h-9 w-9 items-center justify-center rounded-xl border border-transparent text-sm font-medium text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 data-[pressed]:bg-primary data-[pressed]:text-primary-foreground shrink-0 bg-primary text-primary-foreground hover:brightness-95 hover:bg-primary">
        Go
      </Toolbar.Button>
    </Toolbar.Root>
  );
}

ToolbarButton

A button that can be used as-is or as a trigger for other components. Renders a &lt;button&gt; element.

Documentation: Base UI Toolbar

API reference

Root

A container for grouping a set of controls, such as buttons, toggle groups, or menus. Renders a <div> element.

Root Props:

PropTypeDefaultDescription
loopFocusbooleantrueIf true, using keyboard navigation will wrap focus to the other end of the toolbar once the end is reached.
disabledboolean--
orientationToolbar.Root.Orientation'horizontal'The orientation of the toolbar.
classNamestring | ((state: Toolbar.Root.State) => string | undefined)-CSS class applied to the element, or a function that returns a class based on the component’s state.
styleCSSProperties | ((state: Toolbar.Root.State) => CSSProperties | undefined)-*
renderReactElement | ((props: HTMLProps, state: Toolbar.Root.State) => ReactElement)-Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.

Root Data Attributes:

AttributeTypeDescription
data-orientation'horizontal' | 'vertical'Indicates the orientation of the toolbar.
data-disabled-Present when the toolbar is disabled.

Button

A button that can be used as-is or as a trigger for other components. Renders a <button> element.

Button Props:

PropTypeDefaultDescription
focusableWhenDisabledbooleantrueWhen true the item remains focuseable when disabled.
nativeButtonbooleantrueWhether the component renders a native <button> element when replacing it via the render prop. Set to false if the rendered element is not a button (e.g. <div>).
disabledbooleanfalseWhen true the item is disabled.
classNamestring | ((state: Toolbar.Button.State) => string | undefined)-CSS class applied to the element, or a function that returns a class based on the component’s state.
styleCSSProperties | ((state: Toolbar.Button.State) => CSSProperties | undefined)--
renderReactElement | ((props: HTMLProps, state: Toolbar.Button.State) => ReactElement)-Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.

Button Data Attributes:

AttributeTypeDescription
data-orientation'horizontal' | 'vertical'Indicates the orientation of the toolbar.
data-disabled-Present when the button is disabled.
data-focusable-Present when the button remains focusable when disabled.

A link component. Renders an <a> element.

Link Props:

PropTypeDefaultDescription
classNamestring | ((state: Toolbar.Link.State) => string | undefined)-CSS class applied to the element, or a function that returns a class based on the component’s state.
styleCSSProperties | ((state: Toolbar.Link.State) => CSSProperties | undefined)--
renderReactElement | ((props: HTMLProps, state: Toolbar.Link.State) => ReactElement)-Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.

Link Data Attributes:

AttributeTypeDescription
data-orientation'horizontal' | 'vertical'Indicates the orientation of the toolbar.

Input

A native input element that integrates with Toolbar keyboard navigation. Renders an <input> element.

Input Props:

PropTypeDefaultDescription
defaultValuestring | number | string[]--
focusableWhenDisabledbooleantrueWhen true the item remains focuseable when disabled.
disabledbooleanfalseWhen true the item is disabled.
classNamestring | ((state: Toolbar.Input.State) => string | undefined)-CSS class applied to the element, or a function that returns a class based on the component’s state.
styleCSSProperties | ((state: Toolbar.Input.State) => CSSProperties | undefined)-*
renderReactElement | ((props: HTMLProps, state: Toolbar.Input.State) => ReactElement)-Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.

Input Data Attributes:

AttributeTypeDescription
data-orientation'horizontal' | 'vertical'Indicates the orientation of the toolbar.
data-disabled-Present when the input is disabled.
data-focusable-Present when the input remains focusable when disabled.

Group

Groups several toolbar items or toggles. Renders a <div> element.

Group Props:

PropTypeDefaultDescription
disabledbooleanfalseWhen true all toolbar items in the group are disabled.
classNamestring | ((state: Toolbar.Root.State) => string | undefined)-CSS class applied to the element, or a function that returns a class based on the component’s state.
styleCSSProperties | ((state: Toolbar.Root.State) => CSSProperties | undefined)--
renderReactElement | ((props: HTMLProps, state: Toolbar.Root.State) => ReactElement)-Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.

Group Data Attributes:

AttributeTypeDescription
data-orientation'horizontal' | 'vertical'Indicates the orientation of the toolbar.
data-disabled-Present when the group is disabled.

Separator

A separator element accessible to screen readers. Renders a <div> element.

Separator Props:

PropTypeDefaultDescription
orientationOrientation'horizontal'The orientation of the separator.
classNamestring | ((state: SeparatorState) => string | undefined)-CSS class applied to the element, or a function that returns a class based on the component’s state.
styleCSSProperties | ((state: SeparatorState) => CSSProperties | undefined)--
renderReactElement | ((props: HTMLProps, state: SeparatorState) => ReactElement)-Allows you to replace the component’s HTML element with a different tag, or compose it with another component.Accepts a ReactElement or a function that returns the element to render.

Separator Data Attributes:

AttributeTypeDescription
data-orientation'horizontal' | 'vertical'Indicates the orientation of the toolbar.

On this page