fix: aspec ratio of rendering

This commit is contained in:
2026-03-10 23:59:04 +01:00
parent 6545c4fc51
commit 6014f34f76

View File

@@ -539,6 +539,23 @@ function RenderingNodeComponent({ id, data, width, height, selected }: Props) {
// Kroki and other SVG sources may prepend <?xml ... ?> so we detect by presence of <svg> tag // Kroki and other SVG sources may prepend <?xml ... ?> so we detect by presence of <svg> tag
const isSvgOutput = Boolean(renderedContent?.trim() && /<svg[\s>]/i.test(renderedContent.trim())) const isSvgOutput = Boolean(renderedContent?.trim() && /<svg[\s>]/i.test(renderedContent.trim()))
/** Process SVG HTML so it keeps aspect ratio and fills the viewport (used only for display, not download). */
const displayContent = useMemo(() => {
if (!renderedContent || !isSvgOutput) return renderedContent
let html = renderedContent
// Force preserve aspect ratio so the diagram is not stretched (Kroki often returns preserveAspectRatio="none")
html = html.replace(/\bpreserveAspectRatio\s*=\s*["']none["']/gi, 'preserveAspectRatio="xMidYMid meet"')
// Make root SVG fill container so it scales uniformly with meet
html = html.replace(/\bwidth\s*=\s*["'][^"']*["']/i, 'width="100%"')
html = html.replace(/\bheight\s*=\s*["'][^"']*["']/i, 'height="100%"')
// Override inline style width/height so they don't override the attributes
html = html.replace(/\bstyle\s*=\s*["']([^"']*)["']/i, (_, style) => {
const overridden = style.replace(/\b(width|height):[^;]+/gi, '$1:100%')
return `style="${overridden}"`
})
return html
}, [renderedContent, isSvgOutput])
const downloadSvg = useCallback(() => { const downloadSvg = useCallback(() => {
if (!renderedContent || !isSvgOutput) return if (!renderedContent || !isSvgOutput) return
const blob = new Blob([renderedContent], { type: 'image/svg+xml' }) const blob = new Blob([renderedContent], { type: 'image/svg+xml' })
@@ -872,14 +889,14 @@ function RenderingNodeComponent({ id, data, width, height, selected }: Props) {
<RotateCcw className="size-3 max-w-[12px] max-h-[12px]" /> <RotateCcw className="size-3 max-w-[12px] max-h-[12px]" />
</button> </button>
</div> </div>
<div className="absolute inset-0 nodrag nopan overflow-hidden"> <div className="absolute inset-0 nodrag nopan overflow-hidden flex flex-col">
<TransformComponent <TransformComponent
wrapperClass="!w-full !h-full" wrapperClass="!w-full !h-full"
contentClass="inline-flex nodrag nopan" contentClass="inline-flex flex-col nodrag nopan !w-full !min-h-0 !flex-1"
> >
<div <div
className="rendering-diagram inline-flex p-4 nodrag nopan" className="rendering-diagram inline-flex w-full min-h-0 flex-1 p-4 nodrag nopan"
dangerouslySetInnerHTML={{ __html: renderedContent }} dangerouslySetInnerHTML={{ __html: displayContent ?? '' }}
/> />
</TransformComponent> </TransformComponent>
</div> </div>