Skip to content

[preview card] Keep inline preview anchored while open#4836

Merged
atomiks merged 2 commits into
mui:masterfrom
atomiks:codex/fix-preview-card-inline-reentry
May 22, 2026
Merged

[preview card] Keep inline preview anchored while open#4836
atomiks merged 2 commits into
mui:masterfrom
atomiks:codex/fix-preview-card-inline-reentry

Conversation

@atomiks
Copy link
Copy Markdown
Contributor

@atomiks atomiks commented May 18, 2026

The React Compiler browser CI exposed a multiline Preview Card test that expected the popup to move to a newly entered line while it was already open. Keeping the opened anchor stable is less disorienting; a new line is only used when opening or reopening.

https://deploy-preview-4836--base-ui.netlify.app/experiments/inline-positioning

With delay enabled, it won't choose a new rect while open. Matches Wikipedia

Root cause

Inline hover coordinates were refreshed on same-trigger mouseenter while open, so incidental positioning updates could make the popup jump.

Changes

  • Keep stored inline coordinates unchanged while the preview card is open.
  • Update the multiline trigger test to assert stable positioning while open.

@atomiks atomiks added type: bug It doesn't behave as expected. component: preview card Changes related to the preview card component. labels May 18, 2026
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 18, 2026

commit: 4a86709

@code-infra-dashboard
Copy link
Copy Markdown

code-infra-dashboard Bot commented May 18, 2026

Bundle size

Bundle Parsed size Gzip size
@base-ui/react 0B(0.00%) 🔺+1B(0.00%)

Details of bundle changes

Performance

Total duration: 1,068.25 ms -104.27 ms(-8.9%) | Renders: 50 (+0) | Paint: 1,635.05 ms -192.39 ms(-10.5%)

No significant changes — details


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

@netlify
Copy link
Copy Markdown

netlify Bot commented May 18, 2026

Deploy Preview for base-ui ready!

Name Link
🔨 Latest commit 4a86709
🔍 Latest deploy log https://app.netlify.com/projects/base-ui/deploys/6a1013b7babfe000091480f6
😎 Deploy Preview https://deploy-preview-4836--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 codex/fix-preview-card-inline-reentry branch 3 times, most recently from fcd013a to 46c82ca Compare May 18, 2026 06:18
@atomiks atomiks changed the title [preview card] Fix inline re-entry positioning [preview card] Keep inline preview anchored while open May 18, 2026
@atomiks atomiks marked this pull request as ready for review May 18, 2026 06:23
@michaldudak
Copy link
Copy Markdown
Member

Codex Review (GPT-5.5)

I reviewed PR 4836 as a bug-fix against freshly fetched upstream/master. The implementation change is narrowly scoped and matches the stated root cause, but one updated browser regression test does not actually guard the old user-facing failure.

1. Bugs / Issues

1. 🟡 Browser regression test still false-passes against the old behavior (non-blocking)

packages/react/src/preview-card/positioner/PreviewCardPositioner.test.tsx

await user.pointer([
  { target: document.body },
  {
    target: trigger,
    coords: {
      clientX: secondLineRect.left + secondLineRect.width / 2,
      clientY: secondLineRect.top + secondLineRect.height / 2,
    },
  },
]);

expectWithin(positioner.getBoundingClientRect().y, firstLineRect.bottom + 5);

The old implementation updates inlineRectCoordsRef on same-trigger mouseenter, but the visible jump only appears after a later positioning update. I verified the PR’s updated browser test still passes when paired with the old inlineRect.ts behavior, while the helper-level inlineRect test fails as expected. That means the browser test can pass before the regression has a chance to manifest.

Fix: After entering the second line, force or wait for the same positioning update path that exposed the jump, then assert the position still tracks firstLineRect.

Root Cause & Patch Assessment

The code change itself is sound: onMouseEnter now uses the same “only while closed” guard as onMouseMove, so the opened trigger’s captured inline rect remains stable. Passing isOpenedByThisTrigger rather than global open state also preserves trigger switching and close-transition re-entry behavior.

Test Coverage Assessment

I ran:

pnpm test:jsdom inlineRect --no-watch
pnpm test:chromium PreviewCardPositioner --no-watch

Both passed on the PR branch. I also checked regression sensitivity against the old implementation: the updated helper test fails as expected, but the updated browser test still passes, which is the coverage gap above.

Recommendation

Approve after nits are addressed 🟡

The runtime fix looks correct, and the helper regression coverage is meaningful. I’d tighten the browser test before merging so the user-facing Preview Card behavior is protected too.

@atomiks atomiks force-pushed the codex/fix-preview-card-inline-reentry branch from 46c82ca to a39b08a Compare May 18, 2026 08:56
@atomiks atomiks added test type: bug It doesn't behave as expected. and removed type: bug It doesn't behave as expected. labels May 22, 2026
Copy link
Copy Markdown
Contributor Author

atomiks commented May 22, 2026

Code Review (GPT-5.5)

Approve ✅ because the inline-rect change matches the intended stable-open behavior, keeps reopen/new-trigger paths intact, and the targeted regression coverage passes.

1. Bugs / Issues (None)

Root Cause & Patch Assessment

The fix is appropriately narrow: getInlineRectTriggerProps now gates both React onMouseEnter and onMouseMove coordinate refreshes while that trigger is already open, so incidental same-trigger re-entry no longer moves the popup to a different wrapped line.

The existing native updateInlineRectCoords path remains available for hover-open handling, and other triggers can still capture coordinates because isOpenedByThisTrigger is scoped per trigger.

Test Coverage Assessment

Validated against a freshly fetched upstream/master diff.

Ran:

pnpm test:jsdom inlineRect --no-watch
pnpm test:chromium PreviewCardPositioner --no-watch

Both passed. I did not separately execute the updated regression test against base-only source, but by inspection the previous onMouseEnter: updateCoords path is the behavior this test now guards against.

@atomiks atomiks merged commit 2b1d635 into mui:master May 22, 2026
26 checks passed
@atomiks atomiks deleted the codex/fix-preview-card-inline-reentry branch May 22, 2026 08:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants