feat: Added showOnMouseUp option to bubble menu#7500
feat: Added showOnMouseUp option to bubble menu#7500
showOnMouseUp option to bubble menu#7500Conversation
🦋 Changeset detectedLatest commit: cada11f The changes in this PR will be included in the next version bump. This PR includes changesets to release 72 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
✅ Deploy Preview for tiptap-embed ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull request overview
This PR adds a new showOnMouseUp option to the BubbleMenu component that defers the menu display until the mouse button is released after text selection, similar to Notion's behavior. This prevents the menu from appearing and following the cursor during text selection.
Changes:
- Added
showOnMouseUpboolean option (default: false) to BubbleMenuPluginProps interface with comprehensive JSDoc documentation - Implemented mouse state tracking via event handlers in BubbleMenuView class to defer menu display while mouse is down
- Integrated the new option across all framework bindings (React, Vue 2, Vue 3) and the extension configuration
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/extension-bubble-menu/src/bubble-menu-plugin.ts | Core implementation: adds showOnMouseUp property, mouse event handlers, pending update logic, and cleanup |
| packages/extension-bubble-menu/src/bubble-menu.ts | Adds showOnMouseUp to extension default options |
| packages/react/src/menus/BubbleMenu.tsx | Adds showOnMouseUp prop with default value false to React BubbleMenu component |
| packages/vue-3/src/menus/BubbleMenu.ts | Adds showOnMouseUp prop with default value false to Vue 3 BubbleMenu component |
| packages/vue-2/src/menus/BubbleMenu.ts | Adds showOnMouseUp prop with default value false and to interface for Vue 2 BubbleMenu component |
@tiptap/extension-character-count
@tiptap/extension-dropcursor
@tiptap/extension-focus
@tiptap/extension-gapcursor
@tiptap/extension-history
@tiptap/extension-list-item
@tiptap/extension-list-keymap
@tiptap/extension-placeholder
@tiptap/extension-table-header
@tiptap/extension-table-cell
@tiptap/extension-table-row
@tiptap/extension-task-item
@tiptap/extension-task-list
@tiptap/core
@tiptap/extension-audio
@tiptap/extension-blockquote
@tiptap/extension-bubble-menu
@tiptap/extension-bold
@tiptap/extension-code
@tiptap/extension-code-block
@tiptap/extension-bullet-list
@tiptap/extension-collaboration
@tiptap/extension-code-block-lowlight
@tiptap/extension-collaboration-caret
@tiptap/extension-color
@tiptap/extension-details
@tiptap/extension-document
@tiptap/extension-drag-handle
@tiptap/extension-drag-handle-react
@tiptap/extension-drag-handle-vue-2
@tiptap/extension-emoji
@tiptap/extension-drag-handle-vue-3
@tiptap/extension-file-handler
@tiptap/extension-floating-menu
@tiptap/extension-font-family
@tiptap/extension-hard-break
@tiptap/extension-heading
@tiptap/extension-highlight
@tiptap/extension-image
@tiptap/extension-horizontal-rule
@tiptap/extension-invisible-characters
@tiptap/extension-italic
@tiptap/extension-link
@tiptap/extension-list
@tiptap/extension-mathematics
@tiptap/extension-node-range
@tiptap/extension-mention
@tiptap/extension-ordered-list
@tiptap/extension-paragraph
@tiptap/extension-strike
@tiptap/extension-subscript
@tiptap/extension-superscript
@tiptap/extension-table
@tiptap/extension-table-of-contents
@tiptap/extension-text
@tiptap/extension-text-style
@tiptap/extension-text-align
@tiptap/extension-twitch
@tiptap/extension-typography
@tiptap/extension-underline
@tiptap/extension-unique-id
@tiptap/extension-youtube
@tiptap/extensions
@tiptap/markdown
@tiptap/pm
@tiptap/starter-kit
@tiptap/react
@tiptap/suggestion
@tiptap/vue-2
@tiptap/static-renderer
@tiptap/vue-3
@tiptap/html
commit: |
bdbch
left a comment
There was a problem hiding this comment.
Not sure if I should approve or reject. Quick question:
- This is meant that while I select something, the Menu only opens after the selection is finished and my mouse is let go right? Should this also work with keyboard selections? In that case - maybe it's better to not handle mouse/keyboard events but build this logic around transactions that update the selection?
- Is this in conflict with
shouldShow
overall the code looks good to me, just want to make sure we build this the right way as I don't know where exactly the requirement came from.
| '@tiptap/extension-bubble-menu': minor | ||
| --- | ||
|
|
||
| Added `showOnMouseUp` option to bubble menu. This option allows the bubble menu to be displayed when the user releases the mouse button after a text selection, enhancing the user experience during text editing. |
There was a problem hiding this comment.
Is this conflicting with the Bubble Menu's shouldShow option? How do they work together?
There was a problem hiding this comment.
It shouldn’t conflict with shouldShow. The menu is shown only after the user releases the mouse (mouseup), and then it goes through shouldShow for validation.
There was a problem hiding this comment.
It does not handle keyboard selection, it only apply to mouse selection
There was a problem hiding this comment.
"maybe it's better to not handle mouse/keyboard events but build this logic around transactions that update the selection?" I am not sure about this one, since what user want is they dont want to see the floating before releasing the mouse (similiar to Notion)
There was a problem hiding this comment.
Yeah that would work - what we would need to do is onTransaction, check if the transaction changes the selection object - and if it does, we'd need to start a timeout / debounce that only resolves when no other transaction in X time occured again - and just then we "activate" the bubble menu so it can be shown. That would mean that it would work for all kind of interactions that change the selection.
There was a problem hiding this comment.
I see what you mean. The current showOnMouseUp works by deferring updates while the mouse is down, I can refactor it so the menu only shows on a commit selection transaction instead.
There was a problem hiding this comment.
Sorry Aslam, coming back to this. I'm not sure if I'd want this functionality on top of shouldShow. Don't you think this behavior is more an integration topic and should be handled by the dev implementing it?
shouldShow should be able to handle this just fine if the user tracks the mousedown state somewhere & checks for it in shouldShow.
There was a problem hiding this comment.
I have send them how they can achieve the same behaviour without adding this implementation to the core package. closing this PR
Changes Overview
Adds a new
showOnMouseUpoption to the bubble menu that defers showing the menu until the mouse button is released, similar to Notion's text selection behavior.Implementation Approach
Added a new optional
showOnMouseUpprop (default:false) to the bubble menu that defers menu display until mouseup occurs.Key implementation details:
isMouseDownflagTesting Done
showOnMouseUp: trueVerification Steps
showOnMouseUp:<BubbleMenu showOnMouseUp={true} />Checklist