main
svelte 49 lines 1.22 KB
Raw
1 <script lang="ts">
2 import { onMount } from 'svelte';
3 import { mode } from 'mode-watcher';
4
5 let { code }: { code: string } = $props();
6
7 let container: HTMLDivElement;
8 let rendered = $state(false);
9
10 async function renderDiagram() {
11 if (!container) return;
12 try {
13 const { default: mermaid } = await import('mermaid');
14 const theme = mode.current === 'dark' ? 'dark' : 'default';
15 mermaid.initialize({
16 startOnLoad: false,
17 theme,
18 fontFamily: 'Open Sans, sans-serif'
19 });
20 const id = `mermaid-${Math.random().toString(36).slice(2, 9)}`;
21 const { svg } = await mermaid.render(id, code);
22 container.innerHTML = svg;
23 rendered = true;
24 } catch (e) {
25 console.error('[Mermaid] render failed:', e);
26 container.innerHTML = `<pre class="text-sm text-red-500">Failed to render diagram</pre>`;
27 }
28 }
29
30 onMount(() => {
31 renderDiagram();
32 });
33
34 $effect(() => {
35 // Track mode changes for re-render
36 const _ = mode.current;
37 if (rendered) {
38 renderDiagram();
39 }
40 });
41 </script>
42
43 <div class="not-prose my-6">
44 <div bind:this={container} class="flex justify-center overflow-x-auto">
45 <noscript>
46 <pre class="rounded-lg border border-border bg-secondary p-4 text-sm"><code>{code}</code></pre>
47 </noscript>
48 </div>
49 </div>