Skip to content

fix(web): the workspace panel's resize handle has a name and works from the keyboard - #32791

Closed
only21mil wants to merge 1 commit into
pingdotgg:mainfrom
only21mil:fix/web-right-panel-resize-a11y
Closed

only21mil wants to merge 1 commit into
pingdotgg:mainfrom
only21mil:fix/web-right-panel-resize-a11y

Conversation

@only21mil

@only21mil only21mil commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

Problem

The divider on the left edge of the right workspace panel (Files, Changes, Browser, Terminal and the rest) can only be moved by dragging it with a pointer. Screen readers see an unnamed separator with no value, Tab skips it, and the arrow keys do nothing. The file explorer's own divider already works from the keyboard (#25737), but only through a handler written inline in FileExplorerPane.

Change

useResizableWidth already holds the width, its bounds, the panel edge and the saved value, so its handlers now also carry what the keyboard needs: tabIndex={0}, aria-valuenow/aria-valuemin/aria-valuemax and an onKeyDown. The keys behave exactly as the file explorer's did: ArrowLeft widens by 16 px, ArrowRight narrows, Home goes to the minimum and End to the maximum, so Home and End match the announced range. The new width is clamped and saved through setWidth, the same as after a drag. For a panel resized from its right edge the arrows swap.

FileExplorerPane drops its inline handler and passes handlers as before. RightPanelResizeHandle drops the props that handlers now supplies. PreviewPanelShell names its handle "Resize workspace panel". That one handle serves both the chat view and the Pull Requests page.

Scope and approval

This is a small, focused fix for an obvious accessibility gap, with no new behavior beyond what the file explorer's divider already does. It reuses that handler instead of copying it. Mobile has its own layout and no resize handle. There is no server, contract or provider change. The sidebar rail and the terminal drawer have similar gaps; they are separate and not touched here.

Prior PRs: #25737 by maria-rcks added the keyboard handling this change moves into the shared hook. #4581 tried the same fix and was closed by its author as opened in error, before review.

Verification

  • vp test run --project browser src/hooks/useResizableWidth.browser.test.tsx (from apps/web). The new case "resizes from the keyboard within its bounds and persists the width" fails on the base at expect.element(handle).toHaveFocus() (1 failed, 2 passed). With the fix all 3 pass. The case focuses the handle, checks min/max/now of 160/560/320, presses ArrowLeft, ArrowRight, End and Home (336, 320, 560, 160) and checks the saved value after each, then checks that ArrowRight widens a right-edge panel.
  • FileExplorerPane.browser.test.tsx passes unchanged (3 of 3).
  • vp run check:changed 71c2d3a302 passes: format, lint, knip, typecheck, tests and React Compiler.
  • Web, local dev server on fake data (a sample project and one Replay thread), 1440x900, Files tab open in the right panel, starting at the default 540 px. Base: the four changed files checked out at 71c2d3a in the same dev server. Fix: this head, 2983f5f. Tab from the composer's last enabled control, then the arrow keys, Home and End, all sent in the Browser panel:
Base Fix
Accessibility tree separator (no name) separator "Resize workspace panel"
Focus after one Tab "Close Files" button the handle
Width after 3×ArrowLeft 540 px 588 px
Home / End / ArrowRight not reachable (no focus) 360 / 824 / 808 px, kept after reload

Before: one Tab skips the divider and lands on the Files tab's close button.

Before: focus after one Tab

Before: after three ArrowLeft presses the panel edge has not moved.

Before: after three ArrowLeft presses

After: one Tab focuses the divider, which shows its focus line.

After: focus after one Tab

After: three ArrowLeft presses widen the panel by 48 px.

After: after three ArrowLeft presses

Not checked: the desktop app (it renders the same web code), the Pull Requests page's panel (same component and handle), and a real screen reader announcement; the name comes from the browser's accessibility tree.

Generated with Claude Opus 5.5 in T3 Code Nightly

…om the keyboard

The right workspace panel's resize handle had no accessible name, could not
take focus and could only be moved with a pointer drag. Only the file
explorer's handle supported the keyboard, through its own inline handler.

useResizableWidth already owns the width, its bounds and the edge, so its
handlers now also make the handle focusable, report its value range and
resize it with the arrow keys, Home and End, persisting like a drag. Both
handles get this, and the workspace one is named "Resize workspace panel".

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@github-actions github-actions Bot added vouch:unvouched Author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Nov 8, 2026
@coderabbitai

coderabbitai Bot commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The resize hook now provides keyboard controls and ARIA values for width handles. Panel components update their handle props, and browser tests check keyboard resizing and persisted widths.

Changes: Keyboard panel resizing

Layer / File(s) Summary
Resize hook keyboard behavior
apps/web/src/hooks/useResizableWidth.ts, apps/web/src/hooks/useResizableWidth.browser.test.tsx
The hook exposes focus and ARIA properties and handles edge-aware arrow keys, Home, and End. Tests check width changes and persisted values for both handle edges.
Resize handle integration
apps/web/src/components/preview/RightPanelResizeHandle.tsx, apps/web/src/components/files/FileExplorerPane.tsx, apps/web/src/components/preview/PreviewPanelShell.tsx
FileExplorerPane removes its local keyboard handling. RightPanelResizeHandle narrows its props, and PreviewPanelShell supplies the label “Resize workspace panel” to the inline handle.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Separator
  participant useResizableWidth
  participant WidthStorage
  User->>Separator: Press a supported key
  Separator->>useResizableWidth: Call onKeyDown
  useResizableWidth->>useResizableWidth: Calculate and clamp width
  useResizableWidth->>WidthStorage: Commit width
Loading

Suggested reviewers: maria-rcks, wrymn, juliusmarminge

Merge Risk: Minimal · up to 2983f

No concrete issue currently blocks merging. The untested surfaces can be covered by normal validation.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title names the main change: the workspace panel's resize handle gets an accessible name and keyboard support. It matches the summary, the objectives, and the code changes in useResizableWidth, Ri…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The description follows the repository template closely. It covers the Problem, Change, Scope, and Verification sections. The Problem section explains the missing keyboard support and screen reader na…
Full details: Title check

Explanation

The title names the main change: the workspace panel's resize handle gets an accessible name and keyboard support. It matches the summary, the objectives, and the code changes in useResizableWidth, RightPanelResizeHandle, and PreviewPanelShell. It uses the conventional commit format from the template. It is 84 characters, a little long, but still clear.

Full details: Description check

Explanation

The description follows the repository template closely. It covers the Problem, Change, Scope, and Verification sections. The Problem section explains the missing keyboard support and screen reader name, and the Change section explains the shared hook update and the removed inline handler. The Scope section states this is a focused accessibility fix, links prior PRs (#25737, #4581), and names what is not touched. The Verification section lists the focused test command, the results before and after the fix, the manual before/after table, and four before/after screenshots. It also states what was not checked. The description does not end with the agent model and harness line in the required form. It does include 'Generated with Claude Opus 5.5 in T3 Code Nightly', which satisfies that line. The title is not part of the pr_description block, so its conventional-commit format cannot be confirmed here. The screenshots are external gist links, which the template allows.

Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 71c2d3a and 2983f5f.

Files selected for processing: 5

  • apps/web/src/components/files/FileExplorerPane.tsx
  • apps/web/src/components/preview/PreviewPanelShell.tsx
  • apps/web/src/components/preview/RightPanelResizeHandle.tsx
  • apps/web/src/hooks/useResizableWidth.browser.test.tsx
  • apps/web/src/hooks/useResizableWidth.ts

Limit details: You’ve used all 10 included reviews currently available.

@macroscopeapp

macroscopeapp Bot commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 2983f5f

Macroscope's review found this PR approvable — The workspace resize handle gains an accessible name and keyboard controls shared with the file explorer. Effects remain limited to bounded panel widths and existing browser-local preferences, with sizing defaults unchanged.

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

@maria-rcks

maria-rcks commented Nov 10, 2026 •

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

Verified in a real dev environment

verified as-is at 2983f5f7ff00f8a9d7c2c83b11f2a09ceaa40120 on this linux boat vm. used repo Playwright with /usr/bin/google-chrome, 1440×900, and real dev servers, one at a time. created the git project through the app, added that same repository through the pr app, and completed real Codex gpt-6.1-sol turns through the web composer on both versions. no replay provider, mocks, fixtures, or demo data.

  • github/main at cec8d73a1f: tab from the enabled voice-input control skips the unnamed workspace divider and focuses "close files". three ArrowLeft presses leave its width at 540 px.
  • exact pr head: the same tab focuses the separator named "Resize workspace panel". three ArrowLeft presses change 540→588 px. ArrowRight shrinks by 16 px. Home/End reach the announced 360/824 px bounds; further outward arrows stay clamped. Control+ArrowLeft leaves width unchanged.
  • keyboard width survives reload. pointer drag changes 824→760 px and survives reload. closing/reopening preserves the width.
  • opened the real README through Files. the inner file explorer divider still supports ArrowLeft/ArrowRight (256→272→256) and Home/End (160/503), while the file contents remain visible.
  • both existing browser test files passed through blacksmith-check: useResizableWidth.browser.test.tsx and FileExplorerPane.browser.test.tsx, 6 tests total. current github ci checks pass. no source changes or pushes were needed.

before, after the same three left-arrow presses:

main: divider skipped and width remains 540 px

pr: focused divider and width grows to 588 px

recording: tab focuses the divider, three left arrows grow it, Home shrinks it, End expands it, and ArrowRight shrinks it. inspected the captures and checked uploaded playback and seeking.

workspace divider keyboard interaction in the real app

Not verified

native electron, ios/android, macos/windows, a real screen reader announcement, the Pull Requests page's separate entry point, and remote/relay/tunnel connections. this pass exercised the local linux web client and real Codex provider path; the pr changes no server or provider code.

@only21mil

Copy link
Copy Markdown
Contributor Author

Note

🤖 Opus 5.5 replying on behalf of Victor.

Thanks, Maria, for testing exact head 2983f5f with real Codex turns on a real repository. The PR body's run used fake data and a Replay thread, so yours shows the same result with a real provider: Tab now lands on the named divider, and three ArrowLeft presses widen it from 540 to 588 px where main stays at 540. Your run also covers things the PR didn't check. A drag keeps its width after a reload, and so does closing and reopening the panel. The file explorer's divider still responds to the arrows and Home/End after its handler moved into the shared hook. Ctrl+ArrowLeft is ignored, which matches the modifier guard carried over from that handler.

Your open notes stand. Electron, macOS and Windows, a real screen reader announcement, the Pull Requests page and remote connections are untested. The Pull Requests page uses the same PreviewPanelShell handle, but nobody has run it there yet. Mobile has no resize handle, so this change doesn't reach it.

@only21mil

Copy link
Copy Markdown
Contributor Author

Note

🤖 Opus 5.5 replying on behalf of Victor.

Closing this: it is not a bug fix, and this repository now takes only bug fixes from outside contributors. The branch stays on my fork if it is useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched Author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants