Skip to content

[Due for payment 2026-10-23] Report - "Find Expense" input is not visible with keyboard opened on landscape mode. #102021

Open

Description

@applause-bot

If you haven’t already, check out our contributing guidelines for onboarding. To join our Slack channel, fill out this form.


Version Number: 9.4.92-0
Reproducible in staging?: Yes
Reproducible in production?: N/A - new feature, doesn't exist in prod
If this was caught during regression testing, add the test name, ID and link from BrowserStack: #100886
Email or phone of affected tester (no customers): ibellicotest+2766@gmail.com
Issue reported by: Applause Internal Team
Bug source: Exploratory - Significant User Experience Deterioration
Device used: Motorola MotoG60 / Android 12 (Hybrid app)
App Component: Money Requests

Action Performed:

Prerequisite: Account has a workspace.
Prerequisite: Account has at least one expense created.

  1. Open the Expensify app.
  2. Navigate to workspace chat.
  3. Create an empty report.
  4. Tap on "Add Expense" > "Add existing expense"
  5. Turn to landscape mode.
  6. Tap on "Find expene" input to trigger keyboard.
  7. Note that input is now displayed behind "Add to report" button.

Expected Result:

"Find expense" input should remain visible while keyboard is opened on landscape mode.

Actual Result:

"Find expense" input is displayed behind "Add to report" button and is not visible while in landscape mode.

Workaround:

Unknown

Platforms:

  • Android: App
  • Android: mWeb Chrome
  • iOS: App
  • iOS: mWeb Safari
  • iOS: mWeb Chrome
  • Windows: Chrome
  • MacOS: Chrome Safari

Screenshots/Videos

Bug7267015_1790155541023.Exist.mp4

View all open jobs on GitHub

Applause Internal Information
Exported by: Julia Ponikarchuk
Bug ID: 7267015

Issue OwnerCurrent Issue Owner: @Krishna2323

Activity

  1. added
    DeployBlockerCashThis issue or pull request should block deployment
    BugSomething is broken. Auto assigns a BugZero manager.
    on Sep 23, 2026
  2. applause-bot commented on Sep 23, 2026

    @applause-bot
    Author

    While Applause doesn't embed attachments for this bug, here are the links for quick view:
    https://platform.applause.com/services/links/v1/external/30eaa20999fb7acf51f2f0645ea0c3d4d7fc3938a199fea797d64b077dc85f3f

  3. melvin-bot commented on Sep 23, 2026

    @melvin-bot

    You have been assigned to this deploy blocker because you recently merged this PR: #100886

  4. melvin-bot commented on Sep 23, 2026

    @melvin-bot

    @JS00001 @situchan you have been assigned to this deploy blocker because you reviewed the offending PR: #100886

  5. github-actions commented on Sep 23, 2026

    @github-actions
    Contributor

    👋 Friendly reminder that deploy blockers are time-sensitive ⏱ issues! Check out the open `StagingDeployCash` deploy checklist to see the list of PRs included in this release, then work quickly to do one of the following:

    1. Identify the pull request that introduced this issue and revert it.
    2. Find someone who can quickly fix the issue.
    3. Fix the issue yourself.
  6. melvin-bot commented on Sep 23, 2026

    @melvin-bot

    @Krishna2323 you have been assigned to this deploy blocker because you authored the offending PR: #100886

  7. melvin-bot commented on Sep 23, 2026

    @melvin-bot

    💬 A slack conversation has been started in #expensify-open-source

  8. MelvinBot commented on Sep 23, 2026

    @MelvinBot
    Contributor

    🔍 Investigation Summary

    Classification: Frontend bug
    Causing PR: feat: use Table component for Add existing expense flow (Expensify/App#100886) by @Krishna2323 (High confidence)
    Related Issues: Reports - Add existing expense to report doesn't work — same causing PR, fix already in review; Expense - Status modal is scrollable — same flow, different causing PR

    Recommendation: ROLL FORWARD

    Confirmed: PR #100886 moved the "Find expense" input from a pinned position above the list into the list's scrollable content, so it gets clipped out of view when the keyboard collapses the list viewport in landscape. A revert is unattractive because the PR is a 15-file refactor of the shared Table component and a fix-forward for another blocker from the same PR (#102003) is already in review, so reverting would invalidate that work; a small targeted fix on this screen is lower risk.

    Assigned: @Krishna2323 (PR author), @JS00001 and @situchan (approving reviewers) — already assigned by Melvin, no change made.
    Labels: No changes. DeployBlockerCash is kept (an App PR caused it); DeployBlocker was not present, so nothing was removed.

    📋 Detailed Analysis

    Evidence

    Before #100886 this screen used SelectionList, which renders the search input outside the FlashList, directly under the screen header (BaseSelectionList.tsx#L513-L515, with the footer rendered after the list at #L570). The input was therefore part of the non-shrinkable page chrome and could never be covered by the footer — the list itself absorbed all the vertical shrink when the keyboard opened.

    After #100886 the input is a Table.FilterBar nested in Table.ListHeader (AddExistingExpenseTable/index.tsx#L141-L143). That slot is explicitly "content that should scroll away with the table rows" (TableListHeader.tsx#L3-L11) and is rendered as the FlashList ListHeaderComponent (TableBody.tsx#L241-L246, TableBody.tsx#L384-L390) — i.e. it now lives inside the region that collapses under the keyboard.

    Two more signals that point at this PR:

    • Expensify/App#100886 is on the current checklist (Deploy Checklist: New Expensify 2026-09-23), the bug is staging-only and the report itself is "N/A in production - new feature".
    • src/pages/AddExistingExpense.tsx is the only screen in the repo that renders both a @components/Tables/* table and a FixedFooter, so this layout combination is new as of this PR and not exercised anywhere else.

    Side effect of the same change worth noting: the old code only showed the search input when there were at least CONST.STANDARD_LIST_ITEM_LIMIT (12) expenses; the Table.FilterBar renders whenever there is any data, so the broken input is now reachable with a couple of expenses too.

    Verification

    Affected files (all touched by #100886):

    Supporting (pre-existing, unchanged) code that makes the new layout fail:

    Static analysis only — no device/browser verification was available in this run, so the geometry below is computed from the styles rather than measured.

    Root Cause

    With the keyboard open, ScreenWrapper's KeyboardAvoidingView (behavior="padding") squeezes header + content + footer into windowHeight - keyboardHeight. In that squeezed box:

    • HeaderWithBackButton keeps its variables.contentHeaderHeight of 72dp.
    • FixedFooter is flexShrink: 0 — 52dp (componentSizeLarge button) + 20dp (pb5) + bottom inset ≈ 72–95dp.
    • The table wrapper is styles.flex1 (flex: 1 → flexGrow: 1, flexShrink: 1, flexBasis: 0) and the FlashList container adds mnh0 (minHeight: 0), so it is the only child that can shrink — and it shrinks all the way to ~0.

    On a MotoG60 in landscape the usable height is roughly 393dp, and the Android landscape IME takes ~180–220dp, leaving ~170–210dp. Header + footer already consume ~145–170dp of that, so the list viewport ends up at roughly 0–50dp while the filter bar alone needs 56dp (h11 44dp + pb3 12dp). The search input, being the first thing inside the list's scroll content, is therefore clipped underneath the footer — which is what the tester sees as "displayed behind the Add to report button".

    useScrollToFocusedInput cannot rescue it: it anchors the focused input to the top of the list container and bails out when delta <= 0, and the search input is already at the top of the content, so no scroll happens — and with a ~0dp viewport there is nowhere to scroll it to anyway.

    Suggested fix directions (for the assignees to pick)

    1. Free the vertical space while typing (smallest, page-level): in AddExistingExpense.tsx, skip/collapse the FixedFooter while the keyboard is shown (useKeyboardState), at least on narrow layouts. The confirm button is unreachable while the keyboard covers it anyway, and Button.KeyboardShortcut still handles Enter. Needs a quick design sanity check.
    2. Pin the filter bar (restores pre-PR behaviour): render <Table.FilterBar> as a direct child of <Table> instead of inside <Table.ListHeader>, so it sits above the header/body run and stops scrolling (TableSemanticContainer.tsx#L121-L130). Caveat: that flips hasPageHeader to false, which changes the empty/no-results path (Table.NoResultsState is only used when a page header exists — TableBody.tsx#L259-L260), so "No results found" would need re-testing.
    3. Table-level (follow-up, not for the blocker): teach Table to keep the FilterBar pinned on narrow layouts when the keyboard is shown, which would protect every future Table + fixed-footer screen.

    If a fix can't land quickly, demoting this to a non-blocker is defensible (portrait is unaffected and the flow is fully usable there), but that call belongs to the DeployBlockerCash owner rather than this investigation.

    💡 Suggested AI code review rule

    This bug looks like a recurring, mechanically detectable pattern, so it may be worth a coding-standards rule so the AI reviewer catches the next one. Proposed for Expensify/App:

    • Rule: UI-4 Keep a list's search input out of the region the keyboard collapses
    • Condition: Flag a narrow-layout screen that renders a Table/list whose search or filter input lives in the scrollable content (Table.ListHeader, ListHeaderComponent) and a non-shrinkable FixedFooter inside a keyboard-avoiding ScreenWrapper; either pin the input outside the list or release the footer's height while the keyboard is shown.
    • Why: ScreenWrapper's KeyboardAvoidingView uses behavior="padding", and FixedFooter is flexShrink: 0, so the flex: 1 list is the only child that shrinks. In landscape the header plus footer consume the entire keyboard-free height, the list viewport collapses to ~0dp, and an input inside its scroll content is clipped behind the footer — exactly this issue.
    • Search pattern: grep -rl "FixedFooter" src/pages src/components --include=*.tsx | xargs grep -ln "@components/Tables/\|Table.ListHeader\|ListHeaderComponent" (this is how the offending screen was isolated — it is currently the only match).
    • Offending code (❌): src/pages/AddExistingExpense.tsx#L200-L232 together with AddExistingExpenseTable/index.tsx#L141-L143
    • Fix (✅): not landed yet — the pre-regression shape is BaseSelectionList.tsx#L513-L515, where the input is rendered above the list rather than inside it.

    The full rule file, with the ❌/✅ code inline in Expensify/App's app-coding-standards format, would go in Expensify/App itself. If it's worth adding, a maintainer can open it there as a draft PR.

  9. 21 remaining items

  10. JS00001 commented on Oct 12, 2026

    @JS00001
    Contributor

    Waiting on a PR here

  11. melvin-bot commented on Oct 13, 2026

    @melvin-bot

    @Krishna2323 Huh... This is 4 days overdue. Who can take care of this?

  12. Krishna2323 commented on Oct 14, 2026

    @Krishna2323
    Contributor

    Started working on the fix.

  13. Krishna2323 commented on Oct 14, 2026

    @Krishna2323
    Contributor

    @situchan PR is ready for review: #104003

  14. melvin-bot commented on Oct 15, 2026

    @melvin-bot

    ⚠️ Looks like this issue was linked to a Deploy Blocker here

    If you are the assigned CME please investigate whether the linked PR caused a regression and leave a comment with the results.

    If a regression has occurred and you are the assigned CM follow the instructions here.

    If this regression could have been avoided please consider also proposing a recommendation to the PR checklist so that we can avoid it in the future.

  15. changed the title [-]Report - "Find Expense" input is not visible with keyboard opened on landscape mode.[/-] [+][Due for payment 2026-10-23] Report - "Find Expense" input is not visible with keyboard opened on landscape mode.[/+] on Oct 16, 2026
  16. melvin-bot commented on Oct 16, 2026

    @melvin-bot

    @Krishna2323 / @situchan

    The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.12-1 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:

    If no regressions arise, payment will be issued on 2026-10-23. 🎊

    The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the Contributor+ Checklist from here into a new comment on this GH and complete it. If you have the K2 extension, you can simply click: [this button]. If no checklist is needed for this issue, you can click: [no checklist button]

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

Metadata

Metadata

Labels

BugSomething is broken. Auto assigns a BugZero manager.DailyKSv2Engineering

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions