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