Enable autofocus on Per Diem destination picker#85310
Conversation
Remove disableAutoFocus from DestinationPicker so the SelectionList's built-in useFocusEffect autofocus fires when the Per Diem tab gains focus. Also fix the stale ref in IOURequestStepDestination's useImperativeHandle by using a lazy getter so the ref is read at call time rather than at render time. Co-authored-by: Cong Pham <suneox@users.noreply.github.com>
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppCleanShot.2026-03-16.at.00.06.52.5.mp4Android: mWeb ChromeCleanShot.2026-03-16.at.00.03.37.3.mp4iOS: HybridAppCleanShot.2026-03-16.at.00.01.38.2.mp4iOS: mWeb SafariCleanShot.2026-03-16.at.00.04.39.4.mp4MacOS: Chrome / SafariCleanShot.2026-03-16.at.00.01.03.1.mp4 |
|
@MelvinBot Please investigate why auto focus sometimes doesn't work when creating a manual expense from Quick Action. This happens when the Manual tab was previously selected and then change tab to Per Diem. CleanShot.2026-03-16.at.00.01.38.2.mp4 |
🔍 Investigation: Autofocus fails when switching from Manual to Per Diem tabSummary: The intermittent autofocus failure when switching from the Manual tab to the Per Diem tab is caused by two interacting issues: (1) an unconditional Root Cause: Two timing conflicts prevent the Per Diem destination picker from gaining focus: 1.
|
|
@MelvinBot Ok so we can revert the current changes and then apply the fix as follows: |
…questStartPage - Reverted removal of disableAutoFocus in DestinationPicker - Reverted stale ref fix in IOURequestStepDestination - Conditioned Keyboard.dismiss() to skip Per Diem tab switches so it does not suppress subsequent focus calls on iOS - Replaced requestAnimationFrame with setTimeout using CONST.ANIMATED_TRANSITION in onTabSelectFocusHandler for reliable focus timing after tab animation completes Co-authored-by: Cong Pham <suneox@users.noreply.github.com>
|
Done! I've reverted the previous changes and applied the new fix approach. Here's what changed:
|
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.
|
|
@MelvinBot ready for review |
|
I have failed to help you. I let you down and for that I am sorry. Please try again later. This may be due to a Claude outage (check here). Failure details: https://github.com/Expensify/Expensify/actions/runs/23245907686 |
|
@MelvinBot Update PR status to ready not draft |
|
Done — PR has been marked as ready for review. |
|
@MelvinBot update Explanation of Change for current PR |
|
Updated the Explanation of Change to match the current implementation. The description now accurately reflects the two changes in
|
joekaufmanexpensify
left a comment
There was a problem hiding this comment.
Fine for product
|
We did not find an internal engineer to review this PR, trying to assign a random engineer to #85277 as well as to this PR... Please reach out for help on Slack if no one gets assigned! |
|
🚧 @rlinoz has triggered a test Expensify/App build. You can view the workflow run here. |
This comment has been minimized.
This comment has been minimized.
|
🚧 @rlinoz 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! 🧪🧪
|
|
🚧 @rlinoz 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! 🧪🧪
|
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚀 Deployed to staging by https://github.com/rlinoz in version: 9.3.42-0 🚀
Bundle Size Analysis (Sentry): |
Explanation of Change
The Per Diem destination picker's search input sometimes failed to autofocus when switching to the Per Diem tab. This was caused by two timing issues in
IOURequestStartPage:Keyboard.dismiss()raced with autofocus —resetIOUTypeIfChangedcalledKeyboard.dismiss()unconditionally on every tab switch. On iOS, the keyboard dismiss animation suppresses subsequent.focus()calls, preventing the Per Diem search input from gaining focus. This is now conditional —Keyboard.dismiss()is skipped when switching to the Per Diem tab.requestAnimationFramewas too early —onTabSelectFocusHandlerusedrequestAnimationFrameto focus the Per Diem input, but with lazy-loaded tabs the component hadn't mounted yet by the next animation frame. This is now replaced withsetTimeout(..., CONST.ANIMATED_TRANSITION)to give the tab enough time to mount before attempting focus.Fixed Issues
$ #85277
PROPOSAL: #85277 (comment)
Tests
Offline tests
N/A — Autofocus behavior is client-side only and does not depend on network state.
QA Steps
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand 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