@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.
- package/README.md +2 -2
- package/dist/packages/react/src/BubbleMenu.d.ts +7 -3
- package/dist/packages/react/src/Editor.d.ts +1 -1
- package/dist/packages/react/src/EditorContent.d.ts +2 -2
- package/dist/packages/react/src/FloatingMenu.d.ts +6 -3
- package/dist/packages/react/src/NodeViewContent.d.ts +1 -1
- package/dist/packages/react/src/NodeViewWrapper.d.ts +1 -1
- package/dist/packages/react/src/ReactNodeViewRenderer.d.ts +12 -6
- package/dist/packages/react/src/ReactRenderer.d.ts +12 -9
- package/dist/packages/react/src/index.d.ts +6 -6
- package/dist/packages/react/src/useEditor.d.ts +2 -1
- package/dist/packages/react/src/useReactNodeView.d.ts +1 -0
- package/dist/tiptap-react.cjs.js +224 -151
- package/dist/tiptap-react.cjs.js.map +1 -1
- package/dist/tiptap-react.esm.js +224 -149
- package/dist/tiptap-react.esm.js.map +1 -1
- package/dist/tiptap-react.umd.js +226 -153
- package/dist/tiptap-react.umd.js.map +1 -1
- package/package.json +18 -12
- package/src/BubbleMenu.tsx +33 -17
- package/src/Editor.ts +2 -1
- package/src/EditorContent.tsx +9 -7
- package/src/FloatingMenu.tsx +37 -14
- package/src/NodeViewContent.tsx +10 -3
- package/src/NodeViewWrapper.tsx +11 -8
- package/src/ReactNodeViewRenderer.tsx +75 -31
- package/src/ReactRenderer.tsx +58 -25
- package/src/index.ts +6 -6
- package/src/useEditor.ts +16 -4
- package/src/useReactNodeView.ts +1 -0
- package/CHANGELOG.md +0 -178
- package/LICENSE.md +0 -21
- package/dist/tiptap-react.bundle.umd.min.js +0 -54
- 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":";;;;;;;;;;;;;;;MAOa,UAAU,GAA8B,KAAK;IACxD,MAAM,OAAO,GAAGA,YAAM,CAAiB,IAAI,CAAC,CAAA;IAE5CC,eAAS,CAAC;QACR,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,EAAE,GAAG,KAAK,CAAA;QAE7C,MAAM,CAAC,cAAc,CAACC,oCAAgB,CAAC;YACrC,MAAM;YACN,OAAO,EAAE,OAAO,CAAC,OAAsB;YACvC,YAAY;SACb,CAAC,CAAC,CAAA;QAEH,OAAO;YACL,MAAM,CAAC,gBAAgB,CAACC,uCAAmB,CAAC,CAAA;SAC7C,CAAA;KACF,EAAE,EAAE,CAAC,CAAA;IAEN,QACEC,iDAAK,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,IAC3E,KAAK,CAAC,QAAQ,CACX,EACP;AACH;;MCzBa,MAAO,SAAQC,WAAU;IAAtC;;QACS,qBAAgB,GAAmE,IAAI,CAAA;KAC/F;;;MCCY,YAAY,GAAgC,KAAK;IAC5D,MAAM,OAAO,GAAGL,YAAM,CAAiB,IAAI,CAAC,CAAA;IAE5CC,eAAS,CAAC;QACR,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;QAExB,MAAM,CAAC,cAAc,CAACK,wCAAkB,CAAC;YACvC,MAAM;YACN,OAAO,EAAE,OAAO,CAAC,OAAsB;SACxC,CAAC,CAAC,CAAA;QAEH,OAAO;YACL,MAAM,CAAC,gBAAgB,CAACC,2CAAqB,CAAC,CAAA;SAC/C,CAAA;KACF,EAAE,EAAE,CAAC,CAAA;IAEN,QACEH,iDAAK,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,IAC3E,KAAK,CAAC,QAAQ,CACX,EACP;AACH;;ACxBA,SAAS,cAAc;IACrB,MAAM,GAAG,QAAQ,CAAC,GAAGI,cAAQ,CAAC,CAAC,CAAC,CAAA;IAEhC,OAAO,MAAM,QAAQ,CAAC,KAAK,IAAI,KAAK,GAAG,CAAC,CAAC,CAAA;AAC3C,CAAC;MAEY,SAAS,GAAG,CAAC,UAAkC,EAAE;IAC5D,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAGA,cAAQ,CAAgB,IAAI,CAAC,CAAA;IACzD,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IAEpCP,eAAS,CAAC;QACR,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,CAAA;QAEpC,SAAS,CAAC,QAAQ,CAAC,CAAA;QAEnB,QAAQ,CAAC,EAAE,CAAC,aAAa,EAAE,WAAW,CAAC,CAAA;QAEvC,OAAO;YACL,QAAQ,CAAC,OAAO,EAAE,CAAA;SACnB,CAAA;KACF,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,MAAM,CAAA;AACf;;ACvBA,SAAS,gBAAgB,CAAC,SAAc;IACtC,OAAO,CAAC,EACN,OAAO,SAAS,KAAK,UAAU;WAC5B,SAAS,CAAC,SAAS;WACnB,SAAS,CAAC,SAAS,CAAC,gBAAgB,CACxC,CAAA;AACH,CAAC;MAQY,aAAa;IAexB,YAAY,SAAoD,EAAE,EAAE,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,GAAG,KAAK,EAAwB;QAF1H,QAAG,GAA2B,IAAI,CAAA;QAGhC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAA;QAC3D,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,CAAA;QACzC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAA;QAC5C,IAAI,CAAC,MAAM,EAAE,CAAA;KACd;IAED,MAAM;;QACJ,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAA;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;QAExB,IAAI,gBAAgB,CAAC,SAAS,CAAC,EAAE;YAC/B,KAAK,CAAC,GAAG,GAAG,CAAC,GAAoB;gBAC/B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;aACf,CAAA;SACF;QAED,IAAI,CAAC,YAAY,GAAGG,wCAAC,SAAS,oBAAK,KAAK,EAAK,CAAA;QAE7C,IAAI,MAAA,IAAI,CAAC,MAAM,0CAAE,gBAAgB,EAAE;YACjC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC;gBACpC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CACzD,IAAI,CAAC,EAAE,EACP,IAAI,CACL;aACF,CAAC,CAAA;SACH;KACF;IAED,WAAW,CAAC,QAAmB,EAAE;QAC/B,IAAI,CAAC,KAAK,GAAG;YACX,GAAG,IAAI,CAAC,KAAK;YACb,GAAG,KAAK;SACT,CAAA;QAED,IAAI,CAAC,MAAM,EAAE,CAAA;KACd;IAED,OAAO;;QACL,IAAI,MAAA,IAAI,CAAC,MAAM,0CAAE,gBAAgB,EAAE;YACjC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAA;YAExD,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YAEzB,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC;gBACpC,SAAS;aACV,CAAC,CAAA;SACH;KACF;;;AC9EI,MAAM,oBAAoB,GAAGK,mBAAa,CAAqC;IACpF,WAAW,EAAE,SAAS;CACvB,CAAC,CAAA;AAEK,MAAM,gBAAgB,GAAG,MAAMC,gBAAU,CAAC,oBAAoB,CAAC;;ACQtE,MAAM,aAAc,SAAQC,aAAyC;IAMnE,KAAK;QACH,MAAM,KAAK,GAAkB;YAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,QAAQ,EAAE,KAAK;YACf,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,MAAM,EAAE,MAAM,IAAI,CAAC,MAAM,EAAE;YAC3B,gBAAgB,EAAE,CAAC,UAAU,GAAG,EAAE,KAAK,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC;SACzE,CAAA;QAED,IAAI,CAAE,IAAI,CAAC,SAAiB,CAAC,WAAW,EAAE;YACxC,MAAM,mBAAmB,GAAG,CAAC,MAAc;gBACzC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;aAC5D,CAAA;YAED,IAAI,CAAC,SAAS,CAAC,WAAW,GAAG,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;SACtE;QAED,MAAM,qBAAqB,GAA4B,cAAc;YACnE,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAA;YAEhC,QACEP,wCAAC,oBAAoB,CAAC,QAAQ,IAAC,KAAK,EAAE,EAAE,WAAW,EAAE;gBACnDA,wCAAC,SAAS,oBAAK,cAAc,EAAI,CACH,EACjC;SACF,CAAA;QAED,qBAAqB,CAAC,WAAW,GAAG,eAAe,CAAA;QAEnD,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM;cACrC,IAAI;cACJ,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC,CAAA;QAE/D,IAAI,CAAC,QAAQ,GAAG,IAAI,aAAa,CAAC,qBAAqB,EAAE;YACvD,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,KAAK;YACL,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ;kBAClB,MAAM;kBACN,KAAK;SACV,CAAC,CAAA;KACH;IAED,IAAI,GAAG;;QACL,IACE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB;eACpC,EAAC,MAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB,0CAAE,YAAY,CAAC,wBAAwB,CAAC,CAAA,EACnF;YACA,MAAM,KAAK,CAAC,8DAA8D,CAAC,CAAA;SAC5E;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAA;KAC7B;IAED,IAAI,UAAU;QACZ,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YACpB,OAAO,IAAI,CAAA;SACZ;QAED,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,0BAA0B,CAAC,CAAA;QAEzE,IACE,IAAI,CAAC,iBAAiB;eACnB,cAAc;eACd,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,EACnD;YACA,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;SACnD;QAED,OAAO,IAAI,CAAC,iBAAiB,CAAA;KAC9B;IAED,MAAM,CAAC,IAAqB,EAAE,WAAyB;QACrD,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,UAAU,EAAE;YAC7C,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;SAC9C;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAChC,OAAO,KAAK,CAAA;SACb;QAED,IAAI,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,KAAK,WAAW,EAAE;YAC1D,OAAO,IAAI,CAAA;SACZ;QAED,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAA;QAC9B,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAA;QAEhD,OAAO,IAAI,CAAA;KACZ;IAED,UAAU;QACR,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;YACxB,QAAQ,EAAE,IAAI;SACf,CAAC,CAAA;KACH;IAED,YAAY;QACV,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;YACxB,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAA;KACH;IAED,OAAO;QACL,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAA;QACvB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAA;KAC9B;CACF;SAEe,qBAAqB,CAAC,SAAc,EAAE,OAA+C;IACnG,OAAO,CAAC,KAA4B;;;;QAIlC,IAAI,CAAE,KAAK,CAAC,MAAiB,CAAC,gBAAgB,EAAE;YAC9C,OAAO,EAAE,CAAA;SACV;QAED,OAAO,IAAI,aAAa,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAwB,CAAA;KAC3E,CAAA;AACH;;AC9IA,MAAM,OAAO,GAAwD,CAAC,EAAE,SAAS,EAAE;IACjF,QACEA,kFACG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC;QACzC,OAAOQ,4BAAQ,CAAC,YAAY,CAC1B,QAAQ,CAAC,YAAY,EACrB,QAAQ,CAAC,OAAO,EAChB,GAAG,CACJ,CAAA;KACF,CAAC,CACD,EACJ;AACH,CAAC,CAAA;MAUY,iBAAkB,SAAQR,yBAAK,CAAC,SAAiD;IAG5F,YAAY,KAAyB;QACnC,KAAK,CAAC,KAAK,CAAC,CAAA;QACZ,IAAI,CAAC,gBAAgB,GAAGA,yBAAK,CAAC,SAAS,EAAE,CAAA;QAEzC,IAAI,CAAC,KAAK,GAAG;YACX,SAAS,EAAE,IAAI,GAAG,EAAE;SACrB,CAAA;KACF;IAED,iBAAiB;QACf,IAAI,CAAC,IAAI,EAAE,CAAA;KACZ;IAED,kBAAkB;QAChB,IAAI,CAAC,IAAI,EAAE,CAAA;KACZ;IAED,IAAI;QACF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;QAE7B,IAAI,MAAM,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE;YACpC,IAAI,MAAM,CAAC,gBAAgB,EAAE;gBAC3B,OAAM;aACP;YAED,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAA;YAE7C,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;YAEtD,MAAM,CAAC,UAAU,CAAC;gBAChB,OAAO;aACR,CAAC,CAAA;YAEF,MAAM,CAAC,gBAAgB,GAAG,IAAI,CAAA;;YAG9B,UAAU,CAAC,MAAM,MAAM,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,CAAA;SAC9C;KACF;IAED,oBAAoB;QAClB,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;QAE7B,IAAI,CAAC,MAAM,EAAE;YACX,OAAM;SACP;QAED,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE;YACvB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;gBACnB,SAAS,EAAE,EAAE;aACd,CAAC,CAAA;SACH;QAED,MAAM,CAAC,gBAAgB,GAAG,IAAI,CAAA;QAE9B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE;YACtC,OAAM;SACP;QAED,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;QAEhD,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;QAEzD,MAAM,CAAC,UAAU,CAAC;YAChB,OAAO,EAAE,UAAU;SACpB,CAAC,CAAA;KACH;IAED,MAAM;QACJ,QACEA;YACEA,iDAAK,GAAG,EAAE,IAAI,CAAC,gBAAgB,GAAI;YACnCA,wCAAC,OAAO,IAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,GAAI,CAC3C,EACJ;KACF;CACF;MAEY,aAAa,GAAGA,yBAAK,CAAC,IAAI,CAAC,iBAAiB;;MCpG5C,eAAe,GAAmC,KAAK;IAClE,MAAM,EAAE,WAAW,EAAE,GAAG,gBAAgB,EAAE,CAAA;IAC1C,MAAM,GAAG,GAAG,KAAK,CAAC,EAAE,IAAI,KAAK,CAAA;IAE7B,QACEA,wCAAC,GAAG,IACF,SAAS,EAAE,KAAK,CAAC,SAAS,4BACH,EAAE,EACzB,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,IAE/B,KAAK,CAAC,QAAQ,CACV,EACP;AACH;;MCfa,eAAe,GAAmC,KAAK;IAClE,MAAM,GAAG,GAAG,KAAK,CAAC,EAAE,IAAI,KAAK,CAAA;IAE7B,QACEA,wCAAC,GAAG,IACF,SAAS,EAAE,KAAK,CAAC,SAAS,4BACH,EAAE,EACzB,KAAK,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,GACjC,EACH;AACH;;;;;;;;;;;;;;;;;;;;;"}
|
|
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":";;;;;;;;;;;;;;;AAWa,MAAA,UAAU,GAAG,CAAC,KAAsB,KAAI;IACnD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAGA,cAAQ,CAAwB,IAAI,CAAC,CAAA;IAEnEC,eAAS,CAAC,MAAK;QACb,IAAI,CAAC,OAAO,EAAE;YACZ,OAAM;AACP,SAAA;AAED,QAAA,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE;YAC5B,OAAM;AACP,SAAA;AAED,QAAA,MAAM,EACJ,SAAS,GAAG,YAAY,EAAE,MAAM,EAAE,YAAY,GAAG,EAAE,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,GAC9E,GAAG,KAAK,CAAA;QAET,MAAM,MAAM,GAAGC,oCAAgB,CAAC;YAC9B,KAAK;YACL,MAAM;YACN,OAAO;YACP,SAAS;YACT,UAAU;YACV,YAAY;AACb,SAAA,CAAC,CAAA;AAEF,QAAA,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;QAC7B,OAAO,MAAM,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAA;KAChD,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IAE3B,QACEC,yBAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,EAC9E,EAAA,KAAK,CAAC,QAAQ,CACX,EACP;AACH;;ACxCM,MAAO,MAAO,SAAQC,WAAU,CAAA;AAAtC,IAAA,WAAA,GAAA;;QACS,IAAgB,CAAA,gBAAA,GAAmE,IAAI,CAAA;KAC/F;AAAA;;ACDD,MAAM,OAAO,GAAwD,CAAC,EAAE,SAAS,EAAE,KAAI;AACrF,IAAA,QACED,yBACG,CAAA,aAAA,CAAAA,yBAAA,CAAA,QAAA,EAAA,IAAA,EAAA,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,KAAI;AAC7C,QAAA,OAAOE,4BAAQ,CAAC,YAAY,CAC1B,QAAQ,CAAC,YAAY,EACrB,QAAQ,CAAC,OAAO,EAChB,GAAG,CACJ,CAAA;KACF,CAAC,CACD,EACJ;AACH,CAAC,CAAA;AAUY,MAAA,iBAAkB,SAAQF,yBAAK,CAAC,SAAiD,CAAA;AAG5F,IAAA,WAAA,CAAY,KAAyB,EAAA;QACnC,KAAK,CAAC,KAAK,CAAC,CAAA;AACZ,QAAA,IAAI,CAAC,gBAAgB,GAAGA,yBAAK,CAAC,SAAS,EAAE,CAAA;QAEzC,IAAI,CAAC,KAAK,GAAG;YACX,SAAS,EAAE,IAAI,GAAG,EAAE;SACrB,CAAA;KACF;IAED,iBAAiB,GAAA;QACf,IAAI,CAAC,IAAI,EAAE,CAAA;KACZ;IAED,kBAAkB,GAAA;QAChB,IAAI,CAAC,IAAI,EAAE,CAAA;KACZ;IAED,IAAI,GAAA;AACF,QAAA,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;AAE7B,QAAA,IAAI,MAAM,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE;YACpC,IAAI,MAAM,CAAC,gBAAgB,EAAE;gBAC3B,OAAM;AACP,aAAA;AAED,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAA;AAE7C,YAAA,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;YAEpD,MAAM,CAAC,UAAU,CAAC;gBAChB,OAAO;AACR,aAAA,CAAC,CAAA;AAEF,YAAA,MAAM,CAAC,gBAAgB,GAAG,IAAI,CAAA;YAE9B,MAAM,CAAC,eAAe,EAAE,CAAA;AACzB,SAAA;KACF;IAED,oBAAoB,GAAA;AAClB,QAAA,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;QAE7B,IAAI,CAAC,MAAM,EAAE;YACX,OAAM;AACP,SAAA;AAED,QAAA,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE;AACvB,YAAA,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;AACnB,gBAAA,SAAS,EAAE,EAAE;AACd,aAAA,CAAC,CAAA;AACH,SAAA;AAED,QAAA,MAAM,CAAC,gBAAgB,GAAG,IAAI,CAAA;QAE9B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE;YACtC,OAAM;AACP,SAAA;QAED,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;AAEhD,QAAA,UAAU,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;QAEvD,MAAM,CAAC,UAAU,CAAC;AAChB,YAAA,OAAO,EAAE,UAAU;AACpB,SAAA,CAAC,CAAA;KACH;IAED,MAAM,GAAA;QACJ,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA;AAEtC,QAAA,QACEA,yBAAA,CAAA,aAAA,CAAAA,yBAAA,CAAA,QAAA,EAAA,IAAA;AACE,YAAAA,yBAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,GAAG,EAAE,IAAI,CAAC,gBAAgB,EAAA,GAAM,IAAI,EAAI,CAAA;AAC7C,YAAAA,yBAAA,CAAA,aAAA,CAAC,OAAO,EAAA,EAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAA,CAAI,CAC3C,EACJ;KACF;AACF,CAAA;AAEY,MAAA,aAAa,GAAGA,yBAAK,CAAC,IAAI,CAAC,iBAAiB;;AClG5C,MAAA,YAAY,GAAG,CAAC,KAAwB,KAAI;IACvD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAGH,cAAQ,CAAwB,IAAI,CAAC,CAAA;IAEnEC,eAAS,CAAC,MAAK;QACb,IAAI,CAAC,OAAO,EAAE;YACZ,OAAM;AACP,SAAA;AAED,QAAA,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE;YAC5B,OAAM;AACP,SAAA;AAED,QAAA,MAAM,EACJ,SAAS,GAAG,cAAc,EAC1B,MAAM,EACN,YAAY,GAAG,EAAE,EACjB,UAAU,GAAG,IAAI,GAClB,GAAG,KAAK,CAAA;QAET,MAAM,MAAM,GAAGK,wCAAkB,CAAC;YAChC,SAAS;YACT,MAAM;YACN,OAAO;YACP,YAAY;YACZ,UAAU;AACX,SAAA,CAAC,CAAA;AAEF,QAAA,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;QAC7B,OAAO,MAAM,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAA;AACjD,KAAC,EAAE;AACD,QAAA,KAAK,CAAC,MAAM;QACZ,OAAO;AACR,KAAA,CAAC,CAAA;IAEF,QACEH,yBAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,EAC9E,EAAA,KAAK,CAAC,QAAQ,CACX,EACP;AACH;;AC5CO,MAAM,oBAAoB,GAAGI,mBAAa,CAAqC;AACpF,IAAA,WAAW,EAAE,SAAS;AACvB,CAAA,CAAC,CAAA;AAEK,MAAM,gBAAgB,GAAG,MAAMC,gBAAU,CAAC,oBAAoB,CAAC;;ACFzD,MAAA,eAAe,GAAmC,KAAK,IAAG;AACrE,IAAA,MAAM,GAAG,GAAG,KAAK,CAAC,EAAE,IAAI,KAAK,CAAA;AAC7B,IAAA,MAAM,EAAE,kBAAkB,EAAE,GAAG,gBAAgB,EAAE,CAAA;AAEjD,IAAA,QACEL,yBAAA,CAAA,aAAA,CAAC,GAAG,EAAA,EAAA,GACE,KAAK,EACT,GAAG,EAAE,kBAAkB,EAAA,wBAAA,EACA,EAAE,EACzB,KAAK,EAAE;AACL,YAAA,UAAU,EAAE,UAAU;YACtB,GAAG,KAAK,CAAC,KAAK;AACf,SAAA,EAAA,CACD,EACH;AACH;;ACfO,MAAM,eAAe,GAAmCA,yBAAK,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,GAAG,KAAI;AAC7F,IAAA,MAAM,EAAE,WAAW,EAAE,GAAG,gBAAgB,EAAE,CAAA;AAC1C,IAAA,MAAM,GAAG,GAAG,KAAK,CAAC,EAAE,IAAI,KAAK,CAAA;AAE7B,IAAA,QACEA,yBAAC,CAAA,aAAA,CAAA,GAAG,EACE,EAAA,GAAA,KAAK,EACT,GAAG,EAAE,GAAG,EAAA,wBAAA,EACe,EAAE,EACzB,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE;AACL,YAAA,UAAU,EAAE,QAAQ;YACpB,GAAG,KAAK,CAAC,KAAK;AACf,SAAA,EAAA,CACD,EACH;AACH,CAAC;;ACnBD,SAAS,gBAAgB,CAAC,SAAc,EAAA;AACtC,IAAA,OAAO,CAAC,EACN,OAAO,SAAS,KAAK,UAAU;AAC5B,WAAA,SAAS,CAAC,SAAS;AACnB,WAAA,SAAS,CAAC,SAAS,CAAC,gBAAgB,CACxC,CAAA;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,SAAc,EAAA;;AAC3C,IAAA,OAAO,CAAC,EACN,OAAO,SAAS,KAAK,QAAQ;WAC1B,CAAA,CAAA,EAAA,GAAA,SAAS,CAAC,QAAQ,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,QAAQ,EAAE,MAAK,2BAA2B,CAClE,CAAA;AACH,CAAC;MAcY,aAAa,CAAA;AAexB,IAAA,WAAA,CAAY,SAA8B,EAAE,EAC1C,MAAM,EACN,KAAK,GAAG,EAAE,EACV,EAAE,GAAG,KAAK,EACV,SAAS,GAAG,EAAE,GACO,EAAA;QAPvB,IAAG,CAAA,GAAA,GAAa,IAAI,CAAA;AAQlB,QAAA,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAA;AAC3D,QAAA,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;AAC1B,QAAA,IAAI,CAAC,MAAM,GAAG,MAAwB,CAAA;AACtC,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,CAAA;QACzC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAA;AAE5C,QAAA,IAAI,SAAS,EAAE;AACb,YAAA,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;AACpD,SAAA;QAED,IAAI,CAAC,MAAM,EAAE,CAAA;KACd;IAED,MAAM,GAAA;AACJ,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAA;AAChC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;QAExB,IAAI,gBAAgB,CAAC,SAAS,CAAC,IAAI,qBAAqB,CAAC,SAAS,CAAC,EAAE;AACnE,YAAA,KAAK,CAAC,GAAG,GAAG,CAAC,GAAM,KAAI;AACrB,gBAAA,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;AAChB,aAAC,CAAA;AACF,SAAA;QAED,IAAI,CAAC,YAAY,GAAGA,yBAAA,CAAA,aAAA,CAAC,SAAS,EAAK,EAAA,GAAA,KAAK,GAAK,CAAA;QAE7C,cAAc,CAAC,MAAK;YAClBM,kBAAS,CAAC,MAAK;;AACb,gBAAA,IAAI,MAAA,IAAI,CAAC,MAAM,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,gBAAgB,EAAE;AACjC,oBAAA,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC;AACpC,wBAAA,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CACzD,IAAI,CAAC,EAAE,EACP,IAAI,CACL;AACF,qBAAA,CAAC,CAAA;AACH,iBAAA;AACH,aAAC,CAAC,CAAA;AACJ,SAAC,CAAC,CAAA;KACH;IAED,WAAW,CAAC,QAA6B,EAAE,EAAA;QACzC,IAAI,CAAC,KAAK,GAAG;YACX,GAAG,IAAI,CAAC,KAAK;AACb,YAAA,GAAG,KAAK;SACT,CAAA;QAED,IAAI,CAAC,MAAM,EAAE,CAAA;KACd;IAED,OAAO,GAAA;QACL,cAAc,CAAC,MAAK;YAClBA,kBAAS,CAAC,MAAK;;AACb,gBAAA,IAAI,MAAA,IAAI,CAAC,MAAM,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,gBAAgB,EAAE;oBACjC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAA;AAExD,oBAAA,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AAEzB,oBAAA,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC;wBACpC,SAAS;AACV,qBAAA,CAAC,CAAA;AACH,iBAAA;AACH,aAAC,CAAC,CAAA;AACJ,SAAC,CAAC,CAAA;KACH;AACF;;ACzFD,MAAM,aAAc,SAAQC,aAI3B,CAAA;IAKC,KAAK,GAAA;AACH,QAAA,MAAM,KAAK,GAAkB;YAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW;AAC7B,YAAA,QAAQ,EAAE,KAAK;YACf,SAAS,EAAE,IAAI,CAAC,SAAS;AACzB,YAAA,MAAM,EAAE,MAAM,IAAI,CAAC,MAAM,EAAE;AAC3B,YAAA,gBAAgB,EAAE,CAAC,UAAU,GAAG,EAAE,KAAK,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC;AACxE,YAAA,UAAU,EAAE,MAAM,IAAI,CAAC,UAAU,EAAE;SACpC,CAAA;AAED,QAAA,IAAI,CAAE,IAAI,CAAC,SAAiB,CAAC,WAAW,EAAE;AACxC,YAAA,MAAM,mBAAmB,GAAG,CAAC,MAAc,KAAY;AACrD,gBAAA,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;AAC7D,aAAC,CAAA;AAED,YAAA,IAAI,CAAC,SAAS,CAAC,WAAW,GAAG,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;AACtE,SAAA;AAED,QAAA,MAAM,qBAAqB,GAA4B,cAAc,IAAG;AACtE,YAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAA;YAChC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC/C,YAAA,MAAM,kBAAkB,GAAoD,OAAO,IAAG;AACpF,gBAAA,IAAI,OAAO,IAAI,IAAI,CAAC,iBAAiB,IAAI,OAAO,CAAC,UAAU,KAAK,IAAI,CAAC,iBAAiB,EAAE;AACtF,oBAAA,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;AAC5C,iBAAA;AACH,aAAC,CAAA;AAED,YAAA,QACEP,yBAAA,CAAA,aAAA,CAAC,oBAAoB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,EAAE,WAAW,EAAE,kBAAkB,EAAE,EAAA;AACvE,gBAAAA,yBAAA,CAAA,aAAA,CAAC,SAAS,EAAK,EAAA,GAAA,cAAc,EAAI,CAAA,CACH,EACjC;AACH,SAAC,CAAA;AAED,QAAA,qBAAqB,CAAC,WAAW,GAAG,eAAe,CAAA;AAEnD,QAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM;AACvC,cAAE,IAAI;AACN,cAAE,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC,CAAA;QAE/D,IAAI,IAAI,CAAC,iBAAiB,EAAE;;;;YAI1B,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,UAAU,GAAG,SAAS,CAAA;AACpD,SAAA;AAED,QAAA,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAA;AAE5C,QAAA,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE;AACnB,YAAA,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAA;AACrB,SAAA;QAED,MAAM,EAAE,SAAS,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,CAAA;AAEvC,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAI,aAAa,CAAC,qBAAqB,EAAE;YACvD,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,KAAK;YACL,EAAE;AACF,YAAA,SAAS,EAAE,CAAA,KAAA,EAAQ,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAI,CAAA,EAAA,SAAS,CAAE,CAAA,CAAC,IAAI,EAAE;AAC7D,SAAA,CAAC,CAAA;KACH;AAED,IAAA,IAAI,GAAG,GAAA;;AACL,QAAA,IACE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB;AACpC,eAAA,EAAC,CAAA,EAAA,GAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB,0CAAE,YAAY,CAAC,wBAAwB,CAAC,CAAA,EACnF;AACA,YAAA,MAAM,KAAK,CAAC,8DAA8D,CAAC,CAAA;AAC5E,SAAA;AAED,QAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAsB,CAAA;KAC5C;AAED,IAAA,IAAI,UAAU,GAAA;AACZ,QAAA,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;AACpB,YAAA,OAAO,IAAI,CAAA;AACZ,SAAA;QAED,OAAO,IAAI,CAAC,iBAAiB,CAAA;KAC9B;IAED,MAAM,CAAC,IAAqB,EAAE,WAAyB,EAAA;AACrD,QAAA,MAAM,WAAW,GAAG,CAAC,KAA2B,KAAI;AAClD,YAAA,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;AAClC,SAAC,CAAA;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;AAChC,YAAA,OAAO,KAAK,CAAA;AACb,SAAA;QAED,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,UAAU,EAAE;AAC7C,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAA;AACzB,YAAA,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,CAAA;AAEvC,YAAA,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;AAChB,YAAA,IAAI,CAAC,WAAW,GAAG,WAAW,CAAA;AAE9B,YAAA,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;gBACzB,OAAO;gBACP,cAAc;AACd,gBAAA,OAAO,EAAE,IAAI;AACb,gBAAA,cAAc,EAAE,WAAW;gBAC3B,WAAW,EAAE,MAAM,WAAW,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;AACtD,aAAA,CAAC,CAAA;AACH,SAAA;QAED,IAAI,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,KAAK,WAAW,EAAE;AAC1D,YAAA,OAAO,IAAI,CAAA;AACZ,SAAA;AAED,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;AAChB,QAAA,IAAI,CAAC,WAAW,GAAG,WAAW,CAAA;AAE9B,QAAA,WAAW,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAA;AAElC,QAAA,OAAO,IAAI,CAAA;KACZ;IAED,UAAU,GAAA;AACR,QAAA,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;AACxB,YAAA,QAAQ,EAAE,IAAI;AACf,SAAA,CAAC,CAAA;KACH;IAED,YAAY,GAAA;AACV,QAAA,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;AACxB,YAAA,QAAQ,EAAE,KAAK;AAChB,SAAA,CAAC,CAAA;KACH;IAED,OAAO,GAAA;AACL,QAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAA;AACvB,QAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAA;KAC9B;AACF,CAAA;AAEe,SAAA,qBAAqB,CACnC,SAAc,EACd,OAA+C,EAAA;IAE/C,OAAO,CAAC,KAA4B,KAAI;;;;AAItC,QAAA,IAAI,CAAE,KAAK,CAAC,MAAiB,CAAC,gBAAgB,EAAE;AAC9C,YAAA,OAAO,EAAE,CAAA;AACV,SAAA;QAED,OAAO,IAAI,aAAa,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAmC,CAAA;AACvF,KAAC,CAAA;AACH;;AC1LA,SAAS,cAAc,GAAA;IACrB,MAAM,GAAG,QAAQ,CAAC,GAAGH,cAAQ,CAAC,CAAC,CAAC,CAAA;AAEhC,IAAA,OAAO,MAAM,QAAQ,CAAC,KAAK,IAAI,KAAK,GAAG,CAAC,CAAC,CAAA;AAC3C,CAAC;AAEY,MAAA,SAAS,GAAG,CAAC,OAAkC,GAAA,EAAE,EAAE,IAAA,GAAuB,EAAE,KAAI;IAC3F,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAGA,cAAQ,CAAgB,IAAI,CAAC,CAAA;AACzD,IAAA,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IAEpCC,eAAS,CAAC,MAAK;QACb,IAAI,SAAS,GAAG,IAAI,CAAA;AAEpB,QAAA,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,CAAA;QAEpC,SAAS,CAAC,QAAQ,CAAC,CAAA;AAEnB,QAAA,QAAQ,CAAC,EAAE,CAAC,aAAa,EAAE,MAAK;YAC9B,qBAAqB,CAAC,MAAK;gBACzB,qBAAqB,CAAC,MAAK;AACzB,oBAAA,IAAI,SAAS,EAAE;AACb,wBAAA,WAAW,EAAE,CAAA;AACd,qBAAA;AACH,iBAAC,CAAC,CAAA;AACJ,aAAC,CAAC,CAAA;AACJ,SAAC,CAAC,CAAA;AAEF,QAAA,OAAO,MAAK;YACV,QAAQ,CAAC,OAAO,EAAE,CAAA;YAClB,SAAS,GAAG,KAAK,CAAA;AACnB,SAAC,CAAA;KACF,EAAE,IAAI,CAAC,CAAA;AAER,IAAA,OAAO,MAAM,CAAA;AACf;;;;;;;;;;;;;;;;;;;"}
|
package/dist/tiptap-react.esm.js
CHANGED
|
@@ -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
|
|
4
|
-
import {
|
|
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 =
|
|
8
|
+
const BubbleMenu = (props) => {
|
|
9
|
+
const [element, setElement] = useState(null);
|
|
10
10
|
useEffect(() => {
|
|
11
|
-
|
|
12
|
-
|
|
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
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
|
32
|
-
|
|
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
|
-
|
|
35
|
-
|
|
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
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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,
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
-
|
|
141
|
-
|
|
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
|
|
151
|
-
|
|
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
|
-
|
|
177
|
-
|
|
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
|
-
|
|
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
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
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
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
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 };
|