diff --git a/desktop/plugins/public/ui-debugger/components/Tree.tsx b/desktop/plugins/public/ui-debugger/components/Tree.tsx index 04a801eee..d5e70366a 100644 --- a/desktop/plugins/public/ui-debugger/components/Tree.tsx +++ b/desktop/plugins/public/ui-debugger/components/Tree.tsx @@ -9,23 +9,40 @@ import {Id, UINode} from '../types'; import {DataNode} from 'antd/es/tree'; -import {Tree as AntTree, Typography} from 'antd'; +import {Tree as AntTree} from 'antd'; import {DownOutlined} from '@ant-design/icons'; import React from 'react'; export function Tree(props: { rootId: Id; nodes: Map; - setSelectedNode: (id: Id) => void; + selectedNode?: Id; + onSelectNode: (id: Id) => void; + onHoveredNode: (id?: Id) => void; }) { const [antTree, inactive] = nodesToAntTree(props.rootId, props.nodes); return ( { + //when mouse exits the entire tree then unhover + props.onHoveredNode(undefined); + }} showIcon showLine + titleRender={(node) => { + return ( +
{ + props.onHoveredNode(node.key as Id); + }}> + {node.title} +
+ ); + }} + selectedKeys={[props.selectedNode ?? '']} onSelect={(selected) => { - props.setSelectedNode(selected[0] as Id); + props.onSelectNode(selected[0] as Id); }} defaultExpandAll expandedKeys={[...props.nodes.keys()].filter( diff --git a/desktop/plugins/public/ui-debugger/components/Visualization2D.tsx b/desktop/plugins/public/ui-debugger/components/Visualization2D.tsx index 799265d14..2b404caff 100644 --- a/desktop/plugins/public/ui-debugger/components/Visualization2D.tsx +++ b/desktop/plugins/public/ui-debugger/components/Visualization2D.tsx @@ -9,48 +9,52 @@ import React from 'react'; import {Bounds, Id, Tag, UINode} from '../types'; -import {styled, Layout} from 'flipper-plugin'; +import {styled, Layout, theme} from 'flipper-plugin'; import {Typography} from 'antd'; export const Visualization2D: React.FC< - {root: Id; nodes: Map} & React.HTMLAttributes -> = ({root, nodes}) => { - // - const bounds = nodes.get(root)?.bounds; - const rootBorderStyle = bounds - ? { - borderWidth: '3px', - margin: '-3px', - borderStyle: 'solid', - borderColor: 'black', - width: bounds.width / 2, - height: bounds.height / 2, - } - : {}; + { + root: Id; + nodes: Map; + hoveredNode?: Id; + onSelectNode: (id: Id) => void; + } & React.HTMLAttributes +> = ({root, nodes, hoveredNode, onSelectNode}) => { return ( Visualizer +
- ; + + ;
); }; -function VisualizationNode({ +function Visualization2DNode({ nodeId, nodes, isRoot, + hoveredNode, + onSelectNode, }: { isRoot: boolean; nodeId: Id; nodes: Map; + hoveredNode?: Id; + onSelectNode: (id: Id) => void; }) { const node = nodes.get(nodeId); @@ -58,19 +62,28 @@ function VisualizationNode({ return null; } - let childrenIds = node.children; + const isHovered = hoveredNode === nodeId; - //if there is an active child dont draw the other children - //this means we don't draw overlapping activities / tabs - if (node.activeChild) { - childrenIds = [node.activeChild]; + let childrenIds: Id[] = []; + + if (!isHovered) { + //if there is an active child don't draw the other children + //this means we don't draw overlapping activities / tabs etc + if (node.activeChild) { + childrenIds = [node.activeChild]; + } else { + childrenIds = node.children; + } } + const children = childrenIds.map((childId) => ( - )); @@ -81,7 +94,15 @@ function VisualizationNode({ const isZeroWidthOrHeight = node.bounds?.height === 0 || node.bounds?.width === 0; return ( - + { + e.stopPropagation(); + onSelectNode(nodeId); + }} + bounds={node.bounds} + isRoot={isRoot} + tags={node.tags} + isHovered={isHovered}> {/* Dirty hack to avoid showing highly overlapping text */} {!hasOverlappingChild && !isZeroWidthOrHeight && node.bounds ? node.name @@ -94,11 +115,13 @@ function VisualizationNode({ const BoundsBox = styled.div<{ bounds?: Bounds; isRoot: boolean; + isHovered: boolean; tags: Tag[]; }>((props) => { const bounds = props.bounds ?? {x: 0, y: 0, width: 0, height: 0}; return { // borderWidth: props.isRoot ? '5px' : '1px', + cursor: 'pointer', borderWidth: '1px', //to offset the border margin: '-1px', @@ -109,6 +132,7 @@ const BoundsBox = styled.div<{ : 'black', borderStyle: 'solid', position: 'absolute', + backgroundColor: props.isHovered ? theme.selectionBackgroundColor : 'white', //todo need to understand why its so big and needs halving left: bounds.x / 2, top: bounds.y / 2, diff --git a/desktop/plugins/public/ui-debugger/components/main.tsx b/desktop/plugins/public/ui-debugger/components/main.tsx index 3000e5d7a..a299cbd8c 100644 --- a/desktop/plugins/public/ui-debugger/components/main.tsx +++ b/desktop/plugins/public/ui-debugger/components/main.tsx @@ -31,6 +31,7 @@ export function Component() { const [showPerfStats, setShowPerfStats] = useState(false); const [selectedNode, setSelectedNode] = useState(undefined); + const [hoveredNode, setHoveredNode] = useState(undefined); useHotkeys('ctrl+i', () => setShowPerfStats((show) => !show)); @@ -58,11 +59,18 @@ export function Component() { - + {selectedNode && renderAttributesInspector(nodes.get(selectedNode))}