@@ -18,18 +18,30 @@ export const useAnimations = ({
18
18
const [ isMounted , setIsMounted ] = React . useState ( isVisible ) ;
19
19
const [ isOpen , setIsOpen ] = React . useState ( isVisible ) ;
20
20
const [ shouldBeVisible , setShouldBeVisible ] = React . useState ( isVisible ) ;
21
+ const transitionTimeout = React . useRef < number | null > ( null ) ;
21
22
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
+ } ;
23
30
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
25
32
React . useEffect ( ( ) => {
26
33
const currentElement = elementRef . current ;
27
34
28
35
if ( ! shouldBeVisible && currentElement ) {
36
+ // Set isOpen to false for closing animation
29
37
currentElement . addEventListener ( 'transitionend' , handleTransitionEnd ) ;
30
38
setIsOpen ( false ) ;
31
39
40
+ // Fallback timer in case transitionend doesn’t fire due to sleep
41
+ transitionTimeout . current = window . setTimeout ( handleTransitionEnd , 300 ) ; // Adjust duration as needed
42
+
32
43
return ( ) => {
44
+ clearTimeout ( transitionTimeout . current as number ) ;
33
45
currentElement . removeEventListener (
34
46
'transitionend' ,
35
47
handleTransitionEnd
@@ -39,13 +51,27 @@ export const useAnimations = ({
39
51
40
52
if ( shouldBeVisible ) {
41
53
setIsMounted ( true ) ;
42
- requestAnimationFrame ( ( ) => setIsOpen ( true ) ) ;
43
-
44
- return ;
54
+ requestAnimationFrame ( ( ) => setIsOpen ( true ) ) ; // Trigger opening animation
45
55
}
46
56
} , [ shouldBeVisible ] ) ;
47
57
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
49
75
React . useEffect ( ( ) => {
50
76
setShouldBeVisible ( isVisible ) ;
51
77
} , [ isVisible ] ) ;
0 commit comments