diff --git a/src/components/ui/Transition.tsx b/src/components/ui/Transition.tsx index 4f90ee4a0..1eb8e16e0 100644 --- a/src/components/ui/Transition.tsx +++ b/src/components/ui/Transition.tsx @@ -38,6 +38,7 @@ export type TransitionProps = { const classNames = { active: 'Transition__slide--active', }; +const FALLBACK_ANIMATION_END = 1000; const Transition: FC = ({ ref, @@ -211,7 +212,7 @@ const Transition: FC = ({ : childNodes[activeIndex]; if (watchedNode) { - waitForAnimationEnd(watchedNode, onAnimationEnd); + waitForAnimationEnd(watchedNode, onAnimationEnd, undefined, FALLBACK_ANIMATION_END); } else { onAnimationEnd(); } diff --git a/src/util/cssAnimationEndListeners.ts b/src/util/cssAnimationEndListeners.ts index 23fe51471..bd89eb15b 100644 --- a/src/util/cssAnimationEndListeners.ts +++ b/src/util/cssAnimationEndListeners.ts @@ -1,12 +1,16 @@ // Sometimes event is fired earlier than animation completes const ANIMATION_END_DELAY = 50; -export function waitForTransitionEnd(node: Node, handler: NoneToVoidFunction, propertyName?: string) { - waitForEndEvent('transitionend', node, handler, propertyName); +export function waitForTransitionEnd( + node: Node, handler: NoneToVoidFunction, propertyName?: string, fallbackMs?: number, +) { + waitForEndEvent('transitionend', node, handler, propertyName, fallbackMs); } -export function waitForAnimationEnd(node: Node, handler: NoneToVoidFunction, animationName?: string) { - waitForEndEvent('animationend', node, handler, animationName); +export function waitForAnimationEnd( + node: Node, handler: NoneToVoidFunction, animationName?: string, fallbackMs?: number, +) { + waitForEndEvent('animationend', node, handler, animationName, fallbackMs); } function waitForEndEvent( @@ -14,10 +18,11 @@ function waitForEndEvent( node: Node, handler: NoneToVoidFunction, detailedName?: string, + fallbackMs?: number, ) { let isHandled = false; - node.addEventListener(eventType, function handleAnimationEnd(e: TransitionEvent | AnimationEvent) { + function handleAnimationEnd(e: TransitionEvent | AnimationEvent | Event) { if (isHandled || e.target !== e.currentTarget) { return; } @@ -31,10 +36,22 @@ function waitForEndEvent( isHandled = true; - node.removeEventListener(eventType, handleAnimationEnd as EventListener); + node.removeEventListener(eventType, handleAnimationEnd); setTimeout(() => { handler(); }, ANIMATION_END_DELAY); - } as EventListener); + } + + node.addEventListener(eventType, handleAnimationEnd); + + if (fallbackMs) { + setTimeout(() => { + if (isHandled) return; + + node.removeEventListener(eventType, handleAnimationEnd); + + handler(); + }, fallbackMs); + } }