Skip to content

Commit 4ec3abd

Browse files
committed
fix(cdk/overlay): don't close if scroll is coming from inside overlay (#26840)
Fixes that the `CloseScrollStrategy` was being triggered by scrollables inside the overlay. Fixes #26780. (cherry picked from commit 24fab99)
1 parent 600d40e commit 4ec3abd

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

src/cdk/overlay/scroll/close-scroll-strategy.spec.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import {inject, TestBed, fakeAsync} from '@angular/core/testing';
2-
import {Component, NgZone} from '@angular/core';
2+
import {Component, ElementRef, NgZone} from '@angular/core';
33
import {Subject} from 'rxjs';
44
import {ComponentPortal, PortalModule} from '@angular/cdk/portal';
5-
import {ScrollDispatcher, ViewportRuler} from '@angular/cdk/scrolling';
5+
import {CdkScrollable, ScrollDispatcher, ViewportRuler} from '@angular/cdk/scrolling';
66
import {Overlay, OverlayConfig, OverlayRef, OverlayModule, OverlayContainer} from '../index';
77

88
describe('CloseScrollStrategy', () => {
99
let overlayRef: OverlayRef;
1010
let componentPortal: ComponentPortal<MozarellaMsg>;
11-
let scrolledSubject = new Subject();
11+
let scrolledSubject = new Subject<CdkScrollable | undefined>();
1212
let scrollPosition: number;
1313

1414
beforeEach(fakeAsync(() => {
@@ -55,6 +55,16 @@ describe('CloseScrollStrategy', () => {
5555
expect(overlayRef.detach).toHaveBeenCalled();
5656
});
5757

58+
it('should not detach if the scrollable is inside the overlay', () => {
59+
overlayRef.attach(componentPortal);
60+
spyOn(overlayRef, 'detach');
61+
62+
scrolledSubject.next({
63+
getElementRef: () => new ElementRef(overlayRef.overlayElement),
64+
} as CdkScrollable);
65+
expect(overlayRef.detach).not.toHaveBeenCalled();
66+
});
67+
5868
it('should not attempt to detach the overlay after it has been detached', () => {
5969
overlayRef.attach(componentPortal);
6070
overlayRef.detach();

src/cdk/overlay/scroll/close-scroll-strategy.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {ScrollStrategy, getMatScrollStrategyAlreadyAttachedError} from './scroll
1010
import {OverlayReference} from '../overlay-reference';
1111
import {Subscription} from 'rxjs';
1212
import {ScrollDispatcher, ViewportRuler} from '@angular/cdk/scrolling';
13+
import {filter} from 'rxjs/operators';
1314

1415
/**
1516
* Config options for the CloseScrollStrategy.
@@ -49,7 +50,14 @@ export class CloseScrollStrategy implements ScrollStrategy {
4950
return;
5051
}
5152

52-
const stream = this._scrollDispatcher.scrolled(0);
53+
const stream = this._scrollDispatcher.scrolled(0).pipe(
54+
filter(scrollable => {
55+
return (
56+
!scrollable ||
57+
!this._overlayRef.overlayElement.contains(scrollable.getElementRef().nativeElement)
58+
);
59+
}),
60+
);
5361

5462
if (this._config && this._config.threshold && this._config.threshold > 1) {
5563
this._initialScrollPosition = this._viewportRuler.getViewportScrollPosition().top;

0 commit comments

Comments
 (0)