diff --git a/desktop/plugins/public/ui-debugger/components/Tree2.tsx b/desktop/plugins/public/ui-debugger/components/Tree2.tsx index 056ef56ff..f3064ed04 100644 --- a/desktop/plugins/public/ui-debugger/components/Tree2.tsx +++ b/desktop/plugins/public/ui-debugger/components/Tree2.tsx @@ -8,7 +8,7 @@ */ import {Id, UINode} from '../types'; -import React from 'react'; +import React, {useEffect, useState} from 'react'; import { HighlightManager, HighlightProvider, @@ -20,6 +20,7 @@ import { } from 'flipper-plugin'; import {plugin} from '../index'; import {Glyph} from 'flipper'; +import {head} from 'lodash'; export function Tree2({ nodes, @@ -42,7 +43,10 @@ export function Tree2({ -
+
{ + instance.uiState.hoveredNodes.set([]); + }}> {items.map((treeNode) => ( void; }) { const instance = usePlugin(plugin); + const isHovered = useIsHovered(treeNode.id); return ( { + instance.uiState.hoveredNodes.set([treeNode.id]); + }} onClick={() => { onSelectNode(treeNode.id); }} @@ -100,6 +107,27 @@ function TreeItemContainer({ ); } +function useIsHovered(nodeId: Id) { + const instance = usePlugin(plugin); + const [isHovered, setIsHovered] = useState(false); + useEffect(() => { + const listener = (newValue?: Id[], prevValue?: Id[]) => { + //only change state if the prev or next hover state affect us, this avoids rerendering the whole tree for a hover + //change + if (head(prevValue) === nodeId || head(newValue) === nodeId) { + const hovered = head(newValue) === nodeId; + setIsHovered(hovered); + } + }; + instance.uiState.hoveredNodes.subscribe(listener); + return () => { + instance.uiState.hoveredNodes.unsubscribe(listener); + }; + }, [instance.uiState.hoveredNodes, nodeId]); + + return isHovered; +} + const TreeItem = styled.li<{ item: TreeNode; isHovered: boolean;