Toolbar

Toolbar is the canonical control strip for editor chrome, inspector headers, and dense app-shell layouts — the place to line up formatting toggles, view switchers, action buttons, and shortcuts without each one re-declaring its own size, shape, and surface treatment. The toolbar acts as a Surface container and a context provider in one: size, rounded, variant, and outline set on the toolbar are forwarded to every ToolbarButton inside, so a row of buttons stays coherent with a single prop on the parent.

This page covers Toolbar together with its children, ToolbarButton and ToolbarSeparator. Segmented is designed to nest inside Toolbar as well — see the Segmented example below.

<ExampleToolbar>
  <Tooltip tooltip="Bold">
    <ToolbarButton
      color={marks.bold ? 'brand' : undefined}
      variant={marks.bold ? 'gradient' : 'transparent'}
      outline={marks.bold}
      onClick={() => toggle('bold')}
      aria-label="Bold"
    >
      <BoldIcon />
    </ToolbarButton>
  </Tooltip>
  <Tooltip tooltip="Italic">
    <ToolbarButton
      color={marks.italic ? 'brand' : undefined}
      variant={marks.italic ? 'gradient' : 'transparent'}
      outline={marks.italic}
      onClick={() => toggle('italic')}
      aria-label="Italic"
    >
      <ItalicIcon />
    </ToolbarButton>
  </Tooltip>
  <Tooltip tooltip="Underline">
    <ToolbarButton
      color={marks.underline ? 'brand' : undefined}
      variant={marks.underline ? 'gradient' : 'transparent'}
      outline={marks.underline}
      onClick={() => toggle('underline')}
      aria-label="Underline"
    >
      <UnderlineIcon />
    </ToolbarButton>
  </Tooltip>
  <ToolbarSeparator />
  <Segmented>
    {ALIGNMENTS.map((a) => {
      const Icon = ALIGNMENT_ICONS[a];
      return (
        <SegmentedButton
          key={a}
          active={a === align}
          onClick={() => setAlign(a)}
          aria-label={a}
        >
          <Icon />
        </SegmentedButton>
      );
    })}
  </Segmented>
  <ToolbarSeparator />
  <ToolbarButton variant="gradient" color="green">
    <CheckIcon />
    Publish
  </ToolbarButton>
</ExampleToolbar>

Usage

import { Toolbar, ToolbarButton, ToolbarSeparator } from '@cladd-ui/react';
 
<Toolbar>
  <ToolbarButton>
    <BoldIcon />
  </ToolbarButton>
  <ToolbarButton>
    <ItalicIcon />
  </ToolbarButton>
  <ToolbarSeparator />
  <ToolbarButton>Publish</ToolbarButton>
</Toolbar>;

Toolbar renders a pill-shaped gradient Surface with an outline ring by default — the standard floating-toolbar look. It lays out children in a horizontal flex row with consistent padding.

ToolbarButton is the same as Button — it accepts the full Button API — except that size, rounded, variant, and outline default to values read from the surrounding toolbar context. The defaults are tuned to the typical app-toolbar look: transparent variant, no outline, so buttons fade into the toolbar surface until hovered, and the active/focused one reads as the real control. Pass any of those props explicitly on a ToolbarButton to override per slot.

ToolbarSeparator is a thin vertical rule for grouping items — it has no props beyond className and children.

Examples

Sizes

size accepts the standard 2xs → 2xl scale. The value is forwarded to every ToolbarButton (and any nested Segmented) through context, so you set the rhythm of the whole toolbar with a single prop on the parent. Use 2xsxs for inspector panels, smmd for editor toolbars, lg+ for prominent action bars.

<Toolbar size="md">
  <ToolbarButton>
    <BoldIcon />
  </ToolbarButton>
  <ToolbarButton>
    <ItalicIcon />
  </ToolbarButton>
  <ToolbarButton>
    <UnderlineIcon />
  </ToolbarButton>
  <ToolbarSeparator />
  <ToolbarButton>Publish</ToolbarButton>
</Toolbar>

Container variant

variant picks the surface treatment of the toolbar shell itself — 'gradient' (default) and 'solid' read as a real floating toolbar; 'transparent' makes the toolbar dissolve into its parent so only the buttons remain; the *-fill variants tint the shell with the accent color. Pair with outline and color to dial in exactly how loud the housing reads.

When you switch the shell to 'solid-fill' or 'gradient-fill', set buttonVariant to the matching fill so the children inherit the same colored surface. Otherwise the default 'transparent' buttons sit on top of the filled shell with no contrast and the labels become unreadable. The example below derives buttonVariant from variant automatically.

<Toolbar variant="gradient" buttonVariant="transparent">
  <ToolbarButton>
    <BoldIcon />
  </ToolbarButton>
  <ToolbarButton>
    <ItalicIcon />
  </ToolbarButton>
  <ToolbarButton>
    <UnderlineIcon />
  </ToolbarButton>
</Toolbar>

Outline

outline toggles the ring around the toolbar shell. With outline on (default), the toolbar reads as a self-contained pill — the typical look for a floating editor toolbar. Without outline, the shell relies on its fill alone, which works well when the toolbar is already inside a contrasting Surface and an extra ring would be noise.

<Toolbar outline>
  <ToolbarButton>
    <BoldIcon />
  </ToolbarButton>
  <ToolbarButton>
    <ItalicIcon />
  </ToolbarButton>
  <ToolbarButton>
    <UnderlineIcon />
  </ToolbarButton>
</Toolbar>

Colors

color sets the accent token applied to the toolbar (cladd-color-{name}). On its own it doesn't change much — the default toolbar shell is mostly neutral — but it tints anything inside that uses the accent: any ToolbarButton with variant="gradient"/"solid-fill"/"gradient-fill", accent rings on outlined buttons, and the active segment of a nested Segmented. Treat it as the toolbar's accent context, not its main fill.

<Toolbar color="brand">
  <ToolbarButton>
    <BoldIcon />
  </ToolbarButton>
  <ToolbarButton>
    <ItalicIcon />
  </ToolbarButton>
  <ToolbarButton>
    <UnderlineIcon />
  </ToolbarButton>
  <ToolbarSeparator />
  <ToolbarButton variant="gradient">
    <CheckIcon />
    Publish
  </ToolbarButton>
</Toolbar>

Rounded

rounded controls the shell's corner shape — pill (true, default) or the size-specific radius. The same flag is forwarded to child ToolbarButtons through context so the buttons' corners follow the shell. Pill is right for floating toolbars; the size-radius look pairs well with toolbars docked inside a panel header that already has square-ish corners.

<Toolbar rounded>
  <ToolbarButton>
    <BoldIcon />
  </ToolbarButton>
  <ToolbarButton>
    <ItalicIcon />
  </ToolbarButton>
  <ToolbarButton>
    <UnderlineIcon />
  </ToolbarButton>
  <ToolbarSeparator />
  <ToolbarButton>Publish</ToolbarButton>
</Toolbar>

Button style

buttonVariant and buttonOutline control the look of every ToolbarButton inside, via context. The defaults ('transparent', no outline) make buttons fade into the toolbar surface until hovered — the typical app-toolbar feel. Switch to 'solid' if you want every slot to read as a discrete button (handy when the toolbar is also acting as a key/legend); add buttonOutline for sharp ringed buttons.

<Toolbar buttonVariant="transparent" buttonOutline={false}>
  <ToolbarButton>
    <BoldIcon />
  </ToolbarButton>
  <ToolbarButton>
    <ItalicIcon />
  </ToolbarButton>
  <ToolbarButton>
    <UnderlineIcon />
  </ToolbarButton>
</Toolbar>

Per-button override

Anything set on a ToolbarButton directly wins over the toolbar's context defaults. Use this for one-off emphasis — a primary "Publish" with variant="gradient" color="brand", a destructive "Discard" with variant="solid" color="red" — without disturbing the muted look of the surrounding buttons.

<Toolbar>
  <ToolbarButton>
    <BoldIcon />
  </ToolbarButton>
  <ToolbarButton>
    <ItalicIcon />
  </ToolbarButton>
  <ToolbarButton>
    <UnderlineIcon />
  </ToolbarButton>
  <ToolbarSeparator />
  <ToolbarButton color="red" variant="solid">
    Discard
  </ToolbarButton>
  <ToolbarButton color="brand" variant="gradient">
    <CheckIcon />
    Publish
  </ToolbarButton>
</Toolbar>

With separator

ToolbarSeparator is a 1px vertical rule used to group items inside a toolbar — formatting on one side, alignment on the other; navigation on one side, actions on the other. It's the simplest piece in the trio: no props beyond className, no behavior, just a thin line that picks up the toolbar's outline color.

<Toolbar>
  <ToolbarButton>
    <BoldIcon />
  </ToolbarButton>
  <ToolbarButton>
    <ItalicIcon />
  </ToolbarButton>
  <ToolbarButton>
    <UnderlineIcon />
  </ToolbarButton>
  <ToolbarSeparator />
  <ToolbarButton>
    <AlignLeftIcon />
  </ToolbarButton>
  <ToolbarButton>
    <AlignCenterIcon />
  </ToolbarButton>
  <ToolbarButton>
    <AlignRightIcon />
  </ToolbarButton>
</Toolbar>

With Segmented

Segmented is designed to drop straight into a Toolbar. It reads the toolbar's size, rounded, and color from context, so a view switcher or alignment picker stays in sync with the surrounding controls without any extra prop wiring. Pair ToolbarButtons for stateless actions with Segmented for single-select state — that's the canonical editor-toolbar shape.

<Toolbar>
  <ToolbarButton>
    <BoldIcon />
  </ToolbarButton>
  <ToolbarButton>
    <ItalicIcon />
  </ToolbarButton>
  <ToolbarButton>
    <UnderlineIcon />
  </ToolbarButton>
  <ToolbarSeparator />
  <Segmented>
    {ALIGNMENTS.map((a) => {
      const Icon = ALIGNMENT_ICONS[a];
      return (
        <SegmentedButton
          key={a}
          active={a === align}
          onClick={() => setAlign(a)}
          aria-label={a}
        >
          <Icon />
        </SegmentedButton>
      );
    })}
  </Segmented>
</Toolbar>

Playground

The toolbar exposes two parallel sets of style props — one for the shell (variant, outline, color), one for the children (buttonVariant, buttonOutline) — plus the shared layout knobs (size, rounded). They compose freely; the playground below combines them all.

container
buttons
<Toolbar
  variant="gradient"
  color="neutral"
  size="md"
  outline
  rounded
  buttonVariant="transparent"
  buttonOutline={false}
>
  <ToolbarButton>
    <BoldIcon />
  </ToolbarButton>
  <ToolbarButton>
    <ItalicIcon />
  </ToolbarButton>
  <ToolbarButton>
    <UnderlineIcon />
  </ToolbarButton>
  <ToolbarSeparator />
  <ToolbarButton>Publish</ToolbarButton>
</Toolbar>

API Reference

Toolbar

C extends ElementType = 'div'/Inherits from SurfaceProps
as: ElementType'div'Polymorphic root element. Defaults to 'div'.
buttonOutline: booleanfalseOutline ring on child ToolbarButtons. Default false.
buttonVariant: SurfaceVariant'transparent'Surface variant applied to child ToolbarButtons through context.

Default 'transparent' - buttons fade into the toolbar surface until hovered.
children: ReactNodeToolbar items - typically ToolbarButton and ToolbarSeparator.
className: stringExtra classes for the toolbar surface root.
color: ColorAccent color token. Sets the toolbar's cladd-color-{name} class.
contentClassName: stringExtra classes for the inner SurfaceContent wrapper (where toolbar items are laid out).
outline: booleantrueOutline ring on the toolbar container. Default true.
rounded: booleantruePill-shape the toolbar container (rounded-full). Default true.

Also forwarded via context as the default rounded for child ToolbarButtons.
size: ButtonSize'md'Toolbar button size. Default 'md'. Forwarded via context to child ToolbarButtons.
surfaceLevel: number | stringForwarded to the underlying Surface as level - see SurfaceProps.level.
variant: SurfaceVariant'gradient'Surface variant for the toolbar container. Default 'gradient'.

ToolbarButton

C extends ElementType = 'button'/Inherits from ButtonProps
No own props — see inherited types above.

ToolbarSeparator

children: ReactNodeOptional content rendered inside the separator (rare - the separator is normally just a thin rule).
className: stringExtra classes for the separator element.