feat(desktop): the side panel drags until the document's floor, and full screen asks a longer pull

Merged
DA
10d ago
+193-67

Dean asked to tune drag-to-expand on the right panel: let the main column get skinnier, make full screen need a longer pull, and find out whether expand used the same mechanics and values as collapse.

Did expand and collapse share mechanics and values? Yes, both.

On main, use-resizable-edge.ts used one SNAP_OVERSHOOT = 80 and one SNAP_HYSTERESIS = 24 for both directions:

  • Collapse: the panel shut once the drag asked for less than MIN − 80 = 280 − 80 = 200px. It let go again above 224.
  • Expand: the panel went full screen once the drag asked for more than max + 80. max was min(720, plan area − 360), so on a typical window the panel stopped at a fixed 720px with the document still wide, and 80px of extra pull filled the window. It let go again below max + 56.

The pointer distance was the same both ways. Expand felt early for two reasons: it stopped at an arbitrary 720 rather than at a limit you can see, and the same 80px then covered the whole document instead of shutting one pane.

What changes

  • The panel has no fixed greatest width. It drags until the document reaches its floor, as an editor's secondary side bar does. SIDE_PANEL_WIDTH keeps MIN 280 and DEFAULT 400; MAX 720 is gone.
  • The document's floor is lower, and it follows the sidebar. It is declared once in CSS as a registered @property --document-reserve length. The panel's max-width uses it, and the drag reads it when a drag or key press starts. There is no number duplicated in TypeScript.
    • Sidebar open: the floor is 280px, down from 360 and equal to the panel's least width, so the two panes have the same floor.
    • Sidebar folded: the floor is 280px plus the clearance the toolbar spends getting past the traffic lights and title-bar buttons (--sidebar-toggle-clearance − --column-inset), which is 423px today. A change to that clearance moves this floor with it.
  • Collapse is unchanged: it still snaps 80px past the least width (COLLAPSE_OVERSHOOT).
  • Full screen needs twice the pull: 160px past the greatest width (EXPAND_OVERSHOOT).
  • Hysteresis is still 24px in both directions.
  • Same live snap as #1850: it snaps mid-drag, a drag back undoes it, there is no preview, and a snap keeps the width you had.
  • The edge's announced range follows the room. With no fixed maximum, the separator measures the room its container allows whenever the container resizes, and announces it as aria-valuemax. aria-valuenow is the width actually drawn, so the value always falls inside the range (Devin flagged the missing maximum).
  • The sidebar's edge is unchanged: MAX 400, a 360px reserve, the same 80px collapse, and no expand action. The hook's reserve option became a function, so the sidebar passes () => WORK_RESERVE.

Why the folded floor is larger

I measured the plan toolbar in headless Chrome.

FloorPlan tabCopy plan⋯
280px, sidebar open103pxfitsfits
280px, sidebar folded0pxfitspushed past the edge, under the panel, so it can't be clicked
360px (main), sidebar folded40px, shows only "T"fitsfits
423px, sidebar folded103pxfitsfits

The folded toolbar starts 155px in to clear the title-bar buttons, which is why it needs the extra room. The orchestrator approved this split.

Evidence

CI could not verify the Mac UI, and ./scripts/verify.sh was not run. This was built on a Linux cloud VM; LUKE-159 is the manual Mac pass.

I checked the real renderer components and the built styles.css in headless Chrome 154, driving the edge with CDP mouse drags in 4px steps. The window was 1200px wide with the sidebar folded:

PointerPanel
at the floor777px wide, document 423px
93px past the floorstill 777px
153px past the floorstill 777px
168px past the floorfull screen
back 15pxstill full screen
back 35px777px again

With the sidebar open, the document stops at 280px. With the panel at its widest, the document still shows its plan tab ("Teamm…"), Copy plan and ⋯, and the call bar reads in full. I couldn't attach the screenshots here (no upload path from the VM); they are in the workspace's .context/shots/.

Tests

The tests go through the page (desktop-plans.test.ts). Ten of them fail without this change.

  • The clamp is the document's floor, including on a 2000px-wide area where main stopped at 720.
  • The floor the stylesheet declares (folded: 423) is the one the drag holds to.
  • Expand holds 90px past the greatest width, further than collapse's 80, and goes full screen past 160.
  • Collapse still snaps past 200 and lets go past 224.
  • Hysteresis works in both directions.
  • In a narrow window, the drag holds 130px past the room and snaps past 160.
  • The keyboard's End and arrow keys are held to the same room.

./scripts/check.sh exits 0. A first run timed out once in packages/voice/src/live-session-source.test.ts, which this PR doesn't touch; it passes 3/3 alone and the full re-run was green.

🤖 Generated with Claude Code


Open workspace in Conductor


Devin Review