From be2e4586afa55aa298a86f86926c50ed19aa0752 Mon Sep 17 00:00:00 2001 From: Alexander Onnikov Date: Wed, 4 Feb 2026 22:14:22 +0700 Subject: [PATCH] fix: proper mermaid diagram size Signed-off-by: Alexander Onnikov --- packages/theme/styles/prose.scss | 4 +- .../codeSnippets/MermaidPopup.svelte | 43 ++++++++++++++----- .../extension/codeSnippets/mermaid.ts | 36 +++++++++++----- 3 files changed, 60 insertions(+), 23 deletions(-) diff --git a/packages/theme/styles/prose.scss b/packages/theme/styles/prose.scss index 1797af3e72e..235628047c0 100644 --- a/packages/theme/styles/prose.scss +++ b/packages/theme/styles/prose.scss @@ -584,9 +584,11 @@ pre.proseCodeBlock>pre.proseCode { .mermaidPreview { width: 100%; + display: flex; + justify-content: center; svg { - width: 100%; + width: auto; max-width: 100%; height: auto; display: block; diff --git a/plugins/text-editor-resources/src/components/extension/codeSnippets/MermaidPopup.svelte b/plugins/text-editor-resources/src/components/extension/codeSnippets/MermaidPopup.svelte index df6e3692e64..2c7dff9f3bd 100644 --- a/plugins/text-editor-resources/src/components/extension/codeSnippets/MermaidPopup.svelte +++ b/plugins/text-editor-resources/src/components/extension/codeSnippets/MermaidPopup.svelte @@ -15,7 +15,7 @@ // --> - + - -
- +
+
+
+ + + {@html svg} +
- +
diff --git a/plugins/text-editor-resources/src/components/extension/codeSnippets/mermaid.ts b/plugins/text-editor-resources/src/components/extension/codeSnippets/mermaid.ts index b12e6e40e55..3d546dd98f1 100644 --- a/plugins/text-editor-resources/src/components/extension/codeSnippets/mermaid.ts +++ b/plugins/text-editor-resources/src/components/extension/codeSnippets/mermaid.ts @@ -473,24 +473,38 @@ function buildState ( // Ensure SVG maintains its natural size const svg = container.querySelector('svg') if (svg !== null) { - svg.style.width = '100%' + svg.style.width = 'auto' svg.style.maxWidth = '100%' svg.style.height = 'auto' svg.style.display = 'block' - // Remove any width/height attributes that might cause stretching + + const widthAttr = svg.getAttribute('width') + const heightAttr = svg.getAttribute('height') + const viewBox = svg.getAttribute('viewBox') + const viewBoxParts = viewBox + ?.trim() + .split(/[\s,]+/) + .map((v) => Number.parseFloat(v)) + const viewBoxWidth = viewBoxParts?.length === 4 ? viewBoxParts[2] : NaN + const viewBoxHeight = viewBoxParts?.length === 4 ? viewBoxParts[3] : NaN + + const widthIsPercent = widthAttr?.trim().endsWith('%') ?? false + const heightIsPercent = heightAttr?.trim().endsWith('%') ?? false + + if ((widthAttr !== undefined || widthIsPercent) && Number.isFinite(viewBoxWidth)) { + svg.setAttribute('width', String(viewBoxWidth)) + } + if ((heightAttr !== undefined || heightIsPercent) && Number.isFinite(viewBoxHeight)) { + svg.setAttribute('height', String(viewBoxHeight)) + } + + // If no viewBox, derive one from numeric width/height to allow scaling down if (!svg.hasAttribute('viewBox')) { - const width = svg.getAttribute('width') - const height = svg.getAttribute('height') - const widthValue = width !== null ? Number.parseFloat(width) : NaN - const heightValue = height !== null ? Number.parseFloat(height) : NaN + const widthValue = widthAttr !== null ? Number.parseFloat(widthAttr) : NaN + const heightValue = heightAttr !== null ? Number.parseFloat(heightAttr) : NaN if (Number.isFinite(widthValue) && Number.isFinite(heightValue)) { svg.setAttribute('viewBox', `0 0 ${widthValue} ${heightValue}`) - svg.removeAttribute('width') - svg.removeAttribute('height') } - } else { - svg.removeAttribute('width') - svg.removeAttribute('height') } }