import { useEffect , useRef , useState } from 'react' ; import { HoverTarget } from '../HoverVideoPlayer.types' ; param { HoverTarget } hoverTarget param { bool } disableDefaultEventHandling param { func } onHoverStart param { func } onHoverEnd returns { bool } export default function useIsHoveringOverVideo ( hoverTarget , disableDefaultEventHandling , onHoverStartCallback , onHoverEndCallback ) { const [ isHoveringOverVideo , setIsHoveringOverVideo ] = useState ( false ) ; const previousIsHoveringOverVideoRef = useRef ( isHoveringOverVideo ) ; useEffect ( ( ) => { if ( disableDefaultEventHandling ) return undefined ; let hoverEventTargetElement ; if ( typeof hoverTarget === 'function' ) { hoverEventTargetElement = hoverTarget ( ) ; } else if ( hoverTarget instanceof Node ) { hoverEventTargetElement = hoverTarget ; } else if ( hoverTarget . current ) { hoverEventTargetElement = hoverTarget . current ; } if ( ! hoverEventTargetElement || ! hoverEventTargetElement . addEventListener ) { console . error ( 'HoverVideoPlayer was unable to add event listeners to a hover target. Please check your usage of the `hoverTarget` prop.' ) ; return undefined ; } const onHoverStart = ( ) => setIsHoveringOverVideo ( true ) ; const onHoverEnd = ( ) => setIsHoveringOverVideo ( false ) ; hoverEventTargetElement . addEventListener ( 'mouseenter' , onHoverStart ) ; hoverEventTargetElement . addEventListener ( 'mouseleave' , onHoverEnd ) ; hoverEventTargetElement . addEventListener ( 'focus' , onHoverStart ) ; hoverEventTargetElement . addEventListener ( 'blur' , onHoverEnd ) ; const touchStartListenerOptions = { passive : true } ; hoverEventTargetElement . addEventListener ( 'touchstart' , onHoverStart , touchStartListenerOptions ) ; const onWindowTouchStart = ( event ) => { if ( ! ( event . target instanceof Node ) || ! hoverEventTargetElement . contains ( event . target ) ) { onHoverEnd ( ) ; } } ; window . addEventListener ( 'touchstart' , onWindowTouchStart , touchStartListenerOptions ) ; return ( ) => { hoverEventTargetElement . removeEventListener ( 'mouseenter' , onHoverStart ) ; hoverEventTargetElement . removeEventListener ( 'mouseleave' , onHoverEnd ) ; hoverEventTargetElement . removeEventListener ( 'focus' , onHoverStart ) ; hoverEventTargetElement . removeEventListener ( 'blur' , onHoverEnd ) ; hoverEventTargetElement . removeEventListener ( 'touchstart' , onHoverStart ) ; window . removeEventListener ( 'touchstart' , onWindowTouchStart ) ; } ; } , [ disableDefaultEventHandling , hoverTarget ] ) ; useEffect ( ( ) => { if ( previousIsHoveringOverVideoRef . current === isHoveringOverVideo ) return ; previousIsHoveringOverVideoRef . current = isHoveringOverVideo ; if ( isHoveringOverVideo && onHoverStartCallback != null ) { onHoverStartCallback ( ) ; } else if ( ! isHoveringOverVideo && onHoverEndCallback != null ) { onHoverEndCallback ( ) ; } } , [ isHoveringOverVideo , onHoverEndCallback , onHoverStartCallback ] ) ; return isHoveringOverVideo ; }