1- import { useContext , useId } from "react" ;
1+ import { useContext , useEffect , useId , useState } from "react" ;
22import DxcIcon from "../icon/Icon" ;
33import SubMenu from "./SubMenu" ;
44import ItemAction from "./ItemAction" ;
@@ -10,14 +10,17 @@ import BaseMenuContext from "./BaseMenuContext";
1010
1111const GroupItem = ( { items, ...props } : GroupItemProps ) => {
1212 const groupMenuId = `group-menu-${ useId ( ) } ` ;
13-
14- const NavigationTreeId = `sidenav-${ useId ( ) } ` ;
13+ const navigationTreeId = `sidenav-${ useId ( ) } ` ;
1514 const contextValue = useContext ( BaseMenuContext ) ?? { } ;
1615 const { groupSelected, isOpen, toggleOpen, hasPopOver, isHorizontal } = useGroupItem (
1716 items ,
1817 contextValue ,
1918 props . defaultOpen
2019 ) ;
20+ const [ portalContainer , setPortalContainer ] = useState < HTMLElement | null > ( null ) ;
21+ useEffect ( ( ) => {
22+ setPortalContainer ( document ?. getElementById ( `${ navigationTreeId } -portal` ) ) ;
23+ } , [ ] ) ;
2124
2225 return hasPopOver ? (
2326 < >
@@ -38,60 +41,64 @@ const GroupItem = ({ items, ...props }: GroupItemProps) => {
3841 { ...props }
3942 />
4043 </ Popover . Trigger >
41- < Popover . Portal container = { document . getElementById ( `${ NavigationTreeId } -portal` ) } >
42- < BaseMenuContext . Provider value = { { ...contextValue , displayGroupLines : false , hasPopOver : false } } >
43- < Popover . Content
44- aria-label = "Group details"
45- onKeyDown = { ( event ) => {
46- if ( event . key === "Escape" ) {
47- toggleOpen ( ) ;
48- }
49- } }
50- align = "start"
51- side = { isHorizontal ? "bottom" : "right" }
52- style = { {
53- zIndex : "var(--z-contextualmenu)" ,
54- padding : "var(--spacing-padding-xs)" ,
55- boxShadow : "var(--shadow-100)" ,
56- backgroundColor : "var(--color-bg-neutral-lightest)" ,
57- borderRadius : "var(--border-radius-m)" ,
58- ...( isHorizontal
59- ? { }
60- : {
61- display : "flex" ,
62- flexDirection : "column" ,
63- gap : "var(--spacing-gap-xxs)" ,
64- } ) ,
65- } }
66- sideOffset = { isHorizontal ? 16 : 0 }
67- onInteractOutside = { ( ) => toggleOpen ( ) }
68- >
69- { ! isHorizontal && props . depthLevel === 0 && (
70- < ItemAction
71- aria-controls = { isOpen ? groupMenuId : undefined }
72- aria-expanded = { isOpen ? true : undefined }
73- aria-pressed = { groupSelected && ! isOpen }
74- collapseIcon = { isOpen ? < DxcIcon icon = "filled_expand_less" /> : < DxcIcon icon = "filled_expand_more" /> }
75- onClick = { ( ) => toggleOpen ( ) }
76- selected = { groupSelected && ! isOpen }
77- { ...props }
78- icon = { undefined }
79- />
80- ) }
81- < SubMenu id = { groupMenuId } depthLevel = { props . depthLevel } isPopOver = { true } >
82- { items . map ( ( item , index ) => (
83- < MenuItem
84- item = { item }
85- depthLevel = { isHorizontal ? props . depthLevel : props . depthLevel + 1 }
86- key = { `${ item . label } -${ index } ` }
44+ { portalContainer && (
45+ < Popover . Portal container = { portalContainer } >
46+ < BaseMenuContext . Provider value = { { ...contextValue , displayGroupLines : false , hasPopOver : false } } >
47+ < Popover . Content
48+ aria-label = "Group details"
49+ onKeyDown = { ( event ) => {
50+ if ( event . key === "Escape" ) {
51+ toggleOpen ( ) ;
52+ }
53+ } }
54+ align = "start"
55+ side = { isHorizontal ? "bottom" : "right" }
56+ style = { {
57+ zIndex : "var(--z-contextualmenu)" ,
58+ padding : "var(--spacing-padding-xs)" ,
59+ boxShadow : "var(--shadow-100)" ,
60+ backgroundColor : "var(--color-bg-neutral-lightest)" ,
61+ borderRadius : "var(--border-radius-m)" ,
62+ ...( isHorizontal
63+ ? { }
64+ : {
65+ display : "flex" ,
66+ flexDirection : "column" ,
67+ gap : "var(--spacing-gap-xxs)" ,
68+ } ) ,
69+ } }
70+ sideOffset = { isHorizontal ? 16 : 0 }
71+ onInteractOutside = { ( ) => toggleOpen ( ) }
72+ >
73+ { ! isHorizontal && props . depthLevel === 0 && (
74+ < ItemAction
75+ aria-controls = { isOpen ? groupMenuId : undefined }
76+ aria-expanded = { isOpen ? true : undefined }
77+ aria-pressed = { groupSelected && ! isOpen }
78+ collapseIcon = {
79+ isOpen ? < DxcIcon icon = "filled_expand_less" /> : < DxcIcon icon = "filled_expand_more" />
80+ }
81+ onClick = { ( ) => toggleOpen ( ) }
82+ selected = { groupSelected && ! isOpen }
83+ { ...props }
84+ icon = { undefined }
8785 />
88- ) ) }
89- </ SubMenu >
90- </ Popover . Content >
91- </ BaseMenuContext . Provider >
92- </ Popover . Portal >
86+ ) }
87+ < SubMenu id = { groupMenuId } depthLevel = { props . depthLevel } isPopOver = { true } >
88+ { items . map ( ( item , index ) => (
89+ < MenuItem
90+ item = { item }
91+ depthLevel = { isHorizontal ? props . depthLevel : props . depthLevel + 1 }
92+ key = { `${ item . label } -${ index } ` }
93+ />
94+ ) ) }
95+ </ SubMenu >
96+ </ Popover . Content >
97+ </ BaseMenuContext . Provider >
98+ </ Popover . Portal >
99+ ) }
93100 </ Popover . Root >
94- < div id = { `${ NavigationTreeId } -portal` } style = { { position : "absolute" } } />
101+ < div id = { `${ navigationTreeId } -portal` } style = { { position : "absolute" } } />
95102 </ >
96103 ) : (
97104 < >
0 commit comments