diff --git a/apps/web/components/app-sidebar/app-sidebar-resize-handle.tsx b/apps/web/components/app-sidebar/app-sidebar-resize-handle.tsx index 28d6388f83..b8d26cb1b1 100644 --- a/apps/web/components/app-sidebar/app-sidebar-resize-handle.tsx +++ b/apps/web/components/app-sidebar/app-sidebar-resize-handle.tsx @@ -5,8 +5,8 @@ type AppSidebarResizeHandleProps = { }; /** - * Hairline drag handle on the right edge of the expanded AppSidebar. - * Hover-visible only; widens slightly when active for affordance. + * Drag handle centered over the right edge of the expanded AppSidebar. + * The full hit area highlights to match the dockview resize sashes. */ export function AppSidebarResizeHandle({ onMouseDown }: AppSidebarResizeHandleProps) { return ( @@ -15,11 +15,7 @@ export function AppSidebarResizeHandle({ onMouseDown }: AppSidebarResizeHandlePr aria-label="Resize sidebar" onMouseDown={onMouseDown} tabIndex={-1} - className="absolute right-0 top-0 h-full w-1.5 cursor-ew-resize group flex items-center justify-center" - > - {/* Transparent at rest — the aside's own border-r is the visible edge. - Colouring this too would double the hairline. Highlights on hover. */} -
- + className="absolute -right-px top-0 z-10 h-full w-1 translate-x-1/2 cursor-ew-resize bg-transparent transition-colors hover:bg-primary active:bg-primary" + /> ); } diff --git a/apps/web/e2e/tests/layout/sidebar-resize-handle.spec.ts b/apps/web/e2e/tests/layout/sidebar-resize-handle.spec.ts new file mode 100644 index 0000000000..d24c4bae6b --- /dev/null +++ b/apps/web/e2e/tests/layout/sidebar-resize-handle.spec.ts @@ -0,0 +1,50 @@ +import { test, expect } from "../../fixtures/test-base"; +import { openWideTask } from "../../helpers/dockview-resize"; + +test.describe("App sidebar resize handle", () => { + test("straddles the sidebar edge and highlights its full width while dragging", async ({ + testPage, + }) => { + await testPage.goto("/"); + + const sidebar = testPage.getByTestId("app-sidebar"); + const handle = sidebar.getByRole("button", { name: "Resize sidebar" }); + await expect(handle).toBeVisible(); + + const [sidebarBox, handleBox] = await Promise.all([ + sidebar.boundingBox(), + handle.boundingBox(), + ]); + expect(sidebarBox).not.toBeNull(); + expect(handleBox).not.toBeNull(); + + const sidebarEdge = sidebarBox!.x + sidebarBox!.width; + const handleCenter = handleBox!.x + handleBox!.width / 2; + expect(handleCenter).toBeCloseTo(sidebarEdge, 0); + + await testPage.mouse.move(handleCenter, handleBox!.y + handleBox!.height / 2); + await testPage.mouse.down(); + + await expect(handle).not.toHaveCSS("background-color", "rgba(0, 0, 0, 0)"); + await testPage.mouse.up(); + }); + + test("matches the Dockview sash hover width", async ({ testPage, apiClient, seedData }) => { + await openWideTask(testPage, apiClient, seedData, "Sidebar sash width"); + + const handle = testPage + .getByTestId("app-sidebar") + .getByRole("button", { name: "Resize sidebar" }); + const handleBox = await handle.boundingBox(); + const sashWidth = await testPage.locator(".dv-sash").evaluateAll((sashes) => { + const verticalSash = sashes + .map((sash) => sash.getBoundingClientRect()) + .find((box) => box.height > box.width); + return verticalSash?.width ?? 0; + }); + + expect(handleBox).not.toBeNull(); + expect(sashWidth).toBeGreaterThan(0); + expect(handleBox!.width).toBe(sashWidth); + }); +});