BubbleMenu trigger option & updateDelay not working on focus events #7367
Unanswered
tomo-kn
asked this question in
Questions & Help
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
After migrating to Tiptap v3, I noticed that BubbleMenu has some focus-related issues that were easier to handle in v2 with tippy.js options.
Context
I'm using custom
shouldShowto display BubbleMenu only when specific nodes are active (e.g., links, images, tables). I addedview.hasFocus()check as recommended in the docs.Issue 1: Flickering on click-through
Steps to reproduce:
Cause:
When clicking inside the editor, focus returns before selection updates:
view.hasFocus()= trueisActive('link')= trueshouldShowreturns true → Menu shows (flicker!)isActive('link')= false → Menu hidesIssue 2:
updateDelaydoesn't helpI tried using
updateDelayto debounce the evaluation, but it has no effect on focus events.Looking at the source code, I found that
focusHandlerdoesn't passoldState:The debounce logic in
handleDebouncedUpdaterequiresoldStateto work, so it gets skipped for focus events.Feature Request:
triggeroptionIn tippy.js, we could use
trigger: 'click'to show the menu only on explicit clicks. This would solve the flickering issue because selection would be stable before evaluation.Would it be possible to add a similar option to BubbleMenu?
Current Workaround
Using
view.hasFocus()inshouldShowhelps with blur, but doesn't prevent the click-through flickering.Environment
Thanks for any insights! 🙏
Additional context: Why this worked in v2
After more investigation, I found the root cause of this regression.
In v2 with Tippy.js, we had:
Tippy.js itself handled the show/hide timing based on click events. The
shouldShowcallback was mainly for initial evaluation, and subsequent visibility control was managed by Tippy's internal trigger mechanism. This abstracted away any timing differences between focus and selection state updates.In v3 with Floating UI:
triggeroption existsdurationordelayoptions existshouldShowshouldShowis evaluated on every updateThe flickering happens because:
view.hasFocus()updates immediately (DOM-level)editor.isActive()updates after the transaction is processed (ProseMirror state-level)In v2, Tippy's click-based trigger mechanism naturally synchronized these timings. In v3, we're exposed to the raw timing mismatch.
Possible solutions for the Tiptap team:
triggeroption similar to Tippy'sshowDelay/hideDelayoptionsshouldShowis evaluated after selection state is fully updatedRelated
Beta Was this translation helpful? Give feedback.
All reactions