Repository navigation
[all components] Fix canceled exit unmount - #5401
Conversation
commit: |
Bundle size
PerformanceTotal duration: 991.64 ms -53.14 ms(-5.1%) | Renders: 78 (+0) | Paint: 1,524.47 ms -116.43 ms(-7.1%) No significant changes — details Check out the code infra dashboard for more information about this PR. |
✅ Deploy Preview for base-ui ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
@claude review |
PR reviewThe core change is right: the aborted-animation branch previously had no terminal state, so a canceled exit transition with no replacement animation left the cleanup callback permanently unfired (the stuck tooltip in #5395). Nothing here is merge-blocking, but the new terminal Bugs (2)1. 🟠 Stale viewport cleanup can now fire and abort an in-flight morphLocation: onAnimationsFinished(() => {
setPreviousContentNode(null);
setPreviousContentDimensions(null);
capturedNodeRef.current = null;
});All seven Before this diff a stale chain whose element had no live animations simply died in the empty-array branch. Now it calls Failure scenario: Fix: Thread an 2. 🟡
|
6bb0e94 to
e4acf09
Compare
|
Note GPT-5.6 finds this bug: |
…still unmount (#22338) TLDR: upgrades Base UI 1.5.0 → 1.7.0, which fixes the actual popup leak behind the double-scrollbar bug: a popup whose exit animation gets canceled by quick repeated interactions stayed mounted forever. --- ``` before quick hovers across tooltips → exit canceled → popup mounted forever at opacity 0 after canceled exit with no replacement animation still unmounts the popup ``` The double-scroll fix (#22329) contained the damage — a stale popup can no longer grow the page — but the popup that got stuck was an upstream bug, not tab-visibility timing as I first read it: base-ui's `useAnimationsFinished` had no terminal state when an exit animation was canceled without a replacement (mui/base-ui#5395, fixed by mui/base-ui#5401). 1.7.0 also keeps unpositioned popups at the viewport origin instead of stale absolute coordinates (mui/base-ui#5299) — upstream converging on the same conclusion as #22329. I reproduced the leak A/B in storybook (`Elements/Tooltip → AllSides`, synthetic rapid cross-trigger hovers, uninterrupted tab visibility, 16 canceled-exit cycles): ``` 1.5.0 2 tooltips left mounted after settle (data-open=false, opacity 0) 1.7.0 0 ``` ### Judgment call Two minor versions in one jump. The 1.6/1.7 changelogs are bug fixes only; the single rename (`OTPFieldPreview` → `OTPField`) touches nothing we import. Full playground-ui (2564) and factory-ui (996) suites plus both typechecks pass on 1.7.0. ### Not verified The A/B repro is manual (storybook + synthetic pointer events) — no automated regression test on our side. Upstream ships one with mui/base-ui#5401, and the DS `fixed` positioning default independently caps the blast radius if a future leak appears. ``` lockfile +41 -36 source +1 -1 changeset +5 0 ``` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## ELI5 This update uses a newer Base UI version. It prevents popups from staying invisible and stuck on screen after quick tooltip interactions. ## Changes - Upgraded `@base-ui/react` from `^1.5.0` to `^1.7.0`. - Added a patch changeset for `@mastra/playground-ui`. - Fixed interrupted popup exit animations that could leave popups mounted at zero opacity. - Prevented popups from reopening at stale absolute coordinates. ## Validation - Playground UI and factory UI test suites passed. - Typechecks passed. - Manual Storybook testing confirmed that rapid tooltip interactions leave no mounted popups. - No automated regression test was added. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Fixes #5395
Changes