diff options
| author | Adam Malczewski <[email protected]> | 2026-09-06 16:00:12 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-09-06 16:07:33 +0900 |
| commit | 706aa41955f86eeb6fb35af0b844048e2f53a788 (patch) | |
| tree | 29df364617c2cc2baf78e9c94becb08fa5c7d5f8 /src/features/layout/ui/TileRoot.test.ts | |
| parent | 21de98f8929b566badec7390afb26c5821c8931d (diff) | |
| download | dispatch-web-706aa41955f86eeb6fb35af0b844048e2f53a788.tar.gz dispatch-web-706aa41955f86eeb6fb35af0b844048e2f53a788.zip | |
fix(layout): draw diagnostic tile markers inset + frame the sidebar viewport, not its scrolled content
Two renderer bugs made the diagnostic layout plugin's borders useless:
1. Borders went past the panels and were invisible at screen edges: CSS
outlines draw OUTSIDE the border box by default, and tiles span their
containers edge-to-edge, so the 4px ring overflowed the visible area
and was clipped. The outline is now inset (outline-offset: -4px) so
it draws inside the tile's box.
2. The green side border scrolled with the sidebar: the marker was drawn
on the TilePanels root, which is the SCROLLED CONTENT of the split's
collapsible child. The marker now lives on the split's scroll-viewport
div — the sidebar's fixed, opaquely-painted frame: its box never moves
(only its contents scroll), and its own outline is never clipped by its
overflow. (The aside behind it can't carry the marker — the scroll
viewport's bg-base-100 paints over an outline drawn on the aside.)
markerStyle() centralizes the full declaration (outline + inset offset)
and returns undefined for unmarked/unknown markers, so unmarked trees
still render with zero outline CSS (pinned by the existing tests).
Paint layering verified with a headless-Chromium screenshot of a probe
page reproducing the exact DOM + computed styles.
Diffstat (limited to 'src/features/layout/ui/TileRoot.test.ts')
| -rw-r--r-- | src/features/layout/ui/TileRoot.test.ts | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/src/features/layout/ui/TileRoot.test.ts b/src/features/layout/ui/TileRoot.test.ts index ace280a..2f95854 100644 --- a/src/features/layout/ui/TileRoot.test.ts +++ b/src/features/layout/ui/TileRoot.test.ts @@ -245,8 +245,34 @@ describe("TileRoot", () => { }); const stack = container.querySelector("[data-testid='fixture-a']")?.closest(".flex-col"); expect(stack?.getAttribute("style")).toContain("outline: 4px solid red"); + // The SIDE marker frames the SCROLL CONTAINER — the sidebar's fixed, + // opaquely-painted viewport (the aside's bg is transparent; this div's + // bg-base-100 would cover an outline drawn on the aside). The panels + // root is its SCROLLED content, so an outline there would wrap the + // whole scrollable region and scroll along with it. + const viewport = container.querySelector("[data-testid='sidebar-scroll-viewport']"); + expect(viewport?.getAttribute("style")).toContain("outline: 4px solid green"); + }); + + it("outlines are INSET so they draw inside the tile's box (never clipped at screen edges)", () => { + // Tiles span their containers edge-to-edge, so a default (outside) + // outline overflows the visible area and is clipped away — the offset + // pulls the ring inside the box. Pin it on both marked tiles. + const { container } = render(TileRoot, { + props: { tree: markedTestTree(), collapse: createCollapseStore({ viewportWidth: 1024 }) }, + }); + const stack = container.querySelector("[data-testid='fixture-a']")?.closest(".flex-col"); + expect(stack?.getAttribute("style")).toContain("outline-offset: -4px"); + const viewport = container.querySelector("[data-testid='sidebar-scroll-viewport']"); + expect(viewport?.getAttribute("style")).toContain("outline-offset: -4px"); + }); + + it("the panels CONTENT carries no outline (it scrolls — the marker must not scroll with it)", () => { + const { container } = render(TileRoot, { + props: { tree: markedTestTree(), collapse: createCollapseStore({ viewportWidth: 1024 }) }, + }); const panels = container.querySelector("[data-testid='fixture-b']")?.closest(".gap-2"); - expect(panels?.getAttribute("style")).toContain("outline: 4px solid green"); + expect(panels?.getAttribute("style") ?? "").not.toContain("outline"); }); it("an unmarked tree draws NO outlines (trees without the field render exactly as before)", () => { |
