From a3d94d4d5e532e25353a204906121b42ab04abc6 Mon Sep 17 00:00:00 2001 From: Blomios Date: Thu, 6 Aug 2026 21:57:48 +0200 Subject: [PATCH] =?UTF-8?q?fix(layout):=20barre=20sup=C3=A9rieure=20CLI=20?= =?UTF-8?q?custom=20cliquable=20=E2=80=94=20stacking=20context=20du=20corp?= =?UTF-8?q?s=20de=20leaf?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le corps d'une leaf (layout-leaf-body) crée désormais son propre stacking context (z-index 0). Les vues CLI custom peuvent comporter des enfants à haut z local (toolbar z-20) qui restaient au-dessus des contrôles de cellule (CELL_Z 5) et captaient les clics ; ils restent désormais sous les contrôles. Test de layering dédié ajouté dans LayoutGrid.cellControlsLayering.test.tsx. --- .../LayoutGrid.cellControlsLayering.test.tsx | 23 +++++++++++++++++++ frontend/src/features/layout/LayoutGrid.tsx | 6 +++++ 2 files changed, 29 insertions(+) diff --git a/frontend/src/features/layout/LayoutGrid.cellControlsLayering.test.tsx b/frontend/src/features/layout/LayoutGrid.cellControlsLayering.test.tsx index a871167..901a14a 100644 --- a/frontend/src/features/layout/LayoutGrid.cellControlsLayering.test.tsx +++ b/frontend/src/features/layout/LayoutGrid.cellControlsLayering.test.tsx @@ -206,6 +206,29 @@ describe("LayoutGrid — ticket #48 cell control layering", () => { expect(controls.style.overflow).toBe("hidden"); }); + it("keeps cell controls above the custom CLI view stacking context", async () => { + const setup = await makeSplitAgentGrid(); + window.localStorage.setItem(`idea.agent-cell-mode.p1.${setup.bId}`, "custom"); + + renderGrid(setup.gateways); + + await screen.findByTestId("custom-agent-chat-view"); + window.localStorage.removeItem(`idea.agent-cell-mode.p1.${setup.bId}`); + const leafBody = screen.getAllByTestId("layout-leaf-body").find((element) => + element.closest(`[data-node-id="${setup.bId}"]`), + ) as HTMLElement; + const customToolbar = screen.getByRole("toolbar", { + name: "custom agent chat actions", + }); + const { controls } = controlsFor(setup.bId); + + expect(leafBody).toBeTruthy(); + expect(leafBody.style.position).toBe("relative"); + expect(leafBody.style.zIndex).toBe("0"); + expect(customToolbar.className).toContain("z-20"); + expect(controls.style.zIndex).toBe("5"); + }); + it("keeps busy Cancel above persistent cell controls and removes History (#151, #160)", async () => { const setup = await makeSplitAgentGrid(); await setup.layout.mutateLayout("p1", { diff --git a/frontend/src/features/layout/LayoutGrid.tsx b/frontend/src/features/layout/LayoutGrid.tsx index ee5dd3a..60a2348 100644 --- a/frontend/src/features/layout/LayoutGrid.tsx +++ b/frontend/src/features/layout/LayoutGrid.tsx @@ -338,6 +338,10 @@ function goToCell(nodeId: string): void { * full-cell veils 4 (write-portal + F3 overlays; mutually exclusive) * cell controls 5 (always on top and clickable) * turn actions 6 (busy-state actions; Cancel must stay visible) + * + * The terminal/chat body must create its own z-index 0 stacking context. Custom + * CLI views can legitimately contain local high-z children (for example their + * own toolbar), but those children must stay below the cell controls. */ const CELL_Z = { banner: 3, @@ -1300,8 +1304,10 @@ function LeafView({ navigating. The agent cell passes its {@link WritePortal} so keystroke counting + injection suspension are wired; a plain cell passes none. */}