Skip to content

[tabs] Fix indicator positioning inside transformed wrappers - #5601

Draft
atomiks wants to merge 1 commit into
mui:masterfrom
atomiks:tabs-indicator-wrapper-transforms
Draft

[tabs] Fix indicator positioning inside transformed wrappers#5601
atomiks wants to merge 1 commit into
mui:masterfrom
atomiks:tabs-indicator-wrapper-transforms

Conversation

@atomiks

@atomiks atomiks commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

The indicator only compensated for the active tab's own translation. A translated wrapper between the tab and the list (a common shape for per-tab motion wrappers) made the rect and layout offsets disagree, so the indicator fell back to the tab's static layout slot and ignored the motion. The prehydration script had the same blind spot and painted at the wrong position before hydration moved it.

Changes

  • Replaced the tab-local translation measurement (getActiveTabTranslation/resolveTranslateLength) with hasDistortingTransform, which walks the ancestor chain and keeps the precise rect-based offset unless it finds a transform the rect math cannot undo: rotation, skew, flip, perspective, or a scale not shared with the list. Pure translations anywhere in the chain now work, including calc() values in the translate longhand, which the old parser gave up on.
  • Scale at or above the list stays allowed because the existing scaleX/scaleY division already cancels it. Tab-local scale falls back to layout offsets, which keeps the indicator centered on the tab's slot.
  • The untransformed common case still takes the rect≈layout fast path with zero getComputedStyle reads. The walk only runs when the offsets disagree.
  • Environments without DOMMatrixReadOnly (jsdom) fall back to layout offsets.
  • The prehydration script now checks every element between the tab and the list for transforms, not just the tab, and skips the pre-hydration paint when it finds one.

@atomiks atomiks added component: tabs Changes related to the tabs component. type: bug It doesn't behave as expected. labels Aug 31, 2026
@pkg-pr-new

pkg-pr-new Bot commented Aug 31, 2026

Copy link
Copy Markdown

commit: c4f79ad

@code-infra-dashboard

code-infra-dashboard Bot commented Aug 31, 2026

Copy link
Copy Markdown

Bundle size

Bundle Parsed size Gzip size
@base-ui/react 🔺+264B(+0.06%) 🔺+116B(+0.08%)

Details of bundle changes

Performance

Total duration: 967.04 ms -81.29 ms(-7.8%) | Renders: 76 (+0) | Paint: 1,555.21 ms -127.94 ms(-7.6%)

Test Duration Renders
Dialog mount (300 instances) 21.46 ms ▼-6.09 ms(-22.1%) 1 (+0)

14 tests within noise — details


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

@netlify

netlify Bot commented Aug 31, 2026

Copy link
Copy Markdown

Deploy Preview for base-ui ready!

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

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

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant