Repository navigation
Add page navigation to multi-page PDF receipts - #102776
Conversation
On desktop the receipt preview already renders the full PDF over the page 1 thumbnail for hover zoom. The page count badge becomes a pill with previous/next buttons that scroll that PDF, once it has loaded.
|
Hey, I noticed you changed If you want to automatically generate translations for other locales, an Expensify employee will have to:
Alternatively, if you are an external contributor, you can run the translation script locally with your own OpenAI API key. To learn more, try running: npx bun ./scripts/generateTranslations.ts --helpTypically, you'd want to translate only what you changed by running |
PDFPreviewer measures every page before showing any, which took tens of seconds on long PDFs. Page navigation now renders just the requested page with react-pdf, so it no longer needs the react-fast-pdf change.
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.
|
@ishpaul777 Do we need to wait for the backend or anything else? If not, we can remove the draft status and start working on it. If there are any changes, I’ll update them here as well. |
Screen.Recording.2026-10-02.at.14.41.01.movCould you check why the page navigation controls are displayed so late? I can see that the PDF has already been uploaded successfully. |
Screen.Recording.2026-10-02.at.15.06.17.movBUG: When I click Next or Previous, the navigation controls jump in and out because there isn't enough width. |
Screen.Recording.2026-10-02.at.15.10.21.movBUG: The tooltip still appears when the button is disabled. |
Show the pill as soon as pages can be flipped, with its buttons disabled until the PDF loads, so it no longer grows when the arrows appear. Reserve the widest label's width, hide tooltips on disabled buttons, and fall back to the static badge when the PDF or a page fails to load.
… redundant comment, fix page param in test
…cus outlines aren't clipped
|
@huult Both fixed. The pill now sizes to its longest label ("Page N of N" for the last page), so long translations no longer clip. Removing overflow: hidden also fixes the clipped focus outlines. Please re-check on your side. |
huult
left a comment
There was a problem hiding this comment.
Screen.Recording.2026-10-12.at.10.19.02.mov
LGTM.
|
We did not find an internal engineer to review this PR, trying to assign a random engineer to #102435 as well as to this PR... Please reach out for help on Slack if no one gets assigned! |
|
@MelvinBot I just approved this. Please update the PR title to include [Payment due @huult]. |
|
Done. I updated the PR title to |
|
🚧 MonilBhavsar has triggered a test Expensify/App build. You can view the workflow run here. |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
🚀 Deployed to staging by https://github.com/MonilBhavsar in version: 9.5.9-0 🚀
|
|
No help site update needed. This PR adds previous/next buttons to the existing "Page 1 of N" badge on desktop, which explains itself in the app, and no article in |
|
🚀 Deployed to production by https://github.com/cristipaval in version: 9.5.9-4 🚀
Bundle Size Analysis (Sentry): |
Explanation of Change
Multi-page PDF receipts showed a static "Page 1 of N" badge, and there was no way to flip pages in the expense's receipt preview. On desktop, that preview already draws the real PDF over the page 1 thumbnail so hover zoom stays sharp. This PR turns the badge into a pill with previous/next buttons that change which page that layer shows.
For multi-page PDFs the layer now renders only the current page with react-pdf, instead of
PDFPreviewer, which measures every page before showing any. Every other receipt still usesPDFPrevieweras before. The previous page stays visible until the next one has drawn, so the thumbnail underneath doesn't flash.The pill shows as soon as pages can be flipped, with its buttons disabled until the PDF loads, so it doesn't change size once it can flip. On devices without hover support, or if the PDF fails to load, the static badge stays instead. Hover zoom pauses while the pointer is over the pill, since tracking the cursor there would hide the page you just flipped to.
receipt.pageCountnow takes the current page.Receipts uploaded in the current session are local files, which this layer didn't cover before. With page navigation on, it now does, which adds one extra PDF load for fresh multi-page uploads on desktop.
Known limitation: the PDF is downloaded again each time the receipt is opened, so on large PDFs the arrows take a few seconds to appear. Caching that is a separate out of scope task.
Fixed Issues
$ #102435
Tests
Offline tests
QA Steps
Same as tests.
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectionAvatar, 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.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Screen.Recording.2026-10-02.at.6.25.47.PM.mov