Repository navigation
fix(core): let PlacementController clear its own inline styles - #6912
Conversation
- popover and menu left the inline top, left, translate, and --swc-placement-available-* styles on the closed surface, while tooltip removed them by hand, so the three close paths had drifted apart - add PlacementController.clearStyles() so the controller owns what it wrote; each component still decides when to call it, after its own close transition - fix comments that claimed stop() resets the inline translate
- closing popover or menu during its entrance cancels the entrance transition and starts the exit one in its place, and runAfterTransition treated that cancel as the end of the close - the after-close work then ran while the surface was still fading, and with the new style cleanup that snapped a visible surface to the corner - keep waiting on a transitioncancel while another transition still runs on the element
📚 Branch Preview Links🔍 Gen1 Visual Regression Test ResultsWhen a visual regression test fails (or has previously failed while working on this branch), its results can be found in the following URLs:
Deployed to Azure Blob Storage: If the changes are expected, update the |
|
miwha-adobe
left a comment
There was a problem hiding this comment.
LGTM! Nice separation between stopping positioning and clearing styles after the fade. Appreciate the safeguards for rapid reopen and the close-during-entrance tests.
Description
PlacementControllernow removes the inline position styles it writes, with a newclearStyles(), and each overlay decides when to call it. Popover and Menu now clean up after they close, like Tooltip already did. This also fixes closing a popover or menu during its entrance animation, which ended the close too early.What changed
PlacementController.clearStyles()removes only what the controller wrote in its last session:top,left,translate, and--swc-placement-available-*on the floating element, andtop,left, andtranslateon the tip. Other inline styles stay (Tooltip keeps--_swc-tooltip-animation-distance). It does nothing while positioning is active, so a late call can't move a surface that reopened, and it's safe to call more than once.clearPositioningState()callsclearStyles()instead of its ownremovePropertycalls. Same behavior._stopPositioningWhenClosed()callsclearStyles()afterstop(). It already runs after the close transition and bails if the surface reopened. Every open now starts unpositioned, like the first one, and the surface stays hidden until the first compute setsactual-placement.runAfterTransition(): atransitioncancelno longer counts as the end while another transition is still running on the element. Closing during the entrance cancels the entrance transition and starts the exit one, so the after-close work, includingswc-after-close, used to run mid-fade. With the new cleanup, that snapped a still-visible surface to the corner.stop()resets the inlinetranslate, and updated thestop()JSDoc andplacement-controller.mdx.actual-placementhandling is unchanged.Motivation and context
The three overlays had drifted: only Tooltip removed the controller's styles after closing, so a closed popover or menu kept its last position until the next open. Nothing visibly broke, but the list of styles to remove lived outside the controller that writes them. Now the controller owns it, and each component still picks the moment, since their close lifecycles differ.
Related issue(s)
Screenshots (if appropriate)
No visual change: the styles are removed only after the surface is hidden.
Author's checklist
Reviewer's checklist
patch,minor, ormajorfeaturesManual review test cases
Steps
Popover and Menu clear their inline position styles after closing
.swc-Popoverand.swc-Popover-tip(or.swc-Menu) in the shadow root have no inlinetop,left,translate, or--swc-placement-available-*. Reopening fades in at the trigger, with no flash in the corner.Closing during the entrance fades out in place
swc-after-closefires only after the fade ends.A rapid reopen keeps its position
Tooltip behaves as before
swc-tooltiphost and its.swc-Tooltip-tiphave no inline position styles, and the host keeps--_swc-tooltip-animation-distance.Device review
Accessibility testing checklist
Required: Complete each applicable item and document your testing steps (replace the placeholders with your component-specific instructions).
Keyboard (required — document steps below) — What to test for: Focus order is logical; Tab reaches the component and all interactive descendants; Enter/Space activate where appropriate; arrow keys work for tabs, menus, sliders, etc.; no focus traps; Escape dismisses when applicable; focus indicator is visible.
Steps
Screen reader (required — document steps below) — What to test for: Role and name are announced correctly; state changes (e.g. expanded, selected) are announced; labels and relationships are clear; no unnecessary or duplicate announcements.
Steps
Validation
The new tests failed before each fix and pass after it. The full Storybook suite passes locally (1252 tests), and CI passes, including the Firefox and WebKit jobs.
Commands and results
Run from
gen2/packages/swcunless noted. Local tests ran in Chromium.npx cem analyze --config cem.config.js: passednpx vitest --run --project storybook ../core/controllers/placement-controller/test/placement-controller.test.ts: failed before the controller change (host.controller.clearStyles is not a function), 18/18 passed afternpx vitest --run --project storybook components/popover/test/popover.test.ts components/menu/test/menu.test.ts components/tooltip/test/tooltip.test.ts: Popover and Menu failed before the fix (surface top is removed: expected '0px' to be ''), all passed afternpx vitest --run --project storybook ../core/utils/test/transition.test.ts components/popover/test/popover.test.ts components/menu/test/menu.test.ts -t "Transition Cancel Test|Close During Entrance Keeps Position Test": failed before therunAfterTransition()change (3 of 3 runs), passed after (5 of 5 runs)npx vitest --run --project storybook: 1252 passedyarn type-check:gen2,npx eslint, andnpx prettier --checkon the changed files (repo root): passedstyleattribute, skipping the custom properties, or dropping Tooltip'sclearStyles()call each fail a testCross-model review
gpt-6.1-solandgemini-4-argoneach reviewed the full diff twice. After one fix, both returned MERGE with no findings.Findings
gemini-4-argonreturned MERGE with no findings.gpt-6.1-solreturned DO NOT MERGE with one MAJOR: closing during the entrance ran the after-close teardown mid-fade (runAfterTransition()settled on the entrance'stransitioncancel), soclearStyles()snapped a visible popover or menu to the corner. Fixed in the second commit, with tests that failed first.gpt-6.1-solalso probed reopen, re-anchor, modal swap, and suppressed discrete-transition events in Chromium and WebKit. It couldn't launch Firefox, but the CI Firefox job passes.