summaryrefslogtreecommitdiffhomepage
path: root/src/features/layout/logic
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-09-06 16:00:12 +0900
committerAdam Malczewski <[email protected]>2026-09-06 16:07:33 +0900
commit706aa41955f86eeb6fb35af0b844048e2f53a788 (patch)
tree29df364617c2cc2baf78e9c94becb08fa5c7d5f8 /src/features/layout/logic
parent21de98f8929b566badec7390afb26c5821c8931d (diff)
downloaddispatch-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/logic')
-rw-r--r--src/features/layout/logic/marker.test.ts15
-rw-r--r--src/features/layout/logic/marker.ts21
2 files changed, 35 insertions, 1 deletions
diff --git a/src/features/layout/logic/marker.test.ts b/src/features/layout/logic/marker.test.ts
index d9e3826..53b91b0 100644
--- a/src/features/layout/logic/marker.test.ts
+++ b/src/features/layout/logic/marker.test.ts
@@ -1,5 +1,6 @@
+import type { TileMarker } from "@dispatch/layout-contract";
import { describe, expect, it } from "vitest";
-import { markerOutline } from "./marker";
+import { markerOutline, markerStyle } from "./marker";
describe("markerOutline — the diagnostic tile-border mapping", () => {
it("main → a 4px solid red outline (the main tile's marker)", () => {
@@ -14,3 +15,15 @@ describe("markerOutline — the diagnostic tile-border mapping", () => {
expect(markerOutline(undefined)).toBeUndefined();
});
});
+
+describe("markerStyle — the complete inline style (outline + inset offset)", () => {
+ it("insets the outline so it draws INSIDE the tile's box (never clipped at screen edges)", () => {
+ expect(markerStyle("main")).toBe("outline: 4px solid red; outline-offset: -4px");
+ expect(markerStyle("side")).toBe("outline: 4px solid green; outline-offset: -4px");
+ });
+
+ it("no/unknown marker → NO style at all (unmarked nodes carry zero outline CSS)", () => {
+ expect(markerStyle(undefined)).toBeUndefined();
+ expect(markerStyle("purple" as unknown as TileMarker)).toBeUndefined();
+ });
+});
diff --git a/src/features/layout/logic/marker.ts b/src/features/layout/logic/marker.ts
index eb1ff84..46259e0 100644
--- a/src/features/layout/logic/marker.ts
+++ b/src/features/layout/logic/marker.ts
@@ -10,6 +10,12 @@
* (not a border) is used so the diagnostic draws WITHOUT changing any
* tile's layout/size (4px solid, clearly visible).
*
+ * The outline is INSET (`outline-offset: -4px`) so it draws INSIDE the
+ * tile's box: tiles span their containers edge-to-edge, so the default
+ * (outside) outline overflows the visible area and is clipped away at the
+ * screen edges. The views inside the tiles have no opaque full-bleed
+ * background, so the inset ring stays on top of the tile's content.
+ *
* The marker is purely presentational: unknown/absent → no outline
* (existing trees render exactly as before), and no other behavior is
* attached to it anywhere in the renderer.
@@ -23,3 +29,18 @@ export function markerOutline(marker: TileMarker | undefined): string | undefine
if (marker === "side") return "4px solid green";
return undefined;
}
+
+/** The inset that keeps the outline INSIDE the tile's box (see the header note). */
+export const MARKER_OUTLINE_OFFSET = "-4px";
+
+/**
+ * The COMPLETE inline style for a marked element — outline + inset offset in
+ * one declaration — or `undefined` when unmarked/unknown, so unmarked nodes
+ * carry no outline CSS at all (existing trees render exactly as before).
+ */
+export function markerStyle(marker: TileMarker | undefined): string | undefined {
+ const outline = markerOutline(marker);
+ return outline === undefined
+ ? undefined
+ : `outline: ${outline}; outline-offset: ${MARKER_OUTLINE_OFFSET}`;
+}