Every screen draws its own headers; the collapsed sidebar keeps the window controls in one band

Merged
SA
1mo ago
+1750-1519

What changes

No app-wide top bar (v2). Each screen draws its own header rows through PageHeader (48px, start slot, drag area, end slot). The old TopBar stays only on the v1 screens #7859 deletes.

The sidebar can't close, only collapse to its 52px rail. A persisted closed state migrates to the rail (store v3). ⌘B and the palette's "Toggle left sidebar" collapse and expand.

Collapsed = one band, like production. While the rail shows, the leftmost header renders the window controls (traffic-light space, sidebar toggle, back/forward, ports, offline). Every top-row header and the rail's top strip share the tab bar's color, so the macOS buttons sit in a continuous bar. Panes that aren't leftmost opt out with WindowChromeScope.

Controls don't move between states. They're pinned 7pt from the window top in a 32pt row, in the sidebar header and in WindowChrome alike. That centers them on the macOS buttons, which sit at 22.75pt (measured from a real window capture on macOS 26). Canary had them 1pt low, and the workspace tab bar moved them 4.5pt when collapsed.

Record pages (task, project, cloud workspace) use RecordLayout: the main and side columns each have a header, so the divider runs unbroken. A page without side actions (project) lets its side column run to the top.

Also

  • Loading and not-found screens keep a header (StateScreenShell), so a closed sidebar never strands you without a toggle.
  • Settings' top strip became its sidebar's header.
  • Back/forward shortcuts and mouse side-buttons moved into useHistoryNavigationShortcuts, so they work while the buttons are unmounted.
  • PortsDropdown and RightSidebarToggle moved out of TopBar/.
  • Automations, Pages and Plugins titles got 16px of room under the header.

Cloud workspaces

  • Share sits before the presence stack.
  • AvatarStack takes a surface and rings each avatar in it.
  • The creator counts as present; last seen falls back to created_at.
  • The stack hides while the viewer is alone.

Verified (dev app, CDP)

  • 36 screen × sidebar-state combinations, plus Settings, covering every dashboard route, the missing-task screen, and the PR detail with its list hidden. The toggle, back and forward icons sit at identical positions (x 88/122/150, center y 23) in both states, pixel-checked against the Canary capture. Every header has a drag area, and no clickable control sits inside a drag region.
  • Narrow window (800px): record headers merge onto one row and stay pinned while scrolling.
  • Checks: repo lint, typecheck (42/42), i18n, and 6,287 renderer tests pass.

Known, not from this PR

  • Plugins logs a React duplicate-key warning for sentry, coming from #7912's new Sentry plugin.
  • packages/trpc deriveSandboxCredentials tests fail locally; this PR doesn't touch lib/sandbox.

Summary by cubic

Removes the app-wide top bar on v2 screens; each screen now draws its own 48px header row via PageHeader, and the old TopBar stays only on the v1 screens. The sidebar can no longer close, only collapse to a 52px rail, with persisted closed state migrating to the rail.

Window chrome

  • While the rail shows, the leftmost header renders the window controls (traffic-light space, sidebar toggle, back/forward, ports, offline); all top-row headers and the rail's top strip share one band so the macOS buttons sit in a continuous bar. Non-leftmost panes opt out via WindowChromeScope.
  • Controls are pinned 7pt from the window top in a 32pt row in both states, so they stay centered on the macOS buttons and don't shift between expanded and collapsed.
  • PageHeader accepts children for rows that lay out their own drag area; Tasks, New Workspace, and page detail headers use it, and WindowChrome sits only in PageHeader and the pane tab bar's leading slot.
  • Back/forward hotkeys and mouse side-buttons moved into useHistoryNavigationShortcuts so they work even when the buttons are unmounted.

Record pages and cloud workspaces

  • Record pages (task, project, cloud workspace) use RecordLayout: main and side columns each have a header so the divider runs unbroken; pages without side actions let the side column run to the top.
  • Loading and not-found screens keep a header via StateScreenShell, so a collapsed sidebar never strands the user without a toggle.
  • Cloud workspaces: share sits before the presence stack, AvatarStack takes a surface for avatar rings, and the presence stack counts the creator as present (last seen falls back to created_at) and hides while the viewer is alone.

Summary by CodeRabbit

  • New Features
    • Cloud workspace records now have dedicated sharing and action controls. Presence indicators show other active collaborators without counting your own session.
    • An offline status indicator appears in the dashboard sidebar.
  • Improvements
    • Dashboard pages use more consistent headers and record layouts, with updated window-control placement across workspace, project, task, automation, and pull-request views.
    • Sidebar collapse behavior is more consistent, and workspace creators appear in presence information.
  • Bug Fixes
    • Loading and not-found states for records now retain the page header instead of appearing blank.