Skip to content

[select][popover] Fix nested Select requiring extra outside clicks to dismiss parent#4820

Merged
atomiks merged 7 commits into
mui:masterfrom
mattrothenberg:mrothenberg/repro-nested-popover-select-dismiss
May 14, 2026
Merged

[select][popover] Fix nested Select requiring extra outside clicks to dismiss parent#4820
atomiks merged 7 commits into
mui:masterfrom
mattrothenberg:mrothenberg/repro-nested-popover-select-dismiss

Conversation

@mattrothenberg
Copy link
Copy Markdown
Contributor

@mattrothenberg mattrothenberg commented May 13, 2026

Summary

Fixes nested Select/Popover dismissal paths where a parent Popover could require extra outside presses after Select interactions.

The final fix is intentionally small:

  • Select.Root now uses useDismiss(floatingContext) defaults instead of hardcoding bubbles: false. This keeps Escape isolated while allowing outside-press dismissal to cascade like other popup components.
  • useDismiss clears leftover drag-out suppression when a new press begins outside the floating element and its trigger, so stale suppression from a previous Select interaction cannot consume the next real outside click.

Details

Popover uses intentional mouse outside-press handling. In nested popup flows, an earlier interaction can leave suppressNextOutsideClickRef set even though the next press is a fresh outside dismissal attempt. The guard clears that stale suppression on the new outside pointerdown/mousedown; it does not clear suppression for the eventual click, so legitimate inside-to-outside drag suppression is preserved.

Removing Select's explicit bubbles: false relies on normalizeProp(undefined) defaults: escapeKey remains non-bubbling and outsidePress can bubble.

Tests

Added Chromium coverage for Select inside Popover dismissal:

  • reopened aligned Select dismisses the Popover with one outside press
  • selected/reopened Select dismisses the Popover with one outside press
  • modal Popover stays open when choosing a non-modal aligned Select item
  • Escape from a non-modal Select does not bubble to the Popover
  • drag from a modal Select trigger outside all popups does not consume the next outside press

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 13, 2026

commit: b1c20b3

@code-infra-dashboard
Copy link
Copy Markdown

code-infra-dashboard Bot commented May 13, 2026

Bundle size

Bundle Parsed size Gzip size
@base-ui/react 🔺+37B(+0.01%) 🔺+8B(+0.01%)

Details of bundle changes

Performance

Total duration: 1,159.02 ms -271.55 ms(-19.0%) | Renders: 50 (+0) | Paint: 1,771.61 ms -420.93 ms(-19.2%)

Test Duration Renders
Slider mount (300 instances) 163.98 ms ▼-43.23 ms(-20.9%) 3 (+0)
Menu mount (300 instances) 122.25 ms ▼-36.42 ms(-23.0%) 2 (+0)
Select mount (200 instances) 124.97 ms ▼-32.40 ms(-20.6%) 3 (+0)
Scroll Area mount (300 instances) 88.26 ms ▼-28.50 ms(-24.4%) 3 (+0)
Menu open (500 items) 68.63 ms ▼-19.52 ms(-22.1%) 12 (+0)

…and 1 more (+6 within noise) — details


Check out the code infra dashboard for more information about this PR.

@netlify
Copy link
Copy Markdown

netlify Bot commented May 13, 2026

Deploy Preview for base-ui ready!

Name Link
🔨 Latest commit b1c20b3
🔍 Latest deploy log https://app.netlify.com/projects/base-ui/deploys/6a0598ef8005ae0008e55971
😎 Deploy Preview https://deploy-preview-4820--base-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@mattrothenberg mattrothenberg force-pushed the mrothenberg/repro-nested-popover-select-dismiss branch from 4479439 to eee9152 Compare May 13, 2026 20:11
@atomiks atomiks added component: select Changes related to the select component. type: bug It doesn't behave as expected. labels May 14, 2026
@atomiks atomiks force-pushed the mrothenberg/repro-nested-popover-select-dismiss branch from 5496d98 to 0da72f1 Compare May 14, 2026 05:05
mattrothenberg and others added 6 commits May 14, 2026 18:58
Adds a minimal demo under popover/demos/nested-select-dismiss/ that
reproduces a dismissal bug: a Popover containing a Select requires two
outside clicks to dismiss instead of one. The Select dropdown does not
need to be opened — its mere presence inside the Popup is enough.

Not for upstream — drafted to validate the repro locally before
filing an issue.
… dismiss parent

When a Select is rendered inside a Popover, dismissing the Popover via
outside click requires extra clicks instead of one. Two independent
issues contribute:

1. Select hardcodes `bubbles: false` in its `useDismiss` config,
   which prevents the parent Popover's dismiss from firing while the
   Select is open. Changed to `bubbles: !modal` so non-modal Selects
   (the correct API for nesting inside another popup) allow the parent
   to dismiss.

2. `handlePressEndCapture` in `useDismiss` falsely detects a
   drag-from-inside-to-outside when the user clicks a nested popup
   trigger that opens on mousedown (Select uses
   `useClick({ event: 'mousedown' })`). The pointerup lands on the
   nested popup's portal, which is outside the parent's DOM and not a
   registered FloatingTree child. Added a guard that checks whether
   the pointerup target is inside any open popup via
   `[data-open]` / `[data-popup-open]` before triggering drag-out
   suppression.
@atomiks atomiks force-pushed the mrothenberg/repro-nested-popover-select-dismiss branch from a166e40 to efde047 Compare May 14, 2026 08:58
@atomiks
Copy link
Copy Markdown
Contributor

atomiks commented May 14, 2026

Coudn't get an automated failing test for:

  • Open Popover
  • Open Select
  • Click outside both (force-click, not soft-tap) requiring 3 clicks instead of 2 (or 1 depending on if the popups both close simultaneously which depends on the pointer flow.)

But I manually verified that it works now in browser, with regular dismiss and drag dismiss flows

Before: https://stackblitz.com/edit/emel6xue
After: https://stackblitz.com/edit/emel6xue-thchawh7

@atomiks atomiks force-pushed the mrothenberg/repro-nested-popover-select-dismiss branch from efde047 to b1c20b3 Compare May 14, 2026 09:42
@atomiks atomiks merged commit df31ec8 into mui:master May 14, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: select Changes related to the select component. type: bug It doesn't behave as expected.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants