diff --git a/desktop/plugins/public/ui-debugger/components/Tree.tsx b/desktop/plugins/public/ui-debugger/components/Tree.tsx index 23d2beeb3..9d0ed7504 100644 --- a/desktop/plugins/public/ui-debugger/components/Tree.tsx +++ b/desktop/plugins/public/ui-debugger/components/Tree.tsx @@ -31,6 +31,7 @@ import { import {head} from 'lodash'; import {Dropdown, Menu} from 'antd'; +import {UIDebuggerMenuItem} from './util/UIDebuggerMenuItem'; export function Tree(props: { rootId: Id; @@ -209,23 +210,23 @@ const ContextMenu: React.FC = ({id, title, children}) => { overlay={() => ( {focusedNode !== head(instance.hoveredNodes.get()) && ( - { instance.focusedNode.set(id); - instance.isContextMenuOpen.set(false); - }}> - Focus {title} - + }} + /> )} {focusedNode && ( - { instance.focusedNode.set(undefined); - instance.isContextMenuOpen.set(false); - }}> - Remove focus - + }} + /> )} )} diff --git a/desktop/plugins/public/ui-debugger/components/Visualization2D.tsx b/desktop/plugins/public/ui-debugger/components/Visualization2D.tsx index 49585a6f5..46b2066a1 100644 --- a/desktop/plugins/public/ui-debugger/components/Visualization2D.tsx +++ b/desktop/plugins/public/ui-debugger/components/Visualization2D.tsx @@ -14,6 +14,7 @@ import {produce, styled, theme, usePlugin, useValue} from 'flipper-plugin'; import {plugin} from '../index'; import {head, isEqual, throttle} from 'lodash'; import {Dropdown, Menu} from 'antd'; +import {UIDebuggerMenuItem} from './util/UIDebuggerMenuItem'; export const Visualization2D: React.FC< { @@ -244,7 +245,6 @@ const ContextMenu: React.FC<{nodes: Map}> = ({children}) => { const hoveredNodeId = head(useValue(instance.hoveredNodes)); const nodes = useValue(instance.nodes); const hoveredNode = hoveredNodeId ? nodes.get(hoveredNodeId) : null; - const isMenuOpen = useValue(instance.isContextMenuOpen); return ( }> = ({children}) => { overlay={() => { return ( - {isMenuOpen && hoveredNode?.id !== focusedNodeId && ( - { instance.focusedNode.set(hoveredNode?.id); - instance.isContextMenuOpen.set(false); - }}> - Focus {hoveredNode?.name} - + }} + /> )} - {isMenuOpen && focusedNodeId != null && ( - { instance.focusedNode.set(undefined); - instance.isContextMenuOpen.set(false); - }}> - Remove focus - + }} + /> )} ); diff --git a/desktop/plugins/public/ui-debugger/components/util/UIDebuggerMenuItem.tsx b/desktop/plugins/public/ui-debugger/components/util/UIDebuggerMenuItem.tsx new file mode 100644 index 000000000..2427b6f88 --- /dev/null +++ b/desktop/plugins/public/ui-debugger/components/util/UIDebuggerMenuItem.tsx @@ -0,0 +1,45 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ + +import {Menu} from 'antd'; +import {usePlugin, useValue} from 'flipper-plugin'; +import {plugin} from '../../index'; +import React from 'react'; + +/** + * The Menu item visibility event does not fire when a menu item is clicked. + * This is apparently by design https://github.com/ant-design/ant-design/issues/4994#issuecomment-281585872 + * This component simply wraps a menu item but will ensure that the atom is set to false when an item is clicked. + * Additionally, it ensures menu items do not render when the atom is false + */ +export const UIDebuggerMenuItem: React.FC<{ + text: string; + onClick: () => void; +}> = ({text, onClick}) => { + const instance = usePlugin(plugin); + + const isMenuOpen = useValue(instance.isContextMenuOpen); + /** + * The menu is not a controlled component and seems to be a bit slow to close when user clicks on it. + * React may rerender the menu before it has time to close resulting in seeing an incorrect context menu for a frame. + * This is here to just hide all the menu items when the menu closes. A little strange but works well in practice. + */ + if (!isMenuOpen) { + return null; + } + return ( + { + onClick(); + instance.isContextMenuOpen.set(false); + }}> + {text} + + ); +};