Skip to content

fix(overflow-menu): close-on-scroll fires on scrollIntoView, prevents tap-through to menu item #1480

@steilerDev

Description

@steilerDev

Summary

The OverflowMenu component's close-on-scroll handler (added in #1427, portal mode) closes the menu on any scroll event — including the tiny scroll that Playwright's scrollIntoViewIfNeeded (and likely real mobile touch interactions) trigger as part of resolving a click target. This makes the new mobile deposit-card "Mark paid" flow unreachable in automated tests on the 375px viewport, and is plausibly flaky for real touch users on small screens.

Reproduction

Playwright call log (representative)

```

  • waiting for locator('[role="menuitem"]').filter({ visible: true }).filter({ hasText: /Mark paid/ }).first()
  • locator resolved to <button role="menuitem">Mark paid…
  • attempting click action
  • waiting for element to be visible, enabled and stable
  • element is visible, enabled and stable
  • scrolling into view if needed
  • done scrolling
  • from
    subtree intercepts pointer events
  • retrying click action
  • element was detached from the DOM, retrying
    ```

Root cause

OverflowMenu.tsx (portal mode) registers a capture-phase scroll handler that calls setIsOpen(false) on the first scroll event. Playwright's auto-scroll-into-view fires a scroll before the click → menu closes → click coordinate now hits cardActions instead of the menu item.

Proposed fix

Make the close-on-scroll handler tolerant of incidental scrolls:

  • Option A (recommended): snapshot scroll offsets when the menu opens; only close if the absolute delta exceeds a small threshold (e.g., 5–10px). This filters out scroll-into-view jitter while still closing on real user scrolls.
  • Option B: debounce / defer the handler attachment by a short delay (e.g., 100–150ms after open) so that scroll-into-view triggered by initial focus / opening doesn't close the menu.

Add a unit test covering each scenario (tiny scroll under threshold ⇒ stays open; meaningful scroll ⇒ closes).

Acceptance criteria

  • OverflowMenu no longer closes on scroll deltas smaller than the chosen threshold.
  • e2e/tests/invoices/invoice-deposits.spec.ts:665 passes locally and in CI on the mobile project.
  • No regression in close-on-actual-scroll behavior (verified by unit test).
  • No regression on close-on-outside-click and close-on-resize.

Scope

  • client/src/components/OverflowMenu/OverflowMenu.tsx
  • client/src/components/OverflowMenu/OverflowMenu.test.tsx

Blocks

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions