Skip to content

Commit 49e599e

Browse files
committed
fix(Presence): handle escape characters in animation names correctly
Fixes radix-ui#2763. Using [CSS.escape](https://developer.mozilla.org/en-US/docs/Web/API/CSS/escape_static_method). As I checked, this API is supported in all browsers even in the [2022 browserslist targets](radix-ui#1019 (comment)) of this project. Further explanation of the bug: `getComputedStyle()` returns a `CSSStyleDeclaration`, which is serialized according to the spec. Meanwhile, the values from `AnimationEvent` are not required to be serialized (which makes sense, as it's intended for JavaScript usage, where escaping for CSS syntax is unnecessary). Therefore the `animationName` is returned as-is in the event handler, causing the mismatch.
1 parent f61d68e commit 49e599e

File tree

2 files changed

+8
-1
lines changed

2 files changed

+8
-1
lines changed

.changeset/nasty-pandas-float.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@radix-ui/react-presence': patch
3+
---
4+
5+
Handle the animationend event correctly when keyframe has escapable characters. Fixes #2763.

packages/react/presence/src/presence.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ function usePresence(present: boolean) {
100100
*/
101101
const handleAnimationEnd = (event: AnimationEvent) => {
102102
const currentAnimationName = getAnimationName(stylesRef.current);
103-
const isCurrentAnimation = currentAnimationName.includes(event.animationName);
103+
// The event.animationName is unescaped for CSS syntax,
104+
// so we need to escape it to compare with the animationName computed from the style.
105+
const isCurrentAnimation = currentAnimationName.includes(CSS.escape(event.animationName));
104106
if (event.target === node && isCurrentAnimation) {
105107
// With React 18 concurrency this update is applied a frame after the
106108
// animation ends, creating a flash of visible content. By setting the

0 commit comments

Comments
 (0)