toolbar

Toolbar

Action row for tools, filters, and controls.

Toolbar Examples

Copy-ready examples for a presentational action toolbar built with Button children.

Basic usage

Floating toolbar with an extra floating action button slot (scoped to the preview box).

Children must be Button elements.

Use `data-main` on a child Button to mark the main item wrapper.

Use `forceWidth` / `forceHeight` on Buttons to keep icon-only items symmetric.

Live preview

Preview scope (fixed stays inside this box)
Content
The toolbar is positioned using fixed layout, but it is scoped to this preview container so it won't overlap other docs content.

Floating (vibrant) + symmetric buttons

"use client";

import Toolbar from "@/packages/ui/src/_components/toolbar/Toolbar";
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
import Icon from "@/packages/ui/src/_components/icon/Icon";

export default function Example() {
  return (
    <div style={{ position: "relative", transform: "translateZ(0)", height: 320, overflow: "hidden" }}>
      <Toolbar
        style="floating"
        isVibrant
        extraButtonFloating={
          <Button
            variant="primary"
            ripple
            forceWidth="54px"
            forceHeight="54px"
            iconContent={<Icon name="add" />}
          />
        }
      >
        <Button variant="transparent" ripple forceWidth="40px" forceHeight="40px" iconContent={<Icon name="menu" />} />
        <Button data-main ripple forceWidth="40px" forceHeight="40px" iconContent={<Icon name="edit" />} />
        <Button variant="transparent" ripple forceWidth="40px" forceHeight="40px" iconContent={<Icon name="format_bold" />} />
      </Toolbar>
    </div>
  );
}

Docked style

Use `style="docked"` to place the extra button in a separate FAB slot.

Live preview

Docked style ("extraButtonFloating" becomes a FAB slot)
Use data-main on a child Button to mark the main item wrapper.

Docked + extraButtonFloating

import Toolbar from "@/packages/ui/src/_components/toolbar/Toolbar";
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
import Icon from "@/packages/ui/src/_components/icon/Icon";

export default function Example() {
  return (
    <div style={{ position: "relative", transform: "translateZ(0)", height: 320, overflow: "hidden" }}>
      <Toolbar
        style="docked"
        extraButtonFloating={
          <Button variant="info" ripple forceWidth="54px" forceHeight="54px" iconContent={<Icon name="add" />} />
        }
      >
        <Button variant="transparent" ripple forceWidth="40px" forceHeight="40px" iconContent={<Icon name="menu" />} />
        <Button variant="transparent" ripple forceWidth="40px" forceHeight="40px" iconContent={<Icon name="format_bold" />} />
        <Button data-main ripple forceWidth="40px" forceHeight="40px" iconContent={<Icon name="edit" />} />
      </Toolbar>
    </div>
  );
}

Vertical toolbar

Use `isVertical` to treat the toolbar as vertical (layout/shell changes).

Live preview

Vertical toolbar

Floating vertical

import Toolbar from "@/packages/ui/src/_components/toolbar/Toolbar";
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
import Icon from "@/packages/ui/src/_components/icon/Icon";

export default function Example() {
  return (
    <div style={{ position: "relative", transform: "translateZ(0)", height: 320, overflow: "hidden" }}>
      <Toolbar
        style="floating"
        isVertical
        isVibrant
        extraButtonFloating={<Button variant="primary" ripple forceWidth="54px" forceHeight="54px" iconContent={<Icon name="add" />} />}
      >
        <Button variant="transparent" ripple forceWidth="40px" forceHeight="40px" iconContent={<Icon name="menu" />} />
        <Button data-main ripple forceWidth="40px" forceHeight="40px" iconContent={<Icon name="edit" />} />
        <Button variant="transparent" ripple forceWidth="40px" forceHeight="40px" iconContent={<Icon name="format_bold" />} />
      </Toolbar>
    </div>
  );
}

Floating collapsed

Control compact mode using `isFloatingCollapsed`.

Live preview

Toggle isFloatingCollapsed (scoped to preview container).
Notes
Buttons use forceWidth and forceHeight for consistent geometry.

Collapse toggle (safe)

"use client";

import React from "react";
import Toolbar from "@/packages/ui/src/_components/toolbar/Toolbar";
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
import Icon from "@/packages/ui/src/_components/icon/Icon";

function SafePress(props: { onPress: () => void; children: React.ReactNode }) {
  return (
    <span
      style={{ display: "inline-flex" }}
      onClickCapture={(e) => {
        e.preventDefault();
        e.stopPropagation();
        props.onPress();
      }}
    >
      {props.children}
    </span>
  );
}

export default function Example() {
  const [collapsed, setCollapsed] = React.useState(false);

  return (
    <>
      <SafePress onPress={() => setCollapsed((v) => !v)}>
        <Button variant="secondary" ripple outline>
          Collapsed: {String(collapsed)}
        </Button>
      </SafePress>

      <div style={{ position: "relative", transform: "translateZ(0)", height: 340, overflow: "hidden" }}>
        <Toolbar
          style="floating"
          isVibrant
          isFloatingCollapsed={collapsed}
          extraButtonFloating={<Button variant="primary" ripple forceWidth="54px" forceHeight="54px" iconContent={<Icon name="add" />} />}
        >
          <Button variant="transparent" ripple forceWidth="40px" forceHeight="40px" iconContent={<Icon name="menu" />} />
          <Button data-main ripple forceWidth="40px" forceHeight="40px" iconContent={<Icon name="edit" />} />
          <Button variant="transparent" ripple forceWidth="40px" forceHeight="40px" iconContent={<Icon name="format_bold" />} />
        </Toolbar>
      </div>
    </>
  );
}

Scroll test (scoped fixed)

Use a scrollable preview container to validate that the floating toolbar stays fixed inside the preview, not the whole page.

Live preview

Scroll inside the preview box and the toolbar remains fixed inside it.
Scroll container (scoped fixed)
Card #1
Dummy content to validate how a scoped fixed toolbar behaves while scrolling.
Card #2
Dummy content to validate how a scoped fixed toolbar behaves while scrolling.
Card #3
Dummy content to validate how a scoped fixed toolbar behaves while scrolling.
Card #4
Dummy content to validate how a scoped fixed toolbar behaves while scrolling.
Card #5
Dummy content to validate how a scoped fixed toolbar behaves while scrolling.
Card #6
Dummy content to validate how a scoped fixed toolbar behaves while scrolling.
Card #7
Dummy content to validate how a scoped fixed toolbar behaves while scrolling.
Card #8
Dummy content to validate how a scoped fixed toolbar behaves while scrolling.
Card #9
Dummy content to validate how a scoped fixed toolbar behaves while scrolling.
Card #10
Dummy content to validate how a scoped fixed toolbar behaves while scrolling.

Scoped fixed toolbar inside a scroll container

"use client";

import React from "react";
import Toolbar from "@/packages/ui/src/_components/toolbar/Toolbar";
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";
import Icon from "@/packages/ui/src/_components/icon/Icon";

export default function Example() {
  const [collapsed, setCollapsed] = React.useState(false);

  return (
    <div style={{ position: "relative", transform: "translateZ(0)", height: 420, overflow: "auto", borderRadius: 16 }}>
      <Button variant="secondary" ripple outline onClick={() => setCollapsed((v) => !v)}>
        Collapsed: {String(collapsed)}
      </Button>

      <div style={{ display: "grid", gap: 12, padding: 12 }}>
        {Array.from({ length: 10 }).map((_, i) => (
          <div key={i} style={{ padding: 16, borderRadius: 16, border: "1px solid rgba(0,0,0,0.12)" }}>
            Card #{i + 1}
          </div>
        ))}
      </div>

      <Toolbar
        style="floating"
        isVibrant
        isFloatingCollapsed={collapsed}
        extraButtonFloating={<Button variant="primary" ripple forceWidth="54px" forceHeight="54px" iconContent={<Icon name="add" />} />}
      >
        <Button variant="transparent" ripple forceWidth="40px" forceHeight="40px" iconContent={<Icon name="menu" />} />
        <Button data-main ripple forceWidth="40px" forceHeight="40px" iconContent={<Icon name="edit" />} />
        <Button variant="transparent" ripple forceWidth="40px" forceHeight="40px" iconContent={<Icon name="format_bold" />} />
      </Toolbar>
    </div>
  );
}

On this page

Toolbar Props

Toolbar — Props
PropTypeRequiredDefaultDescription
childrenReact.ReactElement[]YesToolbar items. Intended to be `Button` elements.
style"floating" | "docked"No"floating"Layout mode. In `floating`, the extra button is placed in an auxiliary slot. In `docked`, it becomes a separate FAB slot.
extraButtonFloatingReact.ReactElementNoOptional extra action button (usually a FAB). Placement depends on `style` (floating vs docked).
isVerticalbooleanNofalseTreats the toolbar as vertical (affects shell layout).
isVibrantbooleanNofalseAdds a vibrant visual treatment class.
isFloatingCollapsedbooleanNofalseCollapsed visual state for floating toolbars (compact mode).