()
| 3 | export const MODAL_EXIT_ANIMATION_MS = 150; |
| 4 | |
| 5 | export function useDeferredModalOpen() { |
| 6 | const frameRef = React.useRef<number | null>(null); |
| 7 | const timeoutRef = React.useRef<number | null>(null); |
| 8 | |
| 9 | const cancelDeferredModalOpen = React.useCallback(() => { |
| 10 | if (frameRef.current !== null) { |
| 11 | window.cancelAnimationFrame(frameRef.current); |
| 12 | frameRef.current = null; |
| 13 | } |
| 14 | |
| 15 | if (timeoutRef.current !== null) { |
| 16 | window.clearTimeout(timeoutRef.current); |
| 17 | timeoutRef.current = null; |
| 18 | } |
| 19 | }, []); |
| 20 | |
| 21 | const openNextFrame = React.useCallback( |
| 22 | (open: () => void) => { |
| 23 | cancelDeferredModalOpen(); |
| 24 | frameRef.current = window.requestAnimationFrame(() => { |
| 25 | frameRef.current = null; |
| 26 | open(); |
| 27 | }); |
| 28 | }, |
| 29 | [cancelDeferredModalOpen], |
| 30 | ); |
| 31 | |
| 32 | const openAfterExit = React.useCallback( |
| 33 | (open: () => void) => { |
| 34 | cancelDeferredModalOpen(); |
| 35 | timeoutRef.current = window.setTimeout(() => { |
| 36 | timeoutRef.current = null; |
| 37 | openNextFrame(open); |
| 38 | }, MODAL_EXIT_ANIMATION_MS); |
| 39 | }, |
| 40 | [cancelDeferredModalOpen, openNextFrame], |
| 41 | ); |
| 42 | |
| 43 | React.useEffect(() => cancelDeferredModalOpen, [cancelDeferredModalOpen]); |
| 44 | |
| 45 | return { |
| 46 | cancelDeferredModalOpen, |
| 47 | openAfterExit, |
| 48 | openNextFrame, |
| 49 | }; |
| 50 | } |
no outgoing calls
no test coverage detected