"use client";
import { useEffect, useId, useRef, useState } from "react";
import { useTheme } from "next-themes";
export function Mermaid({ chart }: { chart: string }) {
const id = useId();
const [svg, setSvg] = useState("");
const containerRef = useRef<HTMLDivElement>(null);
const currentChartRef = useRef<string | null>(null);
const { resolvedTheme } = useTheme();
useEffect(() => {
const container = containerRef.current;
if (currentChartRef.current === chart || !container) return;
currentChartRef.current = chart;
async function renderChart() {
const { default: mermaid } = await import("mermaid");
try {
mermaid.initialize({
startOnLoad: false,
securityLevel: "loose",
fontFamily: "inherit",
themeCSS: "margin: 1.5rem auto 0;",
theme: resolvedTheme === "dark" ? "dark" : "default",
});
const { svg, bindFunctions } = await mermaid.render(
id,
chart.replaceAll("\\n", "\n")
);
if (container && bindFunctions) {
bindFunctions(container);
}
setSvg(svg);
} catch (error) {
console.error("Error while rendering mermaid", error);
}
}
void renderChart();
}, [chart, id, resolvedTheme]);
return (
<div
ref={containerRef}
className="border border-border rounded-lg p-4"
dangerouslySetInnerHTML={{ __html: svg }}
/>
);
}