@tiptap/react 3.19.0 → 3.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/menus/index.cjs
CHANGED
|
@@ -114,7 +114,7 @@ var BubbleMenu = import_react2.default.forwardRef(
|
|
|
114
114
|
return;
|
|
115
115
|
}
|
|
116
116
|
pluginEditor.view.dispatch(
|
|
117
|
-
pluginEditor.state.tr.setMeta(
|
|
117
|
+
pluginEditor.state.tr.setMeta(pluginKey, {
|
|
118
118
|
type: "updateOptions",
|
|
119
119
|
options: bubbleMenuPluginPropsRef.current
|
|
120
120
|
})
|
|
@@ -212,7 +212,7 @@ var FloatingMenu = import_react4.default.forwardRef(
|
|
|
212
212
|
return;
|
|
213
213
|
}
|
|
214
214
|
pluginEditor.view.dispatch(
|
|
215
|
-
pluginEditor.state.tr.setMeta(
|
|
215
|
+
pluginEditor.state.tr.setMeta(pluginKey, {
|
|
216
216
|
type: "updateOptions",
|
|
217
217
|
options: floatingMenuPluginPropsRef.current
|
|
218
218
|
})
|
package/dist/menus/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/menus/index.ts","../../src/menus/BubbleMenu.tsx","../../src/menus/FloatingMenu.tsx"],"sourcesContent":["export * from './BubbleMenu.js'\nexport * from './FloatingMenu.js'\n","import { type BubbleMenuPluginProps, BubbleMenuPlugin } from '@tiptap/extension-bubble-menu'\nimport { useCurrentEditor } from '@tiptap/react'\nimport React, { useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\n\ntype Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>\n\nexport type BubbleMenuProps = Optional<Omit<Optional<BubbleMenuPluginProps, 'pluginKey'>, 'element'>, 'editor'> &\n React.HTMLAttributes<HTMLDivElement>\n\nexport const BubbleMenu = React.forwardRef<HTMLDivElement, BubbleMenuProps>(\n (\n {\n pluginKey = 'bubbleMenu',\n editor,\n updateDelay,\n resizeDelay,\n appendTo,\n shouldShow = null,\n getReferencedVirtualElement,\n options,\n children,\n ...restProps\n },\n ref,\n ) => {\n const menuEl = useRef(document.createElement('div'))\n\n if (typeof ref === 'function') {\n ref(menuEl.current)\n } else if (ref) {\n ref.current = menuEl.current\n }\n\n const { editor: currentEditor } = useCurrentEditor()\n\n /**\n * The editor instance where the bubble menu plugin will be registered.\n */\n const pluginEditor = editor || currentEditor\n\n // Creating a useMemo would be more computationally expensive than just\n // re-creating this object on every render.\n const bubbleMenuPluginProps: Omit<BubbleMenuPluginProps, 'editor' | 'element'> = {\n updateDelay,\n resizeDelay,\n appendTo,\n pluginKey,\n shouldShow,\n getReferencedVirtualElement,\n options,\n }\n /**\n * The props for the bubble menu plugin. They are accessed inside a ref to\n * avoid running the useEffect hook and re-registering the plugin when the\n * props change.\n */\n const bubbleMenuPluginPropsRef = useRef(bubbleMenuPluginProps)\n bubbleMenuPluginPropsRef.current = bubbleMenuPluginProps\n\n /**\n * Track whether the plugin has been initialized, so we only send updates\n * after the initial registration.\n */\n const [pluginInitialized, setPluginInitialized] = useState(false)\n\n /**\n * Track whether we need to skip the first options update dispatch.\n * This prevents unnecessary updates right after plugin initialization.\n */\n const skipFirstUpdateRef = useRef(true)\n\n useEffect(() => {\n if (pluginEditor?.isDestroyed) {\n return\n }\n\n if (!pluginEditor) {\n console.warn('BubbleMenu component is not rendered inside of an editor component or does not have editor prop.')\n return\n }\n\n const bubbleMenuElement = menuEl.current\n bubbleMenuElement.style.visibility = 'hidden'\n bubbleMenuElement.style.position = 'absolute'\n\n const plugin = BubbleMenuPlugin({\n ...bubbleMenuPluginPropsRef.current,\n editor: pluginEditor,\n element: bubbleMenuElement,\n })\n\n pluginEditor.registerPlugin(plugin)\n\n const createdPluginKey = bubbleMenuPluginPropsRef.current.pluginKey\n\n skipFirstUpdateRef.current = true\n setPluginInitialized(true)\n\n return () => {\n setPluginInitialized(false)\n pluginEditor.unregisterPlugin(createdPluginKey)\n window.requestAnimationFrame(() => {\n if (bubbleMenuElement.parentNode) {\n bubbleMenuElement.parentNode.removeChild(bubbleMenuElement)\n }\n })\n }\n }, [pluginEditor])\n\n /**\n * Update the plugin options when props change after the plugin has been initialized.\n * This allows dynamic updates to options like scrollTarget without re-registering the entire plugin.\n */\n useEffect(() => {\n if (!pluginInitialized || !pluginEditor || pluginEditor.isDestroyed) {\n return\n }\n\n // Skip the first update right after initialization since the plugin was just created with these options\n if (skipFirstUpdateRef.current) {\n skipFirstUpdateRef.current = false\n return\n }\n\n pluginEditor.view.dispatch(\n pluginEditor.state.tr.setMeta('bubbleMenu', {\n type: 'updateOptions',\n options: bubbleMenuPluginPropsRef.current,\n }),\n )\n }, [\n pluginInitialized,\n pluginEditor,\n updateDelay,\n resizeDelay,\n shouldShow,\n options,\n appendTo,\n getReferencedVirtualElement,\n ])\n\n return createPortal(<div {...restProps}>{children}</div>, menuEl.current)\n },\n)\n","import type { FloatingMenuPluginProps } from '@tiptap/extension-floating-menu'\nimport { FloatingMenuPlugin } from '@tiptap/extension-floating-menu'\nimport { useCurrentEditor } from '@tiptap/react'\nimport React, { useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\n\ntype Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>\n\nexport type FloatingMenuProps = Omit<Optional<FloatingMenuPluginProps, 'pluginKey'>, 'element' | 'editor'> & {\n editor: FloatingMenuPluginProps['editor'] | null\n options?: FloatingMenuPluginProps['options']\n} & React.HTMLAttributes<HTMLDivElement>\n\nexport const FloatingMenu = React.forwardRef<HTMLDivElement, FloatingMenuProps>(\n (\n {\n pluginKey = 'floatingMenu',\n editor,\n updateDelay,\n resizeDelay,\n appendTo,\n shouldShow = null,\n options,\n children,\n ...restProps\n },\n ref,\n ) => {\n const menuEl = useRef(document.createElement('div'))\n\n if (typeof ref === 'function') {\n ref(menuEl.current)\n } else if (ref) {\n ref.current = menuEl.current\n }\n\n const { editor: currentEditor } = useCurrentEditor()\n\n /**\n * The editor instance where the floating menu plugin will be registered.\n */\n const pluginEditor = editor || currentEditor\n\n // Creating a useMemo would be more computationally expensive than just\n // re-creating this object on every render.\n const floatingMenuPluginProps: Omit<FloatingMenuPluginProps, 'editor' | 'element'> = {\n updateDelay,\n resizeDelay,\n appendTo,\n pluginKey,\n shouldShow,\n options,\n }\n\n /**\n * The props for the floating menu plugin. They are accessed inside a ref to\n * avoid running the useEffect hook and re-registering the plugin when the\n * props change.\n */\n const floatingMenuPluginPropsRef = useRef(floatingMenuPluginProps)\n floatingMenuPluginPropsRef.current = floatingMenuPluginProps\n\n /**\n * Track whether the plugin has been initialized, so we only send updates\n * after the initial registration.\n */\n const [pluginInitialized, setPluginInitialized] = useState(false)\n\n /**\n * Track whether we need to skip the first options update dispatch.\n * This prevents unnecessary updates right after plugin initialization.\n */\n const skipFirstUpdateRef = useRef(true)\n\n useEffect(() => {\n if (pluginEditor?.isDestroyed) {\n return\n }\n\n if (!pluginEditor) {\n console.warn(\n 'FloatingMenu component is not rendered inside of an editor component or does not have editor prop.',\n )\n return\n }\n\n const floatingMenuElement = menuEl.current\n floatingMenuElement.style.visibility = 'hidden'\n floatingMenuElement.style.position = 'absolute'\n\n const plugin = FloatingMenuPlugin({\n ...floatingMenuPluginPropsRef.current,\n editor: pluginEditor,\n element: floatingMenuElement,\n })\n\n pluginEditor.registerPlugin(plugin)\n\n const createdPluginKey = floatingMenuPluginPropsRef.current.pluginKey\n\n skipFirstUpdateRef.current = true\n setPluginInitialized(true)\n\n return () => {\n setPluginInitialized(false)\n pluginEditor.unregisterPlugin(createdPluginKey)\n window.requestAnimationFrame(() => {\n if (floatingMenuElement.parentNode) {\n floatingMenuElement.parentNode.removeChild(floatingMenuElement)\n }\n })\n }\n }, [pluginEditor])\n\n /**\n * Update the plugin options when props change after the plugin has been initialized.\n * This allows dynamic updates to options like scrollTarget without re-registering the entire plugin.\n */\n useEffect(() => {\n if (!pluginInitialized || !pluginEditor || pluginEditor.isDestroyed) {\n return\n }\n\n // Skip the first update right after initialization since the plugin was just created with these options\n if (skipFirstUpdateRef.current) {\n skipFirstUpdateRef.current = false\n return\n }\n\n pluginEditor.view.dispatch(\n pluginEditor.state.tr.setMeta('floatingMenu', {\n type: 'updateOptions',\n options: floatingMenuPluginPropsRef.current,\n }),\n )\n }, [pluginInitialized, pluginEditor, updateDelay, resizeDelay, shouldShow, options, appendTo])\n\n return createPortal(<div {...restProps}>{children}</div>, menuEl.current)\n },\n)\n"],"mappings":"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","names":["import_react","React","import_react","import_react_dom","import_jsx_runtime","React"]}
|
|
1
|
+
{"version":3,"sources":["../../src/menus/index.ts","../../src/menus/BubbleMenu.tsx","../../src/menus/FloatingMenu.tsx"],"sourcesContent":["export * from './BubbleMenu.js'\nexport * from './FloatingMenu.js'\n","import { type BubbleMenuPluginProps, BubbleMenuPlugin } from '@tiptap/extension-bubble-menu'\nimport { useCurrentEditor } from '@tiptap/react'\nimport React, { useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\n\ntype Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>\n\nexport type BubbleMenuProps = Optional<Omit<Optional<BubbleMenuPluginProps, 'pluginKey'>, 'element'>, 'editor'> &\n React.HTMLAttributes<HTMLDivElement>\n\nexport const BubbleMenu = React.forwardRef<HTMLDivElement, BubbleMenuProps>(\n (\n {\n pluginKey = 'bubbleMenu',\n editor,\n updateDelay,\n resizeDelay,\n appendTo,\n shouldShow = null,\n getReferencedVirtualElement,\n options,\n children,\n ...restProps\n },\n ref,\n ) => {\n const menuEl = useRef(document.createElement('div'))\n\n if (typeof ref === 'function') {\n ref(menuEl.current)\n } else if (ref) {\n ref.current = menuEl.current\n }\n\n const { editor: currentEditor } = useCurrentEditor()\n\n /**\n * The editor instance where the bubble menu plugin will be registered.\n */\n const pluginEditor = editor || currentEditor\n\n // Creating a useMemo would be more computationally expensive than just\n // re-creating this object on every render.\n const bubbleMenuPluginProps: Omit<BubbleMenuPluginProps, 'editor' | 'element'> = {\n updateDelay,\n resizeDelay,\n appendTo,\n pluginKey,\n shouldShow,\n getReferencedVirtualElement,\n options,\n }\n /**\n * The props for the bubble menu plugin. They are accessed inside a ref to\n * avoid running the useEffect hook and re-registering the plugin when the\n * props change.\n */\n const bubbleMenuPluginPropsRef = useRef(bubbleMenuPluginProps)\n bubbleMenuPluginPropsRef.current = bubbleMenuPluginProps\n\n /**\n * Track whether the plugin has been initialized, so we only send updates\n * after the initial registration.\n */\n const [pluginInitialized, setPluginInitialized] = useState(false)\n\n /**\n * Track whether we need to skip the first options update dispatch.\n * This prevents unnecessary updates right after plugin initialization.\n */\n const skipFirstUpdateRef = useRef(true)\n\n useEffect(() => {\n if (pluginEditor?.isDestroyed) {\n return\n }\n\n if (!pluginEditor) {\n console.warn('BubbleMenu component is not rendered inside of an editor component or does not have editor prop.')\n return\n }\n\n const bubbleMenuElement = menuEl.current\n bubbleMenuElement.style.visibility = 'hidden'\n bubbleMenuElement.style.position = 'absolute'\n\n const plugin = BubbleMenuPlugin({\n ...bubbleMenuPluginPropsRef.current,\n editor: pluginEditor,\n element: bubbleMenuElement,\n })\n\n pluginEditor.registerPlugin(plugin)\n\n const createdPluginKey = bubbleMenuPluginPropsRef.current.pluginKey\n\n skipFirstUpdateRef.current = true\n setPluginInitialized(true)\n\n return () => {\n setPluginInitialized(false)\n pluginEditor.unregisterPlugin(createdPluginKey)\n window.requestAnimationFrame(() => {\n if (bubbleMenuElement.parentNode) {\n bubbleMenuElement.parentNode.removeChild(bubbleMenuElement)\n }\n })\n }\n }, [pluginEditor])\n\n /**\n * Update the plugin options when props change after the plugin has been initialized.\n * This allows dynamic updates to options like scrollTarget without re-registering the entire plugin.\n */\n useEffect(() => {\n if (!pluginInitialized || !pluginEditor || pluginEditor.isDestroyed) {\n return\n }\n\n // Skip the first update right after initialization since the plugin was just created with these options\n if (skipFirstUpdateRef.current) {\n skipFirstUpdateRef.current = false\n return\n }\n\n pluginEditor.view.dispatch(\n pluginEditor.state.tr.setMeta(pluginKey, {\n type: 'updateOptions',\n options: bubbleMenuPluginPropsRef.current,\n }),\n )\n }, [\n pluginInitialized,\n pluginEditor,\n updateDelay,\n resizeDelay,\n shouldShow,\n options,\n appendTo,\n getReferencedVirtualElement,\n ])\n\n return createPortal(<div {...restProps}>{children}</div>, menuEl.current)\n },\n)\n","import type { FloatingMenuPluginProps } from '@tiptap/extension-floating-menu'\nimport { FloatingMenuPlugin } from '@tiptap/extension-floating-menu'\nimport { useCurrentEditor } from '@tiptap/react'\nimport React, { useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\n\ntype Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>\n\nexport type FloatingMenuProps = Omit<Optional<FloatingMenuPluginProps, 'pluginKey'>, 'element' | 'editor'> & {\n editor: FloatingMenuPluginProps['editor'] | null\n options?: FloatingMenuPluginProps['options']\n} & React.HTMLAttributes<HTMLDivElement>\n\nexport const FloatingMenu = React.forwardRef<HTMLDivElement, FloatingMenuProps>(\n (\n {\n pluginKey = 'floatingMenu',\n editor,\n updateDelay,\n resizeDelay,\n appendTo,\n shouldShow = null,\n options,\n children,\n ...restProps\n },\n ref,\n ) => {\n const menuEl = useRef(document.createElement('div'))\n\n if (typeof ref === 'function') {\n ref(menuEl.current)\n } else if (ref) {\n ref.current = menuEl.current\n }\n\n const { editor: currentEditor } = useCurrentEditor()\n\n /**\n * The editor instance where the floating menu plugin will be registered.\n */\n const pluginEditor = editor || currentEditor\n\n // Creating a useMemo would be more computationally expensive than just\n // re-creating this object on every render.\n const floatingMenuPluginProps: Omit<FloatingMenuPluginProps, 'editor' | 'element'> = {\n updateDelay,\n resizeDelay,\n appendTo,\n pluginKey,\n shouldShow,\n options,\n }\n\n /**\n * The props for the floating menu plugin. They are accessed inside a ref to\n * avoid running the useEffect hook and re-registering the plugin when the\n * props change.\n */\n const floatingMenuPluginPropsRef = useRef(floatingMenuPluginProps)\n floatingMenuPluginPropsRef.current = floatingMenuPluginProps\n\n /**\n * Track whether the plugin has been initialized, so we only send updates\n * after the initial registration.\n */\n const [pluginInitialized, setPluginInitialized] = useState(false)\n\n /**\n * Track whether we need to skip the first options update dispatch.\n * This prevents unnecessary updates right after plugin initialization.\n */\n const skipFirstUpdateRef = useRef(true)\n\n useEffect(() => {\n if (pluginEditor?.isDestroyed) {\n return\n }\n\n if (!pluginEditor) {\n console.warn(\n 'FloatingMenu component is not rendered inside of an editor component or does not have editor prop.',\n )\n return\n }\n\n const floatingMenuElement = menuEl.current\n floatingMenuElement.style.visibility = 'hidden'\n floatingMenuElement.style.position = 'absolute'\n\n const plugin = FloatingMenuPlugin({\n ...floatingMenuPluginPropsRef.current,\n editor: pluginEditor,\n element: floatingMenuElement,\n })\n\n pluginEditor.registerPlugin(plugin)\n\n const createdPluginKey = floatingMenuPluginPropsRef.current.pluginKey\n\n skipFirstUpdateRef.current = true\n setPluginInitialized(true)\n\n return () => {\n setPluginInitialized(false)\n pluginEditor.unregisterPlugin(createdPluginKey)\n window.requestAnimationFrame(() => {\n if (floatingMenuElement.parentNode) {\n floatingMenuElement.parentNode.removeChild(floatingMenuElement)\n }\n })\n }\n }, [pluginEditor])\n\n /**\n * Update the plugin options when props change after the plugin has been initialized.\n * This allows dynamic updates to options like scrollTarget without re-registering the entire plugin.\n */\n useEffect(() => {\n if (!pluginInitialized || !pluginEditor || pluginEditor.isDestroyed) {\n return\n }\n\n // Skip the first update right after initialization since the plugin was just created with these options\n if (skipFirstUpdateRef.current) {\n skipFirstUpdateRef.current = false\n return\n }\n\n pluginEditor.view.dispatch(\n pluginEditor.state.tr.setMeta(pluginKey, {\n type: 'updateOptions',\n options: floatingMenuPluginPropsRef.current,\n }),\n )\n }, [pluginInitialized, pluginEditor, updateDelay, resizeDelay, shouldShow, options, appendTo])\n\n return createPortal(<div {...restProps}>{children}</div>, menuEl.current)\n },\n)\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mCAA6D;AAC7D,mBAAiC;AACjC,IAAAA,gBAAmD;AACnD,uBAA6B;AA2IL;AApIjB,IAAM,aAAa,cAAAC,QAAM;AAAA,EAC9B,CACE;AAAA,IACE,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,aAAS,sBAAO,SAAS,cAAc,KAAK,CAAC;AAEnD,QAAI,OAAO,QAAQ,YAAY;AAC7B,UAAI,OAAO,OAAO;AAAA,IACpB,WAAW,KAAK;AACd,UAAI,UAAU,OAAO;AAAA,IACvB;AAEA,UAAM,EAAE,QAAQ,cAAc,QAAI,+BAAiB;AAKnD,UAAM,eAAe,UAAU;AAI/B,UAAM,wBAA2E;AAAA,MAC/E;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAMA,UAAM,+BAA2B,sBAAO,qBAAqB;AAC7D,6BAAyB,UAAU;AAMnC,UAAM,CAAC,mBAAmB,oBAAoB,QAAI,wBAAS,KAAK;AAMhE,UAAM,yBAAqB,sBAAO,IAAI;AAEtC,iCAAU,MAAM;AACd,UAAI,6CAAc,aAAa;AAC7B;AAAA,MACF;AAEA,UAAI,CAAC,cAAc;AACjB,gBAAQ,KAAK,kGAAkG;AAC/G;AAAA,MACF;AAEA,YAAM,oBAAoB,OAAO;AACjC,wBAAkB,MAAM,aAAa;AACrC,wBAAkB,MAAM,WAAW;AAEnC,YAAM,aAAS,+CAAiB;AAAA,QAC9B,GAAG,yBAAyB;AAAA,QAC5B,QAAQ;AAAA,QACR,SAAS;AAAA,MACX,CAAC;AAED,mBAAa,eAAe,MAAM;AAElC,YAAM,mBAAmB,yBAAyB,QAAQ;AAE1D,yBAAmB,UAAU;AAC7B,2BAAqB,IAAI;AAEzB,aAAO,MAAM;AACX,6BAAqB,KAAK;AAC1B,qBAAa,iBAAiB,gBAAgB;AAC9C,eAAO,sBAAsB,MAAM;AACjC,cAAI,kBAAkB,YAAY;AAChC,8BAAkB,WAAW,YAAY,iBAAiB;AAAA,UAC5D;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,GAAG,CAAC,YAAY,CAAC;AAMjB,iCAAU,MAAM;AACd,UAAI,CAAC,qBAAqB,CAAC,gBAAgB,aAAa,aAAa;AACnE;AAAA,MACF;AAGA,UAAI,mBAAmB,SAAS;AAC9B,2BAAmB,UAAU;AAC7B;AAAA,MACF;AAEA,mBAAa,KAAK;AAAA,QAChB,aAAa,MAAM,GAAG,QAAQ,WAAW;AAAA,UACvC,MAAM;AAAA,UACN,SAAS,yBAAyB;AAAA,QACpC,CAAC;AAAA,MACH;AAAA,IACF,GAAG;AAAA,MACD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,eAAO,+BAAa,4CAAC,SAAK,GAAG,WAAY,UAAS,GAAQ,OAAO,OAAO;AAAA,EAC1E;AACF;;;AC/IA,qCAAmC;AACnC,IAAAC,gBAAiC;AACjC,IAAAA,gBAAmD;AACnD,IAAAC,oBAA6B;AAqIL,IAAAC,sBAAA;AA5HjB,IAAM,eAAe,cAAAC,QAAM;AAAA,EAChC,CACE;AAAA,IACE,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,aAAS,sBAAO,SAAS,cAAc,KAAK,CAAC;AAEnD,QAAI,OAAO,QAAQ,YAAY;AAC7B,UAAI,OAAO,OAAO;AAAA,IACpB,WAAW,KAAK;AACd,UAAI,UAAU,OAAO;AAAA,IACvB;AAEA,UAAM,EAAE,QAAQ,cAAc,QAAI,gCAAiB;AAKnD,UAAM,eAAe,UAAU;AAI/B,UAAM,0BAA+E;AAAA,MACnF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAOA,UAAM,iCAA6B,sBAAO,uBAAuB;AACjE,+BAA2B,UAAU;AAMrC,UAAM,CAAC,mBAAmB,oBAAoB,QAAI,wBAAS,KAAK;AAMhE,UAAM,yBAAqB,sBAAO,IAAI;AAEtC,iCAAU,MAAM;AACd,UAAI,6CAAc,aAAa;AAC7B;AAAA,MACF;AAEA,UAAI,CAAC,cAAc;AACjB,gBAAQ;AAAA,UACN;AAAA,QACF;AACA;AAAA,MACF;AAEA,YAAM,sBAAsB,OAAO;AACnC,0BAAoB,MAAM,aAAa;AACvC,0BAAoB,MAAM,WAAW;AAErC,YAAM,aAAS,mDAAmB;AAAA,QAChC,GAAG,2BAA2B;AAAA,QAC9B,QAAQ;AAAA,QACR,SAAS;AAAA,MACX,CAAC;AAED,mBAAa,eAAe,MAAM;AAElC,YAAM,mBAAmB,2BAA2B,QAAQ;AAE5D,yBAAmB,UAAU;AAC7B,2BAAqB,IAAI;AAEzB,aAAO,MAAM;AACX,6BAAqB,KAAK;AAC1B,qBAAa,iBAAiB,gBAAgB;AAC9C,eAAO,sBAAsB,MAAM;AACjC,cAAI,oBAAoB,YAAY;AAClC,gCAAoB,WAAW,YAAY,mBAAmB;AAAA,UAChE;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,GAAG,CAAC,YAAY,CAAC;AAMjB,iCAAU,MAAM;AACd,UAAI,CAAC,qBAAqB,CAAC,gBAAgB,aAAa,aAAa;AACnE;AAAA,MACF;AAGA,UAAI,mBAAmB,SAAS;AAC9B,2BAAmB,UAAU;AAC7B;AAAA,MACF;AAEA,mBAAa,KAAK;AAAA,QAChB,aAAa,MAAM,GAAG,QAAQ,WAAW;AAAA,UACvC,MAAM;AAAA,UACN,SAAS,2BAA2B;AAAA,QACtC,CAAC;AAAA,MACH;AAAA,IACF,GAAG,CAAC,mBAAmB,cAAc,aAAa,aAAa,YAAY,SAAS,QAAQ,CAAC;AAE7F,eAAO,gCAAa,6CAAC,SAAK,GAAG,WAAY,UAAS,GAAQ,OAAO,OAAO;AAAA,EAC1E;AACF;","names":["import_react","React","import_react","import_react_dom","import_jsx_runtime","React"]}
|
package/dist/menus/index.js
CHANGED
|
@@ -77,7 +77,7 @@ var BubbleMenu = React.forwardRef(
|
|
|
77
77
|
return;
|
|
78
78
|
}
|
|
79
79
|
pluginEditor.view.dispatch(
|
|
80
|
-
pluginEditor.state.tr.setMeta(
|
|
80
|
+
pluginEditor.state.tr.setMeta(pluginKey, {
|
|
81
81
|
type: "updateOptions",
|
|
82
82
|
options: bubbleMenuPluginPropsRef.current
|
|
83
83
|
})
|
|
@@ -175,7 +175,7 @@ var FloatingMenu = React2.forwardRef(
|
|
|
175
175
|
return;
|
|
176
176
|
}
|
|
177
177
|
pluginEditor.view.dispatch(
|
|
178
|
-
pluginEditor.state.tr.setMeta(
|
|
178
|
+
pluginEditor.state.tr.setMeta(pluginKey, {
|
|
179
179
|
type: "updateOptions",
|
|
180
180
|
options: floatingMenuPluginPropsRef.current
|
|
181
181
|
})
|
package/dist/menus/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/menus/BubbleMenu.tsx","../../src/menus/FloatingMenu.tsx"],"sourcesContent":["import { type BubbleMenuPluginProps, BubbleMenuPlugin } from '@tiptap/extension-bubble-menu'\nimport { useCurrentEditor } from '@tiptap/react'\nimport React, { useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\n\ntype Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>\n\nexport type BubbleMenuProps = Optional<Omit<Optional<BubbleMenuPluginProps, 'pluginKey'>, 'element'>, 'editor'> &\n React.HTMLAttributes<HTMLDivElement>\n\nexport const BubbleMenu = React.forwardRef<HTMLDivElement, BubbleMenuProps>(\n (\n {\n pluginKey = 'bubbleMenu',\n editor,\n updateDelay,\n resizeDelay,\n appendTo,\n shouldShow = null,\n getReferencedVirtualElement,\n options,\n children,\n ...restProps\n },\n ref,\n ) => {\n const menuEl = useRef(document.createElement('div'))\n\n if (typeof ref === 'function') {\n ref(menuEl.current)\n } else if (ref) {\n ref.current = menuEl.current\n }\n\n const { editor: currentEditor } = useCurrentEditor()\n\n /**\n * The editor instance where the bubble menu plugin will be registered.\n */\n const pluginEditor = editor || currentEditor\n\n // Creating a useMemo would be more computationally expensive than just\n // re-creating this object on every render.\n const bubbleMenuPluginProps: Omit<BubbleMenuPluginProps, 'editor' | 'element'> = {\n updateDelay,\n resizeDelay,\n appendTo,\n pluginKey,\n shouldShow,\n getReferencedVirtualElement,\n options,\n }\n /**\n * The props for the bubble menu plugin. They are accessed inside a ref to\n * avoid running the useEffect hook and re-registering the plugin when the\n * props change.\n */\n const bubbleMenuPluginPropsRef = useRef(bubbleMenuPluginProps)\n bubbleMenuPluginPropsRef.current = bubbleMenuPluginProps\n\n /**\n * Track whether the plugin has been initialized, so we only send updates\n * after the initial registration.\n */\n const [pluginInitialized, setPluginInitialized] = useState(false)\n\n /**\n * Track whether we need to skip the first options update dispatch.\n * This prevents unnecessary updates right after plugin initialization.\n */\n const skipFirstUpdateRef = useRef(true)\n\n useEffect(() => {\n if (pluginEditor?.isDestroyed) {\n return\n }\n\n if (!pluginEditor) {\n console.warn('BubbleMenu component is not rendered inside of an editor component or does not have editor prop.')\n return\n }\n\n const bubbleMenuElement = menuEl.current\n bubbleMenuElement.style.visibility = 'hidden'\n bubbleMenuElement.style.position = 'absolute'\n\n const plugin = BubbleMenuPlugin({\n ...bubbleMenuPluginPropsRef.current,\n editor: pluginEditor,\n element: bubbleMenuElement,\n })\n\n pluginEditor.registerPlugin(plugin)\n\n const createdPluginKey = bubbleMenuPluginPropsRef.current.pluginKey\n\n skipFirstUpdateRef.current = true\n setPluginInitialized(true)\n\n return () => {\n setPluginInitialized(false)\n pluginEditor.unregisterPlugin(createdPluginKey)\n window.requestAnimationFrame(() => {\n if (bubbleMenuElement.parentNode) {\n bubbleMenuElement.parentNode.removeChild(bubbleMenuElement)\n }\n })\n }\n }, [pluginEditor])\n\n /**\n * Update the plugin options when props change after the plugin has been initialized.\n * This allows dynamic updates to options like scrollTarget without re-registering the entire plugin.\n */\n useEffect(() => {\n if (!pluginInitialized || !pluginEditor || pluginEditor.isDestroyed) {\n return\n }\n\n // Skip the first update right after initialization since the plugin was just created with these options\n if (skipFirstUpdateRef.current) {\n skipFirstUpdateRef.current = false\n return\n }\n\n pluginEditor.view.dispatch(\n pluginEditor.state.tr.setMeta('bubbleMenu', {\n type: 'updateOptions',\n options: bubbleMenuPluginPropsRef.current,\n }),\n )\n }, [\n pluginInitialized,\n pluginEditor,\n updateDelay,\n resizeDelay,\n shouldShow,\n options,\n appendTo,\n getReferencedVirtualElement,\n ])\n\n return createPortal(<div {...restProps}>{children}</div>, menuEl.current)\n },\n)\n","import type { FloatingMenuPluginProps } from '@tiptap/extension-floating-menu'\nimport { FloatingMenuPlugin } from '@tiptap/extension-floating-menu'\nimport { useCurrentEditor } from '@tiptap/react'\nimport React, { useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\n\ntype Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>\n\nexport type FloatingMenuProps = Omit<Optional<FloatingMenuPluginProps, 'pluginKey'>, 'element' | 'editor'> & {\n editor: FloatingMenuPluginProps['editor'] | null\n options?: FloatingMenuPluginProps['options']\n} & React.HTMLAttributes<HTMLDivElement>\n\nexport const FloatingMenu = React.forwardRef<HTMLDivElement, FloatingMenuProps>(\n (\n {\n pluginKey = 'floatingMenu',\n editor,\n updateDelay,\n resizeDelay,\n appendTo,\n shouldShow = null,\n options,\n children,\n ...restProps\n },\n ref,\n ) => {\n const menuEl = useRef(document.createElement('div'))\n\n if (typeof ref === 'function') {\n ref(menuEl.current)\n } else if (ref) {\n ref.current = menuEl.current\n }\n\n const { editor: currentEditor } = useCurrentEditor()\n\n /**\n * The editor instance where the floating menu plugin will be registered.\n */\n const pluginEditor = editor || currentEditor\n\n // Creating a useMemo would be more computationally expensive than just\n // re-creating this object on every render.\n const floatingMenuPluginProps: Omit<FloatingMenuPluginProps, 'editor' | 'element'> = {\n updateDelay,\n resizeDelay,\n appendTo,\n pluginKey,\n shouldShow,\n options,\n }\n\n /**\n * The props for the floating menu plugin. They are accessed inside a ref to\n * avoid running the useEffect hook and re-registering the plugin when the\n * props change.\n */\n const floatingMenuPluginPropsRef = useRef(floatingMenuPluginProps)\n floatingMenuPluginPropsRef.current = floatingMenuPluginProps\n\n /**\n * Track whether the plugin has been initialized, so we only send updates\n * after the initial registration.\n */\n const [pluginInitialized, setPluginInitialized] = useState(false)\n\n /**\n * Track whether we need to skip the first options update dispatch.\n * This prevents unnecessary updates right after plugin initialization.\n */\n const skipFirstUpdateRef = useRef(true)\n\n useEffect(() => {\n if (pluginEditor?.isDestroyed) {\n return\n }\n\n if (!pluginEditor) {\n console.warn(\n 'FloatingMenu component is not rendered inside of an editor component or does not have editor prop.',\n )\n return\n }\n\n const floatingMenuElement = menuEl.current\n floatingMenuElement.style.visibility = 'hidden'\n floatingMenuElement.style.position = 'absolute'\n\n const plugin = FloatingMenuPlugin({\n ...floatingMenuPluginPropsRef.current,\n editor: pluginEditor,\n element: floatingMenuElement,\n })\n\n pluginEditor.registerPlugin(plugin)\n\n const createdPluginKey = floatingMenuPluginPropsRef.current.pluginKey\n\n skipFirstUpdateRef.current = true\n setPluginInitialized(true)\n\n return () => {\n setPluginInitialized(false)\n pluginEditor.unregisterPlugin(createdPluginKey)\n window.requestAnimationFrame(() => {\n if (floatingMenuElement.parentNode) {\n floatingMenuElement.parentNode.removeChild(floatingMenuElement)\n }\n })\n }\n }, [pluginEditor])\n\n /**\n * Update the plugin options when props change after the plugin has been initialized.\n * This allows dynamic updates to options like scrollTarget without re-registering the entire plugin.\n */\n useEffect(() => {\n if (!pluginInitialized || !pluginEditor || pluginEditor.isDestroyed) {\n return\n }\n\n // Skip the first update right after initialization since the plugin was just created with these options\n if (skipFirstUpdateRef.current) {\n skipFirstUpdateRef.current = false\n return\n }\n\n pluginEditor.view.dispatch(\n pluginEditor.state.tr.setMeta('floatingMenu', {\n type: 'updateOptions',\n options: floatingMenuPluginPropsRef.current,\n }),\n )\n }, [pluginInitialized, pluginEditor, updateDelay, resizeDelay, shouldShow, options, appendTo])\n\n return createPortal(<div {...restProps}>{children}</div>, menuEl.current)\n },\n)\n"],"mappings":";AAAA,SAAqC,wBAAwB;AAC7D,SAAS,wBAAwB;AACjC,OAAO,SAAS,WAAW,QAAQ,gBAAgB;AACnD,SAAS,oBAAoB;AA2IL;AApIjB,IAAM,aAAa,MAAM;AAAA,EAC9B,CACE;AAAA,IACE,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,SAAS,OAAO,SAAS,cAAc,KAAK,CAAC;AAEnD,QAAI,OAAO,QAAQ,YAAY;AAC7B,UAAI,OAAO,OAAO;AAAA,IACpB,WAAW,KAAK;AACd,UAAI,UAAU,OAAO;AAAA,IACvB;AAEA,UAAM,EAAE,QAAQ,cAAc,IAAI,iBAAiB;AAKnD,UAAM,eAAe,UAAU;AAI/B,UAAM,wBAA2E;AAAA,MAC/E;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAMA,UAAM,2BAA2B,OAAO,qBAAqB;AAC7D,6BAAyB,UAAU;AAMnC,UAAM,CAAC,mBAAmB,oBAAoB,IAAI,SAAS,KAAK;AAMhE,UAAM,qBAAqB,OAAO,IAAI;AAEtC,cAAU,MAAM;AACd,UAAI,6CAAc,aAAa;AAC7B;AAAA,MACF;AAEA,UAAI,CAAC,cAAc;AACjB,gBAAQ,KAAK,kGAAkG;AAC/G;AAAA,MACF;AAEA,YAAM,oBAAoB,OAAO;AACjC,wBAAkB,MAAM,aAAa;AACrC,wBAAkB,MAAM,WAAW;AAEnC,YAAM,SAAS,iBAAiB;AAAA,QAC9B,GAAG,yBAAyB;AAAA,QAC5B,QAAQ;AAAA,QACR,SAAS;AAAA,MACX,CAAC;AAED,mBAAa,eAAe,MAAM;AAElC,YAAM,mBAAmB,yBAAyB,QAAQ;AAE1D,yBAAmB,UAAU;AAC7B,2BAAqB,IAAI;AAEzB,aAAO,MAAM;AACX,6BAAqB,KAAK;AAC1B,qBAAa,iBAAiB,gBAAgB;AAC9C,eAAO,sBAAsB,MAAM;AACjC,cAAI,kBAAkB,YAAY;AAChC,8BAAkB,WAAW,YAAY,iBAAiB;AAAA,UAC5D;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,GAAG,CAAC,YAAY,CAAC;AAMjB,cAAU,MAAM;AACd,UAAI,CAAC,qBAAqB,CAAC,gBAAgB,aAAa,aAAa;AACnE;AAAA,MACF;AAGA,UAAI,mBAAmB,SAAS;AAC9B,2BAAmB,UAAU;AAC7B;AAAA,MACF;AAEA,mBAAa,KAAK;AAAA,QAChB,aAAa,MAAM,GAAG,QAAQ,cAAc;AAAA,UAC1C,MAAM;AAAA,UACN,SAAS,yBAAyB;AAAA,QACpC,CAAC;AAAA,MACH;AAAA,IACF,GAAG;AAAA,MACD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,WAAO,aAAa,oBAAC,SAAK,GAAG,WAAY,UAAS,GAAQ,OAAO,OAAO;AAAA,EAC1E;AACF;;;AC/IA,SAAS,0BAA0B;AACnC,SAAS,oBAAAA,yBAAwB;AACjC,OAAOC,UAAS,aAAAC,YAAW,UAAAC,SAAQ,YAAAC,iBAAgB;AACnD,SAAS,gBAAAC,qBAAoB;AAqIL,gBAAAC,YAAA;AA5HjB,IAAM,eAAeL,OAAM;AAAA,EAChC,CACE;AAAA,IACE,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,SAASE,QAAO,SAAS,cAAc,KAAK,CAAC;AAEnD,QAAI,OAAO,QAAQ,YAAY;AAC7B,UAAI,OAAO,OAAO;AAAA,IACpB,WAAW,KAAK;AACd,UAAI,UAAU,OAAO;AAAA,IACvB;AAEA,UAAM,EAAE,QAAQ,cAAc,IAAIH,kBAAiB;AAKnD,UAAM,eAAe,UAAU;AAI/B,UAAM,0BAA+E;AAAA,MACnF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAOA,UAAM,6BAA6BG,QAAO,uBAAuB;AACjE,+BAA2B,UAAU;AAMrC,UAAM,CAAC,mBAAmB,oBAAoB,IAAIC,UAAS,KAAK;AAMhE,UAAM,qBAAqBD,QAAO,IAAI;AAEtC,IAAAD,WAAU,MAAM;AACd,UAAI,6CAAc,aAAa;AAC7B;AAAA,MACF;AAEA,UAAI,CAAC,cAAc;AACjB,gBAAQ;AAAA,UACN;AAAA,QACF;AACA;AAAA,MACF;AAEA,YAAM,sBAAsB,OAAO;AACnC,0BAAoB,MAAM,aAAa;AACvC,0BAAoB,MAAM,WAAW;AAErC,YAAM,SAAS,mBAAmB;AAAA,QAChC,GAAG,2BAA2B;AAAA,QAC9B,QAAQ;AAAA,QACR,SAAS;AAAA,MACX,CAAC;AAED,mBAAa,eAAe,MAAM;AAElC,YAAM,mBAAmB,2BAA2B,QAAQ;AAE5D,yBAAmB,UAAU;AAC7B,2BAAqB,IAAI;AAEzB,aAAO,MAAM;AACX,6BAAqB,KAAK;AAC1B,qBAAa,iBAAiB,gBAAgB;AAC9C,eAAO,sBAAsB,MAAM;AACjC,cAAI,oBAAoB,YAAY;AAClC,gCAAoB,WAAW,YAAY,mBAAmB;AAAA,UAChE;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,GAAG,CAAC,YAAY,CAAC;AAMjB,IAAAA,WAAU,MAAM;AACd,UAAI,CAAC,qBAAqB,CAAC,gBAAgB,aAAa,aAAa;AACnE;AAAA,MACF;AAGA,UAAI,mBAAmB,SAAS;AAC9B,2BAAmB,UAAU;AAC7B;AAAA,MACF;AAEA,mBAAa,KAAK;AAAA,QAChB,aAAa,MAAM,GAAG,QAAQ,gBAAgB;AAAA,UAC5C,MAAM;AAAA,UACN,SAAS,2BAA2B;AAAA,QACtC,CAAC;AAAA,MACH;AAAA,IACF,GAAG,CAAC,mBAAmB,cAAc,aAAa,aAAa,YAAY,SAAS,QAAQ,CAAC;AAE7F,WAAOG,cAAa,gBAAAC,KAAC,SAAK,GAAG,WAAY,UAAS,GAAQ,OAAO,OAAO;AAAA,EAC1E;AACF;","names":["useCurrentEditor","React","useEffect","useRef","useState","createPortal","jsx"]}
|
|
1
|
+
{"version":3,"sources":["../../src/menus/BubbleMenu.tsx","../../src/menus/FloatingMenu.tsx"],"sourcesContent":["import { type BubbleMenuPluginProps, BubbleMenuPlugin } from '@tiptap/extension-bubble-menu'\nimport { useCurrentEditor } from '@tiptap/react'\nimport React, { useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\n\ntype Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>\n\nexport type BubbleMenuProps = Optional<Omit<Optional<BubbleMenuPluginProps, 'pluginKey'>, 'element'>, 'editor'> &\n React.HTMLAttributes<HTMLDivElement>\n\nexport const BubbleMenu = React.forwardRef<HTMLDivElement, BubbleMenuProps>(\n (\n {\n pluginKey = 'bubbleMenu',\n editor,\n updateDelay,\n resizeDelay,\n appendTo,\n shouldShow = null,\n getReferencedVirtualElement,\n options,\n children,\n ...restProps\n },\n ref,\n ) => {\n const menuEl = useRef(document.createElement('div'))\n\n if (typeof ref === 'function') {\n ref(menuEl.current)\n } else if (ref) {\n ref.current = menuEl.current\n }\n\n const { editor: currentEditor } = useCurrentEditor()\n\n /**\n * The editor instance where the bubble menu plugin will be registered.\n */\n const pluginEditor = editor || currentEditor\n\n // Creating a useMemo would be more computationally expensive than just\n // re-creating this object on every render.\n const bubbleMenuPluginProps: Omit<BubbleMenuPluginProps, 'editor' | 'element'> = {\n updateDelay,\n resizeDelay,\n appendTo,\n pluginKey,\n shouldShow,\n getReferencedVirtualElement,\n options,\n }\n /**\n * The props for the bubble menu plugin. They are accessed inside a ref to\n * avoid running the useEffect hook and re-registering the plugin when the\n * props change.\n */\n const bubbleMenuPluginPropsRef = useRef(bubbleMenuPluginProps)\n bubbleMenuPluginPropsRef.current = bubbleMenuPluginProps\n\n /**\n * Track whether the plugin has been initialized, so we only send updates\n * after the initial registration.\n */\n const [pluginInitialized, setPluginInitialized] = useState(false)\n\n /**\n * Track whether we need to skip the first options update dispatch.\n * This prevents unnecessary updates right after plugin initialization.\n */\n const skipFirstUpdateRef = useRef(true)\n\n useEffect(() => {\n if (pluginEditor?.isDestroyed) {\n return\n }\n\n if (!pluginEditor) {\n console.warn('BubbleMenu component is not rendered inside of an editor component or does not have editor prop.')\n return\n }\n\n const bubbleMenuElement = menuEl.current\n bubbleMenuElement.style.visibility = 'hidden'\n bubbleMenuElement.style.position = 'absolute'\n\n const plugin = BubbleMenuPlugin({\n ...bubbleMenuPluginPropsRef.current,\n editor: pluginEditor,\n element: bubbleMenuElement,\n })\n\n pluginEditor.registerPlugin(plugin)\n\n const createdPluginKey = bubbleMenuPluginPropsRef.current.pluginKey\n\n skipFirstUpdateRef.current = true\n setPluginInitialized(true)\n\n return () => {\n setPluginInitialized(false)\n pluginEditor.unregisterPlugin(createdPluginKey)\n window.requestAnimationFrame(() => {\n if (bubbleMenuElement.parentNode) {\n bubbleMenuElement.parentNode.removeChild(bubbleMenuElement)\n }\n })\n }\n }, [pluginEditor])\n\n /**\n * Update the plugin options when props change after the plugin has been initialized.\n * This allows dynamic updates to options like scrollTarget without re-registering the entire plugin.\n */\n useEffect(() => {\n if (!pluginInitialized || !pluginEditor || pluginEditor.isDestroyed) {\n return\n }\n\n // Skip the first update right after initialization since the plugin was just created with these options\n if (skipFirstUpdateRef.current) {\n skipFirstUpdateRef.current = false\n return\n }\n\n pluginEditor.view.dispatch(\n pluginEditor.state.tr.setMeta(pluginKey, {\n type: 'updateOptions',\n options: bubbleMenuPluginPropsRef.current,\n }),\n )\n }, [\n pluginInitialized,\n pluginEditor,\n updateDelay,\n resizeDelay,\n shouldShow,\n options,\n appendTo,\n getReferencedVirtualElement,\n ])\n\n return createPortal(<div {...restProps}>{children}</div>, menuEl.current)\n },\n)\n","import type { FloatingMenuPluginProps } from '@tiptap/extension-floating-menu'\nimport { FloatingMenuPlugin } from '@tiptap/extension-floating-menu'\nimport { useCurrentEditor } from '@tiptap/react'\nimport React, { useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\n\ntype Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>\n\nexport type FloatingMenuProps = Omit<Optional<FloatingMenuPluginProps, 'pluginKey'>, 'element' | 'editor'> & {\n editor: FloatingMenuPluginProps['editor'] | null\n options?: FloatingMenuPluginProps['options']\n} & React.HTMLAttributes<HTMLDivElement>\n\nexport const FloatingMenu = React.forwardRef<HTMLDivElement, FloatingMenuProps>(\n (\n {\n pluginKey = 'floatingMenu',\n editor,\n updateDelay,\n resizeDelay,\n appendTo,\n shouldShow = null,\n options,\n children,\n ...restProps\n },\n ref,\n ) => {\n const menuEl = useRef(document.createElement('div'))\n\n if (typeof ref === 'function') {\n ref(menuEl.current)\n } else if (ref) {\n ref.current = menuEl.current\n }\n\n const { editor: currentEditor } = useCurrentEditor()\n\n /**\n * The editor instance where the floating menu plugin will be registered.\n */\n const pluginEditor = editor || currentEditor\n\n // Creating a useMemo would be more computationally expensive than just\n // re-creating this object on every render.\n const floatingMenuPluginProps: Omit<FloatingMenuPluginProps, 'editor' | 'element'> = {\n updateDelay,\n resizeDelay,\n appendTo,\n pluginKey,\n shouldShow,\n options,\n }\n\n /**\n * The props for the floating menu plugin. They are accessed inside a ref to\n * avoid running the useEffect hook and re-registering the plugin when the\n * props change.\n */\n const floatingMenuPluginPropsRef = useRef(floatingMenuPluginProps)\n floatingMenuPluginPropsRef.current = floatingMenuPluginProps\n\n /**\n * Track whether the plugin has been initialized, so we only send updates\n * after the initial registration.\n */\n const [pluginInitialized, setPluginInitialized] = useState(false)\n\n /**\n * Track whether we need to skip the first options update dispatch.\n * This prevents unnecessary updates right after plugin initialization.\n */\n const skipFirstUpdateRef = useRef(true)\n\n useEffect(() => {\n if (pluginEditor?.isDestroyed) {\n return\n }\n\n if (!pluginEditor) {\n console.warn(\n 'FloatingMenu component is not rendered inside of an editor component or does not have editor prop.',\n )\n return\n }\n\n const floatingMenuElement = menuEl.current\n floatingMenuElement.style.visibility = 'hidden'\n floatingMenuElement.style.position = 'absolute'\n\n const plugin = FloatingMenuPlugin({\n ...floatingMenuPluginPropsRef.current,\n editor: pluginEditor,\n element: floatingMenuElement,\n })\n\n pluginEditor.registerPlugin(plugin)\n\n const createdPluginKey = floatingMenuPluginPropsRef.current.pluginKey\n\n skipFirstUpdateRef.current = true\n setPluginInitialized(true)\n\n return () => {\n setPluginInitialized(false)\n pluginEditor.unregisterPlugin(createdPluginKey)\n window.requestAnimationFrame(() => {\n if (floatingMenuElement.parentNode) {\n floatingMenuElement.parentNode.removeChild(floatingMenuElement)\n }\n })\n }\n }, [pluginEditor])\n\n /**\n * Update the plugin options when props change after the plugin has been initialized.\n * This allows dynamic updates to options like scrollTarget without re-registering the entire plugin.\n */\n useEffect(() => {\n if (!pluginInitialized || !pluginEditor || pluginEditor.isDestroyed) {\n return\n }\n\n // Skip the first update right after initialization since the plugin was just created with these options\n if (skipFirstUpdateRef.current) {\n skipFirstUpdateRef.current = false\n return\n }\n\n pluginEditor.view.dispatch(\n pluginEditor.state.tr.setMeta(pluginKey, {\n type: 'updateOptions',\n options: floatingMenuPluginPropsRef.current,\n }),\n )\n }, [pluginInitialized, pluginEditor, updateDelay, resizeDelay, shouldShow, options, appendTo])\n\n return createPortal(<div {...restProps}>{children}</div>, menuEl.current)\n },\n)\n"],"mappings":"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","names":["useCurrentEditor","React","useEffect","useRef","useState","createPortal","jsx"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiptap/react",
|
|
3
3
|
"description": "React components for tiptap",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.20.0",
|
|
5
5
|
"homepage": "https://tiptap.dev",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"tiptap",
|
|
@@ -48,20 +48,20 @@
|
|
|
48
48
|
"@types/react-dom": "^19.0.0",
|
|
49
49
|
"react": "^19.0.0",
|
|
50
50
|
"react-dom": "^19.0.0",
|
|
51
|
-
"@tiptap/core": "^3.
|
|
52
|
-
"@tiptap/pm": "^3.
|
|
51
|
+
"@tiptap/core": "^3.20.0",
|
|
52
|
+
"@tiptap/pm": "^3.20.0"
|
|
53
53
|
},
|
|
54
54
|
"optionalDependencies": {
|
|
55
|
-
"@tiptap/extension-bubble-menu": "^3.
|
|
56
|
-
"@tiptap/extension-floating-menu": "^3.
|
|
55
|
+
"@tiptap/extension-bubble-menu": "^3.20.0",
|
|
56
|
+
"@tiptap/extension-floating-menu": "^3.20.0"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"react": "^17.0.0 || ^18.0.0 || ^19.0.0",
|
|
60
60
|
"react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0",
|
|
61
61
|
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
|
|
62
62
|
"@types/react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0",
|
|
63
|
-
"@tiptap/core": "^3.
|
|
64
|
-
"@tiptap/pm": "^3.
|
|
63
|
+
"@tiptap/core": "^3.20.0",
|
|
64
|
+
"@tiptap/pm": "^3.20.0"
|
|
65
65
|
},
|
|
66
66
|
"repository": {
|
|
67
67
|
"type": "git",
|
package/src/menus/BubbleMenu.tsx
CHANGED
|
@@ -124,7 +124,7 @@ export const BubbleMenu = React.forwardRef<HTMLDivElement, BubbleMenuProps>(
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
pluginEditor.view.dispatch(
|
|
127
|
-
pluginEditor.state.tr.setMeta(
|
|
127
|
+
pluginEditor.state.tr.setMeta(pluginKey, {
|
|
128
128
|
type: 'updateOptions',
|
|
129
129
|
options: bubbleMenuPluginPropsRef.current,
|
|
130
130
|
}),
|
|
@@ -128,7 +128,7 @@ export const FloatingMenu = React.forwardRef<HTMLDivElement, FloatingMenuProps>(
|
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
pluginEditor.view.dispatch(
|
|
131
|
-
pluginEditor.state.tr.setMeta(
|
|
131
|
+
pluginEditor.state.tr.setMeta(pluginKey, {
|
|
132
132
|
type: 'updateOptions',
|
|
133
133
|
options: floatingMenuPluginPropsRef.current,
|
|
134
134
|
}),
|