Fix: Keyboard Navigation: Paid expense details: The content is focused in a confusing order#80122
Fix: Keyboard Navigation: Paid expense details: The content is focused in a confusing order#80122lakchote merged 30 commits intoExpensify:mainfrom
Conversation
|
@eVoloshchak Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
Codecov Report❌ Looks like you've decreased code coverage for some files. Please write tests to increase, or at least maintain, the existing level of code coverage. See our documentation here for how to interpret this table.
|
trjExpensify
left a comment
There was a problem hiding this comment.
Small accessibility update 👍
|
@annaweber830, this isn't the approach that was initially approved in #76923 (comment)
Does this approach have any caveats? |
|
Hi @eVoloshchak So when PrevNextButtons passed tabIndex={1} / tabIndex={2}, that expression became truthy → tabIndex was forced to -1, removing the chevrons from the tab order. That’s consistent with the behavior you’re seeing: focus skips past the chevrons and lands on elements lower in the section first. Separately, positive tabIndex is generally an accessibility anti-pattern (it overrides natural DOM order). The correct fix is to keep the chevrons tabbable (tabIndex omitted → defaults to 0) and rely on render/DOM order for a meaningful sequence. |
Yeah, I suspect that will be the hard part. We might want to find a more universal approach for this, the problem is app-wide. Screen.Recording.2026-01-26.at.20.49.02.mov |
|
Hi @eVoloshchak Please check again. On my side, this code works correctly. |
|
@annaweber830, this works for some expenses, but not for others, weird. Here I isolated two expenses: Screen.Recording.2026-02-05.at.12.14.58.mov |
|
Hi @eVoloshchak I will ready PR tomorrow. |
|
Hi @eVoloshchak I updated my PR. |
|
@annaweber830 the jest tests are failing could you please take a look? |
|
Hi @lakchote I updated PR. |
|
🚧 @lakchote has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
🚀 Deployed to staging by https://github.com/lakchote in version: 9.3.51-0 🚀
Bundle Size Analysis (Sentry): |
|
🤖 Help Site Review: No changes required I reviewed all changes in this PR against the help site articles under
I searched the help site for any articles covering keyboard navigation, focus order, tab order, accessibility, or screen reader behavior — none of the existing articles document these internal behaviors. Conclusion: No changes to |
|
Deploy Blocker #86794 was identified to be related to this PR. |
|
Able to reproduce the issue when a Concierge comment is present. The navigation starts from that comment and then moves to the fields above. The Concierge option buttons are not announced at all. 124.mp4 |
|
🚀 Deployed to production by https://github.com/jasperhuangg in version: 9.3.51-10 🚀
|
|
🚀 Deployed to staging by https://github.com/lakchote in version: 9.3.52-0 🚀
Bundle Size Analysis (Sentry): |
|
No help site changes are required for this PR. This PR is a keyboard navigation/accessibility fix that corrects the tab focus order in paid expense details when using screen readers. The changes are limited to internal React component logic (focus management, scroll behavior, test IDs) and do not:
The existing help site articles do not document keyboard navigation behavior at this level of detail, so no updates are needed. |
|
🚀 Deployed to production by https://github.com/roryabraham in version: 9.3.52-9 🚀
|

Explanation of Change
Fix Keyboard Navigation: Paid expense details: The content is focused in a confusing order
Fixed Issues
$#76923
PROPOSAL:#76923 (comment)
Tests
Offline tests
Same as test
QA Steps
// TODO: These must be filled out, or the issue title must include "[No QA]."
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectioncanBeMissingparam foruseOnyxtoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
Screen.Recording.2026-01-21.at.6.54.37.AM.mov