Skip to content

Commit 7066768

Browse files
fix(useAnimations): fix for animations hook (#1424)
1 parent 1df2188 commit 7066768

File tree

1 file changed

+32
-6
lines changed

1 file changed

+32
-6
lines changed

packages/react-components/src/hooks/useAnimations.ts

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,30 @@ export const useAnimations = ({
1818
const [isMounted, setIsMounted] = React.useState(isVisible);
1919
const [isOpen, setIsOpen] = React.useState(isVisible);
2020
const [shouldBeVisible, setShouldBeVisible] = React.useState(isVisible);
21+
const transitionTimeout = React.useRef<number | null>(null);
2122

22-
const handleTransitionEnd = () => setIsMounted(false);
23+
// Handle transition end, unmounting the element
24+
const handleTransitionEnd = () => {
25+
setIsMounted(false);
26+
if (transitionTimeout.current) {
27+
clearTimeout(transitionTimeout.current); // Clear fallback if transition completes
28+
}
29+
};
2330

24-
// The main part of the logic responsible for managing the states used to animate the container opening/closing and mounting/unmounting the container elements
31+
// Effect to add event listener for transitionend with a fallback timer
2532
React.useEffect(() => {
2633
const currentElement = elementRef.current;
2734

2835
if (!shouldBeVisible && currentElement) {
36+
// Set isOpen to false for closing animation
2937
currentElement.addEventListener('transitionend', handleTransitionEnd);
3038
setIsOpen(false);
3139

40+
// Fallback timer in case transitionend doesn’t fire due to sleep
41+
transitionTimeout.current = window.setTimeout(handleTransitionEnd, 300); // Adjust duration as needed
42+
3243
return () => {
44+
clearTimeout(transitionTimeout.current as number);
3345
currentElement.removeEventListener(
3446
'transitionend',
3547
handleTransitionEnd
@@ -39,13 +51,27 @@ export const useAnimations = ({
3951

4052
if (shouldBeVisible) {
4153
setIsMounted(true);
42-
requestAnimationFrame(() => setIsOpen(true));
43-
44-
return;
54+
requestAnimationFrame(() => setIsOpen(true)); // Trigger opening animation
4555
}
4656
}, [shouldBeVisible]);
4757

48-
// Additional logic, dedicated to the container wrapper whose visibility is managed by the context
58+
// Effect to listen for visibility changes (detecting sleep/wake scenarios)
59+
React.useEffect(() => {
60+
const handleVisibilityChange = () => {
61+
if (document.visibilityState === 'visible') {
62+
// Reset the animation state when returning to the visible state
63+
setShouldBeVisible(isVisible);
64+
}
65+
};
66+
67+
document.addEventListener('visibilitychange', handleVisibilityChange);
68+
69+
return () => {
70+
document.removeEventListener('visibilitychange', handleVisibilityChange);
71+
};
72+
}, [isVisible]);
73+
74+
// Synchronize shouldBeVisible with the isVisible prop
4975
React.useEffect(() => {
5076
setShouldBeVisible(isVisible);
5177
}, [isVisible]);

0 commit comments

Comments
 (0)