import type { Editor } from "@tiptap/core"; import { ReactRenderer } from "@tiptap/react"; type RendererProps = Record; export interface MountedEditorRenderer { destroy(): void; readonly ref: Handle | null; updateProps(next: Partial): void; } export function mountEditorRenderer( editor: Editor, component: React.ComponentType, props: Props, ): MountedEditorRenderer { let destroyed = false; const renderer = new ReactRenderer(component as React.ComponentType, { editor, props: props as unknown as RendererProps, }); document.body.appendChild(renderer.element); function destroy() { if (destroyed) return; destroyed = true; editor.off("destroy", destroy); renderer.destroy(); renderer.element.remove(); } editor.on("destroy", destroy); return { destroy, get ref() { return destroyed ? null : renderer.ref; }, updateProps(next) { if (destroyed) return; renderer.updateProps(next as RendererProps); }, }; }