@@ -8,24 +8,17 @@ export default function Mermaid() {
88
99 useEffect ( ( ) => {
1010 const renderMermaid = async ( ) => {
11- const mermaidBlocks =
12- document . querySelectorAll < HTMLDivElement > ( '.language-mermaid' ) ;
11+ const mermaidBlocks = document . querySelectorAll < HTMLDivElement > ( '.language-mermaid' ) ;
1312 if ( mermaidBlocks . length === 0 ) return ;
1413
15- const escapeHTML = ( str : string ) =>
16- str . replace (
17- / [ & < > " ' ] / g,
18- match =>
19- ( {
20- '&' : '&' ,
21- '<' : '<' ,
22- '>' : '>' ,
23- '"' : '"' ,
24- "'" : ''' ,
25- } ) [ match ] || match
26- ) ;
14+ const escapeHTML = ( str : string ) =>
15+ str . replace ( / [ & < > " ' ] / g, ( match ) => ( {
16+ '&' : '&' , '<' : '<' , '>' : '>' , '"' : '"' , "'" : '''
17+ } [ match ] || match ) ) ;
2718
2819 const { default : mermaid } = await import ( 'mermaid/dist/mermaid.esm.min.mjs' ) ;
20+ const svgPanZoom = ( await import ( 'svg-pan-zoom' ) ) . default ;
21+
2922 // Create light and dark versions
3023 mermaidBlocks . forEach ( block => {
3124 const code = block . textContent ?? '' ;
@@ -51,44 +44,20 @@ export default function Mermaid() {
5144 // Render both themes
5245 mermaid . initialize ( { startOnLoad : false , theme : 'default' } ) ;
5346 await mermaid . run ( { nodes : document . querySelectorAll ( '.language-mermaid.light' ) } ) ;
54-
47+
5548 mermaid . initialize ( { startOnLoad : false , theme : 'dark' } ) ;
5649 await mermaid . run ( { nodes : document . querySelectorAll ( '.language-mermaid.dark' ) } ) ;
5750
58- // Initialize pan/zoom
59- await initializePanZoom ( ) ;
60- setDoneRendering ( true ) ;
61- } ;
62-
63- const initializePanZoom = async ( ) => {
64- const svgPanZoom = ( await import ( 'svg-pan-zoom' ) ) . default ;
65-
51+ // Initialize pan/zoom for all SVGs (including hidden ones)
6652 document . querySelectorAll ( '.language-mermaid svg' ) . forEach ( svg => {
6753 const svgElement = svg as SVGSVGElement ;
68- const container = svgElement . closest ( '.language-mermaid' ) as HTMLElement ;
69- const isVisible = window . getComputedStyle ( container ) . display !== 'none' ;
70-
71- if ( isVisible ) {
72- const rect = svgElement . getBoundingClientRect ( ) ;
73- if ( rect . width > 0 && rect . height > 0 ) {
74- svgElement . setAttribute ( 'width' , rect . width . toString ( ) ) ;
75- svgElement . setAttribute ( 'height' , rect . height . toString ( ) ) ;
76- }
77-
78- svgPanZoom ( svgElement , {
79- zoomEnabled : true ,
80- panEnabled : true ,
81- controlIconsEnabled : true ,
82- fit : true ,
83- center : true ,
84- minZoom : 0.1 ,
85- maxZoom : 10 ,
86- zoomScaleSensitivity : 0.2 ,
87- } ) ;
88- } else {
89- svgElement . dataset . needsPanZoom = 'true' ;
54+ const rect = svgElement . getBoundingClientRect ( ) ;
55+
56+ if ( rect . width > 0 && rect . height > 0 ) {
57+ svgElement . setAttribute ( 'width' , rect . width . toString ( ) ) ;
58+ svgElement . setAttribute ( 'height' , rect . height . toString ( ) ) ;
9059 }
91-
60+
9261 svgPanZoom ( svgElement , {
9362 zoomEnabled : true ,
9463 panEnabled : true ,
@@ -107,46 +76,6 @@ export default function Mermaid() {
10776 renderMermaid ( ) ;
10877 } , [ ] ) ;
10978
110- // Initialize pan/zoom for newly visible SVGs on theme change
111- useEffect ( ( ) => {
112- if ( ! isDoneRendering ) return ;
113-
114- const initializeDelayedPanZoom = async ( ) => {
115- const svgPanZoom = ( await import ( 'svg-pan-zoom' ) ) . default ;
116-
117- document
118- . querySelectorAll ( '.language-mermaid svg[data-needs-pan-zoom="true"]' )
119- . forEach ( svg => {
120- const svgElement = svg as SVGSVGElement ;
121- const container = svgElement . closest ( '.language-mermaid' ) as HTMLElement ;
122- const isVisible = window . getComputedStyle ( container ) . display !== 'none' ;
123-
124- if ( isVisible ) {
125- const rect = svgElement . getBoundingClientRect ( ) ;
126- if ( rect . width > 0 && rect . height > 0 ) {
127- svgElement . setAttribute ( 'width' , rect . width . toString ( ) ) ;
128- svgElement . setAttribute ( 'height' , rect . height . toString ( ) ) ;
129- }
130-
131- svgPanZoom ( svgElement , {
132- zoomEnabled : true ,
133- panEnabled : true ,
134- controlIconsEnabled : true ,
135- fit : true ,
136- center : true ,
137- minZoom : 0.1 ,
138- maxZoom : 10 ,
139- zoomScaleSensitivity : 0.2 ,
140- } ) ;
141-
142- svgElement . removeAttribute ( 'data-needs-pan-zoom' ) ;
143- }
144- } ) ;
145- } ;
146-
147- setTimeout ( initializeDelayedPanZoom , 50 ) ;
148- } , [ theme , isDoneRendering ] ) ;
149-
15079 return isDoneRendering ? (
15180 < style >
15281 { `
@@ -157,4 +86,4 @@ export default function Mermaid() {
15786 ` }
15887 </ style >
15988 ) : null ;
160- }
89+ }
0 commit comments