Skip to content

Commit d9f82c8

Browse files
authored
fix(cdk/menu): not closing when inside shadow DOM (#26112)
Fixes that the CDK menu wasn't closing on outside clicks when the trigger is inside the shadow DOM. The problem is that reading the `Event.target` doesn't work as expected in the shadow DOM and we have to go through a helper. Fixes #26107.
1 parent 6fa02f2 commit d9f82c8

File tree

2 files changed

+20
-20
lines changed

2 files changed

+20
-20
lines changed

src/cdk/menu/context-menu-trigger.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
STANDARD_DROPDOWN_BELOW_POSITIONS,
1616
} from '@angular/cdk/overlay';
1717
import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion';
18+
import {_getEventTarget} from '@angular/cdk/platform';
1819
import {merge, partition} from 'rxjs';
1920
import {skip, takeUntil} from 'rxjs/operators';
2021
import {MENU_STACK, MenuStack} from './menu-stack';
@@ -191,7 +192,7 @@ export class CdkContextMenuTrigger extends CdkMenuTriggerBase implements OnDestr
191192
outsideClicks = merge(nonAuxClicks, auxClicks.pipe(skip(1)));
192193
}
193194
outsideClicks.pipe(takeUntil(this.stopOutsideClicksListener)).subscribe(event => {
194-
if (!this.isElementInsideMenuStack(event.target as Element)) {
195+
if (!this.isElementInsideMenuStack(_getEventTarget(event)!)) {
195196
this.menuStack.closeAll();
196197
}
197198
});

src/cdk/menu/menu-trigger.ts

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
SPACE,
2626
UP_ARROW,
2727
} from '@angular/cdk/keycodes';
28+
import {_getEventTarget} from '@angular/cdk/platform';
2829
import {fromEvent} from 'rxjs';
2930
import {filter, takeUntil} from 'rxjs/operators';
3031
import {CDK_MENU, Menu} from './menu-interface';
@@ -191,20 +192,20 @@ export class CdkMenuTrigger extends CdkMenuTriggerBase implements OnDestroy {
191192
* into.
192193
*/
193194
private _subscribeToMouseEnter() {
194-
// Closes any sibling menu items and opens the menu associated with this trigger.
195-
const toggleMenus = () =>
196-
this._ngZone.run(() => {
197-
this._closeSiblingTriggers();
198-
this.open();
199-
});
200-
201195
this._ngZone.runOutsideAngular(() => {
202196
fromEvent(this._elementRef.nativeElement, 'mouseenter')
203197
.pipe(
204198
filter(() => !this.menuStack.isEmpty() && !this.isOpen()),
205199
takeUntil(this.destroyed),
206200
)
207201
.subscribe(() => {
202+
// Closes any sibling menu items and opens the menu associated with this trigger.
203+
const toggleMenus = () =>
204+
this._ngZone.run(() => {
205+
this._closeSiblingTriggers();
206+
this.open();
207+
});
208+
208209
if (this._menuAim) {
209210
this._menuAim.toggle(toggleMenus);
210211
} else {
@@ -283,19 +284,17 @@ export class CdkMenuTrigger extends CdkMenuTriggerBase implements OnDestroy {
283284
if (this.overlayRef) {
284285
this.overlayRef
285286
.outsidePointerEvents()
286-
.pipe(
287-
filter(
288-
e =>
289-
e.target != this._elementRef.nativeElement &&
290-
!this._elementRef.nativeElement.contains(e.target as Element),
291-
),
292-
takeUntil(this.stopOutsideClicksListener),
293-
)
287+
.pipe(takeUntil(this.stopOutsideClicksListener))
294288
.subscribe(event => {
295-
if (!this.isElementInsideMenuStack(event.target as Element)) {
296-
this.menuStack.closeAll();
297-
} else {
298-
this._closeSiblingTriggers();
289+
const target = _getEventTarget(event) as Element;
290+
const element = this._elementRef.nativeElement;
291+
292+
if (target !== element && !element.contains(target)) {
293+
if (!this.isElementInsideMenuStack(target)) {
294+
this.menuStack.closeAll();
295+
} else {
296+
this._closeSiblingTriggers();
297+
}
299298
}
300299
});
301300
}

0 commit comments

Comments
 (0)