mirror of
https://github.com/documenso/documenso.git
synced 2026-07-15 07:17:09 +10:00
67 lines
1.5 KiB
TypeScript
67 lines
1.5 KiB
TypeScript
'use client';
|
|
|
|
import { useTheme } from 'next-themes';
|
|
import { useEffect, useId, useRef, useState } from 'react';
|
|
|
|
export const Mermaid = ({ chart }: { chart: string }) => {
|
|
const [mounted, setMounted] = useState(false);
|
|
|
|
useEffect(() => {
|
|
setMounted(true);
|
|
}, []);
|
|
|
|
if (!mounted) {
|
|
return null;
|
|
}
|
|
|
|
return <MermaidContent chart={chart} />;
|
|
};
|
|
|
|
const MermaidContent = ({ chart }: { chart: string }) => {
|
|
const id = useId();
|
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
const { resolvedTheme } = useTheme();
|
|
const [svg, setSvg] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
let cancelled = false;
|
|
|
|
const render = async () => {
|
|
const mermaid = (await import('mermaid')).default;
|
|
|
|
mermaid.initialize({
|
|
startOnLoad: false,
|
|
securityLevel: 'loose',
|
|
fontFamily: 'inherit',
|
|
themeCSS: 'margin: 1.5rem auto 0;',
|
|
theme: resolvedTheme === 'dark' ? 'dark' : 'default',
|
|
});
|
|
|
|
const { svg: rendered, bindFunctions } = await mermaid.render(
|
|
id.replaceAll(':', ''),
|
|
chart.replaceAll('\\n', '\n'),
|
|
);
|
|
|
|
if (!cancelled) {
|
|
setSvg(rendered);
|
|
|
|
if (containerRef.current) {
|
|
bindFunctions?.(containerRef.current);
|
|
}
|
|
}
|
|
};
|
|
|
|
void render();
|
|
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, [chart, id, resolvedTheme]);
|
|
|
|
if (!svg) {
|
|
return null;
|
|
}
|
|
|
|
return <div ref={containerRef} dangerouslySetInnerHTML={{ __html: svg }} />;
|
|
};
|