Raft Design System

Components · Overlays

TextSelectionToolbar

The toolbar that floats over text someone selects, with actions on that text such as Quote, Copy and Comment, in a message, an Artifact or any other readable text.

StableAlso called Text selection toolbar, Selected text toolbar
import { TextSelectionToolbar } from "@botiverse/raft-ui";

TextSelectionToolbar floats over text the person selects, with actions on that text such as Quote, Copy and Comment. It is the same toolbar wherever text can be selected: in a message, in an Artifact, in any other text people read.

text-selection-toolbar/text-selection-toolbar

When to use

SituationUse
Actions on text the person selectedTextSelectionToolbar
Actions on a message under the pointerThe message's hover toolbar (MessageItem)
Actions on several selected messages or tasksSelectionToolbar
A list of choices that opens from a controlDropdownMenu

Anatomy

  • TextSelectionToolbar: the floating frame. Required.
  • TextSelectionToolbarButton: one action, an icon and a label.
  • TextSelectionToolbarSeparator: a line between groups of actions.
  • createTextSelectionAnchor(selection): the anchor that places the toolbar on the selected text, for PopoverContent's anchor.

Look

It is built like a message's hover toolbar, so the two read as one kind of thing. The one difference is that its buttons have text labels, where the hover toolbar's are icons alone:

  • It is 36px high on a touch screen, around 28px buttons with radius-chip, and 42px with a mouse, around buttons at the control height (34px) with radius-control (stdrc, 2026-11-05): radius-container with its hairline drawn inside (ring-inset), the buttons 4px from the frame and 4px apart.
  • Its buttons have text labels after 16px icons in foreground-muted. On hover they take the medium tier, fill-medium, not the brand-soft of a menu row: a toolbar's actions are buttons, not menu rows (States).
  • TextSelectionToolbarSeparator is 20px high, with the toolbar's 4px on each side.

Behavior

  • It anchors to the line where the selection's focus end is, where the person let go, not to the whole range: a whole-line or multi-paragraph selection spans the text column, and the middle of that is nowhere near the pointer. Build the anchor with createTextSelectionAnchor(selection) and pass it to PopoverContent's anchor; it measures the line each time it is read, so the toolbar follows the text when it scrolls.
  • It stays inside the viewport: above the line by default, it flips below when there is no room and shifts along the line near a side edge.

Content

  • Write labels in sentence case. They never wrap: Chinese text can break between any two characters, so a toolbar squeezed at the edge of the window broke a two-character label onto two lines.

Accessibility

  • TextSelectionToolbar wraps Base UI Toolbar; give it an aria-label. Its buttons are Base UI toolbar buttons: the arrow keys move between them.

API

TextSelectionToolbar

The toolbar that floats over selected text, with actions such as Quote, Copy and Comment: in a message, in an Artifact, anywhere text can be selected. Place it with `createTextSelectionAnchor` in a Popover.
PropTypeDefault
disabledboolean
loopFocusIf `true`, using keyboard navigation will wrap focus to the other end of the toolbar once the end is reached.booleantrue
orientationThe orientation of the toolbar.BaseToolbar.Orientation'horizontal'
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

TextSelectionToolbarButton

One action on the selected text: a 28px button with a 16px icon and a sentence-case label that never wraps.
PropTypeDefault
disabledWhen `true` the item is disabled.booleanfalse
focusableWhenDisabledWhen `true` the item remains focusable when disabled.booleantrue
nativeButtonWhether 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 (for example, `<div>`).booleantrue
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

TextSelectionToolbarSeparator

A 20px line between groups of actions in the toolbar.
PropTypeDefault
orientationThe orientation of the separator. Defaults to the opposite of the toolbar's orientation, so a horizontal toolbar renders vertical separators.BaseToolbar.Orientation'horizontal'
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

Changes

  • 0.52.0 · AddedTextSelectionToolbar (+ TextSelectionToolbarButton, TextSelectionToolbarSeparator, createTextSelectionAnchor): the generic name for the toolbar on selected text. The MessageTextSelectionToolbar* names stay as deprecated aliases.