mirror of
https://github.com/mvschwarz/openrig.git
synced 2026-11-10 03:31:40 -10:00
fix(ui): surface-conditional Topology mobile z-index carve-out (slice 26 OPT-C3 repair)
velocity-qa caught at /topology + 375px (slice 26 OPT-B recheck): hamburger tap pegged the headless browser renderer. Reproduced twice; stuck renderers killed to avoid host CPU burn. Forensic finding (qitem-20260512112436-347b6c98): pure CSS z-index swap does NOT trigger React reconciliation work; TopologyTableView (443L) + TopologyTreeView (264L) use standard hook patterns; mounted pre-OPT-B too (just covered by rail-tray). Strong evidence: pre-existing renderer-spin in Topology mobile render path; OPT-B z-index change just made the click path reachable to QA. Repair (OPT-C3 per orch routing at qitem-20260512112530-0de8d3c1): surface-conditional z-index. Topology surface pinned to z-20 (pre-OPT-B baseline; covered by rail-tray on mobile; unreachable; click path doesn't reach the peg trigger). Other 4 destinations (settings / project / specs / for-you) keep z-40 (OPT-B fix preserved; cross-destination chrome consistency for 4/5). Smallest-correct path: 1-block className conditional, no React state changes, no new components, no daemon work. Topology mobile drawer remains broken-by-overlap (legacy state) but does not peg the renderer. 0.3.2 plans a Topology mobile render-path fix (per banked feedback_usestate_not_usemutation_for_fire_and_forget — Table-hang renderer-spin class; useRef + imperative DOM escape-hatch territory). This carve-out reverts at that time. Tests added (slice-26.C OPT-C3 carve-out regressions): - POSITIVE: opaque-mode Topology Explorer className contains z-20 - NEGATIVE: z-40 absent for Topology opaque mode (discriminates the carve-out from the other-destinations OPT-B path) - NUMERIC LAYERING INVARIANT: extract z-N as integer + assert N < MOBILE_RAIL_TRAY_Z (30); Topology Explorer must be BELOW rail-tray to remain covered + prevent peg trigger Preserved (OPT-B regression coverage; all from earlier commit): - 4 opaque surfaces (project/specs/for-you/settings) still assert z-40 + not-z-20 + N > 30 - Topology overlay-mode still asserts z-30 (graph canvas float) Test counts: - explorer-mobile-zindex-layering: 15 tests (13 prior + 2 NEW Topology carve-out regressions) - settings-explorer: 8/8 unchanged - settings-pages: 4/4 unchanged - Full UI suite: 784 pass + 1 skipped + 52 pre-existing fails (baseline identical; +2 net pass / 0 new fail) - Touched files typecheck clean Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
1 parent
125c747c5d
commit
1d935dae5e
2 files changed
+103
-8
No files matched your search
@@ -312,18 +312,34 @@ export function Explorer({
|
||||
//
|
||||
// Slice 26.B HG-8 mobile-drawer-layering repair (OPT-B per
|
||||
// orch routing): opaque-mode Explorer mobile drawer must
|
||||
// layer ABOVE the mobile-rail-tray (AppShell.tsx z-30)
|
||||
// so click hits register on Explorer items. Pre-repair value
|
||||
// layer ABOVE the mobile-rail-tray (AppShell.tsx z-30) so
|
||||
// click hits register on Explorer items. Pre-repair value
|
||||
// was z-20 (below rail-tray) — pre-existing bug exposed by
|
||||
// slice 26 because Settings was the 5th Explorer-bearing
|
||||
// destination on mobile. Bumped to z-40. Overlay-mode stays
|
||||
// z-30 (Topology graph behavior preserved; rail-tray and
|
||||
// overlay-mode Explorer paint at same z, DOM order resolves
|
||||
// Explorer above since it renders later in AppShell). Rail-tray
|
||||
// remains reachable via backdrop dismissal on mobile.
|
||||
// destination on mobile. Bumped to z-40 for opaque-mode
|
||||
// destinations. Overlay-mode stays z-30 (Topology graph
|
||||
// behavior preserved; rail-tray and overlay-mode Explorer
|
||||
// paint at same z, DOM order resolves Explorer above since
|
||||
// it renders later in AppShell). Rail-tray remains reachable
|
||||
// via backdrop dismissal on mobile.
|
||||
//
|
||||
// Slice 26.C OPT-C3 Topology mobile carve-out (per orch
|
||||
// routing on qa renderer-peg report at qitem-2026-05-12...):
|
||||
// Topology surface is intentionally pinned to z-20 on opaque
|
||||
// mode — restoring the pre-OPT-B "covered by rail-tray"
|
||||
// baseline. Pre-existing renderer-spin in TopologyTableView
|
||||
// pegs the headless browser when Explorer mounts/becomes
|
||||
// visible at 375px; keeping Topology Explorer hidden behind
|
||||
// rail-tray on mobile prevents the click path from reaching
|
||||
// the peg trigger. Other 4 Explorer destinations (settings /
|
||||
// project / specs / for-you) keep the OPT-B z-40 fix. 0.3.2
|
||||
// will fix the Topology mobile render path; this carve-out
|
||||
// reverts at that time.
|
||||
isOverlay
|
||||
? "vellum z-30 shadow-[6px_0_14px_rgba(46,52,46,0.06)]"
|
||||
: "z-40 bg-[rgba(250,249,245,0.035)] supports-[backdrop-filter]:bg-[rgba(250,249,245,0.018)] backdrop-blur-[14px] backdrop-saturate-75 shadow-[6px_0_14px_rgba(46,52,46,0.04)]",
|
||||
: surface === "topology"
|
||||
? "z-20 bg-[rgba(250,249,245,0.035)] supports-[backdrop-filter]:bg-[rgba(250,249,245,0.018)] backdrop-blur-[14px] backdrop-saturate-75 shadow-[6px_0_14px_rgba(46,52,46,0.04)]"
|
||||
: "z-40 bg-[rgba(250,249,245,0.035)] supports-[backdrop-filter]:bg-[rgba(250,249,245,0.018)] backdrop-blur-[14px] backdrop-saturate-75 shadow-[6px_0_14px_rgba(46,52,46,0.04)]",
|
||||
// Mobile: slide-over from left below the top-bar header (h-14).
|
||||
"fixed top-14 bottom-0 left-0 transition-transform duration-200 ease-tactical w-72 max-w-[80vw]",
|
||||
open ? "translate-x-0" : "-translate-x-full",
|
||||
|
||||
@@ -137,4 +137,83 @@ describe("Explorer mobile drawer z-index layering (slice 26.B HG-8 OPT-B repair)
|
||||
// changed by this repair.
|
||||
});
|
||||
});
|
||||
|
||||
// Slice 26.C OPT-C3 Topology mobile carve-out: opaque-mode Topology
|
||||
// Explorer is intentionally pinned to z-20 (pre-OPT-B baseline) so
|
||||
// mobile-rail-tray covers it — sidesteps the pre-existing
|
||||
// TopologyTableView renderer-spin that pegs the browser when the
|
||||
// mobile drawer becomes visible at 375px. The 0.3.2 Topology mobile
|
||||
// refactor will fix the renderer-spin; this carve-out reverts then.
|
||||
describe("surface=topology (opaque-mode OPT-C3 carve-out)", () => {
|
||||
it("opaque-mode Topology Explorer pins to z-20 (BELOW mobile-rail-tray z-30)", async () => {
|
||||
render(
|
||||
createAppTestRouter({
|
||||
initialPath: "/topology",
|
||||
routes: [
|
||||
{
|
||||
path: "/topology",
|
||||
component: () => (
|
||||
<Explorer
|
||||
open={true}
|
||||
onClose={() => {}}
|
||||
selection={null}
|
||||
onSelect={() => {}}
|
||||
desktopMode="full"
|
||||
surface="topology"
|
||||
overlayMode="opaque"
|
||||
/>
|
||||
),
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("explorer")).toBeTruthy();
|
||||
});
|
||||
const explorer = screen.getByTestId("explorer");
|
||||
// POSITIVE: z-20 present (the carve-out value; restores
|
||||
// pre-OPT-B baseline for Topology mobile)
|
||||
expect(explorer.className).toMatch(/\bz-20\b/);
|
||||
// NEGATIVE: z-40 absent (the OPT-B fix that applies to other
|
||||
// destinations is intentionally NOT applied to Topology — the
|
||||
// carve-out discriminator)
|
||||
expect(explorer.className).not.toMatch(/\bz-40\b/);
|
||||
});
|
||||
|
||||
it("NUMERIC LAYERING INVARIANT: Topology opaque-mode z-index is LESS THAN mobile-rail-tray z-30", async () => {
|
||||
render(
|
||||
createAppTestRouter({
|
||||
initialPath: "/topology",
|
||||
routes: [
|
||||
{
|
||||
path: "/topology",
|
||||
component: () => (
|
||||
<Explorer
|
||||
open={true}
|
||||
onClose={() => {}}
|
||||
selection={null}
|
||||
onSelect={() => {}}
|
||||
desktopMode="full"
|
||||
surface="topology"
|
||||
overlayMode="opaque"
|
||||
/>
|
||||
),
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("explorer")).toBeTruthy();
|
||||
});
|
||||
const explorer = screen.getByTestId("explorer");
|
||||
const zMatch = explorer.className.match(/\bz-(\d+)\b/);
|
||||
expect(zMatch).toBeTruthy();
|
||||
const explorerZ = Number(zMatch![1]);
|
||||
// Topology mobile drawer must be BELOW rail-tray (z-30) to
|
||||
// remain covered + prevent the renderer-peg path. Inverts the
|
||||
// other-destinations invariant where Explorer must be above.
|
||||
expect(explorerZ).toBeLessThan(MOBILE_RAIL_TRAY_Z);
|
||||
expect(explorerZ).toBe(20);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user