import { observable } from 'mobx' ; import { useEffect , useState } from 'react' ; import { throttle } from '@cloudbeaver/core-utils' ; import { useObjectRef } from './useObjectRef' ; import { useObservableRef } from './useObservableRef' ; interface IOptions { onMouseEnter ? : ( event : MouseEvent ) => void ; onMouseLeave ? : ( event : MouseEvent ) => void ; } interface IState { mouseEnter : boolean ; } export interface IMouseHook < T > { state : IState ; ref : T | null ; reference : ( obj : T ) => void ; } export function useMouse < T extends HTMLElement > ( options = { } ) { const handlersRef = useObjectRef ( options ) ; const [ reference , setReference ] = useState < T | null > ( null ) ; const state = useObservableRef ( ( ) => ( { mouseEnter : false , } ) , { mouseEnter : observable . ref , } , false , 'useMouse' ) ; useEffect ( ( ) => { state . mouseEnter = false ; if ( ! reference ) { return ; } const mouseOverHandler = throttle ( ( event ) => { if ( handlersRef . onMouseEnter ) { handlersRef . onMouseEnter ( event ) ; } if ( ! state . mouseEnter ) { state . mouseEnter = true ; } } , 33 ) ; const mouseOutHandler = throttle ( ( event ) => { if ( handlersRef . onMouseLeave ) { handlersRef . onMouseLeave ( event ) ; } if ( state . mouseEnter ) { state . mouseEnter = false ; } } , 40 ) ; reference . addEventListener ( 'mouseenter' , mouseOverHandler ) ; reference . addEventListener ( 'mouseleave' , mouseOutHandler ) ; return ( ) => { reference . removeEventListener ( 'mouseenter' , mouseOverHandler ) ; reference . removeEventListener ( 'mouseleave' , mouseOutHandler ) ; } ; } , [ reference ] ) ; return { ref : reference , state , reference : setReference } ; }