diff --git a/frontend/src/renderer/components/Sidebar.test.tsx b/frontend/src/renderer/components/Sidebar.test.tsx index 37ec61def..0ff3b2dc1 100644 --- a/frontend/src/renderer/components/Sidebar.test.tsx +++ b/frontend/src/renderer/components/Sidebar.test.tsx @@ -97,18 +97,13 @@ describe("Sidebar", () => { expect(navigateMock).toHaveBeenCalledWith({ to: "/projects/$projectId", params: { projectId: "proj-1" } }); }); - it("hides the worker count in every state that reveals project actions", () => { + it("always shows action icons and reserves padding for them", () => { renderSidebar(); const projectRow = screen.getByText("Project One").closest("button"); - const count = screen.getByText("0"); if (!projectRow) throw new Error("Project row button not found"); - expect(projectRow).toHaveClass("group-hover/menu-item:pr-[84px]"); - expect(projectRow).toHaveClass("group-focus-within/menu-item:pr-[84px]"); - expect(projectRow).toHaveClass("group-has-data-[state=open]/menu-item:pr-[84px]"); - expect(count).toHaveClass("group-hover/menu-item:opacity-0"); - expect(count).toHaveClass("group-focus-within/menu-item:opacity-0"); - expect(count).toHaveClass("group-has-data-[state=open]/menu-item:opacity-0"); + // Padding is always reserved for the action cluster (not hover-gated) + expect(projectRow).toHaveClass("pr-[84px]"); }); }); diff --git a/frontend/src/renderer/components/Sidebar.tsx b/frontend/src/renderer/components/Sidebar.tsx index a218649da..dff796291 100644 --- a/frontend/src/renderer/components/Sidebar.tsx +++ b/frontend/src/renderer/components/Sidebar.tsx @@ -465,10 +465,9 @@ function ProjectItem({ "before:absolute before:top-2 before:bottom-2 before:left-0 before:w-px before:rounded-full before:bg-transparent", "hover:bg-interactive-hover hover:text-foreground active:bg-interactive-hover active:text-foreground", "data-[active=true]:bg-interactive-active data-[active=true]:font-semibold data-[active=true]:text-foreground data-[active=true]:before:bg-accent", - // Make room for the hover actions (dashboard, orchestrator, kebab) - // when the row is hovered, focused, or its menu is open (the - // absolutely-positioned cluster replaces the count). - "group-hover/menu-item:pr-[84px] group-focus-within/menu-item:pr-[84px] group-has-data-[state=open]/menu-item:pr-[84px]", + // Always reserve room for the action cluster (dashboard, + // orchestrator, kebab) — icons are always visible, not hover-gated. + "pr-[84px]", // Icon rail: the old 36px letter tile. "group-data-[collapsible=icon]:size-9! group-data-[collapsible=icon]:justify-center group-data-[collapsible=icon]:rounded-lg group-data-[collapsible=icon]:p-0! group-data-[collapsible=icon]:font-semibold", )} @@ -483,18 +482,16 @@ function ProjectItem({ /> {workspace.name.charAt(0).toUpperCase()} {workspace.name} - + {sessions.length} - {/* Per-project hover actions: dashboard board, orchestrator, and a kebab - menu. The cluster reveals on row hover/focus (or while the kebab is - open), replacing the session count, and stays hidden in the icon rail. */} + {/* Per-project actions: dashboard board, orchestrator, and a kebab + menu. Always visible (not hover-gated) to avoid CSS :hover group + propagation issues in Electron's Chromium. Hidden in the icon rail. */}