@@ -443,8 +443,7 @@ const MenuContentImpl = React.forwardRef<MenuContentImplElement, MenuContentImpl
443443 } else {
444444 // In shadow DOM, force close other submenus when entering any menu item
445445 const target = event . target as Element ;
446- const isInShadowDOM = target && target . getRootNode ( ) !== document && 'host' in target . getRootNode ( ) ;
447- if ( isInShadowDOM ) {
446+ if ( isInShadowDOM ( target ) ) {
448447 const menuItem = event . currentTarget as HTMLElement ;
449448
450449 // Clear grace intent
@@ -755,7 +754,6 @@ const MenuItemImpl = React.forwardRef<MenuItemImplElement, MenuItemImplProps>(
755754 if ( ! event . defaultPrevented ) {
756755 const item = event . currentTarget ;
757756 item . focus ( { preventScroll : true } ) ;
758-
759757 }
760758 }
761759 } )
@@ -1154,49 +1152,35 @@ const MenuSubTrigger = React.forwardRef<MenuSubTriggerElement, MenuSubTriggerPro
11541152 const contentNearEdge = contentRect [ rightSide ? 'left' : 'right' ] ;
11551153 const contentFarEdge = contentRect [ rightSide ? 'right' : 'left' ] ;
11561154
1157- // In shadow DOM, we may need to adjust coordinates to ensure
1158- // both the mouse position and rectangle are in the same coordinate system
1159- let adjustedClientX = event . clientX ;
1160- let adjustedClientY = event . clientY ;
1161- const adjustedContentRect = contentRect ;
1162-
1155+ // Check if we're in shadow DOM for adjusted behavior
11631156 const eventTarget = event . target as Element ;
1164- const isInShadowDOM = eventTarget && eventTarget . getRootNode ( ) !== document && 'host' in eventTarget . getRootNode ( ) ;
1165-
1166- if ( isInShadowDOM && context . content ) {
1167- // Use native event coordinates for more reliable positioning in shadow DOM
1168- const nativeEvent = event . nativeEvent ;
1169- if ( nativeEvent ) {
1170- adjustedClientX = nativeEvent . clientX ;
1171- adjustedClientY = nativeEvent . clientY ;
1172- }
1173- }
1157+ const shadowDOM = isInShadowDOM ( eventTarget ) ;
11741158
11751159 contentContext . onPointerGraceIntentChange ( {
11761160 area : [
11771161 // Apply a bleed on clientX to ensure that our exit point is
11781162 // consistently within polygon bounds
1179- { x : adjustedClientX + bleed , y : adjustedClientY } ,
1180- { x : contentNearEdge , y : adjustedContentRect . top } ,
1181- { x : contentFarEdge , y : adjustedContentRect . top } ,
1182- { x : contentFarEdge , y : adjustedContentRect . bottom } ,
1183- { x : contentNearEdge , y : adjustedContentRect . bottom } ,
1163+ { x : event . clientX + bleed , y : event . clientY } ,
1164+ { x : contentNearEdge , y : contentRect . top } ,
1165+ { x : contentFarEdge , y : contentRect . top } ,
1166+ { x : contentFarEdge , y : contentRect . bottom } ,
1167+ { x : contentNearEdge , y : contentRect . bottom } ,
11841168 ] ,
11851169 side,
11861170 } ) ;
11871171
11881172 window . clearTimeout ( pointerGraceTimerRef . current ) ;
11891173
11901174 // Use longer grace period in shadow DOM since coordinate detection may be less reliable
1191- const gracePeriod = isInShadowDOM ? 800 : 300 ;
1175+ const gracePeriod = shadowDOM ? 800 : 300 ;
11921176
11931177 pointerGraceTimerRef . current = window . setTimeout (
11941178 ( ) => {
11951179 contentContext . onPointerGraceIntentChange ( null ) ;
11961180
11971181 // In shadow DOM, don't automatically close submenu on grace timer expiry
11981182 // Only close via explicit menu item selection logic
1199- if ( ! isInShadowDOM && context . open ) {
1183+ if ( ! shadowDOM && context . open ) {
12001184 // Normal behavior for non-shadow DOM
12011185 context . onOpenChange ( false ) ;
12021186 }
@@ -1404,17 +1388,14 @@ function isPointInPolygon(point: Point, polygon: Polygon) {
14041388
14051389function isPointerInGraceArea ( event : React . PointerEvent , area ?: Polygon ) {
14061390 if ( ! area ) return false ;
1407-
1408- // Use the most reliable coordinates available
1409- const nativeEvent = event . nativeEvent ;
1410- const cursorPos = {
1411- x : nativeEvent ? nativeEvent . clientX : event . clientX ,
1412- y : nativeEvent ? nativeEvent . clientY : event . clientY
1413- } ;
1414-
1391+ const cursorPos = { x : event . clientX , y : event . clientY } ;
14151392 return isPointInPolygon ( cursorPos , area ) ;
14161393}
14171394
1395+ function isInShadowDOM ( element : Element ) : boolean {
1396+ return element && element . getRootNode ( ) !== document && 'host' in element . getRootNode ( ) ;
1397+ }
1398+
14181399function whenMouse < E > ( handler : React . PointerEventHandler < E > ) : React . PointerEventHandler < E > {
14191400 return ( event ) => ( event . pointerType === 'mouse' ? handler ( event ) : undefined ) ;
14201401}
0 commit comments