{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "huge-document-demo",
  "dependencies": [
    "@faker-js/faker"
  ],
  "registryDependencies": [
    "button"
  ],
  "files": [
    {
      "path": "src/registry/examples/huge-document-demo.tsx",
      "content": "'use client';\n\nimport Link from 'next/link';\n\nimport React, {\n  type CSSProperties,\n  type Dispatch,\n  StrictMode,\n  useCallback,\n  useEffect,\n  useMemo,\n  useState,\n  useSyncExternalStore,\n} from 'react';\n\nimport type { Value } from 'platejs';\nimport type { Editor } from 'slate';\n\nimport {\n  createPlateEditor,\n  Editable,\n  Plate,\n  PlateContent,\n  Slate,\n  useSelected,\n  withReact,\n} from 'platejs/react';\nimport { createEditor as slateCreateEditor } from 'slate';\n\nimport { createHugeDocumentValue } from '@/registry/examples/values/huge-document-value';\nimport { Button } from '@/components/ui/button';\n\nconst subscribeBrowserPerformanceSupport = () => () => {};\n\nconst getUnsupportedBrowserFeature = () => false;\n\nconst getBrowserSupportsEventTiming = () =>\n  typeof window !== 'undefined' && 'PerformanceEventTiming' in window;\n\nconst getBrowserSupportsLoafTiming = () =>\n  typeof window !== 'undefined' &&\n  'PerformanceLongAnimationFrameTiming' in window;\n\ntype EngineStatistics = {\n  averageKeyPressDuration: number | null;\n  lastKeyPressDuration: number | null;\n  lastLongAnimationFrameDuration: number | null;\n};\n\nconst lastThreeDigitsPattern = /(\\d{3})$/;\n\nconst defaultStatistics: EngineStatistics = {\n  averageKeyPressDuration: null,\n  lastKeyPressDuration: null,\n  lastLongAnimationFrameDuration: null,\n};\n\nconst DEFAULT_HUGE_DOCUMENT_BLOCKS = 10_000;\nconst DEFAULT_HUGE_DOCUMENT_CHUNK_SIZE = 1000;\nconst HUGE_DOCUMENT_BENCHMARK_SCENARIO_WORKLOAD = 'huge-mixed-block';\n\nconst HUGE_DOCUMENT_BLOCK_OPTIONS = [\n  2, 1000, 2500, 5000, 7500, 10_000, 15_000, 20_000, 25_000, 30_000, 40_000,\n  50_000, 100_000, 200_000,\n];\n\nconst HUGE_DOCUMENT_CHUNK_SIZE_OPTIONS = [3, 10, 100, 1000];\n\ntype EngineKind = 'plate' | 'slate';\ntype ContentVisibilityMode = 'none' | 'element' | 'chunk';\ntype MountedEngines = 'both' | EngineKind;\n\ntype Config = {\n  blocks: number;\n  chunking: boolean;\n  chunkSize: number;\n  chunkDivs: boolean;\n  chunkOutlines: boolean;\n  contentVisibilityMode: ContentVisibilityMode;\n  mountedEngines: MountedEngines;\n  showSelectedHeadings: boolean;\n  strictMode: boolean;\n};\n\ntype BenchmarkConfig = {\n  blocks: number;\n  chunking: boolean;\n  chunkSize: number;\n  contentVisibility: ContentVisibilityMode;\n  scenarioWorkload: string;\n};\n\nconst DEFAULT_CONFIG: Config = {\n  blocks: DEFAULT_HUGE_DOCUMENT_BLOCKS,\n  chunking: true,\n  chunkSize: DEFAULT_HUGE_DOCUMENT_CHUNK_SIZE,\n  chunkDivs: true,\n  chunkOutlines: false,\n  contentVisibilityMode: 'chunk',\n  mountedEngines: 'both',\n  showSelectedHeadings: false,\n  strictMode: false,\n};\n\nfunction getDocumentSearchParams() {\n  if (typeof document === 'undefined') return null;\n\n  return new URLSearchParams(document.location.search);\n}\n\nfunction parseNumber({\n  defaultValue,\n  key,\n  searchParams,\n}: {\n  defaultValue: number;\n  key: string;\n  searchParams: URLSearchParams | null;\n}) {\n  return Number.parseInt(searchParams?.get(key) ?? '', 10) || defaultValue;\n}\n\nfunction parseBoolean({\n  defaultValue,\n  key,\n  searchParams,\n}: {\n  defaultValue: boolean;\n  key: string;\n  searchParams: URLSearchParams | null;\n}) {\n  const value = searchParams?.get(key);\n\n  if (value) return value === 'true';\n\n  return defaultValue;\n}\n\nfunction parseEnum<T extends string>({\n  defaultValue,\n  key,\n  options,\n  searchParams,\n}: {\n  defaultValue: T;\n  key: string;\n  options: readonly T[];\n  searchParams: URLSearchParams | null;\n}) {\n  const value = searchParams?.get(key) as T | null | undefined;\n\n  if (value && options.includes(value)) return value;\n\n  return defaultValue;\n}\n\nfunction replaceSearchParams(searchParams: URLSearchParams) {\n  history.replaceState({}, '', `?${searchParams.toString()}`);\n}\n\nfunction getInitialHugeDocumentConfig() {\n  const searchParams = getDocumentSearchParams();\n\n  return {\n    blocks: parseNumber({\n      defaultValue: DEFAULT_CONFIG.blocks,\n      key: 'blocks',\n      searchParams,\n    }),\n    chunking: parseBoolean({\n      defaultValue: DEFAULT_CONFIG.chunking,\n      key: 'chunking',\n      searchParams,\n    }),\n    chunkSize: parseNumber({\n      defaultValue: DEFAULT_CONFIG.chunkSize,\n      key: 'chunk_size',\n      searchParams,\n    }),\n    chunkDivs: parseBoolean({\n      defaultValue: DEFAULT_CONFIG.chunkDivs,\n      key: 'chunk_divs',\n      searchParams,\n    }),\n    chunkOutlines: parseBoolean({\n      defaultValue: DEFAULT_CONFIG.chunkOutlines,\n      key: 'chunk_outlines',\n      searchParams,\n    }),\n    contentVisibilityMode: parseEnum({\n      defaultValue: DEFAULT_CONFIG.contentVisibilityMode,\n      key: 'content_visibility',\n      options: ['none', 'element', 'chunk'],\n      searchParams,\n    }),\n    mountedEngines: parseEnum({\n      defaultValue: DEFAULT_CONFIG.mountedEngines,\n      key: 'engines',\n      options: ['both', 'plate', 'slate'],\n      searchParams,\n    }),\n    showSelectedHeadings: parseBoolean({\n      defaultValue: DEFAULT_CONFIG.showSelectedHeadings,\n      key: 'selected_headings',\n      searchParams,\n    }),\n    strictMode: parseBoolean({\n      defaultValue: DEFAULT_CONFIG.strictMode,\n      key: 'strict',\n      searchParams,\n    }),\n  } satisfies Config;\n}\n\nfunction writeHugeDocumentSearchParams(config: Config) {\n  const searchParams = getDocumentSearchParams();\n\n  if (!searchParams) return;\n\n  searchParams.set('blocks', config.blocks.toString());\n  searchParams.set('chunking', config.chunking ? 'true' : 'false');\n  searchParams.set('chunk_size', config.chunkSize.toString());\n  searchParams.set('chunk_divs', config.chunkDivs ? 'true' : 'false');\n  searchParams.set('chunk_outlines', config.chunkOutlines ? 'true' : 'false');\n  searchParams.set('content_visibility', config.contentVisibilityMode);\n  searchParams.set('engines', config.mountedEngines);\n  searchParams.set(\n    'selected_headings',\n    config.showSelectedHeadings ? 'true' : 'false'\n  );\n  searchParams.set('strict', config.strictMode ? 'true' : 'false');\n  replaceSearchParams(searchParams);\n}\n\nfunction getMountedEngines({ mountedEngines }: Pick<Config, 'mountedEngines'>) {\n  return mountedEngines === 'both'\n    ? (['plate', 'slate'] as const)\n    : [mountedEngines];\n}\n\nfunction toBenchmarkConfig({\n  blocks,\n  chunkSize,\n  chunking,\n  contentVisibilityMode,\n}: Pick<\n  Config,\n  'blocks' | 'chunkSize' | 'chunking' | 'contentVisibilityMode'\n>): BenchmarkConfig {\n  return {\n    blocks,\n    chunking,\n    chunkSize,\n    contentVisibility: contentVisibilityMode,\n    scenarioWorkload: HUGE_DOCUMENT_BENCHMARK_SCENARIO_WORKLOAD,\n  };\n}\n\nfunction createHugeDocumentBenchmarkHref(config: Config) {\n  const searchParams = new URLSearchParams();\n  const benchmarkConfig = toBenchmarkConfig(config);\n\n  searchParams.set('blocks', benchmarkConfig.blocks.toString());\n  searchParams.set('chunking', benchmarkConfig.chunking ? 'true' : 'false');\n  searchParams.set('chunk_size', benchmarkConfig.chunkSize.toString());\n  searchParams.set('content_visibility', benchmarkConfig.contentVisibility);\n  searchParams.set('scenario_workload', benchmarkConfig.scenarioWorkload);\n\n  return `/dev/editor-perf?${searchParams.toString()}`;\n}\n\nconst createEditor = ({\n  config,\n  engine,\n  initialValue,\n}: {\n  config: Config;\n  engine: EngineKind;\n  initialValue: Value;\n}) => {\n  if (engine === 'slate') {\n    const editor = withReact(slateCreateEditor());\n\n    editor.getChunkSize = (node) =>\n      config.chunking && node === editor ? config.chunkSize : null;\n\n    return editor as Editor;\n  }\n\n  return createPlateEditor({\n    chunking: config.chunking ? { chunkSize: config.chunkSize } : false,\n    nodeId: false,\n    value: structuredClone(initialValue),\n  }) as unknown as Editor;\n};\n\nconst Chunk = ({\n  attributes,\n  children,\n  contentVisibilityLowest,\n  lowest,\n  outline,\n}: {\n  attributes: any;\n  children: React.ReactNode;\n  contentVisibilityLowest: boolean;\n  lowest?: boolean;\n  outline: boolean;\n}) => {\n  const style: CSSProperties = {\n    border: outline ? '1px solid red' : undefined,\n    contentVisibility: contentVisibilityLowest && lowest ? 'auto' : undefined,\n    marginBottom: outline ? 20 : undefined,\n    padding: outline ? 20 : undefined,\n  };\n\n  return (\n    <div {...attributes} style={style}>\n      {children}\n    </div>\n  );\n};\n\nconst Heading = ({\n  showSelectedHeadings = false,\n  style: styleProp,\n  ...props\n}: React.ComponentProps<'h1'> & { showSelectedHeadings: boolean }) => {\n  const selected = useSelected();\n  const highlightSelected = showSelectedHeadings && selected;\n  const style = {\n    ...styleProp,\n    color: highlightSelected ? 'green' : undefined,\n  };\n\n  return (\n    <h1\n      {...props}\n      data-selected={highlightSelected ? '' : undefined}\n      style={style}\n    />\n  );\n};\n\nconst Paragraph = 'p';\n\nconst Element = ({\n  attributes,\n  children,\n  contentVisibility,\n  element,\n  showSelectedHeadings,\n}: {\n  attributes: any;\n  children: React.ReactNode;\n  contentVisibility: boolean;\n  element: { type?: string };\n  showSelectedHeadings: boolean;\n}) => {\n  const style: CSSProperties = {\n    contentVisibility: contentVisibility ? 'auto' : undefined,\n  };\n\n  switch (element.type) {\n    case 'h1':\n    case 'heading-one':\n      return (\n        <Heading\n          {...attributes}\n          showSelectedHeadings={showSelectedHeadings}\n          style={style}\n        >\n          {children}\n        </Heading>\n      );\n    default:\n      return (\n        <Paragraph {...attributes} style={style}>\n          {children}\n        </Paragraph>\n      );\n  }\n};\n\nfunction EnginePane({\n  active,\n  config,\n  engine,\n  onFocus,\n  onStatisticsChange,\n  rendering,\n}: {\n  active: boolean;\n  config: Config;\n  engine: EngineKind;\n  onFocus: (engine: EngineKind) => void;\n  onStatisticsChange: (\n    engine: EngineKind,\n    statistics: EngineStatistics\n  ) => void;\n  rendering: boolean;\n}) {\n  const [keyPressDurations, setKeyPressDurations] = useState<number[]>([]);\n  const [lastLongAnimationFrameDuration, setLastLongAnimationFrameDuration] =\n    useState<number | null>(null);\n\n  const initialValue = useMemo(\n    () => createHugeDocumentValue({ blocks: config.blocks, engine }),\n    [config.blocks, engine]\n  );\n\n  const [editor] = useState(() =>\n    createEditor({\n      config,\n      engine,\n      initialValue,\n    })\n  );\n\n  const lastKeyPressDuration = keyPressDurations[0] ?? null;\n  const averageKeyPressDuration =\n    keyPressDurations.length === 10\n      ? Math.round(\n          keyPressDurations.reduce((total, duration) => total + duration, 0) /\n            10\n        )\n      : null;\n\n  useEffect(() => {\n    onStatisticsChange(engine, {\n      averageKeyPressDuration,\n      lastKeyPressDuration,\n      lastLongAnimationFrameDuration,\n    });\n  }, [\n    averageKeyPressDuration,\n    engine,\n    lastKeyPressDuration,\n    lastLongAnimationFrameDuration,\n    onStatisticsChange,\n  ]);\n\n  useEffect(() => {\n    if (!getBrowserSupportsEventTiming()) return;\n\n    const observer = new PerformanceObserver((list) => {\n      if (!active) return;\n\n      list.getEntries().forEach((entry) => {\n        if (entry.name !== 'keypress') return;\n\n        const duration = Math.round(\n          // @ts-expect-error browser API typing lags the runtime here\n          entry.processingEnd - entry.processingStart\n        );\n\n        setKeyPressDurations((durations) => [\n          duration,\n          ...durations.slice(0, 9),\n        ]);\n      });\n    });\n\n    // @ts-expect-error browser API typing lags the runtime here\n    observer.observe({ type: 'event', durationThreshold: 16 });\n\n    return () => observer.disconnect();\n  }, [active]);\n\n  useEffect(() => {\n    if (!getBrowserSupportsLoafTiming()) return;\n\n    const apply = editor.apply;\n    let afterOperation = false;\n\n    // eslint-disable-next-line react-hooks/immutability -- Demo component intentionally monkeypatches editor.apply to measure long animation frames\n    editor.apply = (operation) => {\n      apply(operation);\n      afterOperation = true;\n    };\n\n    const observer = new PerformanceObserver((list) => {\n      list.getEntries().forEach((entry) => {\n        if (!afterOperation) return;\n\n        setLastLongAnimationFrameDuration(Math.round(entry.duration));\n        afterOperation = false;\n      });\n    });\n\n    observer.observe({ type: 'long-animation-frame' });\n\n    return () => {\n      editor.apply = apply;\n      observer.disconnect();\n    };\n  }, [editor]);\n\n  const renderElement = useCallback(\n    (props: any) => (\n      <Element\n        {...props}\n        contentVisibility={config.contentVisibilityMode === 'element'}\n        showSelectedHeadings={config.showSelectedHeadings}\n      />\n    ),\n    [config.contentVisibilityMode, config.showSelectedHeadings]\n  );\n\n  const renderChunk = useCallback(\n    (props: any) => (\n      <Chunk\n        {...props}\n        contentVisibilityLowest={config.contentVisibilityMode === 'chunk'}\n        outline={config.chunkOutlines}\n      />\n    ),\n    [config.contentVisibilityMode, config.chunkOutlines]\n  );\n\n  const editable = rendering ? (\n    <div>Rendering&hellip;</div>\n  ) : engine === 'slate' ? (\n    <Slate editor={editor as any} initialValue={initialValue as any}>\n      <Editable\n        placeholder=\"Enter some text…\"\n        renderChunk={config.chunkDivs ? renderChunk : undefined}\n        renderElement={renderElement}\n        spellCheck\n      />\n    </Slate>\n  ) : (\n    <Plate editor={editor as any}>\n      <PlateContent\n        placeholder=\"Enter some text…\"\n        renderChunk={config.chunkDivs ? (renderChunk as any) : undefined}\n        renderElement={renderElement as any}\n        spellCheck\n      />\n    </Plate>\n  );\n\n  const editableWithStrictMode = config.strictMode ? (\n    <StrictMode>{editable}</StrictMode>\n  ) : (\n    editable\n  );\n\n  return (\n    <section\n      onFocusCapture={() => onFocus(engine)}\n      style={{\n        display: 'flex',\n        flexDirection: 'column',\n        gap: 12,\n        minWidth: 0,\n      }}\n    >\n      <h2 style={{ margin: 0 }}>{engine === 'plate' ? 'Plate' : 'Slate'}</h2>\n\n      <div\n        style={{\n          border: '1px solid color-mix(in srgb, currentColor 16%, transparent)',\n          borderRadius: 8,\n          maxHeight: 560,\n          overflow: 'auto',\n          padding: 16,\n        }}\n      >\n        {editableWithStrictMode}\n      </div>\n    </section>\n  );\n}\n\nfunction PerformanceControls({\n  config,\n  setConfig,\n  statistics,\n}: {\n  config: Config;\n  setConfig: Dispatch<Partial<Config>>;\n  statistics: Record<EngineKind, EngineStatistics>;\n}) {\n  const [configurationOpen, setConfigurationOpen] = useState(true);\n  const supportsEventTiming = useSyncExternalStore(\n    subscribeBrowserPerformanceSupport,\n    getBrowserSupportsEventTiming,\n    getUnsupportedBrowserFeature\n  );\n  const supportsLoafTiming = useSyncExternalStore(\n    subscribeBrowserPerformanceSupport,\n    getBrowserSupportsLoafTiming,\n    getUnsupportedBrowserFeature\n  );\n\n  const renderStatisticValue = (\n    mounted: boolean,\n    supported: boolean,\n    value: number | null\n  ): React.ReactNode => {\n    if (!mounted) return 'Not mounted';\n    if (!supported) return 'Not supported';\n\n    return value ?? '-';\n  };\n\n  const mountedEngines = getMountedEngines(config);\n  const benchmarkHref = createHugeDocumentBenchmarkHref(config);\n\n  return (\n    <div className=\"performance-controls\">\n      <div style={{ marginBottom: 16 }}>\n        <Button asChild size=\"sm\" variant=\"outline\">\n          <Link href={benchmarkHref}>Open in benchmark mode</Link>\n        </Button>\n      </div>\n\n      <p>\n        <label>\n          Blocks:{' '}\n          <select\n            onChange={(event) =>\n              setConfig({\n                blocks: Number.parseInt(event.target.value, 10),\n              })\n            }\n            value={config.blocks}\n          >\n            {HUGE_DOCUMENT_BLOCK_OPTIONS.map((blocks) => (\n              <option key={blocks} value={blocks}>\n                {blocks.toString().replace(lastThreeDigitsPattern, ',$1')}\n              </option>\n            ))}\n          </select>\n        </label>\n      </p>\n\n      <p>\n        <label>\n          Mounted editors:{' '}\n          <select\n            onChange={(event) =>\n              setConfig({\n                mountedEngines: event.target.value as Config['mountedEngines'],\n              })\n            }\n            value={config.mountedEngines}\n          >\n            <option value=\"both\">Plate + Slate</option>\n            <option value=\"plate\">Plate only</option>\n            <option value=\"slate\">Slate only</option>\n          </select>\n        </label>\n      </p>\n\n      <details\n        onToggle={(event) => setConfigurationOpen(event.currentTarget.open)}\n        open={configurationOpen}\n      >\n        <summary>Configuration</summary>\n\n        <p>\n          <label>\n            <input\n              checked={config.chunking}\n              onChange={(event) =>\n                setConfig({\n                  chunking: event.target.checked,\n                })\n              }\n              type=\"checkbox\"\n            />{' '}\n            Chunking enabled\n          </label>\n        </p>\n\n        {config.chunking && (\n          <>\n            <p>\n              <label>\n                <input\n                  checked={config.chunkDivs}\n                  onChange={(event) =>\n                    setConfig({\n                      chunkDivs: event.target.checked,\n                    })\n                  }\n                  type=\"checkbox\"\n                />{' '}\n                Render each chunk as a separate <code>&lt;div&gt;</code>\n              </label>\n            </p>\n\n            {config.chunkDivs && (\n              <p>\n                <label>\n                  <input\n                    checked={config.chunkOutlines}\n                    onChange={(event) =>\n                      setConfig({\n                        chunkOutlines: event.target.checked,\n                      })\n                    }\n                    type=\"checkbox\"\n                  />{' '}\n                  Outline each chunk\n                </label>\n              </p>\n            )}\n\n            <p>\n              <label>\n                Chunk size:{' '}\n                <select\n                  onChange={(event) =>\n                    setConfig({\n                      chunkSize: Number.parseInt(event.target.value, 10),\n                    })\n                  }\n                  value={config.chunkSize}\n                >\n                  {HUGE_DOCUMENT_CHUNK_SIZE_OPTIONS.map((chunkSize) => (\n                    <option key={chunkSize} value={chunkSize}>\n                      {chunkSize}\n                    </option>\n                  ))}\n                </select>\n              </label>\n            </p>\n          </>\n        )}\n\n        <p>\n          <label>\n            Set <code>content-visibility: auto</code> on:{' '}\n            <select\n              onChange={(event) =>\n                setConfig({\n                  contentVisibilityMode: event.target\n                    .value as Config['contentVisibilityMode'],\n                })\n              }\n              value={config.contentVisibilityMode}\n            >\n              <option value=\"none\">None</option>\n              <option value=\"element\">Elements</option>\n              {config.chunking && config.chunkDivs && (\n                <option value=\"chunk\">Lowest chunks</option>\n              )}\n            </select>\n          </label>\n        </p>\n\n        <p>\n          <label>\n            <input\n              checked={config.showSelectedHeadings}\n              onChange={(event) =>\n                setConfig({\n                  showSelectedHeadings: event.target.checked,\n                })\n              }\n              type=\"checkbox\"\n            />{' '}\n            Call <code>useSelected</code> in each heading\n          </label>\n        </p>\n\n        <p>\n          <label>\n            <input\n              checked={config.strictMode}\n              onChange={(event) =>\n                setConfig({\n                  strictMode: event.target.checked,\n                })\n              }\n              type=\"checkbox\"\n            />{' '}\n            React strict mode (only works in localhost)\n          </label>\n        </p>\n      </details>\n\n      <details>\n        <summary>Statistics</summary>\n\n        <table\n          style={{\n            borderCollapse: 'collapse',\n            width: '100%',\n          }}\n        >\n          <thead>\n            <tr>\n              <th align=\"left\">Metric</th>\n              <th align=\"right\">Plate</th>\n              <th align=\"right\">Slate</th>\n            </tr>\n          </thead>\n\n          <tbody>\n            <tr>\n              <td>Last keypress (ms)</td>\n              <td align=\"right\">\n                {renderStatisticValue(\n                  mountedEngines.includes('plate'),\n                  supportsEventTiming,\n                  statistics.plate.lastKeyPressDuration\n                )}\n              </td>\n              <td align=\"right\">\n                {renderStatisticValue(\n                  mountedEngines.includes('slate'),\n                  supportsEventTiming,\n                  statistics.slate.lastKeyPressDuration\n                )}\n              </td>\n            </tr>\n            <tr>\n              <td>Average of last 10 keypresses (ms)</td>\n              <td align=\"right\">\n                {renderStatisticValue(\n                  mountedEngines.includes('plate'),\n                  supportsEventTiming,\n                  statistics.plate.averageKeyPressDuration\n                )}\n              </td>\n              <td align=\"right\">\n                {renderStatisticValue(\n                  mountedEngines.includes('slate'),\n                  supportsEventTiming,\n                  statistics.slate.averageKeyPressDuration\n                )}\n              </td>\n            </tr>\n            <tr>\n              <td>Last long animation frame (ms)</td>\n              <td align=\"right\">\n                {renderStatisticValue(\n                  mountedEngines.includes('plate'),\n                  supportsLoafTiming,\n                  statistics.plate.lastLongAnimationFrameDuration\n                )}\n              </td>\n              <td align=\"right\">\n                {renderStatisticValue(\n                  mountedEngines.includes('slate'),\n                  supportsLoafTiming,\n                  statistics.slate.lastLongAnimationFrameDuration\n                )}\n              </td>\n            </tr>\n          </tbody>\n        </table>\n\n        {supportsEventTiming &&\n          statistics.plate.lastKeyPressDuration === null &&\n          statistics.slate.lastKeyPressDuration === null && (\n            <p>\n              Focus a pane and type. Events shorter than 16ms may not be\n              detected.\n            </p>\n          )}\n\n        {config.mountedEngines === 'both' && (\n          <p>\n            Mount one editor at a time for cleaner engine-specific numbers. The\n            two-editor view is useful for eyeballing parity, not for honest perf\n            baselines.\n          </p>\n        )}\n      </details>\n    </div>\n  );\n}\n\nexport default function HugeDocumentDemo() {\n  const [activePane, setActivePane] = useState<EngineKind>('slate');\n  const [config, baseSetConfig] = useState<Config>(() =>\n    getInitialHugeDocumentConfig()\n  );\n  const [paneVersion, setPaneVersion] = useState(0);\n  const [rendering, setRendering] = useState(false);\n  const [statistics, setStatistics] = useState<\n    Record<EngineKind, EngineStatistics>\n  >({\n    plate: defaultStatistics,\n    slate: defaultStatistics,\n  });\n\n  const setConfig = useCallback(\n    (partialConfig: Partial<Config>) => {\n      const newConfig = { ...config, ...partialConfig };\n      const nextActivePane =\n        newConfig.mountedEngines === 'both'\n          ? activePane\n          : newConfig.mountedEngines;\n\n      setRendering(true);\n      baseSetConfig(newConfig);\n      setActivePane(nextActivePane);\n      writeHugeDocumentSearchParams(newConfig);\n      setStatistics({\n        plate: defaultStatistics,\n        slate: defaultStatistics,\n      });\n\n      setTimeout(() => {\n        setRendering(false);\n        setPaneVersion((version) => version + 1);\n      });\n    },\n    [activePane, config]\n  );\n\n  const handleStatisticsChange = useCallback(\n    (engine: EngineKind, nextStatistics: EngineStatistics) => {\n      setStatistics((current) => {\n        const previous = current[engine];\n\n        if (\n          previous.averageKeyPressDuration ===\n            nextStatistics.averageKeyPressDuration &&\n          previous.lastKeyPressDuration ===\n            nextStatistics.lastKeyPressDuration &&\n          previous.lastLongAnimationFrameDuration ===\n            nextStatistics.lastLongAnimationFrameDuration\n        ) {\n          return current;\n        }\n\n        return {\n          ...current,\n          [engine]: nextStatistics,\n        };\n      });\n    },\n    []\n  );\n\n  return (\n    <div\n      style={{\n        display: 'flex',\n        flexDirection: 'column',\n        gap: 24,\n      }}\n    >\n      <p style={{ margin: 0 }}>\n        Slate huge-document controls, two isolated editors.\n      </p>\n\n      <PerformanceControls\n        config={config}\n        setConfig={setConfig}\n        statistics={statistics}\n      />\n\n      <div\n        style={{\n          display: 'grid',\n          gap: 24,\n          gridTemplateColumns: 'repeat(auto-fit, minmax(360px, 1fr))',\n        }}\n      >\n        {getMountedEngines(config).map((engine) => (\n          <EnginePane\n            active={activePane === engine}\n            config={config}\n            engine={engine}\n            key={`${engine}:${paneVersion}`}\n            onFocus={setActivePane}\n            onStatisticsChange={handleStatisticsChange}\n            rendering={rendering}\n          />\n        ))}\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:example"
    },
    {
      "path": "src/registry/examples/values/huge-document-value.tsx",
      "content": "import { faker } from '@faker-js/faker';\nimport type { Value } from 'platejs';\n\ntype HugeDocumentBlock = {\n  text: string;\n  type: 'heading-one' | 'paragraph';\n};\n\ntype HugeDocumentEngine = 'plate' | 'slate';\n\nconst DEFAULT_HUGE_DOCUMENT_BLOCKS = 10_000;\nconst HEADING_INTERVAL = 100;\nconst cachedHugeDocumentBlocks: HugeDocumentBlock[] = [];\n\nconst buildHugeDocumentBlocks = (blocks: number): HugeDocumentBlock[] => {\n  faker.seed(1);\n\n  return Array.from({ length: blocks }, (_, index) => {\n    if (index % HEADING_INTERVAL === 0) {\n      return {\n        text: faker.lorem.sentence(),\n        type: 'heading-one',\n      };\n    }\n\n    return {\n      text: faker.lorem.paragraph(),\n      type: 'paragraph',\n    };\n  });\n};\n\nconst toPlateValue = (blocks: HugeDocumentBlock[]): Value =>\n  blocks.map(({ text, type }) => ({\n    children: [{ text }],\n    type: type === 'heading-one' ? 'h1' : 'p',\n  })) as Value;\n\nconst toSlateValue = (blocks: HugeDocumentBlock[]): Value =>\n  blocks.map(({ text, type }) => ({\n    children: [{ text }],\n    type,\n  })) as Value;\n\nexport const getHugeDocumentBlocks = (\n  blocks = DEFAULT_HUGE_DOCUMENT_BLOCKS\n): HugeDocumentBlock[] => {\n  if (cachedHugeDocumentBlocks.length >= blocks) {\n    return structuredClone(cachedHugeDocumentBlocks.slice(0, blocks));\n  }\n\n  cachedHugeDocumentBlocks.length = 0;\n  cachedHugeDocumentBlocks.push(...buildHugeDocumentBlocks(blocks));\n\n  return structuredClone(cachedHugeDocumentBlocks.slice(0, blocks));\n};\n\nexport const createHugeDocumentValue = ({\n  blocks = DEFAULT_HUGE_DOCUMENT_BLOCKS,\n  engine = 'plate',\n}: {\n  blocks?: number;\n  engine?: HugeDocumentEngine;\n} = {}): Value => {\n  const hugeDocumentBlocks = getHugeDocumentBlocks(blocks);\n\n  return engine === 'slate'\n    ? toSlateValue(hugeDocumentBlocks)\n    : toPlateValue(hugeDocumentBlocks);\n};\n",
      "type": "registry:example"
    }
  ],
  "type": "registry:example"
}