Skip to content
ResearchSelection toolbarMenu

Selection toolbar

A floating toolbar over selected text with Ask, Rewrite, Explain and Copy. Ask turns it into a question field.

Select text to Ask, Rewrite, Explain or Copy. Ask turns the toolbar into a question field.

Installation

$ pnpm dlx shadcn@latest add https://chatcn.dev/r/selection-toolbar.json

Usage

tsx
import { SelectionToolbar } from "@/components/ui/chatcn/selection-toolbar"

const ref = React.useRef<HTMLDivElement>(null)

<div ref={ref}>{answer}</div>
<SelectionToolbar
  target={ref}
  onAsk={(question, selection) => ask(question, selection.text)}
  onAction={(action, selection) => run(action, selection.text)}
/>

It works on any text: answers, reports or an editor. Placement is measured from the selection, centered above it and flipped below near the top of the viewport. While the Ask field has focus, the selection stays painted with the CSS Custom Highlight API.

Props

PropTypeNotes
targetRefObject<HTMLElement>Selections inside it get the toolbar
actionsSelectionToolbarAction[]{ id, label, icon? }. Defaults to Ask, Rewrite, Explain, Copy
onAsk(question, selection) => voidTurns ask into a question field
onAction(action, selection) => voidEvery other action
askPlaceholderstringDefault Ask about this…
minLengthnumberIgnore shorter selections. Default 2
disabledboolean

The useChatcnCanvasSelection(ref) hook underneath returns the selection's text, range, rect and source, with dismiss, setFrozen and restore, for building your own floating UI.

Keyboard

KeyAction
Shift plus arrowsSelect text. The toolbar shows instantly and follows
TabMove from the text into the toolbar
ArrowLeft, ArrowRight, Home, EndMove between actions
Esc, Tab in the toolbarBack to the text with the selection restored
Enter in the Ask fieldAsk. Ignored during IME composition

Accessibility

  • A toolbar with roving focus: one tab stop, arrow keys inside.
  • Keyboard selections announce that actions are available with Tab. Copy announces Copied.
  • Buttons keep the text selection alive by not taking it on mouse down.

Motion

  • After a pointer selection the toolbar comes in over 150 ms: opacity plus 4 px toward the text. It leaves over 110 ms.
  • Keyboard selections show and move it with no animation. Reduced motion keeps only the fade.