Only render a single context menu for the entire tree
Summary: There is no reason to have a context menu rendered by react for each item in the tree, its pretty wastefull. It also means less props drilled to the tree node Reviewed By: lblasa Differential Revision: D41872778 fbshipit-source-id: b13491a310c03334d7f3056207f5de23d20c3e61
This commit is contained in:
committed by
Facebook GitHub Bot
parent
040240ec34
commit
ed35623bef
@@ -83,31 +83,35 @@ export function Tree2({
|
|||||||
<HighlightProvider
|
<HighlightProvider
|
||||||
text={searchTerm}
|
text={searchTerm}
|
||||||
highlightColor={theme.searchHighlightBackground.yellow}>
|
highlightColor={theme.searchHighlightBackground.yellow}>
|
||||||
<div
|
<ContextMenu
|
||||||
onMouseLeave={() => {
|
focusedNode={focusedNode}
|
||||||
if (isContextMenuOpen === false) {
|
hoveredNode={hoveredNode}
|
||||||
instance.uiState.hoveredNodes.set([]);
|
nodes={nodes}
|
||||||
}
|
onContextMenuOpen={instance.uiActions.onContextMenuOpen}
|
||||||
}}>
|
onFocusNode={instance.uiActions.onFocusNode}>
|
||||||
{treeNodes.map((treeNode, index) => (
|
<div
|
||||||
<MemoTreeItemContainer
|
onMouseLeave={() => {
|
||||||
innerRef={refs[index]}
|
if (isContextMenuOpen === false) {
|
||||||
key={treeNode.id}
|
instance.uiState.hoveredNodes.set([]);
|
||||||
treeNode={treeNode}
|
}
|
||||||
selectedNode={selectedNode}
|
}}>
|
||||||
hoveredNode={hoveredNode}
|
{treeNodes.map((treeNode, index) => (
|
||||||
focusedNode={focusedNode}
|
<MemoTreeItemContainer
|
||||||
isUsingKBToScroll={isUsingKBToScroll}
|
innerRef={refs[index]}
|
||||||
isContextMenuOpen={isContextMenuOpen}
|
key={treeNode.id}
|
||||||
onSelectNode={onSelectNode}
|
treeNode={treeNode}
|
||||||
onExpandNode={instance.uiActions.onExpandNode}
|
selectedNode={selectedNode}
|
||||||
onCollapseNode={instance.uiActions.onCollapseNode}
|
hoveredNode={hoveredNode}
|
||||||
onContextMenuOpen={instance.uiActions.onContextMenuOpen}
|
isUsingKBToScroll={isUsingKBToScroll}
|
||||||
onFocusNode={instance.uiActions.onFocusNode}
|
isContextMenuOpen={isContextMenuOpen}
|
||||||
onHoverNode={instance.uiActions.onHoverNode}
|
onSelectNode={onSelectNode}
|
||||||
/>
|
onExpandNode={instance.uiActions.onExpandNode}
|
||||||
))}
|
onCollapseNode={instance.uiActions.onCollapseNode}
|
||||||
</div>
|
onHoverNode={instance.uiActions.onHoverNode}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</ContextMenu>
|
||||||
</HighlightProvider>
|
</HighlightProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -138,11 +142,8 @@ function TreeItemContainer({
|
|||||||
treeNode,
|
treeNode,
|
||||||
selectedNode,
|
selectedNode,
|
||||||
hoveredNode,
|
hoveredNode,
|
||||||
focusedNode,
|
|
||||||
isUsingKBToScroll,
|
isUsingKBToScroll,
|
||||||
isContextMenuOpen,
|
isContextMenuOpen,
|
||||||
onFocusNode,
|
|
||||||
onContextMenuOpen,
|
|
||||||
onSelectNode,
|
onSelectNode,
|
||||||
onExpandNode,
|
onExpandNode,
|
||||||
onCollapseNode,
|
onCollapseNode,
|
||||||
@@ -152,55 +153,42 @@ function TreeItemContainer({
|
|||||||
treeNode: TreeNode;
|
treeNode: TreeNode;
|
||||||
selectedNode?: Id;
|
selectedNode?: Id;
|
||||||
hoveredNode?: Id;
|
hoveredNode?: Id;
|
||||||
focusedNode?: Id;
|
|
||||||
isUsingKBToScroll: RefObject<boolean>;
|
isUsingKBToScroll: RefObject<boolean>;
|
||||||
isContextMenuOpen: boolean;
|
isContextMenuOpen: boolean;
|
||||||
onFocusNode: (id?: Id) => void;
|
|
||||||
onContextMenuOpen: (open: boolean) => void;
|
|
||||||
onSelectNode: (node?: Id) => void;
|
onSelectNode: (node?: Id) => void;
|
||||||
onExpandNode: (node: Id) => void;
|
onExpandNode: (node: Id) => void;
|
||||||
onCollapseNode: (node: Id) => void;
|
onCollapseNode: (node: Id) => void;
|
||||||
onHoverNode: (node: Id) => void;
|
onHoverNode: (node: Id) => void;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<ContextMenu
|
<TreeItem
|
||||||
onContextMenuOpen={onContextMenuOpen}
|
ref={innerRef}
|
||||||
onFocusNode={onFocusNode}
|
isSelected={treeNode.id === selectedNode}
|
||||||
focusedNode={focusedNode}
|
isHovered={hoveredNode === treeNode.id}
|
||||||
hoveredNode={hoveredNode}
|
onMouseEnter={() => {
|
||||||
node={treeNode}>
|
if (isUsingKBToScroll.current === false && isContextMenuOpen == false) {
|
||||||
<TreeItem
|
onHoverNode(treeNode.id);
|
||||||
ref={innerRef}
|
}
|
||||||
isSelected={treeNode.id === selectedNode}
|
}}
|
||||||
isHovered={hoveredNode === treeNode.id}
|
onClick={() => {
|
||||||
onMouseEnter={() => {
|
onSelectNode(treeNode.id);
|
||||||
if (
|
}}
|
||||||
isUsingKBToScroll.current === false &&
|
item={treeNode}>
|
||||||
isContextMenuOpen == false
|
<ExpandedIconOrSpace
|
||||||
) {
|
expanded={treeNode.isExpanded}
|
||||||
onHoverNode(treeNode.id);
|
showIcon={treeNode.children.length > 0}
|
||||||
|
onClick={() => {
|
||||||
|
if (treeNode.isExpanded) {
|
||||||
|
onCollapseNode(treeNode.id);
|
||||||
|
} else {
|
||||||
|
onExpandNode(treeNode.id);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
/>
|
||||||
onSelectNode(treeNode.id);
|
{nodeIcon(treeNode)}
|
||||||
}}
|
<HighlightedText text={treeNode.name} />
|
||||||
item={treeNode}>
|
<InlineAttributes attributes={treeNode.inlineAttributes} />
|
||||||
<ExpandedIconOrSpace
|
</TreeItem>
|
||||||
expanded={treeNode.isExpanded}
|
|
||||||
showIcon={treeNode.children.length > 0}
|
|
||||||
onClick={() => {
|
|
||||||
if (treeNode.isExpanded) {
|
|
||||||
onCollapseNode(treeNode.id);
|
|
||||||
} else {
|
|
||||||
onExpandNode(treeNode.id);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{nodeIcon(treeNode)}
|
|
||||||
<HighlightedText text={treeNode.name} />
|
|
||||||
<InlineAttributes attributes={treeNode.inlineAttributes} />
|
|
||||||
</TreeItem>
|
|
||||||
</ContextMenu>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,13 +279,13 @@ const DecorationImage = styled.img({
|
|||||||
const renderDepthOffset = 4;
|
const renderDepthOffset = 4;
|
||||||
|
|
||||||
const ContextMenu: React.FC<{
|
const ContextMenu: React.FC<{
|
||||||
node: TreeNode;
|
nodes: Map<Id, UINode>;
|
||||||
hoveredNode?: Id;
|
hoveredNode?: Id;
|
||||||
focusedNode?: Id;
|
focusedNode?: Id;
|
||||||
onFocusNode: (id?: Id) => void;
|
onFocusNode: (id?: Id) => void;
|
||||||
onContextMenuOpen: (open: boolean) => void;
|
onContextMenuOpen: (open: boolean) => void;
|
||||||
}> = ({
|
}> = ({
|
||||||
node,
|
nodes,
|
||||||
hoveredNode,
|
hoveredNode,
|
||||||
children,
|
children,
|
||||||
focusedNode,
|
focusedNode,
|
||||||
@@ -311,12 +299,12 @@ const ContextMenu: React.FC<{
|
|||||||
}}
|
}}
|
||||||
overlay={() => (
|
overlay={() => (
|
||||||
<Menu>
|
<Menu>
|
||||||
{focusedNode !== hoveredNode && (
|
{hoveredNode != null && focusedNode !== hoveredNode && (
|
||||||
<UIDebuggerMenuItem
|
<UIDebuggerMenuItem
|
||||||
key="focus"
|
key="focus"
|
||||||
text={`Focus ${node.name}`}
|
text={`Focus ${nodes.get(hoveredNode)?.name}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
onFocusNode(node.id);
|
onFocusNode(hoveredNode);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user