docs/references/components/image-preview.md
src/renderer/components/Preview/ provides the special-language previews used
by CodeBlockView. The current language mapping is:
| Code language | Component | Renderer |
|---|---|---|
mermaid | MermaidPreview | Mermaid library loaded by useMermaid |
plantuml | PlantUmlPreview | Remote www.plantuml.com SVG endpoint |
svg | SvgPreview | Supplied SVG string |
dot, graphviz | GraphvizPreview | Lazily initialized @viz-js/viz instance |
The four components are lazy-loaded by
CodeBlockView/constants.ts::SPECIAL_VIEW_COMPONENTS.
Each preview passes its renderer to useDebouncedRender, then renders the
result through ImagePreviewLayout:
source change
→ useDebouncedRender (300 ms by current callers)
→ format-specific renderer
→ renderSvgInShadowHost
→ ImagePreviewLayout
├─ loading overlay or error
├─ sanitized SVG in Shadow DOM
└─ optional ImageToolbar
useDebouncedRender owns the host ref, loading/error state, debounced trigger,
cancel, and an optional shouldRender predicate. Rendering runs inside
React.startTransition. Cancelling drops a pending debounce; it does not abort
an asynchronous render that has already started.
All four formats end at renderSvgInShadowHost. Before parsing, it sanitizes the
SVG with DOMPurify, allowing the additional SVG tags/attributes required by the
renderers. It then parses the result as SVG, falls back to an HTML parse only to
recover an SVG element, normalizes its sizing, and mounts it in an open Shadow
DOM with local base styles.
Shadow DOM provides style isolation; DOMPurify is the content-safety boundary.
Do not replace this path with direct innerHTML in a preview component.
ImagePreviewLayout uses useImageTools for pan, zoom, copy, download, and
expanded-dialog behavior. When enableToolbar is true, ImageToolbar exposes:
(0, 0) and zoom 1;The layout exposes pan, zoom, copy, and download through its preview ref so
CodeBlockView tools can operate on the same SVG.
MermaidPreview validates with mermaid.parse, renders in an off-screen
measurement element, repairs the known translate(undefined, NaN) output, and
then mounts the SVG. A MutationObserver tracks visibility through folded
message containers; hidden diagrams wait until their container has dimensions.
PlantUmlPreview UTF-8 encodes and raw-deflates the diagram, applies PlantUML's
custom base64 alphabet, and fetches SVG from the fixed public PlantUML server.
It reports HTTP and network failures through the shared error state. There is no
automatic retry, server selection, or server-health monitor.
SvgPreview sends the supplied string directly through the shared sanitizer,
parser, size normalization, and Shadow DOM renderer.
GraphvizPreview initializes one shared @viz-js/viz instance on demand,
renders DOT to SVG locally, and sends the result through the shared SVG path.
pnpm test src/renderer/components/Preview
pnpm test src/renderer/components/CodeBlockView