Skip to content

🤖 feat: thinner right sidebar tabs on tablets, touch resize, All tabs menu with New tab - #6995

Merged
ibetitsmike merged 2 commits into
mainfrom
mike/right-sidebar-tablet-tabs
Oct 18, 2026
Merged

ibetitsmike merged 2 commits into
mainfrom
mike/right-sidebar-tablet-tabs

Conversation

@ibetitsmike

Copy link
Copy Markdown
Contributor

Summary

On an iPad the right sidebar's tab strip is now as thin as on desktop, the sidebar can be resized with a finger, and a chevron at the strip's right end lists every open tab with New tab at the bottom. The strip's "+" button is gone on every screen.

iPad before iPad after
iPad before: a 57px strip with 44px tabs and a plus button iPad after: a 37px strip with 24px tabs, the All tabs chevron and the collapse button
All tabs menu (iPad) All tabs menu (phone, one tab)
The menu lists the open tabs, then a separator and a checked New tab row with its shortcut With only the New tab open, the menu holds just the New tab row

Background

In the iPadOS PWA the strip used the phone touch floor: 44px tabs in a 57px strip. The 2px resize handle listened only to mouse events, so a finger drag did nothing. A narrow pane shows a tab or two, and touch users may not know that the row scrolls sideways. The "+" button also took a slot from that row on every screen.

Implementation

  • Strip height: tablets (coarse pointer above the phone breakpoint) keep the desktop row: a 37px strip, 24px tabs, and 24px targets for the tab X, All tabs and collapse buttons (TABLET_TOUCH_TARGET_PX, the WCAG 2.2 minimum). Phones keep their 44px floor.
  • Resize: useResizableSidebar listens to pointer events, so touch and pen drags work. It follows only the pointer that started the drag and ends on pointercancel. Coarse pointers get a 12px handle with a grip. The sidebar hands its left border to the handle, so the strip's bottom border still meets the line.
  • All tabs: a chevron (Radix popover) always sits before the collapse button, also with one tab. The menu lists the open tabs except the New tab, then a separator and a New tab row. A tab row selects, focuses and scrolls to its tab. The New tab row opens or shows the tabset's New tab and moves focus into its launcher. It carries the shortcut in aria-keyshortcuts and as a visible hint (hidden on phones). The menu opens on the selected row, and arrow keys move between rows.
  • Scrolling a picked tab into view uses smaller edge-fade margins when a tab is too wide for both, so a long tab fits whole, X included.
  • The New tab shortcut (Ctrl/Cmd+Alt+N) and the command palette action are unchanged.

Validation

  • Strip stories cover the menu rows and their order, arrow keys, picking a scrolled-out tab, the New tab row in a one-tab strip, and that All tabs and Collapse are the strip's only buttons. The NewTabLauncher story checks that the launcher keeps focus after the menu unmounts.
  • The Storybook test-runner checks the tablet strip height and 24px targets under touch emulation, and drags the sidebar handle with CDP touch input.
  • UI tests, the e2e helper and the bug-bash repros (phone Stats, phone full-screen sidebar, tab order after reload) open the New tab through the menu. make test-bugbash-repros (mock AI): 74 tests pass.

Risks

Low and UI only. Opening a New tab from the strip now takes two clicks (chevron, then New tab) instead of one. The shortcut and the palette action still take one step. Every screen changes, desktop included: no "+", and the chevron shows with one tab.

… menu

On an iPad (coarse pointer above the phone breakpoint) the right sidebar's tab
strip was 57px tall with 44px tabs, the 2px resize handle could not be dragged
with a finger, and tabs scrolled out of the narrow row were hard to reach.

- Tab strip: tablets keep the desktop row height (strip 37px, tabs 24px) and
  size the tab X, "+", All tabs and collapse buttons to the 24px WCAG minimum
  (TABLET_TOUCH_TARGET_PX). Phones keep their 44px touch floor.
- Resize: useResizableSidebar listens to pointer events (useResizeDragListeners)
  so touch and pen drags work; it follows only the pointer that started the
  drag and ends on pointercancel. Both handles get touch-action: none. Coarse
  pointers get a 12px handle with a grip; the sidebar hands its left border to
  the handle (:has() rule) so the strip's bottom border still meets the line.
- All tabs: a ChevronDown button at the strip's right end (2+ tabs) opens a
  menu of every tab. It opens on the selected row, arrow keys move between rows,
  and a pick selects the tab, focuses it and scrolls it into view. Terminal and
  side chat rows render their labels without their buttons (menuLabel).

Tests: hook tests for pointer filtering and pointercancel; strip stories for
the phone/tablet target contract, the All tabs pick and the one-tab case; the
Storybook test-runner checks the tablet strip height and targets under touch
emulation and drags the right sidebar handle with real CDP touch input. The
Narrow swipe check taps the last tab's visible part, since the phone row is now
narrower than a long tab.
…rip's "+"

The strip's "+" took a 24px slot from the tab row on every screen, and the All
tabs chevron only showed with 2+ tabs. On a phone or a narrow pane the row has
room for a tab or two, so the end controls should be as few as possible.

- All tabs is always there, also with one tab. Its menu lists the open tabs
  (not the New tab), a separator, then a "New tab" row that opens or shows the
  tabset's New tab and moves focus into its launcher. The row is checked when
  the New tab is selected, carries aria-keyshortcuts and shows the shortcut
  hint (hidden on phones).
- The "+" button is gone. The shortcut and the command palette action stay.
- A pick moves focus out of the menu, and Radix then does not refocus the
  trigger, so the pickedRef/onCloseAutoFocus guard is gone.
- revealSelectedTab uses smaller fade margins for a tab too wide for both, so
  a long tab fits whole (its X included) when the row can hold it.

Tests and docs follow: stories, UI tests, the e2e helper and the bug-bash
repros open the New tab through the menu; keybinds.mdx mentions the menu.
@mintlify

mintlify Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
Mux 🟢 Ready View Preview Oct 18, 2026, 9:18 PM

💡 Tip: Enable Automations to automatically generate PRs for you.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-18T21:31:33.494769Z aee1d20 Manual request
🔒 Security Review ✅ Completed 2026-10-18T21:31:38.503169Z aee1d20 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: aee1d20cbb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/features/RightSidebar/RightSidebarTabStrip.tsx
Comment thread src/browser/features/RightSidebar/RightSidebarTabStrip.tsx
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

Both findings are answered in their threads with test evidence (no code change), so this asks for a verdict on the same head, aee1d20cbb.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: aee1d20cbb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: aee1d20cbb

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@ibetitsmike
ibetitsmike added this pull request to the merge queue Oct 18, 2026
Merged via the queue into main with commit 8d53b12 Oct 18, 2026
62 of 65 checks passed
@ibetitsmike
ibetitsmike deleted the mike/right-sidebar-tablet-tabs branch October 18, 2026 21:45
github-merge-queue Bot pushed a commit that referenced this pull request Oct 21, 2026
## Summary

The right sidebar's tab strip has a "+" (New tab) button again, right
after the last tab, like the ChatGPT macOS app. Before, New tab was only
a row at the bottom of the All tabs (chevron) menu. The chevron menu
stays, so tabs that scroll out of view are still one pick away. It now
lists every open tab, the New tab too.

| Desktop | Narrow strip (390px viewport) |
| --- | --- |
| ![Desktop: the "+" sits right after the New tab tab, the chevron and
sidebar toggle at the right
end](https://github.com/user-attachments/assets/d70a7621-4b20-446e-8ea2-23562ba173a2)
| ![Narrow: the tabs scroll and the "+" stays in view before the
chevron](https://github.com/user-attachments/assets/1f0420ea-b022-4add-ae70-34af23794fe2)
|

## Background

#6995 moved New tab into the All tabs menu and removed the strip's "+"
on every screen. A New tab hidden in a menu is hard to find, so the "+"
is back.

## Implementation

- `NewTabButton` sits outside the scrolling row, as a sibling of the
tablist, so the tablist still owns only tabs. While the tabs fit, it
follows the last tab. Once they overflow, the row scrolls and the "+"
stays in view.
- It uses the strip's icon-button style, so it gets the 24px
coarse-pointer target and the desktop no-drag region. Its tooltip shows
the New tab shortcut (hidden on phones), and it sets
`aria-keyshortcuts`.
- The All tabs menu has no New tab row now, so no separator is needed.
- Test helpers (jest UI, Storybook plays, Playwright, bug-bash repros)
now open the New tab with the "+".

## Validation

- Storybook interaction tests for the tab strip, RightSidebar, the
seeded a11y pages, phone full-screen and phone viewports pass. The
tablet touch-target check in `.storybook/test-runner.ts` now also covers
the "+".
- Jest UI suites: `layout/rightSidebar`, `review/focus`,
`review/baseSelector` and `chat/contextUsageBoot` pass.
- Bug bash in the sandbox: I ran 5 charters on this branch (mouse,
keyboard, overflow plus reload, phone, split panes) with Sonnet 5.5 and
the real app AI. They found 0 issues. One run cost $3.48 at list price.
The run also gave 2 warnings, and both are older than this PR:
- The tablist does not handle ArrowLeft and ArrowRight. I filed this as
an issue (linked in a comment below).
- Escape does not close a New tab. I rejected this one, because Escape
closes no other tab.

## Risks

Low, limited to the right sidebar's tab strip. The "+" takes about 26px
from the tab row. On a pane at its minimum width, a long tab (240px) can
show cut off at its end. I kept the 10rem cap of
`titlebar-safe-right-capped`: a larger cap would put strip controls
under the Windows/Linux window controls at the 300px minimum width. So
these stories now check what still holds:
- `Narrow` is 330px wide (was 300px), so its 240px tab still fits beside
"+" and All tabs.
- `TabsReachableUnderWideTitlebarInset` checks that the selected tab can
be clicked, not that it is fully visible.

---

_Generated with `xum` • Model: `anthropic:claude-opus-5-5` • Thinking:
`high` • Cost: `$3.03`_

<!-- mux-attribution: model=anthropic:claude-opus-5-5 thinking=high
costs=3.03 -->

This branch was successfully deployed

1 active deployment
staging - docs — aee1d20c Deployed Oct 18, 2026 by mintlify[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant