@@ -34,55 +34,63 @@ export const BubbleMenu = React.forwardRef<HTMLDivElement, BubbleMenuProps>(
3434
3535 const { editor : currentEditor } = useCurrentEditor ( )
3636
37- useEffect ( ( ) => {
38- const bubbleMenuElement = menuEl . current
39- bubbleMenuElement . style . visibility = 'hidden'
40- bubbleMenuElement . style . position = 'absolute'
37+ /**
38+ * The editor instance where the bubble menu plugin will be registered.
39+ */
40+ const pluginEditor = editor || currentEditor
41+
42+ // Creating a useMemo would be more computationally expensive than just
43+ // re-creating this object on every render.
44+ const bubbleMenuPluginProps : Omit < BubbleMenuPluginProps , 'editor' | 'element' > = {
45+ updateDelay,
46+ resizeDelay,
47+ appendTo,
48+ pluginKey,
49+ shouldShow,
50+ getReferencedVirtualElement,
51+ options,
52+ }
53+ /**
54+ * The props for the bubble menu plugin. They are accessed inside a ref to
55+ * avoid running the useEffect hook and re-registering the plugin when the
56+ * props change.
57+ */
58+ const bubbleMenuPluginPropsRef = useRef ( bubbleMenuPluginProps )
59+ bubbleMenuPluginPropsRef . current = bubbleMenuPluginProps
4160
42- if ( editor ?. isDestroyed || ( currentEditor as any ) ?. isDestroyed ) {
61+ useEffect ( ( ) => {
62+ if ( pluginEditor ?. isDestroyed ) {
4363 return
4464 }
4565
46- const attachToEditor = editor || currentEditor
47-
48- if ( ! attachToEditor ) {
66+ if ( ! pluginEditor ) {
4967 console . warn ( 'BubbleMenu component is not rendered inside of an editor component or does not have editor prop.' )
5068 return
5169 }
5270
71+ const bubbleMenuElement = menuEl . current
72+ bubbleMenuElement . style . visibility = 'hidden'
73+ bubbleMenuElement . style . position = 'absolute'
74+
5375 const plugin = BubbleMenuPlugin ( {
54- updateDelay,
55- resizeDelay,
56- editor : attachToEditor ,
76+ ...bubbleMenuPluginPropsRef . current ,
77+ editor : pluginEditor ,
5778 element : bubbleMenuElement ,
58- appendTo,
59- pluginKey,
60- shouldShow,
61- getReferencedVirtualElement,
62- options,
6379 } )
6480
65- attachToEditor . registerPlugin ( plugin )
81+ pluginEditor . registerPlugin ( plugin )
82+
83+ const createdPluginKey = bubbleMenuPluginPropsRef . current . pluginKey
6684
6785 return ( ) => {
68- attachToEditor . unregisterPlugin ( pluginKey )
86+ pluginEditor . unregisterPlugin ( createdPluginKey )
6987 window . requestAnimationFrame ( ( ) => {
7088 if ( bubbleMenuElement . parentNode ) {
7189 bubbleMenuElement . parentNode . removeChild ( bubbleMenuElement )
7290 }
7391 } )
7492 }
75- } , [
76- editor ,
77- currentEditor ,
78- pluginKey ,
79- updateDelay ,
80- resizeDelay ,
81- appendTo ,
82- shouldShow ,
83- getReferencedVirtualElement ,
84- options ,
85- ] )
93+ } , [ pluginEditor ] )
8694
8795 return createPortal ( < div { ...restProps } > { children } </ div > , menuEl . current )
8896 } ,
0 commit comments