Files
memegoat/documentation/src/components/mdx/mermaid.tsx
Mathis HERRIOT 6074917bfb
All checks were successful
Lint / lint (push) Successful in 9m37s
chore(docs): reorder imports across documentation files for consistency
2026-01-05 16:30:02 +01:00

62 lines
1.4 KiB
TypeScript

"use client";
import { useTheme } from "next-themes";
import { use, useEffect, useId, useState } from "react";
export function Mermaid({ chart }: { chart: string }) {
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
if (!mounted) return;
return <MermaidContent chart={chart} />;
}
const cache = new Map<string, Promise<unknown>>();
function cachePromise<T>(
key: string,
setPromise: () => Promise<T>,
): Promise<T> {
const cached = cache.get(key);
if (cached) return cached as Promise<T>;
const promise = setPromise();
cache.set(key, promise);
return promise;
}
function MermaidContent({ chart }: { chart: string }) {
const id = useId();
const { resolvedTheme } = useTheme();
const { default: mermaid } = use(
cachePromise("mermaid", () => import("mermaid")),
);
mermaid.initialize({
startOnLoad: false,
securityLevel: "loose",
fontFamily: "inherit",
themeCSS: "margin: 1.5rem auto 0;",
theme: resolvedTheme === "dark" ? "dark" : "default",
});
const { svg, bindFunctions } = use(
cachePromise(`${chart}-${resolvedTheme}`, () => {
return mermaid.render(id, chart.replaceAll("\\n", "\n"));
}),
);
return (
<div
ref={(container) => {
if (container) bindFunctions?.(container);
}}
// biome-ignore lint/security/noDangerouslySetInnerHtml: conform usage
dangerouslySetInnerHTML={{ __html: svg }}
/>
);
}