fix: recover uncontrolled selection when a tab becomes disabled - #10702
Open
Shubham-Padkonde wants to merge 2 commits into
Open
Shubham-Padkonde wants to merge 2 commits into
Shubham-Padkonde wants to merge 2 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related to #10633 (the uncontrolled-selection case).
When an uncontrolled Tabs selection becomes disabled, keep an enabled tab selected so keyboard users can still enter the tab list. The existing fallback already handles removed items and empty selection; this extends it to disabled items and tracks pending fallback transitions so collection re-renders do not notify twice before the new selection commits. Controlled selection remains the application's responsibility.
The regression tests exercise disabledKeys and per-item isDisabled, focus inside and outside the tab list, re-enabling an initially all-disabled list, repeated fallback changes, immediate disabling from onSelectionChange, and controlled selection. A Storybook example makes the dynamic disabling behavior reproducible. This change was prepared with Codex assistance.
✅ Pull Request Checklist:
📝 Test Instructions:
Run
yarn testandyarn test:ssr.In the React Aria Components Tabs
DisableSelectedTabstory, select Artifacts and press Re-run build. Logs should become selected. Pressing Tab from the button should focus Logs. The automated tests also cover disabling the focused tab, where focus should move to the enabled replacement.Full local validation on Windows / Node 24.15:
yarn test --maxWorkers=4: 379 suites passed, four failed; 8,080 tests passed, 16 failed, 16 skipped; all 262 snapshots passed. The same four failing suites and 16 failures reproduce with all three changed files restored to the base commit: NumberField, NumberParser, the S1-to-S2 CLI end-to-end tests, and LocalesResolver.yarn test:ssr: 57 suites passed, three failed (69 tests passed, five failed). Table, ListBox, and Calendar SSR tests timed out in the final local run. These SSR failures have not been isolated against the base commit; the previous published commit passed all SSR jobs in CircleCI.yarn lint: formatting, oxlint, workspace constraints, and package checks passed. Type checking reports Color.test.tsx:266 (TS2345), which also reproduces on unchanged source.The new regressions failed before the implementation change and pass afterward. The React 18 CI failure was reproduced locally as duplicate onSelectionChange events and addressed by tracking pending fallback transitions. The complete Tabs suite passes with both React 18 and React 19, including repeated transitions and immediate disabling of a newly selected tab. Automated mouse/keyboard and disabled/empty-state behavior is covered. Manual browser, touch, screen reader, RTL, theme, and zoom checks have not been performed.
🧢 Your Project:
Independent contribution addressing the existing issue; no production-project claim.