BubbleMenu extension
This extension will make a contextual menu appear near a selection of text. Use it to let users apply marks to their text selection.
As always, the markup and styling is totally up to you.
Install
npm install @tiptap/extension-bubble-menu
Settings
element
The DOM element that contains your menu.
Type: HTMLElement
Default: null
updateDelay
The BubbleMenu
debounces the update
method to allow the bubble menu to not be updated on every selection update. This can be controlled in milliseconds.
The BubbleMenuPlugin will come with a default delay of 250ms. This can be deactivated, by setting the delay to 0
which deactivates the debounce.
Type: Number
Default: undefined
resizeDelay
The BubbleMenu
debounces the resize calculation for the bubble menu to allow the bubble menu to not be updated on every resize event. This can be controlled in milliseconds.
Type: Number
Default: 100
options
Under the hood, the BubbleMenu
Floating UI. You can control the middleware and positioning of the floating menu with these options.
Type: Object
Default: { strategy: 'absolute', placement: 'right' }
Option | Type | Description |
---|---|---|
strategy | string | The positioning strategy. See here |
placement | string | The placement of the menu. See here |
offset | OffsetOptions or boolean | The offset middleware options. If true use default options, if false disable the middleware |
flip | FlipOptions or boolean | The flip middleware options. If true use default options, if false disable the middleware |
shift | ShiftOptions or boolean | The shift middleware options. If true use default options, if false disable the middleware |
arrow | ArrowOptions or false | The arrow middleware options. If false disable the middleware |
size | SizeOptions or boolean | The size middleware options. If true use default options, if false disable the middleware |
autoPlacement | AutoPlacementOptions or boolean | The autoPlacement middleware options. If true use default options, if false disable the middleware |
hide | HideOptions or boolean | The hide middleware options. If true use default options, if false disable the middleware |
inline | InlineOptions or boolean | The inline middleware options. If true use default options, if false disable the middleware |
onShow | Function or undefined | A callback that is called when the menu is shown. This can be used to add custom logic or styles when the menu is displayed. |
onHide | Function or undefined | A callback that is called when the menu is hidden. This can be used to add custom logic or styles when the menu is hidden. |
onUpdate | Function or undefined | A callback that is called when the menu is updated. This can be used to add custom logic or styles when the menu is updated. |
onDestroy | Function or undefined | A callback that is called when the menu is destroyed. This can be used to add custom logic or styles when the menu is removed. |
pluginKey
The key for the underlying ProseMirror plugin. Make sure to use different keys if you add more than one instance.
Type: string | PluginKey
Default: 'bubbleMenu'
shouldShow
A callback to control whether the menu should be shown or not.
Type: (props) => boolean
Source code
packages/extension-bubble-menu/
Use the extension
JavaScript
import { Editor } from '@tiptap/core'
import BubbleMenu from '@tiptap/extension-bubble-menu'
new Editor({
extensions: [
BubbleMenu.configure({
element: document.querySelector('.menu'),
}),
],
})
Other frameworks
Check out the demo at the top of this page to see how to integrate the bubble menu extension with React or Vue.
Custom logic
Customize the logic for showing the menu with the shouldShow
option. For components, shouldShow
can be passed as a prop.
BubbleMenu.configure({
shouldShow: ({ editor, view, state, oldState, from, to }) => {
// only show the bubble menu for images and links
return editor.isActive('image') || editor.isActive('link')
},
})
Multiple menus
Use multiple menus by setting an unique pluginKey
.
import { Editor } from '@tiptap/core'
import BubbleMenu from '@tiptap/extension-bubble-menu'
new Editor({
extensions: [
BubbleMenu.configure({
pluginKey: 'bubbleMenuOne',
element: document.querySelector('.menu-one'),
}),
BubbleMenu.configure({
pluginKey: 'bubbleMenuTwo',
element: document.querySelector('.menu-two'),
}),
],
})
Alternatively you can pass a ProseMirror PluginKey
.
import { Editor } from '@tiptap/core'
import BubbleMenu from '@tiptap/extension-bubble-menu'
import { PluginKey } from '@tiptap/pm/state'
new Editor({
extensions: [
BubbleMenu.configure({
pluginKey: new PluginKey('bubbleMenuOne'),
element: document.querySelector('.menu-one'),
}),
BubbleMenu.configure({
pluginKey: new PluginKey('bubbleMenuTwo'),
element: document.querySelector('.menu-two'),
}),
],
})