import { FocusManager , FocusManagerHandlers , FocusManagerIterationOptions , FocusManagerScopeOptions } from "./useFocusManager" ; import { RefObject , useCallback , useEffect } from "react" ; import { FocusTarget } from "./focusTarget" ; import { createDisposables } from "./useDisposables" ; import { useChainedEventCallback } from "./useChainedEventCallback" ; export interface AbstractAutoFocusOptions { delay ? : number ; isDisabled ? : boolean ; onFocus ? : ( element ? : HTMLElement ) => void ; } function useAbstractAutoFocus ( { delay , isDisabled , onFocus } ) { useEffect ( ( ) => { const disposables = createDisposables ( ) ; if ( ! isDisabled ) { if ( delay ) { disposables . setTimeout ( ( ) => { onFocus ( ) ; } , delay ) ; } else { disposables . nextFrame ( ( ) => { onFocus ( ) ; } ) ; } } return ( ) => { disposables . dispose ( ) ; } ; } , [ isDisabled , delay , onFocus ] ) ; } export interface AutoFocusOptions { delay ? : number ; isDisabled ? : boolean ; onFocus ? : ( element ? : HTMLElement ) => void ; } export function useAutoFocus ( targetRef , { delay , isDisabled , onFocus } = { } ) { useAbstractAutoFocus ( { delay , isDisabled , onFocus : useChainedEventCallback ( onFocus , ( ) => { if ( ! targetRef . current ?. hasAttribute ( "disabled" ) && ! targetRef . current ?. contains ( document . activeElement ) ) { targetRef . current ?. focus ( ) ; } } ) } ) ; } export interface AutoFocusChildOptions extends FocusManagerScopeOptions , FocusManagerIterationOptions , FocusManagerHandlers { delay ? : number ; isDisabled ? : boolean ; target ? : string ; } export function useAutoFocusChild ( focusManager , { target = FocusTarget . first , isDisabled , delay , canFocus , onFocus , onNotFound , tabbableOnly } = { } ) { useAbstractAutoFocus ( { delay , isDisabled , onFocus : useCallback ( ( ) => { if ( ! focusManager . isInScope ( document . activeElement as HTMLElement ) ) { focusManager . focusTarget ( target , { canFocus , onFocus , onNotFound , tabbableOnly } ) ; } } , [ canFocus , focusManager , onFocus , onNotFound , tabbableOnly , target ] ) } ) ; }