Toolbar

The toolbar is not a single component. Toolbar is a container, and each control group is its own plugin that you place inside it. Add a line to add a control, delete a line to remove it, and move lines to reorder.

Usage

Place Toolbar above the content area and inside the same editor composition, because the plugins read the editor from context. Use ToolbarSeparator between groups.

import { HistoryToolbarPlugin } from "@/components/editor/plugins/toolbar/history-toolbar-plugin"
import { TextFormatToolbarPlugin } from "@/components/editor/plugins/toolbar/text-format-toolbar-plugin"
import { Toolbar } from "@/components/editor/plugins/toolbar/toolbar-plugin"
import { ToolbarSeparator } from "@/components/ui/toolbar"

<Toolbar>
  <HistoryToolbarPlugin />
  <ToolbarSeparator />
  <TextFormatToolbarPlugin />
</Toolbar>

Available plugins

All plugins live in src/components/editor/plugins/toolbar/. Each links to the pattern that shows it working.

PluginWhat it rendersPattern
HistoryToolbarPluginUndo and redoHistory
BlockFormatToolbarPluginParagraph, headings, lists and quote selectorBlock format
FontFamilyToolbarPluginFont family selectorFont
FontSizeToolbarPluginFont size stepperFont
ColorToolbarPluginText and background color pickersColor
TextFormatToolbarPluginBold, italic, underline and moreText format
LinkToolbarPluginLink toggleLink
ElementFormatToolbarPluginText alignmentAlignment and indent
IndentToolbarPluginIndent and outdentAlignment and indent
ClearToolbarPluginClear formatting and clear editorClear
ImportExportToolbarPluginImport a file, export as JSON, Markdown or HTMLImport and export
BlockInsertInsert menu for code blocks, columns, emoji, dividers, images and tablesInsert block menu

Behavior

  • The plugins show the state of the current selection: toggles are pressed when the format is active, and the selectors show the current block type, font and size.
  • Every control has a tooltip and an aria-label.
  • Controls are disabled when the editor is in read-only mode.
  • Toolbar is built on the React Aria Toolbar, so it is a single tab stop and arrow keys move between controls.
  • TextFormatToolbarPlugin and LinkToolbarPlugin are also used inside the floating toolbar, which shows them next to the selection.

Scrolling

The toolbar stays on one row and scrolls horizontally when it is too narrow. A chevron button, styled like the other toolbar buttons, appears at the edge that has hidden controls, over a soft fade. Click a chevron to scroll by most of the width, use the mouse wheel, touch or a trackpad, or tab through the controls and the focused one scrolls into view clear of the buttons.

Styling

Toolbar wraps the Intent UI toolbar in a relative container that holds the two scroll buttons and their fades. It adds aria-label="Formatting" and these classes on top of src/components/ui/toolbar.tsx: w-full flex-nowrap gap-1 overflow-x-auto overscroll-x-contain scroll-px-14 rounded-none border-b border-border bg-background p-1.5 *:shrink-0. It accepts the same props as the underlying toolbar plus className, which is merged after the defaults.

<Toolbar className="bg-muted" aria-label="Text tools">
  <TextFormatToolbarPlugin />
</Toolbar>

Colors come from the background, border, muted and primary tokens, see Theming.