File size: 1,789 Bytes
ada5620 0e1b0c3 ada5620 0e1b0c3 ada5620 0e1b0c3 ada5620 0e1b0c3 ada5620 0e1b0c3 ada5620 0e1b0c3 ada5620 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | import React, { useEffect, useRef, useState } from "react";
export default function Mermaid({ chart }) {
const ref = useRef(null);
const [svg, setSvg] = useState("");
const [error, setError] = useState(false);
useEffect(() => {
let isMounted = true;
async function renderMermaid() {
try {
setError(false);
const { default: mermaid } = await import("https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs");
mermaid.initialize({
startOnLoad: false,
theme: "dark",
securityLevel: "loose",
fontFamily: "Inter, sans-serif",
});
if (isMounted && ref.current) {
const id = `mermaid-${Math.random().toString(36).substr(2, 9)}`;
const { svg } = await mermaid.render(id, chart);
if (isMounted) {
setSvg(svg);
}
}
} catch (err) {
console.error("Mermaid rendering failed:", err);
if (isMounted) {
setError(true);
}
}
}
renderMermaid();
return () => {
isMounted = false;
};
}, [chart]);
const getLoadingContent = () => {
if (error) {
return `<div class="error" style="color: #ffb4a9; font-size: 0.9rem;">Failed to render diagram. Please check the syntax.</div>`;
}
return `<div class="loading">Rendering diagram...</div>`;
};
return (
<div
ref={ref}
className="mermaid-container"
style={{
display: "flex",
justifyContent: "center",
padding: "1rem",
background: "rgba(0,0,0,0.2)",
borderRadius: "8px",
margin: "1rem 0",
overflowX: "auto"
}}
dangerouslySetInnerHTML={{ __html: svg || getLoadingContent() }}
/>
);
}
|