Skip to content

fix(web): pane tabs keep their icon and PR state when you switch tabs - #29080

Merged
maria-rcks merged 3 commits into
pingdotgg:maria/redesign/6-workspace-panesfrom
flamboh:t3/redesign-fix-pane-tab-strip-consistency
Nov 2, 2026
Merged

maria-rcks merged 3 commits into
pingdotgg:maria/redesign/6-workspace-panesfrom
flamboh:t3/redesign-fix-pane-tab-strip-consistency

Conversation

@flamboh

@flamboh flamboh commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Note

🤖 Claude Opus 5.5 on behalf of Oliver

Fix for the redesign stack, targets layer 6 (#28845).

Problem

A pane's tabs changed shape when you switched between them. The active tab and the inactive tabs were drawn by different code with different rules:

  • The Browser tab's globe was 12px when active and 14px when inactive.
  • The active tab's title capped at 240px while inactive tabs reached ~280px. So "Browser · Try Maria's T3 Code Redesign" truncated only while it was active, even with plenty of room.
  • The active tab carried an empty breadcrumb slot that added one more 7px gap.
  • An inactive PR tab lost its state and showed a gray generic PR glyph. The active one showed the red closed or green open icon.
  • Browser and Terminal tabs drew an empty bump at the strip's right end. That's the actions notch, which only Diff and Files fill.

Fix

Inactive layout tabs now use the same icon and title source as the active tab. SurfaceIcon, surfaceTitle and the PR state icon moved out of RightPanelTabs.tsx into SurfaceTabIcon.tsx, so PaneTabs can use them without an import cycle. That fixes PR state, and inactive Browser tabs also show the page's favicon and title like the active one.

Then the geometry is the same in every state:

  • Every tab icon is 14px. That covers favicons, file icons, side chat and PR icons, and the close-button slot that holds the active tab's icon.
  • Two title caps for notch tabs. The active tab's title caps at 272px (PANE_TAB_TITLE_CLASS, used by the active surface tab and the chat tab). Inactive tabs cap at 160px (PANE_INACTIVE_TAB_TITLE_CLASS, used by LayoutPaneTab and inactive surface tabs).
  • The breadcrumb slot hides while it's empty.

Width rule: a title shorter than its cap never truncates while there's room. The active tab shows up to 272px of title. Inactive tabs show up to 160px, so long titles truncate there even with spare room, and a tab can grow or shrink when you switch to or away from it. 160px keeps the surface name plus about 14 characters of thread title ("Browser · Fit Compact Co…"), enough to tell threads apart. 144px leaves only about 8, and 176px brings back the long strip. When room runs out, the existing rules still apply. Inactive tabs shrink first (shrink-[2]), then fold to icons, and the active tab keeps more of its title.

Measured headlessly (1440×900, dark), tab widths in px for chat · Browser · Browser · Terminal while switching the active tab. Titles: chat "Recovery command" (short), Browser (1) "Browser · Fit Compact Control in Small Composers" (long), Browser (2) "Browser · Recovery command" and Terminal "Terminal 1 · Recovery command" (medium). Bold is the active tab, T means truncated.

Active tab Before (layer 6) After
Chat 166 · 320 T · 229 · 237 166 · 201 T · 201 T · 201 T
Browser (1) 166 · 290 T (12px icon) · 229 · 237 166 · 313 T · 201 T · 201 T
Browser (2) 166 · 320 T · 238 (12px icon) · 237 166 · 201 T · 229 · 201 T
Terminal 166 · 320 T · 229 · 246 166 · 201 T · 201 T · 237

The short chat title never truncates. The long Browser title gets 272px of title when active and 160px when not. On layer 6 the same title got only 240px while active, less than the ~280px it had while inactive.

The actions notch now draws only when the active surface has actions. PanelTabActions registers with its tab bar while it's mounted, and RightPanelTabs renders the right notch only while something is registered. The surfaces report this themselves through the same portal they render into, so there's no list of surface kinds. A new surface that renders actions gets the notch automatically.

Right notch in the top pane, measured headlessly (1400×860), left · right · width in px:

Tab Before After
Browser 1364 · 1380 · 16, empty none
Terminal 1364 · 1380 · 16, empty none
Files, no file open 1364 · 1380 · 16, empty none
Files, package.json open — 1216 · 1380 · 164, 5 actions
Diff 1139 · 1380 · 241, 8 actions 1139 · 1380 · 241, 8 actions

The notch is in place by the first frame after switching to a mounted Diff tab, so it doesn't flicker.

After the fix, every icon is 14px in every state. With two PR tabs (#25319 closed, #28945 open), each keeps its red or green state icon whether active or not.

Before / after

Tab switching, dark theme at 1440×900:

Before (layer 6) After
Before: Chat active After: Chat active
Before: Browser (1) active — long title After: Browser (1) active — long title
Before: Browser (2) active — chat thread After: Browser (2) active — chat thread
Before: Terminal active After: Terminal active

Before: chat → Browser (1) → Browser (2) → Terminal → chat.

https://gh-file-drop-api-prod-galwoqjslzlnws6s.oliver-boorstein.workers.dev/f/1a55e6f02283e9c7/before-switch.mp4

After: same tab-switching sequence.

https://gh-file-drop-api-prod-galwoqjslzlnws6s.oliver-boorstein.workers.dev/f/33c6324fc00f3836/after-switch.mp4

Light theme; requested browser viewport 1400×860. The following crops show the right end of the pane tab strip, with the same scratch repository and a modified package.json in both builds. Browser, Terminal and empty Files lose the empty bump; Diff and Files with an open file retain their action notch.

Before (layer 6) After
Before: Chat active, right end of tab strip After: Chat active, right end of tab strip
Before: Browser active, right end of tab strip After: Browser active, right end of tab strip
Before: Terminal active, right end of tab strip After: Terminal active, right end of tab strip
Before: Files with no file open, right end of tab strip After: Files with no file open, right end of tab strip
Before: Files with package.json open, right end of tab strip After: Files with package.json open, right end of tab strip
Before: Diff with uncommitted changes, right end of tab strip After: Diff with uncommitted changes, right end of tab strip

Capture coverage: these short titles do not exercise the title cap. PR tab state not captured: PR detail needs GitHub access on the capture box. The Pull request entry in the pane’s + menu was disabled.

Made with Claude Opus 5.5 in Claude Code.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Nov 2, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Nov 2, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — The change shares tab presentation logic to preserve icons and pull-request state across tab switches. It also adds a line-level oxlint suppression, which requires human review under the configured approval requirements.

You can add or adjust custom eligibility rules. Learn more.

@macroscopeapp
macroscopeapp Bot dismissed their stale review November 2, 2026 19:57

Dismissing prior approval to re-evaluate 24a6f3a

@flamboh flamboh changed the title fix(web): pane tabs keep their size, icon and PR state when you switch tabs fix(web): pane tabs keep their icon and PR state when you switch tabs Nov 2, 2026
Comment thread apps/web/src/layout/PaneTabs.tsx Resolved
@maria-rcks

maria-rcks commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

Verified in a real dev environment

Verified 24a6f3ad800e8bc765b161d334ff0b34b6788331 on this Linux Boat VM using the real dev web app, repository Playwright, and /usr/bin/google-chrome. No code changes were needed.

  • Started github/main (84537c4dd9) in a separate worktree after vp i. Main has no redesigned pane strip, so the exact bug cannot occur there. For a meaningful before/after, also ran the PR's actual base 814c2e3da1. Only one dev server ran at a time.
  • Added the real repository as a project through the app, created a thread, and submitted real Codex gpt-6.1-sol turns. Main and the latest PR head both returned the requested text. One earlier turn hit a transport error; retry and the subsequent latest-head turn completed.
  • Reproduced the base's active Browser icon shrinking to 12px, active title cap of 240px, inactive Browser losing the page title/favicon, and empty 16px Browser/Terminal actions notches.
  • On the latest head, Browser/Terminal icons stay 14px, page title/favicon survive switching away, and empty actions notches disappear. The latest commit intentionally caps active titles at 272px and inactive titles at 160px: long tabs now grow/shrink by design. Measured long surface tabs at 313px active / 201px inactive with spare room. A short terminal title stayed about 187px in both states without truncating.
  • Linked this PR through the command palette and opened its pane. Its green open-state glyph stayed 14px and green while active and inactive.
  • Exercised neighboring behavior: real terminal input/output, Diff refresh and split/stacked controls, file opening, file explorer show/hide, and closing/reopening surface tabs. Diff kept its 241px notch with 8 actions; an open file kept its 164px notch with 5 actions; empty Files had none. Checked light/dark appearance and keyboard access to all tabs at 900px width.
  • Ran the existing RightPanelTabs.test.tsx and PanelTabBreadcrumb.browser.test.tsx through blacksmith-check on the latest head: 2 files, 11 tests passed. The initial worker lacked Chromium; installed it on the replacement worker and reran successfully.

Matching light-theme captures at 1920×1080, cropped to the pane strip and browser controls. Before is the redesign base, after is the latest PR head.

before: base browser tab has a 12px favicon, shorter active title cap and empty right notch

after: latest head has a 14px favicon, compact inactive titles and no empty right notch

Dark-theme interaction recording: open PR state, Browser, Terminal input, Diff controls, file controls, then chat with the completed real provider turns. Inspected the export and reopened the uploaded result. The animated version below renders inline on GitHub.

latest head: real pane switching and neighboring controls

Not verified

  • Native Electron shell and native iOS/Android clients were not exercised on this Linux web pass.
  • Closed/merged/draft PR glyphs were not exercised; this pass used this open PR only.
  • Remote relay/tunnel and other provider adapters were not exercised.
  • Main cannot supply the exact pane-strip before state because that UI lives on the redesign stack. The matching before capture therefore uses the PR's actual base.

@maria-rcks
maria-rcks merged commit b880eaf into pingdotgg:maria/redesign/6-workspace-panes Nov 2, 2026
36 checks passed
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
maria-rcks pushed a commit that referenced this pull request Nov 3, 2026
…#29080)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants