Skip to content

[popups] Fix transform origin for start/end alignment#5015

Open
atomiks wants to merge 6 commits into
mui:masterfrom
atomiks:claude/sad-hertz-0bbe8c
Open

[popups] Fix transform origin for start/end alignment#5015
atomiks wants to merge 6 commits into
mui:masterfrom
atomiks:claude/sad-hertz-0bbe8c

Conversation

@atomiks

@atomiks atomiks commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Before: https://base-ui.com/react/components/combobox#input-inside-popup
After: https://deploy-preview-5015--base-ui.netlify.app/react/components/combobox#input-inside-popup

The transformOrigin middleware in useAnchorPositioning always derived the cross-axis origin from the arrow middleware data. Without an arrow element, a zero-size virtual arrow is used, which the arrow middleware centers against the anchor. That's correct for center alignment (the origin tracks the anchor's center even when the popup shifts), but for start/end the popup's edge is aligned with the anchor's edge, so the scale animation emanated from the anchor's center partway into the popup — and for an anchor wider than the popup, from a clamped point near the popup's far edge.

The cross-axis origin is now picked explicitly:

  • Arrow present → arrow's center (unchanged, regardless of alignment, since the arrow points at the anchor).
  • No arrow, center align → anchor's center via the virtual arrow (unchanged).
  • No arrow, unshifted start/end align → the popup's aligned edge: 0%/100%. Uses the rendered alignment and Floating UI's RTL platform info, so it stays correct after alignment flips and in RTL.
  • No arrow, shifted start/end align → anchor's center via the virtual arrow, since the popup edge no longer lines up with the anchor edge.

The middleware is also simplified: instead of a four-entry side map plus a separate overlap string, it computes one cross-axis and one side-axis coordinate (the anchor-overlap case for context menus is folded into the side coordinate) and joins them in axis order.

Added Chromium tests asserting the exact --transform-origin value for center/start/end alignment, RTL start/end alignment, shifted start alignment, horizontal sides, sideOffset, and the arrow-present case.

@atomiks atomiks added type: bug It doesn't behave as expected. scope: all components Widespread work has an impact on almost all components. labels Jun 11, 2026
@pkg-pr-new

pkg-pr-new Bot commented Jun 11, 2026

Copy link
Copy Markdown

commit: 50ce634

@code-infra-dashboard

code-infra-dashboard Bot commented Jun 11, 2026

Copy link
Copy Markdown

Bundle size

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

Details of bundle changes

Performance

Total duration: 1,186.40 ms +138.58 ms(+13.2%) | Renders: 50 (+0) | Paint: 1,794.69 ms +208.97 ms(+13.2%)

Test Duration Renders
Select mount (200 instances) 147.59 ms 🔺+28.59 ms(+24.0%) 3 (+0)
Menu open (500 items) 81.71 ms 🔺+21.76 ms(+36.3%) 12 (+0)
Mixed surface mount (app-like density) 82.24 ms 🔺+19.32 ms(+30.7%) 5 (+0)
Select open (500 options) 50.69 ms 🔺+11.16 ms(+28.2%) 14 (+0)

8 tests within noise — details


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

@netlify

netlify Bot commented Jun 11, 2026

Copy link
Copy Markdown

Deploy Preview for base-ui ready!

Name Link
🔨 Latest commit 50ce634
🔍 Latest deploy log https://app.netlify.com/projects/base-ui/deploys/6a2b59601462880008689917
😎 Deploy Preview https://deploy-preview-5015--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.

@atomiks atomiks force-pushed the claude/sad-hertz-0bbe8c branch 2 times, most recently from 37bdeb3 to cf30a2a Compare June 12, 2026 00:32
@atomiks atomiks force-pushed the claude/sad-hertz-0bbe8c branch from cf30a2a to 01641f2 Compare June 12, 2026 00:39
@atomiks atomiks marked this pull request as ready for review June 12, 2026 00:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: all components Widespread work has an impact on almost all components. type: bug It doesn't behave as expected.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant