import { FocusEvent } from "react" ; import { isNil } from "./assertions" ; import { useEventCallback } from "./useEventCallback" ; import { useRefState } from "./useRefState" ; export interface UseFocusWithinOptions { isDisabled ? : boolean ; onBlur ? : ( event : FocusEvent ) => void ; onFocus ? : ( event : FocusEvent ) => void ; } export function useFocusWithin ( { isDisabled , onBlur , onFocus } = { } ) { const [ isFocusWithinRef , setIsFocusWithin ] = useRefState ( false ) ; const handleFocus = useEventCallback ( ( event ) => { if ( ! event . currentTarget . contains ( event . relatedTarget as Node ) ) { if ( ! isNil ( onFocus ) ) { onFocus ( event ) ; } setIsFocusWithin ( true ) ; } } ) ; const handleBlur = useEventCallback ( ( event ) => { if ( isFocusWithinRef . current && ! event . currentTarget . contains ( event . relatedTarget as Node ) ) { if ( ! isNil ( onBlur ) ) { onBlur ( event ) ; } setIsFocusWithin ( false ) ; } } ) ; return isDisabled ? { } : { onBlur : handleBlur , onFocus : handleFocus } ; }