WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 470f422

Browse files
bdbchclaude
andcommitted
fix: resolve Vue 2 BubbleMenu plugin registration lifecycle issue (#7226)
The BubbleMenu component was using a watcher with immediate: true, causing it to execute before the component mounted. This resulted in $el being null/undefined, preventing registerPlugin from ever being called. Changed to use the mounted lifecycle hook to ensure the DOM element exists before plugin registration, matching the Vue 3 implementation approach. Co-authored-by: Claude <[email protected]>
1 parent a11188e commit 470f422

File tree

2 files changed

+39
-37
lines changed

2 files changed

+39
-37
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@tiptap/vue-2": patch
3+
---
4+
5+
Fix BubbleMenu plugin registration not triggering due to missing element reference during component initialization.

packages/vue-2/src/menus/BubbleMenu.ts

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import type { BubbleMenuPluginProps } from '@tiptap/extension-bubble-menu'
22
import { BubbleMenuPlugin } from '@tiptap/extension-bubble-menu'
3-
import type { Component, CreateElement, PropType } from 'vue'
4-
import type Vue from 'vue'
3+
import type { Component, CreateElement, PropType, VNode } from 'vue'
54

6-
export interface BubbleMenuInterface extends Vue {
5+
export interface BubbleMenuInterface {
6+
$el: HTMLElement
7+
$nextTick: (callback: () => void) => void
8+
$slots: { default?: VNode[] }
79
pluginKey: BubbleMenuPluginProps['pluginKey']
810
editor: BubbleMenuPluginProps['editor']
911
updateDelay: BubbleMenuPluginProps['updateDelay']
@@ -52,40 +54,35 @@ export const BubbleMenu: Component = {
5254
},
5355
},
5456

55-
watch: {
56-
editor: {
57-
immediate: true,
58-
handler(this: BubbleMenuInterface, editor: BubbleMenuPluginProps['editor']) {
59-
if (!editor) {
60-
return
61-
}
62-
63-
if (!this.$el) {
64-
return
65-
}
66-
67-
;(this.$el as HTMLElement).style.visibility = 'hidden'
68-
;(this.$el as HTMLElement).style.position = 'absolute'
69-
70-
this.$el.remove()
71-
72-
this.$nextTick(() => {
73-
editor.registerPlugin(
74-
BubbleMenuPlugin({
75-
updateDelay: this.updateDelay,
76-
resizeDelay: this.resizeDelay,
77-
options: this.options,
78-
editor,
79-
element: this.$el as HTMLElement,
80-
pluginKey: this.pluginKey,
81-
appendTo: this.appendTo,
82-
shouldShow: this.shouldShow,
83-
getReferencedVirtualElement: this.getReferencedVirtualElement,
84-
}),
85-
)
86-
})
87-
},
88-
},
57+
mounted(this: BubbleMenuInterface) {
58+
const editor = this.editor
59+
const el = this.$el as HTMLElement
60+
61+
if (!editor || !el) {
62+
return
63+
}
64+
65+
el.style.visibility = 'hidden'
66+
el.style.position = 'absolute'
67+
68+
// Remove element from DOM; plugin will re-parent it when shown
69+
el.remove()
70+
71+
this.$nextTick(() => {
72+
editor.registerPlugin(
73+
BubbleMenuPlugin({
74+
updateDelay: this.updateDelay,
75+
resizeDelay: this.resizeDelay,
76+
options: this.options,
77+
editor,
78+
element: el,
79+
pluginKey: this.pluginKey,
80+
appendTo: this.appendTo,
81+
shouldShow: this.shouldShow,
82+
getReferencedVirtualElement: this.getReferencedVirtualElement,
83+
}),
84+
)
85+
})
8986
},
9087

9188
render(this: BubbleMenuInterface, createElement: CreateElement) {

0 commit comments

Comments
 (0)