BubbleMenu
A floating toolbar that appears above selected text, powered by your extensions.
The BubbleMenu component renders a compact floating toolbar whenever the user selects text in the editor. Like Toolbar, it automatically reads from your registered extensions — only extensions that opt into surface.bubbleMenu are shown.
Import
import { BubbleMenu } from 'ritext';Usage
Place BubbleMenu anywhere inside <Editor>. No props are required.
import { Editor, Toolbar, Content, BubbleMenu } from 'ritext';
import { Bold, Italic, Underline, Color } from 'ritext/extension/...';
<Editor extensions={[Bold, Italic, Underline, Color]}>
<Toolbar />
<Content />
<BubbleMenu />
</Editor>Enabling Extensions in the Bubble Menu
By default, extensions only appear in the Toolbar. To also show an extension in the bubble menu, set surface.bubbleMenu: true in its configuration:
import { Bold } from 'ritext/extension/bold';
import { Italic } from 'ritext/extension/italic';
import { Color } from 'ritext/extension/color';
const extensions = [
Bold.configure({
surface: { toolbar: true, bubbleMenu: true },
}),
Italic.configure({
surface: { toolbar: true, bubbleMenu: true },
}),
Color.configure({
surface: { toolbar: false, bubbleMenu: true }, // only in bubble menu
}),
];Controlling Order
Use order.bubbleMenu to control the position of each extension in the bubble menu. Lower numbers appear first. Extensions without an explicit order fall back to the order of the extensions array.
Bold.configure({
surface: { toolbar: true, bubbleMenu: true },
order: { bubbleMenu: 1 },
}),
Italic.configure({
surface: { toolbar: true, bubbleMenu: true },
order: { bubbleMenu: 2 },
}),Surface Options
The surface option is available on every extension. It controls where the extension's button is rendered.
Prop
Type
Visibility Rules
The bubble menu is shown when:
- Text is selected (i.e.
from !== to) - The editor is focused
- The selection is not a node selection (e.g. a selected image)
- The active node is not an image (image has its own floating toolbar)
How It Works
Internally, BubbleMenu iterates over editor.extensionManager.extensions, filters those with surface.bubbleMenu === true, sorts them by order.bubbleMenu (then by extension array order as a tiebreaker), and renders each extension's component inside a floating container anchored above the selection.
BubbleMenu must be a child of <Editor>. It uses React context to access the editor instance.
