/** * The purpose of this file is to contain the logic for rendering the * component in a way that is easy to lazy load for the `enableVisualEditing` function. */ import {StrictMode} from 'react' import {createRoot, type Root} from 'react-dom/client' import type {VisualEditingOptions} from '../types' import {VisualEditing} from './VisualEditing' let node: HTMLElement | null = null let root: Root | null = null let cleanup: ReturnType | null = null export function renderVisualEditing( signal: AbortSignal, {components, history, refresh, zIndex, plugins, onPerspectiveChange}: VisualEditingOptions, ): void { // Cancel pending cleanups, this is useful to avoid overlays blinking as the parent app transition between URLs, or hot module reload is happening if (cleanup) clearTimeout(cleanup) // Setup a cleanup function listener right away, as the signal might abort in-between the next steps signal.addEventListener('abort', () => { // Handle React StrictMode, delay cleanup for a second in case it's a rerender cleanup = setTimeout(() => { if (root) { root.unmount() root = null } if (node) { node.parentNode!.removeChild(node) node = null } }, 1000) }) if (!node) { node = document.createElement('sanity-visual-editing') // render sanity-visual-editing after closing tag document.body.parentNode!.insertBefore(node, document.body.nextSibling) } if (!root) { root = createRoot(node) } root.render( , ) }