From 0792c51fb86e8e0d6f6ce4215aede5e35d5131da Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Wed, 1 May 2019 21:31:06 -0700 Subject: [PATCH] Trap focus --- js/components/FocusTarget.tsx | 19 +++++++++++++++++++ .../MilkdropWindow/PresetOverlay.tsx | 8 +++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/js/components/FocusTarget.tsx b/js/components/FocusTarget.tsx index ea6b0595..1112a16e 100644 --- a/js/components/FocusTarget.tsx +++ b/js/components/FocusTarget.tsx @@ -39,6 +39,25 @@ function FocusTarget(props: Props) { return () => current.removeEventListener("keydown", onKeyDown); }, [onKeyDown, windowId, focusedWindowId]); + useEffect(() => { + const { current } = ref; + if (current == null || windowId !== focusedWindowId) { + return; + } + + // I give up. I can't figure out how to type this. + const out: EventListener = (e: any) => { + if (!(e.currentTarget as Element).contains(e.relatedTarget as Element)) { + current.focus(); + } + }; + // https://github.com/facebook/react/issues/6410 + // React does not implement focusout. In this case we prefer focusout to + // blur because it gets triggered when a child with focus unmounts. + current.addEventListener("focusout", out); + return () => current.removeEventListener("focusout", out); + }, [windowId, focusedWindowId]); + return (
{ this.props.appendPresetFileList(fileReferences); } + _handleNode = (node: HTMLDivElement | null) => { + if (node != null && document.activeElement !== node) { + node.focus(); + } + }; + render() { const { height, width } = this.props; if (this.props.presetKeys == null) { @@ -180,7 +186,7 @@ class PresetOverlay extends React.Component { } return (
node != null && node.focus()} + ref={this._handleNode} tabIndex={-1} style={OUTER_WRAPPER_STYLE} onKeyDown={this._handleFocusedKeyboardInput}