1- import React , { useCallback , useEffect , useState } from "react" ;
1+ import React , { useCallback , useEffect , useRef , useState } from "react" ;
22import type { Editor } from "@tiptap/core" ;
3- import { BubbleMenu as TipTapBubbleMenu } from "@tiptap/react" ;
3+ import type { BubbleMenuPluginProps } from "@tiptap/extension-bubble-menu" ;
4+ import { BubbleMenuPlugin } from "@tiptap/extension-bubble-menu" ;
45import {
56 Bold ,
67 Code ,
@@ -18,6 +19,73 @@ interface BubbleMenuProps {
1819const buttonBase =
1920 "inline-flex h-8 w-8 items-center justify-center rounded text-foreground transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary" ;
2021
22+ type TipTapBubbleMenuProps = {
23+ editor : Editor | null ;
24+ className ?: string ;
25+ children : React . ReactNode ;
26+ pluginKey ?: string ;
27+ } & Partial < Omit < BubbleMenuPluginProps , "editor" | "element" | "pluginKey" > > ;
28+
29+ const TipTapBubbleMenu = ( {
30+ editor,
31+ className,
32+ children,
33+ pluginKey = "inlineBubbleMenu" ,
34+ updateDelay,
35+ resizeDelay,
36+ shouldShow,
37+ appendTo,
38+ getReferencedVirtualElement,
39+ options,
40+ } : TipTapBubbleMenuProps ) : JSX . Element => {
41+ const menuRef = useRef < HTMLDivElement | null > ( null ) ;
42+
43+ useEffect ( ( ) => {
44+ const element = menuRef . current ;
45+
46+ if ( ! editor || editor . isDestroyed || ! element ) {
47+ return ;
48+ }
49+
50+ const plugin = BubbleMenuPlugin ( {
51+ editor,
52+ element,
53+ pluginKey,
54+ updateDelay,
55+ resizeDelay,
56+ shouldShow : shouldShow ?? null ,
57+ appendTo,
58+ getReferencedVirtualElement,
59+ options,
60+ } ) ;
61+
62+ editor . registerPlugin ( plugin ) ;
63+
64+ return ( ) => {
65+ editor . unregisterPlugin ( pluginKey ) ;
66+ } ;
67+ } , [
68+ editor ,
69+ pluginKey ,
70+ updateDelay ,
71+ resizeDelay ,
72+ shouldShow ,
73+ appendTo ,
74+ getReferencedVirtualElement ,
75+ options ,
76+ ] ) ;
77+
78+ return (
79+ < div
80+ ref = { menuRef }
81+ className = { className }
82+ style = { { visibility : "hidden" } }
83+ >
84+ { children }
85+ </ div >
86+ ) ;
87+ } ;
88+
2189function InlineButton ( {
2290 icon : Icon ,
2391 label,
0 commit comments