Skip to content

Commit c10b995

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

File tree

1 file changed

+19
-14
lines changed

1 file changed

+19
-14
lines changed

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

+19-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,11 @@ interface ContextSubMenuItemProps {
1111
children: React.ReactNode[];
1212
}
1313

14+
/** Check if an event target is also a node. Needed to stop runtime errors where the target does not implement Node. */
15+
const isNode = (node: any): boolean => {
16+
return node && typeof node === 'object' && node.nodeType && node.nodeName;
17+
};
18+
1419
const ContextSubMenuItem: React.FunctionComponent<ContextSubMenuItemProps> = ({ label, children, ...other }) => {
1520
const nodeRef = React.useRef<HTMLButtonElement>(null);
1621
const subMenuRef = React.useRef<HTMLDivElement>(null);
@@ -29,7 +34,10 @@ const ContextSubMenuItem: React.FunctionComponent<ContextSubMenuItemProps> = ({
2934
onMouseEnter={() => setOpen(true)}
3035
onMouseLeave={(e) => {
3136
// 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)) {
37+
if (
38+
!subMenuRef.current ||
39+
(isNode(e.relatedTarget) && !subMenuRef.current.contains(e.relatedTarget as Node))
40+
) {
3341
setOpen(false);
3442
}
3543
}}
@@ -51,22 +59,18 @@ const ContextSubMenuItem: React.FunctionComponent<ContextSubMenuItemProps> = ({
5159
closeOnOutsideClick
5260
onRequestClose={(e) => {
5361
// 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)) {
62+
if (!e || !nodeRef.current || (isNode(e.target) && !nodeRef.current.contains(e.target as Node))) {
5563
setOpen(false);
5664
}
5765
}}
5866
reference={referenceCb}
59-
// use the parent node to capture the li
60-
container={nodeRef.current ? nodeRef.current.parentElement : nodeRef.current}
67+
container={nodeRef.current?.closest('.pf-v6-c-menu__content')}
6168
returnFocus
6269
>
63-
<div
64-
ref={subMenuRef}
65-
role="presentation"
66-
className="pf-v6-c-dropdown pf-m-expanded"
70+
<Menu
6771
onMouseLeave={(e) => {
6872
// only close the sub menu if the mouse does not enter the item
69-
if (!nodeRef.current || !nodeRef.current.contains(e.relatedTarget as Node)) {
73+
if (!nodeRef.current || (isNode(e.relatedTarget) && !nodeRef.current.contains(e.relatedTarget as Node))) {
7074
setOpen(false);
7175
}
7276
}}
@@ -77,11 +81,12 @@ const ContextSubMenuItem: React.FunctionComponent<ContextSubMenuItemProps> = ({
7781
e.stopPropagation();
7882
}
7983
}}
84+
ref={subMenuRef}
85+
role="presentation"
86+
isNavFlyout
8087
>
81-
<Dropdown toggle={() => <></>} className={css(topologyStyles.topologyContextMenuCDropdownMenu)}>
82-
{children}
83-
</Dropdown>
84-
</div>
88+
{children}
89+
</Menu>
8590
</Popper>
8691
</>
8792
);

0 commit comments

Comments
 (0)