Skip to content

[Due for payment 2026-03-30] Reports - Keyboard navigation does not work at the first/last item of Column list #85657

Closed

Description

@jponikarchuk

If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!


Version Number: 9.3.40-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: #78869
Email or phone of affected tester (no customers): sjodinjsonjinodisjniod@gmail.com
Issue reported by: Applause Internal Team
Bug source: Exploratory - Significant User Experience Deterioration
Device used: Mac 26.2 / Chrome
App Component: Search

Action Performed:

  1. Go to staging.new.expensify.com
  2. Go to Reports > Expenses.
  3. Click Columns.
  4. Press Up arrow key.
  5. Press Down arrow key until the last item in the list.
  6. Press Down arrow key again.

Expected Result:

  • Pressing Up arrow key at the top of the list will focus on the last item in the list.
  • Pressing Down arrow key at the last item of the list will focus on the first item in the list.

Actual Result:

  • Pressing Up arrow key at the top of the list does not navigate.
  • Pressing Down arrow key at the last item of the list does not navigate.

Workaround:

Unknown

Platforms:

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

Screenshots/Videos

Video.mp4

View all open jobs on GitHub

Issue OwnerCurrent Issue Owner: @mallenexpensify

Activity

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

    @melvin-bot

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

  3. melvin-bot commented on Mar 18, 2026

    @melvin-bot

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

  4. github-actions commented on Mar 18, 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.
  5. OSBotify commented on Mar 18, 2026

    @OSBotify
    Contributor

    🔍 Investigation Summary

    Classification: Frontend bug
    Causing PR: #78869 - "fix: Arrow key navigation not working in Columns selection" by @TaduJR (High confidence)
    Related Issues: None

    Recommendation: REVERT

    The PR should be reverted. It intentionally disabled cyclic keyboard navigation, but the expected behavior is that arrow keys should wrap around at list boundaries.

    Labels: No changes needed. DeployBlockerCash is correctly applied (frontend bug in App repository).

    📋 Detailed Analysis

    Evidence

    1. Timing: PR fix: Arrow key navigation not working in Columns selection #78869 was merged on 2026-03-17 and is included in staging version 9.3.40-0 where the bug appears
    2. Direct code match: The bug symptoms (no wrap-around navigation) exactly match the implementation in the PR
    3. Intentional design choice: In src/hooks/useListKeyboardNav.ts line 44, the PR sets disableCyclicTraversal: true

    Verification

    Files affected by the bug:

    • /home/runner/_work/App/App/src/components/ColumnsSettingsList.tsx - The Columns settings UI where the bug manifests
    • /home/runner/_work/App/App/src/hooks/useListKeyboardNav.ts - New hook added by the PR that controls keyboard navigation

    Confirmed PR modifies these files:

    • ✅ src/components/ColumnsSettingsList.tsx - Modified to integrate keyboard navigation
    • ✅ src/hooks/useListKeyboardNav.ts - New file added by the PR
    • ✅ src/hooks/useArrowKeyFocusManager.ts - Used by the new hook

    Root Cause

    The PR added keyboard navigation support to DraggableList/ColumnsSettingsList using a new useListKeyboardNav hook. This hook calls useArrowKeyFocusManager with disableCyclicTraversal: true (line 44 of useListKeyboardNav.ts).

    When disableCyclicTraversal is true:

    • Pressing Up arrow at the first item returns the current index (no-op) instead of wrapping to the last item
    • Pressing Down arrow at the last item returns the current index (no-op) instead of wrapping to the first item

    However, the expected behavior (per the bug report) is that navigation should wrap cyclically at both ends of the list. The PR implementation contradicts this expectation.

  6. MelvinBot commented on Mar 18, 2026

    @MelvinBot
    Contributor

    Proposal

    Please re-state the problem that we are trying to solve in this issue.

    When using keyboard navigation (arrow keys) in the Columns settings dropdown (Search > Reports > Expenses > Columns), pressing the Up arrow at the top of the list does not cycle to the last item, and pressing the Down arrow at the last item does not cycle to the first item. The arrow keys simply stop working at the boundaries.

    What is the root cause of that problem?

    In src/hooks/useListKeyboardNav.ts, the hook passes disableCyclicTraversal: true to useArrowKeyFocusManager (line 44). This flag explicitly prevents wrapping at list boundaries:

    • ArrowUp at index 0: useArrowKeyFocusManager sets nextIndex = -1 (instead of maxIndex), which triggers the disableCyclicTraversal guard and returns the current index unchanged — a no-op.
    • ArrowDown at last index: nextIndex is set to maxIndex (instead of 0), so currentFocusedIndex stays at the same value — also a no-op.

    The useArrowKeyFocusManager hook already supports cyclic traversal when disableCyclicTraversal is false (the default). The issue is that useListKeyboardNav explicitly opts out of it.

    What changes do you think we should make in order to solve the problem?

    Remove the disableCyclicTraversal: true option from useListKeyboardNav.ts (line 44). Since false is the default value for disableCyclicTraversal in useArrowKeyFocusManager, simply removing this line will enable cyclic traversal — ArrowUp at the first item will wrap to the last, and ArrowDown at the last item will wrap to the first.

    Additionally, add boundary test cases to tests/unit/useListKeyboardNavTest.ts to verify wrapping behavior (ArrowUp at index 0 should focus the last item, ArrowDown at the last index should focus the first item).

    What alternative solutions did you explore? (Optional)

    An alternative would be to make disableCyclicTraversal a configurable parameter on useListKeyboardNav so individual consumers can choose. However, since the issue specifically requests cyclic behavior and there's currently only one consumer (ColumnsSettingsList), the simpler fix of just removing the flag is preferred.


    Next Steps for Contributor+ team: Reply with @MelvinBot implement this to create a draft PR, @MelvinBot <your feedback> to refine this analysis, or explain why you are rejecting Melvin's proposal.

  7. TaduJR commented on Mar 18, 2026

    @TaduJR
    Contributor

    I think this is expected.

    WDYT @aimane-chnaif?

  8. aimane-chnaif commented on Mar 18, 2026

    @aimane-chnaif
    Contributor

    I thought this is expected while testing. But now I see different behavior on SelectionList.

  9. 16 remaining items

  10. melvin-bot commented on Mar 23, 2026

    @melvin-bot

    @aimane-chnaif The PR fixing this issue has been merged! The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the BugZero 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]

  11. melvin-bot commented on Mar 23, 2026

    @melvin-bot

    Triggered auto assignment to @mallenexpensify (Awaiting Payment)

  12. melvin-bot commented on Mar 30, 2026

    @melvin-bot

    Payment Summary

    Upwork Job

    BugZero Checklist (@mallenexpensify)

    • (if NewFeature) I have created a PR for any necessary HelpDot updates, or I confirmed no updates are necessary.
    • I have verified the correct assignees and roles are listed above and updated the necessary manual offers
    • I have verified that there are no duplicate or incorrect contracts on Upwork for this job (https://www.upwork.com/ab/applicants//hired)
    • I have verified the PR was not reverted
    • I have applied any discounts due to bugs/regressions introduced by this PR
    • I have paid out the Upwork contracts or cancelled the ones that are incorrect
    • I have verified the payment summary above is correct
  13. melvin-bot commented on Mar 30, 2026

    @melvin-bot

    Payment Summary

    Upwork Job

    BugZero Checklist (@mallenexpensify)

    • (if NewFeature) I have created a PR for any necessary HelpDot updates, or I confirmed no updates are necessary.
    • I have verified the correct assignees and roles are listed above and updated the necessary manual offers
    • I have verified that there are no duplicate or incorrect contracts on Upwork for this job (https://www.upwork.com/ab/applicants//hired)
    • I have verified the PR was not reverted
    • I have applied any discounts due to bugs/regressions introduced by this PR
    • I have paid out the Upwork contracts or cancelled the ones that are incorrect
    • I have verified the payment summary above is correct
  14. mallenexpensify commented on Mar 31, 2026

    @mallenexpensify
    Contributor

    @MelvinBot were job offers created in Upwork for both @aimane-chnaif and @TaduJR on this issue? if not, why not?

  15. MelvinBot commented on Mar 31, 2026

    @MelvinBot
    Contributor

    I don't have access to Upwork, so I can't verify whether job offers were actually created there. However, based on what's visible in this issue:

    No automated Upwork offers were created for either contributor. The deployment comment from melvin-bot explicitly flagged both as needing manual action:

    • @TaduJR requires payment (Needs manual offer from BZ)
    • @aimane-chnaif requires payment (Needs manual offer from BZ)

    The Payment Summary also has empty Upwork job links ([Upwork Job]()) and placeholder amounts ($(AMOUNT)), which indicates the offers haven't been filled in yet.

    Why not? The "Needs manual offer from BZ" flag means the automated system couldn't create Upwork offers for these contributors — this typically happens when the contributors aren't set up for automatic Upwork job creation (e.g., no linked Upwork profile in the system, or the issue/PR didn't follow the standard automated payment flow). Both offers need to be manually created by the BZ manager (mallenexpensify).

  16. mallenexpensify commented on Mar 31, 2026

    @mallenexpensify
    Contributor

    @TaduJR @aimane-chnaif can you please accept the job below? Please reply here and tag me once you have.
    https://www.upwork.com/jobs/~022038769096114803386

    @TaduJR @aimane-chnaif were either of you sent offers in Upwork?
    I need to fix the bug cuz it takes me a lot longer to pay y'all each time this happens

  17. TaduJR commented on Mar 31, 2026

    @TaduJR
    Contributor

    @mallenexpensify

    @TaduJR @aimane-chnaif were either of you sent offers in Upwork?

    No Automatic offer sent on my side

    Payment is not needed here.

  18. TaduJR commented on Mar 31, 2026

    @TaduJR
    Contributor

    We can close this.

  19. mallenexpensify commented on Apr 1, 2026

    @mallenexpensify
    Contributor

    ugggh, forgot to reduce pay in the parent issue for this regression, commented there

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

Metadata

Metadata

Labels

Awaiting PaymentAuto-added when associated PR is deployed to productionBugSomething 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