Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/theme/styles/prose.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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}
Expand All @@ -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>
Original file line number Diff line number Diff line change
Expand Up @@ -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')
}
}

Expand Down
Loading