mirror of
https://github.com/hcengineering/platform.git
synced 2026-08-17 18:05:42 +02:00
fix: proper mermaid diagram size (#10487)
Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
+32
-11
@@ -15,7 +15,7 @@
|
||||
//
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Html, Modal, ButtonIcon, IconClose, IconMaximize, IconMinimize, Scroller } from '@hcengineering/ui'
|
||||
import { Modal, ButtonIcon, IconClose, IconMaximize, IconMinimize } from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
export let svg: string
|
||||
@@ -24,7 +24,7 @@
|
||||
const dispatch = createEventDispatcher()
|
||||
</script>
|
||||
|
||||
<Modal type={'type-component'} padding={'0.5rem'} bottomPadding={'0'} on:fullsize on:close>
|
||||
<Modal type={'type-component'} scrollableContent={false} on:fullsize on:close>
|
||||
<svelte:fragment slot="beforeTitle">
|
||||
<ButtonIcon
|
||||
icon={IconClose}
|
||||
@@ -49,25 +49,46 @@
|
||||
<div class="hulyHeader-divider short no-print" />
|
||||
</svelte:fragment>
|
||||
|
||||
<Scroller horizontal stickedScrollBars thinScrollBars>
|
||||
<div class="mermaid-container">
|
||||
<Html value={svg} />
|
||||
<div class="mermaid-scroll">
|
||||
<div class="mermaid-center">
|
||||
<div class="mermaid-container">
|
||||
<!-- Mermaid renders SVG with securityLevel=antiscript; render as-is to preserve SVG text -->
|
||||
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
||||
{@html svg}
|
||||
</div>
|
||||
</div>
|
||||
</Scroller>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<style>
|
||||
.mermaid-container {
|
||||
.mermaid-scroll {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0.5rem;
|
||||
overflow: auto;
|
||||
box-sizing: border-box;
|
||||
scrollbar-width: auto;
|
||||
}
|
||||
|
||||
.mermaid-center {
|
||||
min-width: 100%;
|
||||
min-height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mermaid-container {
|
||||
width: max-content;
|
||||
height: max-content;
|
||||
}
|
||||
|
||||
.mermaid-container :global(svg) {
|
||||
max-width: 100%;
|
||||
width: auto;
|
||||
height: auto;
|
||||
max-width: none;
|
||||
max-height: none;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -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')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user