Added context menu and focus mode

Reviewed By: antonk52

Differential Revision: D41838172

fbshipit-source-id: 7c5fad5a7520cea5f0dbabb9f99ef436ad87ec60
This commit is contained in:
Luke De Feo
2022-12-12 07:28:37 -08:00
committed by Facebook GitHub Bot
parent 88e2bb7607
commit 65d6089ed2

View File

@@ -30,6 +30,8 @@ import {plugin} from '../index';
import {Glyph} from 'flipper'; import {Glyph} from 'flipper';
import {head} from 'lodash'; import {head} from 'lodash';
import {reverse} from 'lodash/fp'; import {reverse} from 'lodash/fp';
import {Dropdown, Menu} from 'antd';
import {UIDebuggerMenuItem} from './util/UIDebuggerMenuItem';
export function Tree2({ export function Tree2({
nodes, nodes,
@@ -43,18 +45,19 @@ export function Tree2({
onSelectNode: (node?: Id) => void; onSelectNode: (node?: Id) => void;
}) { }) {
const instance = usePlugin(plugin); const instance = usePlugin(plugin);
const focusedNode = useValue(instance.uiState.focusedNode);
const expandedNodes = useValue(instance.uiState.expandedNodes); const expandedNodes = useValue(instance.uiState.expandedNodes);
const searchTerm = useValue(instance.uiState.searchTerm); const searchTerm = useValue(instance.uiState.searchTerm);
const {treeNodes, refs} = useMemo(() => { const {treeNodes, refs} = useMemo(() => {
const treeNodes = toTreeList(nodes, rootId, expandedNodes); const treeNodes = toTreeList(nodes, focusedNode || rootId, expandedNodes);
const refs: React.RefObject<HTMLLIElement>[] = treeNodes.map(() => const refs: React.RefObject<HTMLLIElement>[] = treeNodes.map(() =>
React.createRef<HTMLLIElement>(), React.createRef<HTMLLIElement>(),
); );
return {treeNodes, refs}; return {treeNodes, refs};
}, [expandedNodes, nodes, rootId]); }, [expandedNodes, focusedNode, nodes, rootId]);
const isUsingKBToScroll = useRef(false); const isUsingKBToScroll = useRef(false);
@@ -121,12 +124,16 @@ function TreeItemContainer({
const instance = usePlugin(plugin); const instance = usePlugin(plugin);
const isHovered = useIsHovered(treeNode.id); const isHovered = useIsHovered(treeNode.id);
return ( return (
<ContextMenu node={treeNode}>
<TreeItem <TreeItem
ref={innerRef} ref={innerRef}
isSelected={treeNode.id === selectedNode} isSelected={treeNode.id === selectedNode}
isHovered={isHovered} isHovered={isHovered}
onMouseEnter={() => { onMouseEnter={() => {
if (isUsingKBToScroll.current === false) { if (
isUsingKBToScroll.current === false &&
instance.uiState.isContextMenuOpen.get() == false
) {
instance.uiState.hoveredNodes.set([treeNode.id]); instance.uiState.hoveredNodes.set([treeNode.id]);
} }
}} }}
@@ -150,6 +157,7 @@ function TreeItemContainer({
{nodeIcon(treeNode)} {nodeIcon(treeNode)}
<HighlightedText text={treeNode.name} /> <HighlightedText text={treeNode.name} />
</TreeItem> </TreeItem>
</ContextMenu>
); );
} }
@@ -232,6 +240,44 @@ const DecorationImage = styled.img({
const renderDepthOffset = 4; const renderDepthOffset = 4;
const ContextMenu: React.FC<{node: TreeNode}> = ({node, children}) => {
const instance = usePlugin(plugin);
const focusedNode = instance.uiState.focusedNode.get();
return (
<Dropdown
onVisibleChange={(visible) => {
instance.uiState.isContextMenuOpen.set(visible);
}}
overlay={() => (
<Menu>
{focusedNode !== head(instance.uiState.hoveredNodes.get()) && (
<UIDebuggerMenuItem
key="focus"
text={`Focus ${node.name}`}
onClick={() => {
instance.uiState.focusedNode.set(node.id);
}}
/>
)}
{focusedNode && (
<UIDebuggerMenuItem
key="remove-focus"
text="Remove focus"
onClick={() => {
instance.uiState.focusedNode.set(undefined);
}}
/>
)}
</Menu>
)}
trigger={['contextMenu']}>
<div>{children}</div>
</Dropdown>
);
};
function toTreeList( function toTreeList(
nodes: Map<Id, UINode>, nodes: Map<Id, UINode>,
rootId: Id, rootId: Id,