1
+ <template >
2
+ <div class =" mermaid-container" >
3
+ <div v-if =" showCode" class =" mermaid-code" >
4
+ <details >
5
+ <summary >Show Mermaid Code</summary >
6
+ <pre ><code >{{ decodedGraph }}</code ></pre >
7
+ </details >
8
+ </div >
9
+ <div :id =" id" class =" mermaid-diagram" v-html =" renderedMermaid" ></div >
10
+ </div >
11
+ </template >
12
+
13
+ <script setup lang="ts">
14
+ import { ref , onMounted , computed , watch , nextTick } from ' vue'
15
+ import { useData } from ' vitepress'
16
+ import mermaid from ' mermaid'
17
+
18
+ const props = defineProps <{
19
+ id: string
20
+ graph: string
21
+ showCode? : boolean
22
+ }>()
23
+
24
+ const { isDark } = useData ()
25
+ const renderedMermaid = ref (' ' )
26
+
27
+ const decodedGraph = computed (() => {
28
+ try {
29
+ return decodeURIComponent (props .graph )
30
+ } catch {
31
+ return props .graph
32
+ }
33
+ })
34
+
35
+ const getMermaidConfig = (isDarkMode : boolean ) => ({
36
+ startOnLoad: false ,
37
+ theme: isDarkMode ? ' dark' : ' default' ,
38
+ securityLevel: ' loose' ,
39
+ fontFamily: ' inherit' ,
40
+ fontSize: 14 ,
41
+ themeVariables: {
42
+ // Ensure text is visible in both themes
43
+ primaryColor: isDarkMode ? ' #4f46e5' : ' #3b82f6' ,
44
+ primaryTextColor: isDarkMode ? ' #f1f5f9' : ' #1e293b' ,
45
+ primaryBorderColor: isDarkMode ? ' #6366f1' : ' #2563eb' ,
46
+ lineColor: isDarkMode ? ' #64748b' : ' #475569' ,
47
+ sectionBkgColor: isDarkMode ? ' #1e293b' : ' #f8fafc' ,
48
+ altSectionBkgColor: isDarkMode ? ' #334155' : ' #e2e8f0' ,
49
+ gridColor: isDarkMode ? ' #475569' : ' #cbd5e1' ,
50
+ secondaryColor: isDarkMode ? ' #374151' : ' #e5e7eb' ,
51
+ tertiaryColor: isDarkMode ? ' #4b5563' : ' #d1d5db' ,
52
+ background: isDarkMode ? ' #0f172a' : ' #ffffff' ,
53
+ mainBkg: isDarkMode ? ' #1e293b' : ' #f8fafc' ,
54
+ secondBkg: isDarkMode ? ' #334155' : ' #e2e8f0' ,
55
+ },
56
+ flowchart: {
57
+ useMaxWidth: true ,
58
+ htmlLabels: true ,
59
+ curve: ' basis'
60
+ },
61
+ sequence: {
62
+ useMaxWidth: true ,
63
+ wrap: true
64
+ },
65
+ gantt: {
66
+ useMaxWidth: true
67
+ }
68
+ })
69
+
70
+ const renderDiagram = async () => {
71
+ try {
72
+ // Re-initialize mermaid with current theme
73
+ mermaid .initialize (getMermaidConfig (isDark .value ))
74
+
75
+ const graphDefinition = decodedGraph .value
76
+ const uniqueId = ` ${props .id }_${isDark .value ? ' dark' : ' light' }_${Date .now ()} `
77
+
78
+ // Render the mermaid diagram
79
+ const { svg } = await mermaid .render (uniqueId , graphDefinition )
80
+ renderedMermaid .value = svg
81
+ } catch (error ) {
82
+ console .error (' Failed to render Mermaid diagram:' , error )
83
+ renderedMermaid .value = ` <div class="mermaid-error">
84
+ <p><strong>Failed to render Mermaid diagram</strong></p>
85
+ <pre>${decodedGraph .value }</pre>
86
+ </div> `
87
+ }
88
+ }
89
+
90
+ // Watch for theme changes and re-render
91
+ watch (isDark , () => {
92
+ nextTick (() => {
93
+ renderDiagram ()
94
+ })
95
+ })
96
+
97
+ onMounted (() => {
98
+ renderDiagram ()
99
+ })
100
+ </script >
101
+
102
+ <style scoped>
103
+ .mermaid-container {
104
+ margin : 1rem 0 ;
105
+ }
106
+
107
+ .mermaid-code {
108
+ margin-bottom : 1rem ;
109
+ }
110
+
111
+ .mermaid-code details {
112
+ border : 1px solid var (--vp-c-divider );
113
+ border-radius : 6px ;
114
+ padding : 0.5rem ;
115
+ background : var (--vp-c-bg-alt );
116
+ }
117
+
118
+ .mermaid-code summary {
119
+ cursor : pointer ;
120
+ font-weight : 500 ;
121
+ color : var (--vp-c-text-2 );
122
+ }
123
+
124
+ .mermaid-code pre {
125
+ margin : 0.5rem 0 0 0 ;
126
+ padding : 0 ;
127
+ background : transparent ;
128
+ border : none ;
129
+ }
130
+
131
+ .mermaid-code code {
132
+ font-family : var (--vp-font-family-mono );
133
+ font-size : 0.875rem ;
134
+ color : var (--vp-c-text-1 );
135
+ }
136
+
137
+ .mermaid-diagram {
138
+ text-align : center ;
139
+ background : var (--vp-c-bg );
140
+ border-radius : 6px ;
141
+ padding : 1rem ;
142
+ border : 1px solid var (--vp-c-divider );
143
+ }
144
+
145
+ .mermaid-diagram :deep(svg ) {
146
+ max-width : 100% ;
147
+ height : auto ;
148
+ }
149
+
150
+ .mermaid-error {
151
+ color : var (--vp-c-danger-1 );
152
+ background : var (--vp-c-danger-soft );
153
+ border : 1px solid var (--vp-c-danger-2 );
154
+ border-radius : 6px ;
155
+ padding : 1rem ;
156
+ }
157
+
158
+ .mermaid-error pre {
159
+ background : transparent ;
160
+ color : var (--vp-c-text-1 );
161
+ font-size : 0.875rem ;
162
+ }
163
+ </style >
0 commit comments