You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Browse filesBrowse the repository at this point in the historyBrowse files
authored
[Bug Fix] Overlays: play the exit animation before hiding (#506)
* [Bug Fix] Popover, HoverCard, ContextMenu: play the exit animation before hiding
All three set data-state="closed" and add `hidden` (display: none) in the
same frame, so data-[state=closed]:animate-out never gets one. Defer
`hidden` to animationend/animationcancel, and add fill-mode-forwards so
the last frame holds until it lands.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Only settle on the exit animation, and settle on disconnect
Closing while the opening animation runs cancels `enter`, and that
animationcancel reached the handler as if the exit had finished. Capture
the exit animation-name when arming and ignore events from any other run.
disconnect() left the handlers attached, unlike every other listener in
these controllers; ContextMenu's disconnect armed them on an element it
was about to drop. It now applies the pending hide instead.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Match the exit run against every computed animation name
animation-name is comma-separated when the content carries more than one
animation, while each event names a single run, so the equality check
rejected them all and the element never hid.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Settle the exit on getAnimations(), and keep disconnect from failing
getComputedStyle reports an element's own `display` and still resolves
`animation-name: exit` under a display:none ancestor, so the guard armed
a listener for an animation with no box to run in, and `hidden` never
landed. getAnimations() returns nothing for that element — as it does
for `animation: none` and for an element already hidden — so all of
those settle synchronously.
HoverCard's disconnect() started with removeEventListeners(), which
resolves both targets unguarded; once one is gone, Stimulus swallows the
throw and the settle at the end never runs. Release what is held outside
the element first, guard each target on its own, and apply the same
order to hide(), which runs from a timer. ContextMenu's hide() touched
the content target before releasing its document listeners, and
disconnect() goes through it — same reorder.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Play the exit animation in every overlay with animate-out
DropdownMenu, ClipboardPopover, Select, Sheet and CommandDialog all
carried data-[state=closed]:animate-out and cut it the same way: `hidden`
or element.remove() in the frame the state changed. DropdownMenu,
Clipboard and Select never set data-state at all, and Select keyed its
exit on the root's open value instead.
The settle block now takes the animated element and hands the outcome to
a per-controller afterExit(): `hidden` on the wrapper for the floating
overlays, element.remove() for Sheet and CommandDialog. The animated
element is an explicit `panel` target (plus `backdrop` where there is
one), and the captured exit names live in a WeakMap per element because
Clipboard can run two exits at once. The block itself is byte-identical
in all eight controllers.
DropdownMenu#toggle reads openValue, since `hidden` now lands after the
exit and no longer tells the states apart; its z-index is released on
settle so the menu fades above its siblings. CommandDialog reopened while
dismissing brings the same instance back through show() rather than
stacking a second one. Clipboard's empty-source branch called a method
that did not exist (showErrorPopover) — fixed while restructuring it.
Every affected content component gets data-[state=closed]:fill-mode-forwards
so the last frame holds until the hide lands, with a rendering test each.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* chore(mcp): rebuild registry.json for the overlay exit-animation changes
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Djalma Araújo <djalma@nossomos.cc>
0 commit comments