@tiptap/react 2.0.0-beta.20 → 2.0.0-beta.201

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.
Files changed (34) hide show
  1. package/README.md +2 -2
  2. package/dist/packages/react/src/BubbleMenu.d.ts +7 -3
  3. package/dist/packages/react/src/Editor.d.ts +1 -1
  4. package/dist/packages/react/src/EditorContent.d.ts +2 -2
  5. package/dist/packages/react/src/FloatingMenu.d.ts +6 -3
  6. package/dist/packages/react/src/NodeViewContent.d.ts +1 -1
  7. package/dist/packages/react/src/NodeViewWrapper.d.ts +1 -1
  8. package/dist/packages/react/src/ReactNodeViewRenderer.d.ts +12 -6
  9. package/dist/packages/react/src/ReactRenderer.d.ts +12 -9
  10. package/dist/packages/react/src/index.d.ts +6 -6
  11. package/dist/packages/react/src/useEditor.d.ts +2 -1
  12. package/dist/packages/react/src/useReactNodeView.d.ts +1 -0
  13. package/dist/tiptap-react.cjs.js +224 -151
  14. package/dist/tiptap-react.cjs.js.map +1 -1
  15. package/dist/tiptap-react.esm.js +224 -149
  16. package/dist/tiptap-react.esm.js.map +1 -1
  17. package/dist/tiptap-react.umd.js +226 -153
  18. package/dist/tiptap-react.umd.js.map +1 -1
  19. package/package.json +18 -12
  20. package/src/BubbleMenu.tsx +33 -17
  21. package/src/Editor.ts +2 -1
  22. package/src/EditorContent.tsx +9 -7
  23. package/src/FloatingMenu.tsx +37 -14
  24. package/src/NodeViewContent.tsx +10 -3
  25. package/src/NodeViewWrapper.tsx +11 -8
  26. package/src/ReactNodeViewRenderer.tsx +75 -31
  27. package/src/ReactRenderer.tsx +58 -25
  28. package/src/index.ts +6 -6
  29. package/src/useEditor.ts +16 -4
  30. package/src/useReactNodeView.ts +1 -0
  31. package/CHANGELOG.md +0 -178
  32. package/LICENSE.md +0 -21
  33. package/dist/tiptap-react.bundle.umd.min.js +0 -54
  34. package/dist/tiptap-react.bundle.umd.min.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"tiptap-react.cjs.js","sources":["../src/BubbleMenu.tsx","../src/Editor.ts","../src/FloatingMenu.tsx","../src/useEditor.ts","../src/ReactRenderer.tsx","../src/useReactNodeView.ts","../src/ReactNodeViewRenderer.tsx","../src/EditorContent.tsx","../src/NodeViewWrapper.tsx","../src/NodeViewContent.tsx"],"sourcesContent":["import React, { useEffect, useRef } from 'react'\nimport { BubbleMenuPlugin, BubbleMenuPluginKey, BubbleMenuPluginProps } from '@tiptap/extension-bubble-menu'\n\nexport type BubbleMenuProps = Omit<BubbleMenuPluginProps, 'element'> & {\n className?: string,\n}\n\nexport const BubbleMenu: React.FC<BubbleMenuProps> = props => {\n const element = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n const { editor, keepInBounds = true } = props\n\n editor.registerPlugin(BubbleMenuPlugin({\n editor,\n element: element.current as HTMLElement,\n keepInBounds,\n }))\n\n return () => {\n editor.unregisterPlugin(BubbleMenuPluginKey)\n }\n }, [])\n\n return (\n <div ref={element} className={props.className} style={{ visibility: 'hidden' }}>\n {props.children}\n </div>\n )\n}\n","import React from 'react'\nimport { Editor as CoreEditor } from '@tiptap/core'\nimport { EditorContentProps, EditorContentState } from './EditorContent'\n\nexport class Editor extends CoreEditor {\n public contentComponent: React.Component<EditorContentProps, EditorContentState> | null = null\n}\n","import React, { useEffect, useRef } from 'react'\nimport { FloatingMenuPlugin, FloatingMenuPluginKey, FloatingMenuPluginProps } from '@tiptap/extension-floating-menu'\n\nexport type FloatingMenuProps = Omit<FloatingMenuPluginProps, 'element'> & {\n className?: string,\n}\n\nexport const FloatingMenu: React.FC<FloatingMenuProps> = props => {\n const element = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n const { editor } = props\n\n editor.registerPlugin(FloatingMenuPlugin({\n editor,\n element: element.current as HTMLElement,\n }))\n\n return () => {\n editor.unregisterPlugin(FloatingMenuPluginKey)\n }\n }, [])\n\n return (\n <div ref={element} className={props.className} style={{ visibility: 'hidden' }}>\n {props.children}\n </div>\n )\n}\n","import { useState, useEffect } from 'react'\nimport { EditorOptions } from '@tiptap/core'\nimport { Editor } from './Editor'\n\nfunction useForceUpdate() {\n const [, setValue] = useState(0)\n\n return () => setValue(value => value + 1)\n}\n\nexport const useEditor = (options: Partial<EditorOptions> = {}) => {\n const [editor, setEditor] = useState<Editor | null>(null)\n const forceUpdate = useForceUpdate()\n\n useEffect(() => {\n const instance = new Editor(options)\n\n setEditor(instance)\n\n instance.on('transaction', forceUpdate)\n\n return () => {\n instance.destroy()\n }\n }, [])\n\n return editor\n}\n","import React from 'react'\nimport { AnyObject } from '@tiptap/core'\nimport { Editor } from './Editor'\n\nfunction isClassComponent(Component: any) {\n return !!(\n typeof Component === 'function'\n && Component.prototype\n && Component.prototype.isReactComponent\n )\n}\n\nexport interface ReactRendererOptions {\n editor: Editor,\n props?: AnyObject,\n as?: string,\n}\n\nexport class ReactRenderer {\n id: string\n\n editor: Editor\n\n component: any\n\n element: Element\n\n props: AnyObject\n\n reactElement: React.ReactNode\n\n ref: React.Component | null = null\n\n constructor(component: React.Component | React.FunctionComponent, { editor, props = {}, as = 'div' }: ReactRendererOptions) {\n this.id = Math.floor(Math.random() * 0xFFFFFFFF).toString()\n this.component = component\n this.editor = editor\n this.props = props\n this.element = document.createElement(as)\n this.element.classList.add('react-renderer')\n this.render()\n }\n\n render(): void {\n const Component = this.component\n const props = this.props\n\n if (isClassComponent(Component)) {\n props.ref = (ref: React.Component) => {\n this.ref = ref\n }\n }\n\n this.reactElement = <Component {...props } />\n\n if (this.editor?.contentComponent) {\n this.editor.contentComponent.setState({\n renderers: this.editor.contentComponent.state.renderers.set(\n this.id,\n this,\n ),\n })\n }\n }\n\n updateProps(props: AnyObject = {}): void {\n this.props = {\n ...this.props,\n ...props,\n }\n\n this.render()\n }\n\n destroy(): void {\n if (this.editor?.contentComponent) {\n const { renderers } = this.editor.contentComponent.state\n\n renderers.delete(this.id)\n\n this.editor.contentComponent.setState({\n renderers,\n })\n }\n }\n}\n","import { createContext, useContext } from 'react'\n\nexport interface ReactNodeViewContextProps {\n onDragStart: (event: DragEvent) => void,\n}\n\nexport const ReactNodeViewContext = createContext<Partial<ReactNodeViewContextProps>>({\n onDragStart: undefined,\n})\n\nexport const useReactNodeView = () => useContext(ReactNodeViewContext)\n","import React from 'react'\nimport {\n NodeView,\n NodeViewProps,\n NodeViewRenderer,\n NodeViewRendererProps,\n} from '@tiptap/core'\nimport { Decoration, NodeView as ProseMirrorNodeView } from 'prosemirror-view'\nimport { Node as ProseMirrorNode } from 'prosemirror-model'\nimport { Editor } from './Editor'\nimport { ReactRenderer } from './ReactRenderer'\nimport { ReactNodeViewContext } from './useReactNodeView'\n\ninterface ReactNodeViewRendererOptions {\n stopEvent: ((event: Event) => boolean) | null,\n update: ((node: ProseMirrorNode, decorations: Decoration[]) => boolean) | null,\n}\n\nclass ReactNodeView extends NodeView<React.FunctionComponent, Editor> {\n\n renderer!: ReactRenderer\n\n contentDOMElement!: Element | null\n\n mount() {\n const props: NodeViewProps = {\n editor: this.editor,\n node: this.node,\n decorations: this.decorations,\n selected: false,\n extension: this.extension,\n getPos: () => this.getPos(),\n updateAttributes: (attributes = {}) => this.updateAttributes(attributes),\n }\n\n if (!(this.component as any).displayName) {\n const capitalizeFirstChar = (string: string): string => {\n return string.charAt(0).toUpperCase() + string.substring(1)\n }\n\n this.component.displayName = capitalizeFirstChar(this.extension.name)\n }\n\n const ReactNodeViewProvider: React.FunctionComponent = componentProps => {\n const onDragStart = this.onDragStart.bind(this)\n const Component = this.component\n\n return (\n <ReactNodeViewContext.Provider value={{ onDragStart }}>\n <Component {...componentProps} />\n </ReactNodeViewContext.Provider>\n )\n }\n\n ReactNodeViewProvider.displayName = 'ReactNodeView'\n\n this.contentDOMElement = this.node.isLeaf\n ? null\n : document.createElement(this.node.isInline ? 'span' : 'div')\n\n this.renderer = new ReactRenderer(ReactNodeViewProvider, {\n editor: this.editor,\n props,\n as: this.node.isInline\n ? 'span'\n : 'div',\n })\n }\n\n get dom() {\n if (\n this.renderer.element.firstElementChild\n && !this.renderer.element.firstElementChild?.hasAttribute('data-node-view-wrapper')\n ) {\n throw Error('Please use the NodeViewWrapper component for your node view.')\n }\n\n return this.renderer.element\n }\n\n get contentDOM() {\n if (this.node.isLeaf) {\n return null\n }\n\n const contentElement = this.dom.querySelector('[data-node-view-content]')\n\n if (\n this.contentDOMElement\n && contentElement\n && !contentElement.contains(this.contentDOMElement)\n ) {\n contentElement.appendChild(this.contentDOMElement)\n }\n\n return this.contentDOMElement\n }\n\n update(node: ProseMirrorNode, decorations: Decoration[]) {\n if (typeof this.options.update === 'function') {\n return this.options.update(node, decorations)\n }\n\n if (node.type !== this.node.type) {\n return false\n }\n\n if (node === this.node && this.decorations === decorations) {\n return true\n }\n\n this.node = node\n this.decorations = decorations\n this.renderer.updateProps({ node, decorations })\n\n return true\n }\n\n selectNode() {\n this.renderer.updateProps({\n selected: true,\n })\n }\n\n deselectNode() {\n this.renderer.updateProps({\n selected: false,\n })\n }\n\n destroy() {\n this.renderer.destroy()\n this.contentDOMElement = null\n }\n}\n\nexport function ReactNodeViewRenderer(component: any, options?: Partial<ReactNodeViewRendererOptions>): NodeViewRenderer {\n return (props: NodeViewRendererProps) => {\n // try to get the parent component\n // this is important for vue devtools to show the component hierarchy correctly\n // maybe it’s `undefined` because <editor-content> isn’t rendered yet\n if (!(props.editor as Editor).contentComponent) {\n return {}\n }\n\n return new ReactNodeView(component, props, options) as ProseMirrorNodeView\n }\n}\n","import React from 'react'\nimport ReactDOM from 'react-dom'\nimport { Editor } from './Editor'\nimport { ReactRenderer } from './ReactRenderer'\n\nconst Portals: React.FC<{ renderers: Map<string, ReactRenderer> }> = ({ renderers }) => {\n return (\n <>\n {Array.from(renderers).map(([key, renderer]) => {\n return ReactDOM.createPortal(\n renderer.reactElement,\n renderer.element,\n key,\n )\n })}\n </>\n )\n}\n\nexport interface EditorContentProps {\n editor: Editor | null,\n}\n\nexport interface EditorContentState {\n renderers: Map<string, ReactRenderer>\n}\n\nexport class PureEditorContent extends React.Component<EditorContentProps, EditorContentState> {\n editorContentRef: React.RefObject<any>\n\n constructor(props: EditorContentProps) {\n super(props)\n this.editorContentRef = React.createRef()\n\n this.state = {\n renderers: new Map(),\n }\n }\n\n componentDidMount() {\n this.init()\n }\n\n componentDidUpdate() {\n this.init()\n }\n\n init() {\n const { editor } = this.props\n\n if (editor && editor.options.element) {\n if (editor.contentComponent) {\n return\n }\n\n const element = this.editorContentRef.current\n\n element.appendChild(editor.options.element.firstChild)\n\n editor.setOptions({\n element,\n })\n\n editor.contentComponent = this\n\n // TODO: alternative to setTimeout?\n setTimeout(() => editor.createNodeViews(), 0)\n }\n }\n\n componentWillUnmount() {\n const { editor } = this.props\n\n if (!editor) {\n return\n }\n\n if (!editor.isDestroyed) {\n editor.view.setProps({\n nodeViews: {},\n })\n }\n\n editor.contentComponent = null\n\n if (!editor.options.element.firstChild) {\n return\n }\n\n const newElement = document.createElement('div')\n\n newElement.appendChild(editor.options.element.firstChild)\n\n editor.setOptions({\n element: newElement,\n })\n }\n\n render() {\n return (\n <>\n <div ref={this.editorContentRef} />\n <Portals renderers={this.state.renderers} />\n </>\n )\n }\n}\n\nexport const EditorContent = React.memo(PureEditorContent)\n","import React from 'react'\nimport { useReactNodeView } from './useReactNodeView'\n\nexport interface NodeViewWrapperProps {\n className?: string,\n as?: React.ElementType,\n}\n\nexport const NodeViewWrapper: React.FC<NodeViewWrapperProps> = props => {\n const { onDragStart } = useReactNodeView()\n const Tag = props.as || 'div'\n\n return (\n <Tag\n className={props.className}\n data-node-view-wrapper=\"\"\n onDragStart={onDragStart}\n style={{ whiteSpace: 'normal' }}\n >\n {props.children}\n </Tag>\n )\n}\n","import React from 'react'\n\nexport interface NodeViewContentProps {\n className?: string,\n as?: React.ElementType,\n}\n\nexport const NodeViewContent: React.FC<NodeViewContentProps> = props => {\n const Tag = props.as || 'div'\n\n return (\n <Tag\n className={props.className}\n data-node-view-content=\"\"\n style={{ whiteSpace: 'pre-wrap' }}\n />\n )\n}\n"],"names":["useRef","useEffect","BubbleMenuPlugin","BubbleMenuPluginKey","React","CoreEditor","FloatingMenuPlugin","FloatingMenuPluginKey","useState","createContext","useContext","NodeView","ReactDOM"],"mappings":"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"}
1
+ {"version":3,"file":"tiptap-react.cjs.js","sources":["../src/BubbleMenu.tsx","../src/Editor.ts","../src/EditorContent.tsx","../src/FloatingMenu.tsx","../src/useReactNodeView.ts","../src/NodeViewContent.tsx","../src/NodeViewWrapper.tsx","../src/ReactRenderer.tsx","../src/ReactNodeViewRenderer.tsx","../src/useEditor.ts"],"sourcesContent":["import { BubbleMenuPlugin, BubbleMenuPluginProps } from '@tiptap/extension-bubble-menu'\nimport React, { useEffect, useState } from 'react'\n\ntype Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;\n\nexport type BubbleMenuProps = Omit<Optional<BubbleMenuPluginProps, 'pluginKey'>, 'element'> & {\n className?: string;\n children: React.ReactNode;\n delay?: number;\n};\n\nexport const BubbleMenu = (props: BubbleMenuProps) => {\n const [element, setElement] = useState<HTMLDivElement | null>(null)\n\n useEffect(() => {\n if (!element) {\n return\n }\n\n if (props.editor.isDestroyed) {\n return\n }\n\n const {\n pluginKey = 'bubbleMenu', editor, tippyOptions = {}, delay, shouldShow = null,\n } = props\n\n const plugin = BubbleMenuPlugin({\n delay,\n editor,\n element,\n pluginKey,\n shouldShow,\n tippyOptions,\n })\n\n editor.registerPlugin(plugin)\n return () => editor.unregisterPlugin(pluginKey)\n }, [props.editor, element])\n\n return (\n <div ref={setElement} className={props.className} style={{ visibility: 'hidden' }}>\n {props.children}\n </div>\n )\n}\n","import { Editor as CoreEditor } from '@tiptap/core'\nimport React from 'react'\n\nimport { EditorContentProps, EditorContentState } from './EditorContent'\n\nexport class Editor extends CoreEditor {\n public contentComponent: React.Component<EditorContentProps, EditorContentState> | null = null\n}\n","import React, { HTMLProps } from 'react'\nimport ReactDOM from 'react-dom'\n\nimport { Editor } from './Editor'\nimport { ReactRenderer } from './ReactRenderer'\n\nconst Portals: React.FC<{ renderers: Map<string, ReactRenderer> }> = ({ renderers }) => {\n return (\n <>\n {Array.from(renderers).map(([key, renderer]) => {\n return ReactDOM.createPortal(\n renderer.reactElement,\n renderer.element,\n key,\n )\n })}\n </>\n )\n}\n\nexport interface EditorContentProps extends HTMLProps<HTMLDivElement> {\n editor: Editor | null,\n}\n\nexport interface EditorContentState {\n renderers: Map<string, ReactRenderer>\n}\n\nexport class PureEditorContent extends React.Component<EditorContentProps, EditorContentState> {\n editorContentRef: React.RefObject<any>\n\n constructor(props: EditorContentProps) {\n super(props)\n this.editorContentRef = React.createRef()\n\n this.state = {\n renderers: new Map(),\n }\n }\n\n componentDidMount() {\n this.init()\n }\n\n componentDidUpdate() {\n this.init()\n }\n\n init() {\n const { editor } = this.props\n\n if (editor && editor.options.element) {\n if (editor.contentComponent) {\n return\n }\n\n const element = this.editorContentRef.current\n\n element.append(...editor.options.element.childNodes)\n\n editor.setOptions({\n element,\n })\n\n editor.contentComponent = this\n\n editor.createNodeViews()\n }\n }\n\n componentWillUnmount() {\n const { editor } = this.props\n\n if (!editor) {\n return\n }\n\n if (!editor.isDestroyed) {\n editor.view.setProps({\n nodeViews: {},\n })\n }\n\n editor.contentComponent = null\n\n if (!editor.options.element.firstChild) {\n return\n }\n\n const newElement = document.createElement('div')\n\n newElement.append(...editor.options.element.childNodes)\n\n editor.setOptions({\n element: newElement,\n })\n }\n\n render() {\n const { editor, ...rest } = this.props\n\n return (\n <>\n <div ref={this.editorContentRef} {...rest} />\n <Portals renderers={this.state.renderers} />\n </>\n )\n }\n}\n\nexport const EditorContent = React.memo(PureEditorContent)\n","import { FloatingMenuPlugin, FloatingMenuPluginProps } from '@tiptap/extension-floating-menu'\nimport React, {\n useEffect, useState,\n} from 'react'\n\ntype Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>\n\nexport type FloatingMenuProps = Omit<Optional<FloatingMenuPluginProps, 'pluginKey'>, 'element'> & {\n className?: string,\n children: React.ReactNode\n}\n\nexport const FloatingMenu = (props: FloatingMenuProps) => {\n const [element, setElement] = useState<HTMLDivElement | null>(null)\n\n useEffect(() => {\n if (!element) {\n return\n }\n\n if (props.editor.isDestroyed) {\n return\n }\n\n const {\n pluginKey = 'floatingMenu',\n editor,\n tippyOptions = {},\n shouldShow = null,\n } = props\n\n const plugin = FloatingMenuPlugin({\n pluginKey,\n editor,\n element,\n tippyOptions,\n shouldShow,\n })\n\n editor.registerPlugin(plugin)\n return () => editor.unregisterPlugin(pluginKey)\n }, [\n props.editor,\n element,\n ])\n\n return (\n <div ref={setElement} className={props.className} style={{ visibility: 'hidden' }}>\n {props.children}\n </div>\n )\n}\n","import { createContext, useContext } from 'react'\n\nexport interface ReactNodeViewContextProps {\n onDragStart: (event: DragEvent) => void,\n nodeViewContentRef: (element: HTMLElement | null) => void,\n}\n\nexport const ReactNodeViewContext = createContext<Partial<ReactNodeViewContextProps>>({\n onDragStart: undefined,\n})\n\nexport const useReactNodeView = () => useContext(ReactNodeViewContext)\n","import React from 'react'\n\nimport { useReactNodeView } from './useReactNodeView'\n\nexport interface NodeViewContentProps {\n [key: string]: any,\n as?: React.ElementType,\n}\n\nexport const NodeViewContent: React.FC<NodeViewContentProps> = props => {\n const Tag = props.as || 'div'\n const { nodeViewContentRef } = useReactNodeView()\n\n return (\n <Tag\n {...props}\n ref={nodeViewContentRef}\n data-node-view-content=\"\"\n style={{\n whiteSpace: 'pre-wrap',\n ...props.style,\n }}\n />\n )\n}\n","import React from 'react'\n\nimport { useReactNodeView } from './useReactNodeView'\n\nexport interface NodeViewWrapperProps {\n [key: string]: any,\n as?: React.ElementType,\n}\n\nexport const NodeViewWrapper: React.FC<NodeViewWrapperProps> = React.forwardRef((props, ref) => {\n const { onDragStart } = useReactNodeView()\n const Tag = props.as || 'div'\n\n return (\n <Tag\n {...props}\n ref={ref}\n data-node-view-wrapper=\"\"\n onDragStart={onDragStart}\n style={{\n whiteSpace: 'normal',\n ...props.style,\n }}\n />\n )\n})\n","import { Editor } from '@tiptap/core'\nimport React from 'react'\nimport { flushSync } from 'react-dom'\n\nimport { Editor as ExtendedEditor } from './Editor'\n\nfunction isClassComponent(Component: any) {\n return !!(\n typeof Component === 'function'\n && Component.prototype\n && Component.prototype.isReactComponent\n )\n}\n\nfunction isForwardRefComponent(Component: any) {\n return !!(\n typeof Component === 'object'\n && Component.$$typeof?.toString() === 'Symbol(react.forward_ref)'\n )\n}\n\nexport interface ReactRendererOptions {\n editor: Editor,\n props?: Record<string, any>,\n as?: string,\n className?: string,\n}\n\ntype ComponentType<R, P> =\n React.ComponentClass<P> |\n React.FunctionComponent<P> |\n React.ForwardRefExoticComponent<React.PropsWithoutRef<P> & React.RefAttributes<R>>;\n\nexport class ReactRenderer<R = unknown, P = unknown> {\n id: string\n\n editor: ExtendedEditor\n\n component: any\n\n element: Element\n\n props: Record<string, any>\n\n reactElement: React.ReactNode\n\n ref: R | null = null\n\n constructor(component: ComponentType<R, P>, {\n editor,\n props = {},\n as = 'div',\n className = '',\n }: ReactRendererOptions) {\n this.id = Math.floor(Math.random() * 0xFFFFFFFF).toString()\n this.component = component\n this.editor = editor as ExtendedEditor\n this.props = props\n this.element = document.createElement(as)\n this.element.classList.add('react-renderer')\n\n if (className) {\n this.element.classList.add(...className.split(' '))\n }\n\n this.render()\n }\n\n render(): void {\n const Component = this.component\n const props = this.props\n\n if (isClassComponent(Component) || isForwardRefComponent(Component)) {\n props.ref = (ref: R) => {\n this.ref = ref\n }\n }\n\n this.reactElement = <Component {...props } />\n\n queueMicrotask(() => {\n flushSync(() => {\n if (this.editor?.contentComponent) {\n this.editor.contentComponent.setState({\n renderers: this.editor.contentComponent.state.renderers.set(\n this.id,\n this,\n ),\n })\n }\n })\n })\n }\n\n updateProps(props: Record<string, any> = {}): void {\n this.props = {\n ...this.props,\n ...props,\n }\n\n this.render()\n }\n\n destroy(): void {\n queueMicrotask(() => {\n flushSync(() => {\n if (this.editor?.contentComponent) {\n const { renderers } = this.editor.contentComponent.state\n\n renderers.delete(this.id)\n\n this.editor.contentComponent.setState({\n renderers,\n })\n }\n })\n })\n }\n}\n","import {\n NodeView,\n NodeViewProps,\n NodeViewRenderer,\n NodeViewRendererOptions,\n NodeViewRendererProps,\n} from '@tiptap/core'\nimport { Node as ProseMirrorNode } from 'prosemirror-model'\nimport { Decoration, NodeView as ProseMirrorNodeView } from 'prosemirror-view'\nimport React from 'react'\n\nimport { Editor } from './Editor'\nimport { ReactRenderer } from './ReactRenderer'\nimport { ReactNodeViewContext, ReactNodeViewContextProps } from './useReactNodeView'\n\nexport interface ReactNodeViewRendererOptions extends NodeViewRendererOptions {\n update:\n | ((props: {\n oldNode: ProseMirrorNode;\n oldDecorations: Decoration[];\n newNode: ProseMirrorNode;\n newDecorations: Decoration[];\n updateProps: () => void;\n }) => boolean)\n | null;\n as?: string;\n className?: string;\n}\n\nclass ReactNodeView extends NodeView<\n React.FunctionComponent,\n Editor,\n ReactNodeViewRendererOptions\n> {\n renderer!: ReactRenderer\n\n contentDOMElement!: HTMLElement | null\n\n mount() {\n const props: NodeViewProps = {\n editor: this.editor,\n node: this.node,\n decorations: this.decorations,\n selected: false,\n extension: this.extension,\n getPos: () => this.getPos(),\n updateAttributes: (attributes = {}) => this.updateAttributes(attributes),\n deleteNode: () => this.deleteNode(),\n }\n\n if (!(this.component as any).displayName) {\n const capitalizeFirstChar = (string: string): string => {\n return string.charAt(0).toUpperCase() + string.substring(1)\n }\n\n this.component.displayName = capitalizeFirstChar(this.extension.name)\n }\n\n const ReactNodeViewProvider: React.FunctionComponent = componentProps => {\n const Component = this.component\n const onDragStart = this.onDragStart.bind(this)\n const nodeViewContentRef: ReactNodeViewContextProps['nodeViewContentRef'] = element => {\n if (element && this.contentDOMElement && element.firstChild !== this.contentDOMElement) {\n element.appendChild(this.contentDOMElement)\n }\n }\n\n return (\n <ReactNodeViewContext.Provider value={{ onDragStart, nodeViewContentRef }}>\n <Component {...componentProps} />\n </ReactNodeViewContext.Provider>\n )\n }\n\n ReactNodeViewProvider.displayName = 'ReactNodeView'\n\n this.contentDOMElement = this.node.isLeaf\n ? null\n : document.createElement(this.node.isInline ? 'span' : 'div')\n\n if (this.contentDOMElement) {\n // For some reason the whiteSpace prop is not inherited properly in Chrome and Safari\n // With this fix it seems to work fine\n // See: https://github.com/ueberdosis/tiptap/issues/1197\n this.contentDOMElement.style.whiteSpace = 'inherit'\n }\n\n let as = this.node.isInline ? 'span' : 'div'\n\n if (this.options.as) {\n as = this.options.as\n }\n\n const { className = '' } = this.options\n\n this.renderer = new ReactRenderer(ReactNodeViewProvider, {\n editor: this.editor,\n props,\n as,\n className: `node-${this.node.type.name} ${className}`.trim(),\n })\n }\n\n get dom() {\n if (\n this.renderer.element.firstElementChild\n && !this.renderer.element.firstElementChild?.hasAttribute('data-node-view-wrapper')\n ) {\n throw Error('Please use the NodeViewWrapper component for your node view.')\n }\n\n return this.renderer.element as HTMLElement\n }\n\n get contentDOM() {\n if (this.node.isLeaf) {\n return null\n }\n\n return this.contentDOMElement\n }\n\n update(node: ProseMirrorNode, decorations: Decoration[]) {\n const updateProps = (props?: Record<string, any>) => {\n this.renderer.updateProps(props)\n }\n\n if (node.type !== this.node.type) {\n return false\n }\n\n if (typeof this.options.update === 'function') {\n const oldNode = this.node\n const oldDecorations = this.decorations\n\n this.node = node\n this.decorations = decorations\n\n return this.options.update({\n oldNode,\n oldDecorations,\n newNode: node,\n newDecorations: decorations,\n updateProps: () => updateProps({ node, decorations }),\n })\n }\n\n if (node === this.node && this.decorations === decorations) {\n return true\n }\n\n this.node = node\n this.decorations = decorations\n\n updateProps({ node, decorations })\n\n return true\n }\n\n selectNode() {\n this.renderer.updateProps({\n selected: true,\n })\n }\n\n deselectNode() {\n this.renderer.updateProps({\n selected: false,\n })\n }\n\n destroy() {\n this.renderer.destroy()\n this.contentDOMElement = null\n }\n}\n\nexport function ReactNodeViewRenderer(\n component: any,\n options?: Partial<ReactNodeViewRendererOptions>,\n): NodeViewRenderer {\n return (props: NodeViewRendererProps) => {\n // try to get the parent component\n // this is important for vue devtools to show the component hierarchy correctly\n // maybe it’s `undefined` because <editor-content> isn’t rendered yet\n if (!(props.editor as Editor).contentComponent) {\n return {}\n }\n\n return new ReactNodeView(component, props, options) as unknown as ProseMirrorNodeView\n }\n}\n","import { EditorOptions } from '@tiptap/core'\nimport { DependencyList, useEffect, useState } from 'react'\n\nimport { Editor } from './Editor'\n\nfunction useForceUpdate() {\n const [, setValue] = useState(0)\n\n return () => setValue(value => value + 1)\n}\n\nexport const useEditor = (options: Partial<EditorOptions> = {}, deps: DependencyList = []) => {\n const [editor, setEditor] = useState<Editor | null>(null)\n const forceUpdate = useForceUpdate()\n\n useEffect(() => {\n let isMounted = true\n\n const instance = new Editor(options)\n\n setEditor(instance)\n\n instance.on('transaction', () => {\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n if (isMounted) {\n forceUpdate()\n }\n })\n })\n })\n\n return () => {\n instance.destroy()\n isMounted = false\n }\n }, deps)\n\n return editor\n}\n"],"names":["useState","useEffect","BubbleMenuPlugin","React","CoreEditor","ReactDOM","FloatingMenuPlugin","createContext","useContext","flushSync","NodeView"],"mappings":"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"}
@@ -1,24 +1,32 @@
1
+ import { BubbleMenuPlugin } from '@tiptap/extension-bubble-menu';
2
+ import React, { useState, useEffect, createContext, useContext } from 'react';
1
3
  import { Editor as Editor$1, NodeView } from '@tiptap/core';
2
4
  export * from '@tiptap/core';
3
- import React, { useRef, useEffect, useState, createContext, useContext } from 'react';
4
- import { BubbleMenuPlugin, BubbleMenuPluginKey } from '@tiptap/extension-bubble-menu';
5
- import { FloatingMenuPlugin, FloatingMenuPluginKey } from '@tiptap/extension-floating-menu';
6
- import ReactDOM from 'react-dom';
5
+ import ReactDOM, { flushSync } from 'react-dom';
6
+ import { FloatingMenuPlugin } from '@tiptap/extension-floating-menu';
7
7
 
8
- const BubbleMenu = props => {
9
- const element = useRef(null);
8
+ const BubbleMenu = (props) => {
9
+ const [element, setElement] = useState(null);
10
10
  useEffect(() => {
11
- const { editor, keepInBounds = true } = props;
12
- editor.registerPlugin(BubbleMenuPlugin({
11
+ if (!element) {
12
+ return;
13
+ }
14
+ if (props.editor.isDestroyed) {
15
+ return;
16
+ }
17
+ const { pluginKey = 'bubbleMenu', editor, tippyOptions = {}, delay, shouldShow = null, } = props;
18
+ const plugin = BubbleMenuPlugin({
19
+ delay,
13
20
  editor,
14
- element: element.current,
15
- keepInBounds,
16
- }));
17
- return () => {
18
- editor.unregisterPlugin(BubbleMenuPluginKey);
19
- };
20
- }, []);
21
- return (React.createElement("div", { ref: element, className: props.className, style: { visibility: 'hidden' } }, props.children));
21
+ element,
22
+ pluginKey,
23
+ shouldShow,
24
+ tippyOptions,
25
+ });
26
+ editor.registerPlugin(plugin);
27
+ return () => editor.unregisterPlugin(pluginKey);
28
+ }, [props.editor, element]);
29
+ return (React.createElement("div", { ref: setElement, className: props.className, style: { visibility: 'hidden' } }, props.children));
22
30
  };
23
31
 
24
32
  class Editor extends Editor$1 {
@@ -28,46 +36,130 @@ class Editor extends Editor$1 {
28
36
  }
29
37
  }
30
38
 
31
- const FloatingMenu = props => {
32
- const element = useRef(null);
39
+ const Portals = ({ renderers }) => {
40
+ return (React.createElement(React.Fragment, null, Array.from(renderers).map(([key, renderer]) => {
41
+ return ReactDOM.createPortal(renderer.reactElement, renderer.element, key);
42
+ })));
43
+ };
44
+ class PureEditorContent extends React.Component {
45
+ constructor(props) {
46
+ super(props);
47
+ this.editorContentRef = React.createRef();
48
+ this.state = {
49
+ renderers: new Map(),
50
+ };
51
+ }
52
+ componentDidMount() {
53
+ this.init();
54
+ }
55
+ componentDidUpdate() {
56
+ this.init();
57
+ }
58
+ init() {
59
+ const { editor } = this.props;
60
+ if (editor && editor.options.element) {
61
+ if (editor.contentComponent) {
62
+ return;
63
+ }
64
+ const element = this.editorContentRef.current;
65
+ element.append(...editor.options.element.childNodes);
66
+ editor.setOptions({
67
+ element,
68
+ });
69
+ editor.contentComponent = this;
70
+ editor.createNodeViews();
71
+ }
72
+ }
73
+ componentWillUnmount() {
74
+ const { editor } = this.props;
75
+ if (!editor) {
76
+ return;
77
+ }
78
+ if (!editor.isDestroyed) {
79
+ editor.view.setProps({
80
+ nodeViews: {},
81
+ });
82
+ }
83
+ editor.contentComponent = null;
84
+ if (!editor.options.element.firstChild) {
85
+ return;
86
+ }
87
+ const newElement = document.createElement('div');
88
+ newElement.append(...editor.options.element.childNodes);
89
+ editor.setOptions({
90
+ element: newElement,
91
+ });
92
+ }
93
+ render() {
94
+ const { editor, ...rest } = this.props;
95
+ return (React.createElement(React.Fragment, null,
96
+ React.createElement("div", { ref: this.editorContentRef, ...rest }),
97
+ React.createElement(Portals, { renderers: this.state.renderers })));
98
+ }
99
+ }
100
+ const EditorContent = React.memo(PureEditorContent);
101
+
102
+ const FloatingMenu = (props) => {
103
+ const [element, setElement] = useState(null);
33
104
  useEffect(() => {
34
- const { editor } = props;
35
- editor.registerPlugin(FloatingMenuPlugin({
105
+ if (!element) {
106
+ return;
107
+ }
108
+ if (props.editor.isDestroyed) {
109
+ return;
110
+ }
111
+ const { pluginKey = 'floatingMenu', editor, tippyOptions = {}, shouldShow = null, } = props;
112
+ const plugin = FloatingMenuPlugin({
113
+ pluginKey,
36
114
  editor,
37
- element: element.current,
38
- }));
39
- return () => {
40
- editor.unregisterPlugin(FloatingMenuPluginKey);
41
- };
42
- }, []);
43
- return (React.createElement("div", { ref: element, className: props.className, style: { visibility: 'hidden' } }, props.children));
115
+ element,
116
+ tippyOptions,
117
+ shouldShow,
118
+ });
119
+ editor.registerPlugin(plugin);
120
+ return () => editor.unregisterPlugin(pluginKey);
121
+ }, [
122
+ props.editor,
123
+ element,
124
+ ]);
125
+ return (React.createElement("div", { ref: setElement, className: props.className, style: { visibility: 'hidden' } }, props.children));
44
126
  };
45
127
 
46
- function useForceUpdate() {
47
- const [, setValue] = useState(0);
48
- return () => setValue(value => value + 1);
49
- }
50
- const useEditor = (options = {}) => {
51
- const [editor, setEditor] = useState(null);
52
- const forceUpdate = useForceUpdate();
53
- useEffect(() => {
54
- const instance = new Editor(options);
55
- setEditor(instance);
56
- instance.on('transaction', forceUpdate);
57
- return () => {
58
- instance.destroy();
59
- };
60
- }, []);
61
- return editor;
128
+ const ReactNodeViewContext = createContext({
129
+ onDragStart: undefined,
130
+ });
131
+ const useReactNodeView = () => useContext(ReactNodeViewContext);
132
+
133
+ const NodeViewContent = props => {
134
+ const Tag = props.as || 'div';
135
+ const { nodeViewContentRef } = useReactNodeView();
136
+ return (React.createElement(Tag, { ...props, ref: nodeViewContentRef, "data-node-view-content": "", style: {
137
+ whiteSpace: 'pre-wrap',
138
+ ...props.style,
139
+ } }));
62
140
  };
63
141
 
142
+ const NodeViewWrapper = React.forwardRef((props, ref) => {
143
+ const { onDragStart } = useReactNodeView();
144
+ const Tag = props.as || 'div';
145
+ return (React.createElement(Tag, { ...props, ref: ref, "data-node-view-wrapper": "", onDragStart: onDragStart, style: {
146
+ whiteSpace: 'normal',
147
+ ...props.style,
148
+ } }));
149
+ });
150
+
64
151
  function isClassComponent(Component) {
65
152
  return !!(typeof Component === 'function'
66
153
  && Component.prototype
67
154
  && Component.prototype.isReactComponent);
68
155
  }
156
+ function isForwardRefComponent(Component) {
157
+ var _a;
158
+ return !!(typeof Component === 'object'
159
+ && ((_a = Component.$$typeof) === null || _a === void 0 ? void 0 : _a.toString()) === 'Symbol(react.forward_ref)');
160
+ }
69
161
  class ReactRenderer {
70
- constructor(component, { editor, props = {}, as = 'div' }) {
162
+ constructor(component, { editor, props = {}, as = 'div', className = '', }) {
71
163
  this.ref = null;
72
164
  this.id = Math.floor(Math.random() * 0xFFFFFFFF).toString();
73
165
  this.component = component;
@@ -75,23 +167,30 @@ class ReactRenderer {
75
167
  this.props = props;
76
168
  this.element = document.createElement(as);
77
169
  this.element.classList.add('react-renderer');
170
+ if (className) {
171
+ this.element.classList.add(...className.split(' '));
172
+ }
78
173
  this.render();
79
174
  }
80
175
  render() {
81
- var _a;
82
176
  const Component = this.component;
83
177
  const props = this.props;
84
- if (isClassComponent(Component)) {
178
+ if (isClassComponent(Component) || isForwardRefComponent(Component)) {
85
179
  props.ref = (ref) => {
86
180
  this.ref = ref;
87
181
  };
88
182
  }
89
- this.reactElement = React.createElement(Component, Object.assign({}, props));
90
- if ((_a = this.editor) === null || _a === void 0 ? void 0 : _a.contentComponent) {
91
- this.editor.contentComponent.setState({
92
- renderers: this.editor.contentComponent.state.renderers.set(this.id, this),
183
+ this.reactElement = React.createElement(Component, { ...props });
184
+ queueMicrotask(() => {
185
+ flushSync(() => {
186
+ var _a;
187
+ if ((_a = this.editor) === null || _a === void 0 ? void 0 : _a.contentComponent) {
188
+ this.editor.contentComponent.setState({
189
+ renderers: this.editor.contentComponent.state.renderers.set(this.id, this),
190
+ });
191
+ }
93
192
  });
94
- }
193
+ });
95
194
  }
96
195
  updateProps(props = {}) {
97
196
  this.props = {
@@ -101,22 +200,21 @@ class ReactRenderer {
101
200
  this.render();
102
201
  }
103
202
  destroy() {
104
- var _a;
105
- if ((_a = this.editor) === null || _a === void 0 ? void 0 : _a.contentComponent) {
106
- const { renderers } = this.editor.contentComponent.state;
107
- renderers.delete(this.id);
108
- this.editor.contentComponent.setState({
109
- renderers,
203
+ queueMicrotask(() => {
204
+ flushSync(() => {
205
+ var _a;
206
+ if ((_a = this.editor) === null || _a === void 0 ? void 0 : _a.contentComponent) {
207
+ const { renderers } = this.editor.contentComponent.state;
208
+ renderers.delete(this.id);
209
+ this.editor.contentComponent.setState({
210
+ renderers,
211
+ });
212
+ }
110
213
  });
111
- }
214
+ });
112
215
  }
113
216
  }
114
217
 
115
- const ReactNodeViewContext = createContext({
116
- onDragStart: undefined,
117
- });
118
- const useReactNodeView = () => useContext(ReactNodeViewContext);
119
-
120
218
  class ReactNodeView extends NodeView {
121
219
  mount() {
122
220
  const props = {
@@ -127,6 +225,7 @@ class ReactNodeView extends NodeView {
127
225
  extension: this.extension,
128
226
  getPos: () => this.getPos(),
129
227
  updateAttributes: (attributes = {}) => this.updateAttributes(attributes),
228
+ deleteNode: () => this.deleteNode(),
130
229
  };
131
230
  if (!this.component.displayName) {
132
231
  const capitalizeFirstChar = (string) => {
@@ -135,21 +234,36 @@ class ReactNodeView extends NodeView {
135
234
  this.component.displayName = capitalizeFirstChar(this.extension.name);
136
235
  }
137
236
  const ReactNodeViewProvider = componentProps => {
138
- const onDragStart = this.onDragStart.bind(this);
139
237
  const Component = this.component;
140
- return (React.createElement(ReactNodeViewContext.Provider, { value: { onDragStart } },
141
- React.createElement(Component, Object.assign({}, componentProps))));
238
+ const onDragStart = this.onDragStart.bind(this);
239
+ const nodeViewContentRef = element => {
240
+ if (element && this.contentDOMElement && element.firstChild !== this.contentDOMElement) {
241
+ element.appendChild(this.contentDOMElement);
242
+ }
243
+ };
244
+ return (React.createElement(ReactNodeViewContext.Provider, { value: { onDragStart, nodeViewContentRef } },
245
+ React.createElement(Component, { ...componentProps })));
142
246
  };
143
247
  ReactNodeViewProvider.displayName = 'ReactNodeView';
144
248
  this.contentDOMElement = this.node.isLeaf
145
249
  ? null
146
250
  : document.createElement(this.node.isInline ? 'span' : 'div');
251
+ if (this.contentDOMElement) {
252
+ // For some reason the whiteSpace prop is not inherited properly in Chrome and Safari
253
+ // With this fix it seems to work fine
254
+ // See: https://github.com/ueberdosis/tiptap/issues/1197
255
+ this.contentDOMElement.style.whiteSpace = 'inherit';
256
+ }
257
+ let as = this.node.isInline ? 'span' : 'div';
258
+ if (this.options.as) {
259
+ as = this.options.as;
260
+ }
261
+ const { className = '' } = this.options;
147
262
  this.renderer = new ReactRenderer(ReactNodeViewProvider, {
148
263
  editor: this.editor,
149
264
  props,
150
- as: this.node.isInline
151
- ? 'span'
152
- : 'div',
265
+ as,
266
+ className: `node-${this.node.type.name} ${className}`.trim(),
153
267
  });
154
268
  }
155
269
  get dom() {
@@ -164,27 +278,34 @@ class ReactNodeView extends NodeView {
164
278
  if (this.node.isLeaf) {
165
279
  return null;
166
280
  }
167
- const contentElement = this.dom.querySelector('[data-node-view-content]');
168
- if (this.contentDOMElement
169
- && contentElement
170
- && !contentElement.contains(this.contentDOMElement)) {
171
- contentElement.appendChild(this.contentDOMElement);
172
- }
173
281
  return this.contentDOMElement;
174
282
  }
175
283
  update(node, decorations) {
176
- if (typeof this.options.update === 'function') {
177
- return this.options.update(node, decorations);
178
- }
284
+ const updateProps = (props) => {
285
+ this.renderer.updateProps(props);
286
+ };
179
287
  if (node.type !== this.node.type) {
180
288
  return false;
181
289
  }
290
+ if (typeof this.options.update === 'function') {
291
+ const oldNode = this.node;
292
+ const oldDecorations = this.decorations;
293
+ this.node = node;
294
+ this.decorations = decorations;
295
+ return this.options.update({
296
+ oldNode,
297
+ oldDecorations,
298
+ newNode: node,
299
+ newDecorations: decorations,
300
+ updateProps: () => updateProps({ node, decorations }),
301
+ });
302
+ }
182
303
  if (node === this.node && this.decorations === decorations) {
183
304
  return true;
184
305
  }
185
306
  this.node = node;
186
307
  this.decorations = decorations;
187
- this.renderer.updateProps({ node, decorations });
308
+ updateProps({ node, decorations });
188
309
  return true;
189
310
  }
190
311
  selectNode() {
@@ -214,78 +335,32 @@ function ReactNodeViewRenderer(component, options) {
214
335
  };
215
336
  }
216
337
 
217
- const Portals = ({ renderers }) => {
218
- return (React.createElement(React.Fragment, null, Array.from(renderers).map(([key, renderer]) => {
219
- return ReactDOM.createPortal(renderer.reactElement, renderer.element, key);
220
- })));
221
- };
222
- class PureEditorContent extends React.Component {
223
- constructor(props) {
224
- super(props);
225
- this.editorContentRef = React.createRef();
226
- this.state = {
227
- renderers: new Map(),
228
- };
229
- }
230
- componentDidMount() {
231
- this.init();
232
- }
233
- componentDidUpdate() {
234
- this.init();
235
- }
236
- init() {
237
- const { editor } = this.props;
238
- if (editor && editor.options.element) {
239
- if (editor.contentComponent) {
240
- return;
241
- }
242
- const element = this.editorContentRef.current;
243
- element.appendChild(editor.options.element.firstChild);
244
- editor.setOptions({
245
- element,
246
- });
247
- editor.contentComponent = this;
248
- // TODO: alternative to setTimeout?
249
- setTimeout(() => editor.createNodeViews(), 0);
250
- }
251
- }
252
- componentWillUnmount() {
253
- const { editor } = this.props;
254
- if (!editor) {
255
- return;
256
- }
257
- if (!editor.isDestroyed) {
258
- editor.view.setProps({
259
- nodeViews: {},
338
+ function useForceUpdate() {
339
+ const [, setValue] = useState(0);
340
+ return () => setValue(value => value + 1);
341
+ }
342
+ const useEditor = (options = {}, deps = []) => {
343
+ const [editor, setEditor] = useState(null);
344
+ const forceUpdate = useForceUpdate();
345
+ useEffect(() => {
346
+ let isMounted = true;
347
+ const instance = new Editor(options);
348
+ setEditor(instance);
349
+ instance.on('transaction', () => {
350
+ requestAnimationFrame(() => {
351
+ requestAnimationFrame(() => {
352
+ if (isMounted) {
353
+ forceUpdate();
354
+ }
355
+ });
260
356
  });
261
- }
262
- editor.contentComponent = null;
263
- if (!editor.options.element.firstChild) {
264
- return;
265
- }
266
- const newElement = document.createElement('div');
267
- newElement.appendChild(editor.options.element.firstChild);
268
- editor.setOptions({
269
- element: newElement,
270
357
  });
271
- }
272
- render() {
273
- return (React.createElement(React.Fragment, null,
274
- React.createElement("div", { ref: this.editorContentRef }),
275
- React.createElement(Portals, { renderers: this.state.renderers })));
276
- }
277
- }
278
- const EditorContent = React.memo(PureEditorContent);
279
-
280
- const NodeViewWrapper = props => {
281
- const { onDragStart } = useReactNodeView();
282
- const Tag = props.as || 'div';
283
- return (React.createElement(Tag, { className: props.className, "data-node-view-wrapper": "", onDragStart: onDragStart, style: { whiteSpace: 'normal' } }, props.children));
284
- };
285
-
286
- const NodeViewContent = props => {
287
- const Tag = props.as || 'div';
288
- return (React.createElement(Tag, { className: props.className, "data-node-view-content": "", style: { whiteSpace: 'pre-wrap' } }));
358
+ return () => {
359
+ instance.destroy();
360
+ isMounted = false;
361
+ };
362
+ }, deps);
363
+ return editor;
289
364
  };
290
365
 
291
366
  export { BubbleMenu, Editor, EditorContent, FloatingMenu, NodeViewContent, NodeViewWrapper, PureEditorContent, ReactNodeViewRenderer, ReactRenderer, useEditor };