From b18c5170de975d71d8ef03bd4b87f905e2e6b3bc Mon Sep 17 00:00:00 2001 From: Ben Phillips Date: Thu, 21 May 2026 09:10:59 +0100 Subject: [PATCH] Fix inbox panel sizing to its container, not the viewport The inbox view content used width: min(90vw, 1200px). 90vw follows the whole window, not the inbox panel, so with sidebars open the content overflowed the panel's right edge and the centred empty-state text drifted right of the panel centre. Size to the panel with width: 100%; max-width and margin: 0 auto still cap and centre on wide panels. Fixes #55 --- styles.css | 2 +- tests/inbox-modal-layout-style.test.ts | 45 ++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 tests/inbox-modal-layout-style.test.ts diff --git a/styles.css b/styles.css index a8f338b..6790aae 100644 --- a/styles.css +++ b/styles.css @@ -2,7 +2,7 @@ .flow-gtd-inbox-modal { padding: 20px; - width: min(90vw, 1200px); + width: 100%; max-width: 1200px; margin: 0 auto; } diff --git a/tests/inbox-modal-layout-style.test.ts b/tests/inbox-modal-layout-style.test.ts new file mode 100644 index 0000000..c5180f9 --- /dev/null +++ b/tests/inbox-modal-layout-style.test.ts @@ -0,0 +1,45 @@ +// ABOUTME: Regression tests for inbox processing view layout styling. +// ABOUTME: Ensures the panel sizes to its container, not the viewport, so content stays centred. + +import { readFileSync } from "fs"; +import { join } from "path"; + +const repoRoot = join(__dirname, ".."); + +function readStyles(): string { + return readFileSync(join(repoRoot, "styles.css"), "utf-8"); +} + +function getCssBlock(styles: string, selector: string): string { + const escapedSelector = selector.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); + const match = styles.match(new RegExp(`${escapedSelector}\\s*\\{([\\s\\S]*?)\\}`)); + + if (!match) { + throw new Error(`Missing CSS selector: ${selector}`); + } + + return match[1]; +} + +function getDeclaration(block: string, property: string): string | undefined { + const declaration = block + .split(";") + .map((line) => line.trim()) + .find((line) => line.startsWith(`${property}:`)); + + return declaration?.slice(property.length + 1).trim(); +} + +describe("inbox modal layout styling", () => { + it("sizes the panel to its container, not the viewport", () => { + const block = getCssBlock(readStyles(), ".flow-gtd-inbox-modal"); + + // Viewport units (vw) follow the window width, not the leaf width, so the + // panel overflows and content drifts off-centre when sidebars are open. + const width = getDeclaration(block, "width"); + expect(width).toBe("100%"); + expect(width).not.toMatch(/vw/); + expect(getDeclaration(block, "max-width")).toBe("1200px"); + expect(getDeclaration(block, "margin")).toBe("0 auto"); + }); +});