File size: 1,789 Bytes
ada5620
 
 
 
 
0e1b0c3
ada5620
 
 
 
 
 
0e1b0c3
ada5620
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0e1b0c3
 
 
 
 
ada5620
 
 
 
 
 
 
 
 
0e1b0c3
 
 
 
 
 
 
ada5620
 
0e1b0c3
ada5620
 
 
 
 
 
 
 
 
 
0e1b0c3
ada5620
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import React, { useEffect, useRef, useState } from "react";

export default function Mermaid({ chart }) {
  const ref = useRef(null);
  const [svg, setSvg] = useState("");
  const [error, setError] = useState(false);

  useEffect(() => {
    let isMounted = true;
    
    async function renderMermaid() {
      try {
        setError(false);
        const { default: mermaid } = await import("https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs");
        
        mermaid.initialize({
          startOnLoad: false,
          theme: "dark",
          securityLevel: "loose",
          fontFamily: "Inter, sans-serif",
        });

        if (isMounted && ref.current) {
          const id = `mermaid-${Math.random().toString(36).substr(2, 9)}`;
          const { svg } = await mermaid.render(id, chart);
          if (isMounted) {
            setSvg(svg);
          }
        }
      } catch (err) {
        console.error("Mermaid rendering failed:", err);
        if (isMounted) {
          setError(true);
        }
      }
    }

    renderMermaid();
    return () => {
      isMounted = false;
    };
  }, [chart]);

  const getLoadingContent = () => {
    if (error) {
      return `<div class="error" style="color: #ffb4a9; font-size: 0.9rem;">Failed to render diagram. Please check the syntax.</div>`;
    }
    return `<div class="loading">Rendering diagram...</div>`;
  };

  return (
    <div 
      ref={ref}
      className="mermaid-container" 
      style={{ 
        display: "flex", 
        justifyContent: "center", 
        padding: "1rem", 
        background: "rgba(0,0,0,0.2)",
        borderRadius: "8px",
        margin: "1rem 0",
        overflowX: "auto"
      }}
      dangerouslySetInnerHTML={{ __html: svg || getLoadingContent() }}
    />
  );
}