From f8a27f868c6f25c69a6c4a9d73a1d840f0839ee8 Mon Sep 17 00:00:00 2001 From: Mathis HERRIOT <197931332+0x485254@users.noreply.github.com> Date: Mon, 5 Jan 2026 10:35:52 +0100 Subject: [PATCH] feat: add Mermaid component for rendering charts in documentation with theme support --- documentation/src/components/mdx/mermaid.tsx | 56 ++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 documentation/src/components/mdx/mermaid.tsx diff --git a/documentation/src/components/mdx/mermaid.tsx b/documentation/src/components/mdx/mermaid.tsx new file mode 100644 index 0000000..cf7724b --- /dev/null +++ b/documentation/src/components/mdx/mermaid.tsx @@ -0,0 +1,56 @@ +'use client'; + +import { use, useEffect, useId, useState } from 'react'; +import { useTheme } from 'next-themes'; + +export function Mermaid({ chart }: { chart: string }) { + const [mounted, setMounted] = useState(false); + + useEffect(() => { + setMounted(true); + }, []); + + if (!mounted) return; + return ; +} + +const cache = new Map>(); + +function cachePromise(key: string, setPromise: () => Promise): Promise { + const cached = cache.get(key); + if (cached) return cached as Promise; + + 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 ( +
{ + if (container) bindFunctions?.(container); + }} + // biome-ignore lint/security/noDangerouslySetInnerHtml: conform usage + dangerouslySetInnerHTML={{ __html: svg }} + /> + ); +} \ No newline at end of file