Use focus state from elements tree instead of ownerDocument

This commit is contained in:
Lucas Cordeiro
2019-04-09 19:04:03 -03:00
parent 26106a4b9d
commit 1c57ca0a1c
2 changed files with 38 additions and 31 deletions
+2 -29
View File
@@ -2,10 +2,8 @@
import React, {
Fragment,
useState,
useCallback,
useContext,
useEffect,
useLayoutEffect,
useMemo,
useRef,
@@ -37,13 +35,12 @@ export default function ElementView({ data, index, style }: Props) {
const bridge = useContext(BridgeContext);
const store = useContext(StoreContext);
const [windowFocused, setWindowFocused] = useState<boolean>(true);
const element = getElementAtIndex(index);
const id = element === null ? null : element.id;
const isSelected = selectedElementID === id;
const lastScrolledIDRef = data.lastScrolledIDRef;
const treeFocused = data.treeFocused;
const handleDoubleClick = useCallback(() => {
if (id !== null) {
@@ -53,30 +50,6 @@ export default function ElementView({ data, index, style }: Props) {
const ref = useRef<HTMLSpanElement | null>(null);
useEffect(() => {
if (ref.current === null || !isSelected) {
return () => {};
}
const handleFocus = () => {
setWindowFocused(true);
};
const handleBlur = () => {
setWindowFocused(false);
};
const ownerDocument = ref.current.ownerDocument.defaultView;
ownerDocument.addEventListener('focus', handleFocus);
ownerDocument.addEventListener('blur', handleBlur);
return () => {
ownerDocument.removeEventListener('focus', handleFocus);
ownerDocument.removeEventListener('blur', handleBlur);
};
}, [isSelected]);
// The tree above has its own autoscrolling, but it only works for rows.
// However, even when the row gets into the viewport, the component name
// might be too far left or right on the screen. Adjust it in this case.
@@ -147,7 +120,7 @@ export default function ElementView({ data, index, style }: Props) {
return (
<div
className={
isSelected && windowFocused
isSelected && treeFocused
? styles.SelectedElement
: isSelected
? styles.InactiveElement
+36 -2
View File
@@ -1,6 +1,7 @@
// @flow
import React, {
useState,
useCallback,
useContext,
useEffect,
@@ -27,6 +28,7 @@ export type ItemData = {|
numElements: number,
getElementAtIndex: (index: number) => Element | null,
lastScrolledIDRef: { current: number | null },
treeFocused: boolean,
|};
type Props = {||};
@@ -46,6 +48,9 @@ export default function Tree(props: Props) {
// $FlowFixMe https://github.com/facebook/flow/issues/7341
const listRef = useRef<FixedSizeList<ItemData> | null>(null);
const treeRef = useRef<HTMLDivElement | null>(null);
const elementsRef = useRef<HTMLDivElement | null>(null);
const [treeFocused, setTreeFocused] = useState<boolean>(false);
const { lineHeight } = useContext(SettingsContext);
@@ -112,6 +117,30 @@ export default function Tree(props: Props) {
selectPreviousElementInTree,
]);
useEffect(() => {
if (elementsRef.current === null) {
return () => {};
}
const handleFocusIn = () => {
setTreeFocused(true);
};
const handleFocusOut = () => {
setTreeFocused(false);
};
const elementsElement = elementsRef.current;
elementsElement.addEventListener('focusin', handleFocusIn);
elementsElement.addEventListener('focusout', handleFocusOut);
return () => {
elementsElement.removeEventListener('focusin', handleFocusIn);
elementsElement.removeEventListener('focusout', handleFocusOut);
};
}, []);
// Let react-window know to re-render any time the underlying tree data changes.
// This includes the owner context, since it controls a filtered view of the tree.
const itemData = useMemo<ItemData>(
@@ -120,8 +149,9 @@ export default function Tree(props: Props) {
numElements,
getElementAtIndex,
lastScrolledIDRef,
treeFocused,
}),
[baseDepth, numElements, getElementAtIndex, lastScrolledIDRef]
[baseDepth, numElements, getElementAtIndex, lastScrolledIDRef, treeFocused]
);
const handleMouseLeave = useCallback(() => {
@@ -134,7 +164,11 @@ export default function Tree(props: Props) {
{ownerStack.length > 0 ? <OwnersStack /> : <SearchInput />}
<InspectHostNodesToggle />
</div>
<div className={styles.AutoSizerWrapper} onMouseLeave={handleMouseLeave}>
<div
className={styles.AutoSizerWrapper}
onMouseLeave={handleMouseLeave}
ref={elementsRef}
>
<AutoSizer>
{({ height, width }) => (
// $FlowFixMe https://github.com/facebook/flow/issues/7341