import React, { useCallback, useRef, useEffect } from "react"; import { WindowId, AppState, Dispatch } from "../types"; import * as Actions from "../actionCreators"; import * as Selectors from "../selectors"; import { connect } from "react-redux"; interface DispatchProps { setFocus(windowId: WindowId): void; } interface StateProps { focusedWindowId: WindowId; } interface OwnProps { onKeyDown?(e: KeyboardEvent): void; windowId: WindowId; children: React.ReactNode; } type Props = StateProps & DispatchProps & OwnProps; function FocusTarget(props: Props) { const { onKeyDown, focusedWindowId, windowId, setFocus, children } = props; const focusHandler = useCallback(() => { if (windowId !== focusedWindowId) { setFocus(windowId); } }, [windowId, focusedWindowId, setFocus]); const ref = useRef(null); useEffect(() => { const { current } = ref; if (current == null) { return; } const listener = (e: KeyboardEvent) => { if (windowId === focusedWindowId && onKeyDown != null) { onKeyDown(e); } }; current.addEventListener("keydown", listener); return () => current.removeEventListener("keydown", listener); }, [onKeyDown, windowId, focusedWindowId]); return (
{children}
); } function mapStateToProps(state: AppState): StateProps { return { focusedWindowId: Selectors.getFocusedWindow(state), }; } function mapDispatchToProps(dispatch: Dispatch): DispatchProps { return { setFocus: windowId => dispatch(Actions.setFocusedWindow(windowId)), }; } export default connect( mapStateToProps, mapDispatchToProps )(FocusTarget);