diff options
| author | 2026-03-26 10:18:46 +0800 | |
|---|---|---|
| committer | 2026-03-26 10:18:46 +0800 | |
| commit | 62d8c7c5c3bc36fbaa1bfba099e3bf04a00c300d (patch) | |
| tree | a8ab7a9ea4707f377271db29eea2a2bd6492e277 /packages/docs | |
| parent | 38d74bf0fedc3224e371e826577f00f7fc62d837 (diff) | |
| download | DropOut-62d8c7c5c3bc36fbaa1bfba099e3bf04a00c300d.tar.gz DropOut-62d8c7c5c3bc36fbaa1bfba099e3bf04a00c300d.zip | |
refactor(mermaid): improve svg rendering with DOMParser
Diffstat (limited to 'packages/docs')
| -rw-r--r-- | packages/docs/app/components/mermaid.tsx | 30 |
1 files changed, 13 insertions, 17 deletions
diff --git a/packages/docs/app/components/mermaid.tsx b/packages/docs/app/components/mermaid.tsx index 04d89d9..3a54a04 100644 --- a/packages/docs/app/components/mermaid.tsx +++ b/packages/docs/app/components/mermaid.tsx @@ -13,24 +13,20 @@ export function Mermaid({ chart }: { chart: string }) { const ref = useRef<HTMLDivElement>(null); useEffect(() => { - const renderChart = async () => { - if (!ref.current) return; - - try { - const id = `mermaid-${Math.random().toString(36).slice(2, 9)}`; - const { svg } = await mermaid.render(id, chart); - // Use innerHTML with sanitized SVG from mermaid.render - // biome-disable-next-line security/noInnerHtml - ref.current.innerHTML = svg; - } catch { - // Invalid chart definition, render nothing - if (ref.current) { - ref.current.innerHTML = ""; + const id = `mermaid-${Math.random().toString(36).slice(2, 9)}`; + mermaid + .render(id, chart) + .then(({ svg }) => { + const parser = new DOMParser(); + const doc = parser.parseFromString(svg, "image/svg+xml"); + const svgEl = doc.querySelector("svg"); + if (ref.current && svgEl) { + ref.current.replaceChildren(svgEl); } - } - }; - - renderChart(); + }) + .catch(() => { + ref.current?.replaceChildren(); + }); }, [chart]); return ( |