packageDocumentation module import * as React from "react" ; import { hasPointerEventsSupport } from "../../base/PointerEvents" ; import { Timer } from "../Timer" ; public export type OutsideClickEvent = PointerEvent | MouseEvent | TouchEvent ; public export function useOnOutsideClick < T extends Element > ( onOutsideClick ? , /** Invoked for intermediate events. Return `false` to prevent outside click. */ outsideEventPredicate ? ) { const handleMouseEvents = React . useRef ( true ) ; const handleMouseEventsTimer = React . useRef ( new Timer ( 1000 ) ) ; const ref = React . useRef < T > ( null ) ; const isDownOutside = React . useRef ( false ) ; React . useEffect ( ( ) => { const listener = ( e ) => { if ( e . type === "touchstart" ) { handleMouseEvents . current = false ; handleMouseEventsTimer . current . start ( ) ; } else if ( e . type === "mousedown" && ! handleMouseEvents . current ) { return ; } const isOutsideEvent = ! outsideEventPredicate || outsideEventPredicate ( e ) ; isDownOutside . current = ( ! ! ref . current && ( e . target instanceof Node ) && ! ref . current . contains ( e . target ) ) && isOutsideEvent ; } ; if ( hasPointerEventsSupport ( ) ) { document . addEventListener ( "pointerdown" , listener ) ; } else { document . addEventListener ( "mousedown" , listener ) ; document . addEventListener ( "touchstart" , listener ) ; } return ( ) => { if ( hasPointerEventsSupport ( ) ) { document . removeEventListener ( "pointerdown" , listener ) ; } else { document . removeEventListener ( "mousedown" , listener ) ; document . removeEventListener ( "touchstart" , listener ) ; } } ; } , [ outsideEventPredicate ] ) ; React . useEffect ( ( ) => { const listener = ( e ) => { if ( e . type === "mouseup" && ! handleMouseEvents . current ) { return ; } onOutsideClick && isDownOutside . current && ( ! outsideEventPredicate || outsideEventPredicate ( e ) ) && ref . current && e . target instanceof Node && ! ref . current . contains ( e . target ) && onOutsideClick ( ) ; isDownOutside . current = false ; } ; if ( hasPointerEventsSupport ( ) ) { document . addEventListener ( "pointerup" , listener ) ; } else { document . addEventListener ( "mouseup" , listener ) ; document . addEventListener ( "touchend" , listener ) ; } return ( ) => { if ( hasPointerEventsSupport ( ) ) { document . removeEventListener ( "pointerup" , listener ) ; } else { document . removeEventListener ( "mouseup" , listener ) ; document . removeEventListener ( "touchend" , listener ) ; } } ; } , [ onOutsideClick , outsideEventPredicate ] ) ; React . useEffect ( ( ) => { const listener = ( ) => { handleMouseEvents . current = true ; } ; const timer = handleMouseEventsTimer . current ; timer . setOnExecute ( listener ) ; return ( ) => { timer . setOnExecute ( undefined ) ; } ; } , [ ] ) ; return ref ; }