Summary
use_animated_open (in primitives/src/lib.rs) waits for in-flight CSS animations/transitions to finish before removing a closed element from the DOM, via:
const id = await dioxus.recv();
const element = document.getElementById(id);
if (element && element.getAnimations().length > 0) {
Promise.all(element.getAnimations().map((animation) => animation.finished)).then(() => {
dioxus.send(true);
});
} else {
dioxus.send(true);
}
If the element (or its animations) gets removed/canceled before the animation finishes naturally, each canceled animation's .finished promise rejects with a DOMException (AbortError: The user aborted a request.) instead of resolving. Since Promise.all(...).then(...) has no .catch(), this surfaces as an uncaught, unhandled promise rejection in the browser console:
Uncaught (in promise) AbortError: The user aborted a request.
at eval (eval:8)
at eval (eval:16)
Repro
Any DropdownMenu (or other component built on use_animated_open) where the content element has a CSS transition (not even a keyframe animation — a plain transition: opacity 0.2s ease, transform 0.2s ease is enough, since CSS Transitions are also returned by Element.getAnimations()) will hit this if the element is unmounted/removed from the DOM while the close transition is still in flight — e.g. navigating away via a DropdownMenuItem's on_select handler immediately after the menu closes.
Confirmed via Chrome DevTools Protocol (Runtime.exceptionThrown + Debugger.getScriptSource) that the exception originates exactly at the animation.finished access inside this eval script.
Suggested fix
Add a .catch() (or per-animation .catch(() => {})) around the Promise.all(...) so a canceled animation doesn't produce an unhandled rejection, e.g.:
Promise.all(element.getAnimations().map((animation) => animation.finished.catch(() => {}))).then(() => {
dioxus.send(true);
});
Workaround (in our app)
We worked around it at the CSS layer by setting animation: none !important; transition: none !important; on the dropdown content elements we control, which prevents getAnimations() from ever returning anything and avoids the Promise.all branch entirely. This isn't a real fix for consumers who rely on the open/close animation, though.
Environment
dioxus / dioxus-primitives 0.7.9 (git dependency, commit bf007c1)
- Chrome (Playwright-driven, headless)
Summary
use_animated_open(inprimitives/src/lib.rs) waits for in-flight CSS animations/transitions to finish before removing a closed element from the DOM, via:If the element (or its animations) gets removed/canceled before the animation finishes naturally, each canceled animation's
.finishedpromise rejects with aDOMException(AbortError: The user aborted a request.) instead of resolving. SincePromise.all(...).then(...)has no.catch(), this surfaces as an uncaught, unhandled promise rejection in the browser console:Repro
Any
DropdownMenu(or other component built onuse_animated_open) where the content element has a CSStransition(not even a keyframeanimation— a plaintransition: opacity 0.2s ease, transform 0.2s easeis enough, since CSS Transitions are also returned byElement.getAnimations()) will hit this if the element is unmounted/removed from the DOM while the close transition is still in flight — e.g. navigating away via aDropdownMenuItem'son_selecthandler immediately after the menu closes.Confirmed via Chrome DevTools Protocol (
Runtime.exceptionThrown+Debugger.getScriptSource) that the exception originates exactly at theanimation.finishedaccess inside this eval script.Suggested fix
Add a
.catch()(or per-animation.catch(() => {})) around thePromise.all(...)so a canceled animation doesn't produce an unhandled rejection, e.g.:Workaround (in our app)
We worked around it at the CSS layer by setting
animation: none !important; transition: none !important;on the dropdown content elements we control, which preventsgetAnimations()from ever returning anything and avoids thePromise.allbranch entirely. This isn't a real fix for consumers who rely on the open/close animation, though.Environment
dioxus/dioxus-primitives0.7.9 (git dependency, commitbf007c1)