import { useCallback , useState , useEffect } from "react" ; import { WindowId } from "../types" ; import * as Actions from "../actionCreators" ; import * as Selectors from "../selectors" ; import { useActionCreator , useTypedSelector } from "../hooks" ; interface Props { onKeyDown ? ( e ) : void ; windowId : WindowId ; children : React . ReactNode ; } function FocusTarget ( { onKeyDown , windowId , children } ) { const focusedWindowId = useTypedSelector ( Selectors . getFocusedWindow ) ; const setFocus = useActionCreator ( Actions . setFocusedWindow ) ; const focusHandler = useCallback ( ( ) => { if ( windowId !== focusedWindowId ) { setFocus ( windowId ) ; } } , [ windowId , focusedWindowId , setFocus ] ) ; const [ ref , setRef ] = useState < HTMLDivElement | null > ( null ) ; useEffect ( ( ) => { if ( ref == null || onKeyDown == null ) { return ; } ref . addEventListener ( "keydown" , onKeyDown ) ; return ( ) => ref . removeEventListener ( "keydown" , onKeyDown ) ; } , [ onKeyDown , windowId , focusedWindowId , ref ] ) ; useEffect ( ( ) => { if ( ref == null || windowId !== focusedWindowId ) { return ; } const observer = new MutationObserver ( ( mutations ) => { if ( document . activeElement !== document . body ) { return ; } if ( mutations . some ( ( mutation ) => mutation . removedNodes . length > 0 ) ) { ref . focus ( ) ; } } ) ; observer . observe ( ref , { subtree : true , attributes : false , childList : true , } ) ; return ( ) => observer . disconnect ( ) ; } , [ windowId , focusedWindowId , ref ] ) ; return ( < div ref = { setRef } onMouseDown = { focusHandler } onTouchStart = { focusHandler } onFocus = { focusHandler } tabIndex = { - 1 } style = { { height : "100%" , width : "100%" } } > { children } < /div>); } export default FocusTarget ;