Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | 7x 7x 7x 7x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 7x 2x 5x | "use client";
import { useEffect, useRef, useState } from "react";
interface MermaidDiagramProps {
chart: string;
caption?: string;
}
export default function MermaidDiagram({
chart,
caption,
}: MermaidDiagramProps) {
const containerRef = useRef<HTMLDivElement>(null);
const [svg, setSvg] = useState<string>("");
const [error, setError] = useState<string>("");
useEffect(() => {
let cancelled = false;
async function render() {
try {
const mermaid = (await import("mermaid")).default;
const isDark = document.documentElement.classList.contains("dark");
mermaid.initialize({
startOnLoad: false,
theme: isDark ? "dark" : "default",
themeVariables: isDark
? {
darkMode: true,
background: "#1a1a2e",
primaryColor: "#6366f1",
primaryTextColor: "#e2e8f0",
primaryBorderColor: "#818cf8",
lineColor: "#e2e8f0",
secondaryColor: "#1e293b",
tertiaryColor: "#0f172a",
edgeLabelBackground: "#1e293b",
fontFamily: "ui-sans-serif, system-ui, sans-serif",
}
: {
darkMode: false,
background: "#ffffff",
primaryColor: "#4f46e5",
primaryTextColor: "#1e293b",
primaryBorderColor: "#6366f1",
lineColor: "#334155",
secondaryColor: "#f1f5f9",
tertiaryColor: "#e2e8f0",
edgeLabelBackground: "#f8fafc",
fontFamily: "ui-sans-serif, system-ui, sans-serif",
},
});
const id = `mermaid-${Math.random().toString(36).slice(2, 9)}`;
const { svg: rendered } = await mermaid.render(id, chart.trim());
if (!cancelled) setSvg(rendered);
} catch (err: unknown) {
if (!cancelled) setError(String(err));
}
}
render();
return () => {
cancelled = true;
};
}, [chart]);
if (error) {
return (
<div className="border border-red-700 rounded-lg p-4 my-4">
<p className="text-red-400 text-sm">Diagram render error: {error}</p>
<pre className="text-xs text-[var(--text-secondary)] mt-2 overflow-x-auto">
{chart}
</pre>
</div>
);
}
return (
<figure className="my-6">
<div
ref={containerRef}
className="bg-[var(--surface)]/50 border border-[var(--border)] rounded-lg p-4 overflow-x-auto flex justify-center"
dangerouslySetInnerHTML={{ __html: svg }}
/>
{caption && (
<figcaption className="text-center text-sm text-[var(--text-secondary)] mt-2 italic">
{caption}
</figcaption>
)}
</figure>
);
}
|