Skip to content

Commit 5eff3e5

Browse files
committed
fix(ContextSubMenuItem): fix popper container
1 parent dc28e8b commit 5eff3e5

File tree

1 file changed

+25
-14
lines changed

1 file changed

+25
-14
lines changed

packages/module/src/components/contextmenu/ContextSubMenuItem.tsx

+25-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as React from 'react';
2-
import { Dropdown, DropdownItem } from '@patternfly/react-core';
2+
import { Menu, DropdownItem } from '@patternfly/react-core';
33
import AngleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-right-icon';
44
import { css } from '@patternfly/react-styles';
55
import topologyStyles from '../../css/topology-components';
@@ -11,6 +11,14 @@ interface ContextSubMenuItemProps {
1111
children: React.ReactNode[];
1212
}
1313

14+
/**
15+
* Check if an event target is also a [Node](https://developer.mozilla.org/en-US/docs/Web/API/Node).
16+
* Needed to stop runtime errors where the target does not implement Node.
17+
*/
18+
const implementsDOMNode = (node: any): boolean => {
19+
return node && typeof node === 'object' && node.nodeType && node.nodeName;
20+
};
21+
1422
const ContextSubMenuItem: React.FunctionComponent<ContextSubMenuItemProps> = ({ label, children, ...other }) => {
1523
const nodeRef = React.useRef<HTMLButtonElement>(null);
1624
const subMenuRef = React.useRef<HTMLDivElement>(null);
@@ -29,7 +37,10 @@ const ContextSubMenuItem: React.FunctionComponent<ContextSubMenuItemProps> = ({
2937
onMouseEnter={() => setOpen(true)}
3038
onMouseLeave={(e) => {
3139
// if the mouse leaves this item, close the sub menu only if the mouse did not enter the sub menu itself
32-
if (!subMenuRef.current || !subMenuRef.current.contains(e.relatedTarget as Node)) {
40+
if (
41+
!subMenuRef.current ||
42+
(implementsDOMNode(e.relatedTarget) && !subMenuRef.current.contains(e.relatedTarget as Node))
43+
) {
3344
setOpen(false);
3445
}
3546
}}
@@ -51,22 +62,21 @@ const ContextSubMenuItem: React.FunctionComponent<ContextSubMenuItemProps> = ({
5162
closeOnOutsideClick
5263
onRequestClose={(e) => {
5364
// only close the sub menu if clicking anywhere outside the menu item that owns the sub menu
54-
if (!e || !nodeRef.current || !nodeRef.current.contains(e.target as Node)) {
65+
if (!e || !nodeRef.current || (implementsDOMNode(e.target) && !nodeRef.current.contains(e.target as Node))) {
5566
setOpen(false);
5667
}
5768
}}
5869
reference={referenceCb}
59-
// use the parent node to capture the li
60-
container={nodeRef.current ? nodeRef.current.parentElement : nodeRef.current}
70+
container={nodeRef.current?.closest('.pf-v6-c-menu__content')}
6171
returnFocus
6272
>
63-
<div
64-
ref={subMenuRef}
65-
role="presentation"
66-
className="pf-v6-c-dropdown pf-m-expanded"
73+
<Menu
6774
onMouseLeave={(e) => {
6875
// only close the sub menu if the mouse does not enter the item
69-
if (!nodeRef.current || !nodeRef.current.contains(e.relatedTarget as Node)) {
76+
if (
77+
!nodeRef.current ||
78+
(implementsDOMNode(e.relatedTarget) && !nodeRef.current.contains(e.relatedTarget as Node))
79+
) {
7080
setOpen(false);
7181
}
7282
}}
@@ -77,11 +87,12 @@ const ContextSubMenuItem: React.FunctionComponent<ContextSubMenuItemProps> = ({
7787
e.stopPropagation();
7888
}
7989
}}
90+
ref={subMenuRef}
91+
role="presentation"
92+
isNavFlyout
8093
>
81-
<Dropdown toggle={() => <></>} className={css(topologyStyles.topologyContextMenuCDropdownMenu)}>
82-
{children}
83-
</Dropdown>
84-
</div>
94+
{children}
95+
</Menu>
8596
</Popper>
8697
</>
8798
);

0 commit comments

Comments
 (0)