mirror of
https://github.com/mvschwarz/openrig.git
synced 2026-11-08 17:31:56 -10:00
shell-redesign V1 attempt-3 Phase 2 BOUNCE-FIX #3: drawer width-coupling
guard-3 caught a real bug missed in bounce-fix #2: VellumSheet wide preset was calibrated 45rem → 38rem, but AppShell.tsx workspaceRightOffset still reserved 45rem of right padding via the --workspace-right-offset CSS variable when drawer is open. Net effect: open-drawer surfaces a 7rem (112px) layout gap between the drawer (38rem) and the right edge of the center workspace's content. Fix: - AppShell.tsx workspaceRightOffset open-drawer literal "45rem" → "38rem". - SharedDetailDrawer.tsx stale lg:w-[45rem] comment → lg:w-[38rem] (with calibration-date reference per content-drawer.md L9). - New regression test in test/app-shell.test.tsx (CSS-source-assertion per pseudo-element-paint test contract / discipline ritual #7): * "VellumSheet wide preset and AppShell workspaceRightOffset use the SAME literal" — extracts widthClass.wide width from VellumSheet source and workspaceRightOffset open-drawer value from AppShell source via regex; asserts equal. * "no live 45rem string in chrome source" — scans AppShell, drawer, and vellum-sheet sources; for any line containing "45rem" verifies it's inside a // line comment OR a /* ... */ block comment context (historical calibration notes are allowed; live class/value strings are not). Permanent guard against the same coupling drift. Verification: - tsc --noEmit: clean - pnpm test: 599/600 PASS (added 2 new tests; pre-existing test/library-review.test.tsx > Send-to-seat modal still failing unrelated to this scope; verified pre-Phase-1 via git stash) - pnpm build: ✓ in 1.94s - Runtime probe (drawer not mounted by default per SC-6) confirms static-source coupling test is the right approach; computed-style of CSS variables in jsdom is too brittle to depend on. Permission preflight caveat acknowledged: bounce-fix #2 §6 fields writable_root_coverage and approval_layer_probe were authored as prose/boolean rather than the exact path+covered_by and command+result subshape per velocity-permission-preflight schema. Orch accepted the field-level close-out; will sharpen to the exact subshape on next preflight authoring (likely Phase 3 dispatch). Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
1 parent
a69275805d
commit
c916c4bed6
3 files changed
+92
-4
No files matched your search
@@ -374,7 +374,11 @@ export function AppShell({ children }: AppShellProps) {
|
||||
const workspaceLeftOffset = isWideLayout
|
||||
? `${3 + (explorerVisible && desktopExplorerOpen ? 18 : 0)}rem`
|
||||
: "0rem";
|
||||
const workspaceRightOffset = isWideLayout && drawerOpen ? "45rem" : "0rem";
|
||||
// Coupled to VellumSheet wide preset (lg:w-[38rem]) — bounce-fix #3
|
||||
// caught the gap that emerged when bounce-fix #2 calibrated the drawer
|
||||
// 45rem → 38rem without updating this offset. Keep these two literals
|
||||
// in sync; the regression test in app-shell.test.tsx asserts they match.
|
||||
const workspaceRightOffset = isWideLayout && drawerOpen ? "38rem" : "0rem";
|
||||
const workspaceStyle = {
|
||||
"--workspace-left-offset": workspaceLeftOffset,
|
||||
"--workspace-right-offset": workspaceRightOffset,
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
// right-sidebar (closer to document-reading width)."
|
||||
//
|
||||
// Phase 2 lays the chrome: VellumSheet primitive (Phase 1) wraps each
|
||||
// panel; default-closed (selection === null returns null); ~720px wide
|
||||
// on desktop (`lg:w-[45rem]` via VellumSheet width="wide"); user-closable
|
||||
// via VellumSheet's onClose [×] button.
|
||||
// panel; default-closed (selection === null returns null); ~608px wide
|
||||
// on desktop (`lg:w-[38rem]` via VellumSheet width="wide"; calibrated
|
||||
// 2026-05-06 per content-drawer.md L9); user-closable via VellumSheet's
|
||||
// onClose [×] button.
|
||||
//
|
||||
// Phase 4 wires the new viewer types (QueueItemViewer, FileViewer,
|
||||
// SubSpecPreview, SeatDetailViewer) and named triggers from feed cards
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
import { render, cleanup, waitFor } from "@testing-library/react";
|
||||
import { createMemoryHistory, RouterProvider, createRouter } from "@tanstack/react-router";
|
||||
import { readFileSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
import { createMockEventSourceClass } from "./helpers/mock-event-source.js";
|
||||
|
||||
const mockFetch = vi.fn();
|
||||
@@ -248,6 +250,87 @@ describe("AppShell — Phase 2 chrome", () => {
|
||||
});
|
||||
});
|
||||
|
||||
// Phase 2 BOUNCE-FIX #3 — width-coupling regression (guard-3 catch).
|
||||
// The center workspace's --workspace-right-offset CSS variable must equal
|
||||
// the VellumSheet wide preset width when drawer is open. Bounce-fix #2
|
||||
// calibrated VellumSheet 45rem → 38rem but missed this consumer; net
|
||||
// effect was a 7rem (112px) gap between drawer and reserved padding.
|
||||
// Per pseudo-element-paint test contract (discipline ritual #7), assert
|
||||
// via CSS source rather than runtime (computed style of CSS vars from
|
||||
// jsdom is brittle).
|
||||
describe("Drawer width / right-offset coupling (bounce-fix #3 regression)", () => {
|
||||
const APP_SHELL_SRC = readFileSync(
|
||||
path.resolve(__dirname, "../src/components/AppShell.tsx"),
|
||||
"utf8",
|
||||
);
|
||||
const VELLUM_SHEET_SRC = readFileSync(
|
||||
path.resolve(__dirname, "../src/components/ui/vellum-sheet.tsx"),
|
||||
"utf8",
|
||||
);
|
||||
const SHARED_DRAWER_SRC = readFileSync(
|
||||
path.resolve(__dirname, "../src/components/SharedDetailDrawer.tsx"),
|
||||
"utf8",
|
||||
);
|
||||
|
||||
it("VellumSheet wide preset and AppShell workspaceRightOffset use the SAME literal", () => {
|
||||
// Pull the wide-preset width from VellumSheet source.
|
||||
const vellumMatch = VELLUM_SHEET_SRC.match(
|
||||
/wide:\s*"w-full\s+lg:w-\[(\d+rem)\]/,
|
||||
);
|
||||
expect(vellumMatch, "VellumSheet wide preset must declare lg:w-[Xrem]").toBeTruthy();
|
||||
const vellumWide = vellumMatch![1];
|
||||
|
||||
// Pull the open-drawer offset from AppShell source.
|
||||
const offsetMatch = APP_SHELL_SRC.match(
|
||||
/workspaceRightOffset\s*=\s*[^?]*\?\s*"(\d+rem)"\s*:/,
|
||||
);
|
||||
expect(offsetMatch, "AppShell workspaceRightOffset must declare ternary 'Xrem' : '0rem'")
|
||||
.toBeTruthy();
|
||||
const offsetOpen = offsetMatch![1];
|
||||
|
||||
expect(offsetOpen, "AppShell workspaceRightOffset must equal VellumSheet wide preset width")
|
||||
.toBe(vellumWide);
|
||||
});
|
||||
|
||||
it("no live 45rem string in chrome source (only historical calibration comments are allowed)", () => {
|
||||
// Extract every line containing "45rem" and verify each is inside
|
||||
// a comment (calibration history). Chrome source must NOT carry
|
||||
// 45rem as a live class or value.
|
||||
const checkSource = (src: string, label: string) => {
|
||||
const lines = src.split("\n");
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
if (!line.includes("45rem")) continue;
|
||||
// Permitted only when the line is a JS/TS line comment ("//") or
|
||||
// an active block-comment context ("/*", "*"). We scan backward
|
||||
// for a recent /* opener if no "//" on this line.
|
||||
const trimmed = line.trim();
|
||||
const isLineComment = trimmed.startsWith("//") || trimmed.startsWith("*");
|
||||
let isInsideBlockComment = false;
|
||||
if (!isLineComment) {
|
||||
// Look backward up to 30 lines for a /* without an intervening */.
|
||||
for (let j = i - 1; j >= Math.max(0, i - 30); j--) {
|
||||
if (lines[j].includes("*/")) break;
|
||||
if (lines[j].includes("/*")) {
|
||||
isInsideBlockComment = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect(
|
||||
isLineComment || isInsideBlockComment,
|
||||
`${label}:${i + 1} contains live (non-comment) "45rem" — bounce-fix #3 width-coupling regression`,
|
||||
).toBe(true);
|
||||
}
|
||||
};
|
||||
checkSource(APP_SHELL_SRC, "AppShell.tsx");
|
||||
checkSource(SHARED_DRAWER_SRC, "SharedDetailDrawer.tsx");
|
||||
// VellumSheet keeps a historical calibration comment with 45rem;
|
||||
// it's inside a // comment so the same checker passes there too.
|
||||
checkSource(VELLUM_SHEET_SRC, "vellum-sheet.tsx");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Legacy buttons removed (Phase 2 deleted Sidebar + header toggle pattern)", () => {
|
||||
it("specs-toggle button does NOT exist", async () => {
|
||||
const { container } = await renderAt("/");
|
||||
|
||||
Reference in new issue
Block a user