import React, { HTMLProps } from 'react' import ReactDOM from 'react-dom' import { Editor } from './Editor' import { ReactRenderer } from './ReactRenderer' const Portals: React.FC<{ renderers: Map }> = ({ renderers }) => { return ( <> {Array.from(renderers).map(([key, renderer]) => { return ReactDOM.createPortal( renderer.reactElement, renderer.element, key, ) })} ) } export interface EditorContentProps extends HTMLProps { editor: Editor | null, } export interface EditorContentState { renderers: Map } export class PureEditorContent extends React.Component { editorContentRef: React.RefObject constructor(props: EditorContentProps) { super(props) this.editorContentRef = React.createRef() this.state = { renderers: new Map(), } } componentDidMount() { this.init() } componentDidUpdate() { this.init() } init() { const { editor } = this.props if (editor && editor.options.element) { if (editor.contentComponent) { return } const element = this.editorContentRef.current element.append(...editor.options.element.childNodes) editor.setOptions({ element, }) editor.contentComponent = this // TODO: alternative to setTimeout? setTimeout(() => editor.createNodeViews(), 0) } } componentWillUnmount() { const { editor } = this.props if (!editor) { return } if (!editor.isDestroyed) { editor.view.setProps({ nodeViews: {}, }) } editor.contentComponent = null if (!editor.options.element.firstChild) { return } const newElement = document.createElement('div') newElement.append(...editor.options.element.childNodes) editor.setOptions({ element: newElement, }) } render() { const { editor, ...rest } = this.props return ( <>
) } } export const EditorContent = React.memo(PureEditorContent)