88 */
99
1010import * as React from 'react' ;
11- import { useLayoutEffect , createRef } from 'react' ;
11+ import { useLayoutEffect } from 'react' ;
1212import { createPortal } from 'react-dom' ;
1313
1414import ContextMenuItem from './ContextMenuItem' ;
1515
1616import type {
1717 ContextMenuItem as ContextMenuItemType ,
1818 ContextMenuPosition ,
19- ContextMenuRef ,
2019} from './types' ;
2120
2221import styles from './ContextMenu.css' ;
@@ -49,15 +48,13 @@ type Props = {
4948 items : ContextMenuItemType [ ] ,
5049 position : ContextMenuPosition ,
5150 hide : ( ) => void ,
52- ref ? : ContextMenuRef ,
5351} ;
5452
5553export default function ContextMenu ( {
5654 anchorElementRef,
5755 position,
5856 items,
5957 hide,
60- ref = createRef ( ) ,
6158} : Props ) : React . Node {
6259 // This works on the assumption that ContextMenu component is only rendered when it should be shown
6360 const anchor = anchorElementRef . current ;
@@ -73,8 +70,21 @@ export default function ContextMenu({
7370 '[data-react-devtools-portal-root]' ,
7471 ) ;
7572
73+ const hideMenu = portalContainer == null || items . length === 0 ;
74+ const menuRef = React . useRef < HTMLDivElement | null > ( null ) ;
75+
7676 useLayoutEffect ( ( ) => {
77- const menu = ( ( ref . current : any ) : HTMLElement ) ;
77+ // Match the early-return condition below.
78+ if ( hideMenu ) {
79+ return ;
80+ }
81+ const maybeMenu = menuRef . current ;
82+ if ( maybeMenu === null ) {
83+ throw new Error (
84+ "Can't access context menu element. This is a bug in React DevTools." ,
85+ ) ;
86+ }
87+ const menu = ( maybeMenu : HTMLDivElement ) ;
7888
7989 function hideUnlessContains ( event : Event ) {
8090 if ( ! menu . contains ( ( ( event . target : any ) : Node ) ) ) {
@@ -98,14 +108,14 @@ export default function ContextMenu({
98108
99109 ownerWindow . removeEventListener ( 'resize' , hide ) ;
100110 } ;
101- } , [ ] ) ;
111+ } , [ hideMenu ] ) ;
102112
103- if ( portalContainer == null || items . length === 0 ) {
113+ if ( hideMenu ) {
104114 return null ;
105115 }
106116
107117 return createPortal (
108- < div className = { styles . ContextMenu } ref = { ref } >
118+ < div className = { styles . ContextMenu } ref = { menuRef } >
109119 { items . map ( ( { onClick, content} , index ) => (
110120 < ContextMenuItem key = { index } onClick = { onClick } hide = { hide } >
111121 { content }
0 commit comments