Skip to content

[WC-3406]: Fix combobox menu jumping#2318

Draft
yordan-st wants to merge 8 commits into
mainfrom
fix/WC-3406-combobox-menu-floating-ui
Draft

[WC-3406]: Fix combobox menu jumping#2318
yordan-st wants to merge 8 commits into
mainfrom
fix/WC-3406-combobox-menu-floating-ui

Conversation

@yordan-st

@yordan-st yordan-st commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Pull request type

Bug fix (non-breaking change which fixes an issue)

Also includes:

  • Dependency change (@floating-ui/react added to combobox-web)
  • Test related change (new unit + E2E coverage for menu positioning)

Description

The Combobox dropdown menu jumped around while open. Near the bottom of the viewport
it flickered between rendering above and below the input, and changing the number of
visible options (e.g. by typing to filter) made it flip placement mid-interaction.

Root cause: menu positioning was hand-rolled in hooks/useMenuStyle.ts.
getMenuPosition() chose top-vs-bottom placement from the measured menu height, and that
same menuHeight was a dependency of the positioning effect — so placing the menu changed
its height, which re-ran the effect, which recomputed placement, which changed the height
again.

Fix: replace the hand-rolled logic with floating-ui via a new useFloatingMenu hook:

  • strategy: "fixed", placement: "bottom-start", whileElementsMounted: autoUpdate
  • middleware: offset(4)flip({ crossAxis: false, fallbackStrategy: "bestFit", padding: 8 })
    size({ padding: 8 }) — the size middleware sets the menu width to the input width and
    caps maxHeight to min(availableHeight, 320)
  • when space is tight the menu now shrinks and scrolls within the viewport instead of
    overflowing or flipping
  • alwaysOpen (keepMenuOpen) mode is unchanged — it renders inline (position: relative)
    and does not use floating positioning

Also: deleted useMenuStyle.ts, reworked the menu SCSS so the wrapper is a flex column and
the option list fills + scrolls inside the (possibly shrunk) wrapper, and made the
Single/Multi selection wiring consistent.

Known limitations (out of scope, documented in the OpenSpec change):

  • No React portal — with position: fixed, a transformed/filter/contain ancestor can
    still mis-anchor the menu (same as the old code, not a regression).
  • No shift middleware (menu width is pinned to the anchor, so horizontal overflow can't
    occur in practice).

What should be covered while testing?

Open the Combobox in the New Country popup (or any combobox), then:

  1. No jump — open it near the bottom of the viewport. The menu picks one placement
    (below by default, above only when there's genuinely no room) and stays there. It must
    NOT flicker between above and below.
  2. No jump on filter — with the menu open near the bottom, type to change the number of
    matching options. The menu re-anchors smoothly and must NOT flip above↔below as the
    option count changes.
  3. Shrink when tight — in a short viewport, the menu shrinks and the list scrolls
    internally; the menu bottom stays on screen (~8px from the edge) instead of overflowing.
  4. Header/footer — with a menu header (select-all) or footer configured, both stay fully
    visible when the menu shrinks; only the option list scrolls.
  5. Width — the menu width matches the input width.
  6. alwaysOpen regression — a combobox with a footer / custom static content (always-open
    mode) still renders inline in the document flow, not floating.
  7. General regressions — select, clear, multi-select boxes, lazy-load scrolling all behave
    as before.

@yordan-st yordan-st force-pushed the fix/WC-3406-combobox-menu-floating-ui branch from 4a0b45c to e05b04a Compare July 10, 2026 12:49
@yordan-st yordan-st changed the title [WC-3406]: Fix combobox menu jumping (migrate to floating-ui) [WC-3406]: Fix combobox menu jumping Jul 10, 2026
@yordan-st yordan-st force-pushed the fix/WC-3406-combobox-menu-floating-ui branch from e05b04a to 8443d61 Compare July 10, 2026 12:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant