From 73742495b03f102546fd4007c0ae721c0c162fbe Mon Sep 17 00:00:00 2001 From: lucaronin Date: Wed, 20 May 2026 18:57:08 +0200 Subject: [PATCH] fix: unzoom fullscreen mermaid diagrams --- src/components/EditorTheme.css | 1 + tests/smoke/mermaid-diagram-notes.spec.ts | 43 +++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/components/EditorTheme.css b/src/components/EditorTheme.css index 3f6c5db9..1237dbce 100644 --- a/src/components/EditorTheme.css +++ b/src/components/EditorTheme.css @@ -356,6 +356,7 @@ max-height: calc(100dvh - 32px); overflow: hidden; padding: 0; + zoom: var(--tolaria-overlay-zoom-inverse, 1); } .mermaid-diagram__dialog-viewport { diff --git a/tests/smoke/mermaid-diagram-notes.spec.ts b/tests/smoke/mermaid-diagram-notes.spec.ts index 4f52e0cd..e70d454e 100644 --- a/tests/smoke/mermaid-diagram-notes.spec.ts +++ b/tests/smoke/mermaid-diagram-notes.spec.ts @@ -243,6 +243,37 @@ async function switchToResolvedTheme(page: Page, mode: 'dark' | 'light'): Promis await expect(root).toHaveAttribute('data-theme', mode) } +async function setDocumentZoom(page: Page, percent: number): Promise { + await page.evaluate((zoomPercent) => { + const factor = zoomPercent / 100 + document.documentElement.style.setProperty('zoom', `${zoomPercent}%`) + document.documentElement.style.setProperty('--tolaria-overlay-zoom-factor', String(factor)) + document.documentElement.style.setProperty('--tolaria-overlay-zoom-inverse', String(1 / factor)) + window.dispatchEvent(new Event('laputa-zoom-change')) + }, percent) +} + +async function readDialogViewportBounds(page: Page) { + return page.getByTestId('mermaid-diagram-dialog-viewport').evaluate((viewport) => { + const rect = viewport.getBoundingClientRect() + return { + width: rect.width, + height: rect.height, + windowWidth: window.innerWidth, + windowHeight: window.innerHeight, + } + }) +} + +async function dialogViewportFitsWindow(page: Page): Promise { + const bounds = await readDialogViewportBounds(page) + const horizontallyContained = bounds.width <= bounds.windowWidth - 16 + const verticallyContained = bounds.height <= bounds.windowHeight - 16 + const stillFullscreenWidth = bounds.width >= bounds.windowWidth - 96 + const stillFullscreenHeight = bounds.height >= bounds.windowHeight - 96 + return horizontallyContained && verticallyContained && stillFullscreenWidth && stillFullscreenHeight +} + function mermaidNodeLabel(node: Locator): Locator { return node.locator('.nodeLabel, text').first() } @@ -327,6 +358,18 @@ test('fullscreen Mermaid diagrams keep the active Tolaria surface in dark mode', await expect.poll(() => computedCss(dialogViewport, 'background-color')).toBe(inlineBackground) }) +test('fullscreen Mermaid diagrams stay within the viewport while the app is zoomed', async ({ page }) => { + await openNote(page, 'Mermaid Reported') + await expectRenderedDiagramCount(page, 1) + await setDocumentZoom(page, 120) + + await page.getByTestId('mermaid-diagram').first().hover() + await page.getByRole('button', { name: 'Open Mermaid diagram' }).first().click() + await expect(page.getByTestId('mermaid-diagram-dialog-viewport')).toBeVisible() + + await expect.poll(() => dialogViewportFitsWindow(page)).toBe(true) +}) + test('Mermaid diagrams stay mounted after property edits refresh frontmatter', async ({ page }) => { const pageErrors: string[] = [] page.on('pageerror', error => pageErrors.push(error.message))