Skip to content

Commit 68d7028

Browse files
committed
fix(cdk/overlay): skip trigger interactions in outside click event
Adds some logic to skip the trigger when considering clicks outside of the overlay since filtering them is the most common case (e.g. we do it in some of our components) and can be annoying to deal with. Fixes #28949.
1 parent 37958ef commit 68d7028

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

src/cdk/overlay/overlay-directives.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
booleanAttribute,
2828
inject,
2929
} from '@angular/core';
30+
import {_getEventTarget} from '@angular/cdk/platform';
3031
import {Subscription} from 'rxjs';
3132
import {takeWhile} from 'rxjs/operators';
3233
import {Overlay} from './overlay';
@@ -311,7 +312,12 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
311312
});
312313

313314
this._overlayRef.outsidePointerEvents().subscribe((event: MouseEvent) => {
314-
this.overlayOutsideClick.next(event);
315+
const origin = this._getOriginElement();
316+
const target = _getEventTarget(event) as Element | null;
317+
318+
if (!target || !origin || (origin !== target && !origin.contains(target))) {
319+
this.overlayOutsideClick.next(event);
320+
}
315321
});
316322
}
317323

@@ -367,7 +373,7 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
367373
}));
368374

369375
return positionStrategy
370-
.setOrigin(this._getFlexibleConnectedPositionStrategyOrigin())
376+
.setOrigin(this._getOrigin())
371377
.withPositions(positions)
372378
.withFlexibleDimensions(this.flexibleDimensions)
373379
.withPush(this.push)
@@ -379,21 +385,35 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
379385

380386
/** Returns the position strategy of the overlay to be set on the overlay config */
381387
private _createPositionStrategy(): FlexibleConnectedPositionStrategy {
382-
const strategy = this._overlay
383-
.position()
384-
.flexibleConnectedTo(this._getFlexibleConnectedPositionStrategyOrigin());
388+
const strategy = this._overlay.position().flexibleConnectedTo(this._getOrigin());
385389
this._updatePositionStrategy(strategy);
386390
return strategy;
387391
}
388392

389-
private _getFlexibleConnectedPositionStrategyOrigin(): FlexibleConnectedPositionStrategyOrigin {
393+
private _getOrigin(): FlexibleConnectedPositionStrategyOrigin {
390394
if (this.origin instanceof CdkOverlayOrigin) {
391395
return this.origin.elementRef;
392396
} else {
393397
return this.origin;
394398
}
395399
}
396400

401+
private _getOriginElement(): Element | null {
402+
if (this.origin instanceof CdkOverlayOrigin) {
403+
return this.origin.elementRef.nativeElement;
404+
}
405+
406+
if (this.origin instanceof ElementRef) {
407+
return this.origin.nativeElement;
408+
}
409+
410+
if (typeof Element !== 'undefined' && this.origin instanceof Element) {
411+
return this.origin;
412+
}
413+
414+
return null;
415+
}
416+
397417
/** Attaches the overlay and subscribes to backdrop clicks if backdrop exists */
398418
private _attachOverlay() {
399419
if (!this._overlayRef) {

0 commit comments

Comments
 (0)