Skip to content

Commit 0bb7b18

Browse files
authored
fix(cdk/overlay): expose currently open overlays (#33768)
Adds the `getAttachedOverlays` function that allows users to check which overlays are open at the moment.
1 parent c330818 commit 0bb7b18

4 files changed

Lines changed: 37 additions & 1 deletion

File tree

‎goldens/cdk/overlay/index.api.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,9 @@ export class FullscreenOverlayContainer extends OverlayContainer implements OnDe
332332
static ɵprov: i0.ɵɵInjectableDeclaration<FullscreenOverlayContainer>;
333333
}
334334

335+
// @public
336+
export function getAttachedOverlays(): OverlayRef[];
337+
335338
// @public
336339
export class GlobalPositionStrategy implements PositionStrategy {
337340
apply(): void;

‎src/cdk/overlay/overlay-ref.ts‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ export function isElement(value: any): value is Element {
3737
return value && (value as Element).nodeType === 1;
3838
}
3939

40+
const attachedOverlays = new Set<OverlayRef>();
41+
42+
/** Gets all overlays that are currently attached. */
43+
export function getAttachedOverlays(): OverlayRef[] {
44+
return Array.from(attachedOverlays);
45+
}
46+
4047
/**
4148
* Reference to an overlay that has been created with the Overlay service.
4249
* Used to manipulate or dispose of said overlay.
@@ -142,6 +149,7 @@ export class OverlayRef implements PortalOutlet {
142149
this._updateStackingOrder();
143150
this._updateElementSize();
144151
this._updateElementDirection();
152+
attachedOverlays.add(this);
145153

146154
if (this._scrollStrategy) {
147155
this._scrollStrategy.enable();
@@ -248,6 +256,7 @@ export class OverlayRef implements PortalOutlet {
248256
this._detachContentWhenEmpty();
249257
this._locationChanges.unsubscribe();
250258
this._outsideClickDispatcher.remove(this);
259+
attachedOverlays.delete(this);
251260
return detachmentResult;
252261
}
253262

@@ -284,6 +293,7 @@ export class OverlayRef implements PortalOutlet {
284293
this._detachments.complete();
285294
this._completeDetachContent();
286295
this._disposed = true;
296+
attachedOverlays.delete(this);
287297
}
288298

289299
/** Whether the overlay has attached content. */

‎src/cdk/overlay/overlay.spec.ts‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
PositionStrategy,
3030
ScrollStrategy,
3131
createOverlayRef,
32+
getAttachedOverlays,
3233
} from './index';
3334

3435
describe('Overlay', () => {
@@ -478,6 +479,28 @@ describe('Overlay', () => {
478479
expect(document.querySelector('.cdk-overlay-pane')).toBeFalsy();
479480
});
480481

482+
it('should track when an overlay is attached and detached', () => {
483+
const overlayRef = createOverlayRef(injector);
484+
expect(getAttachedOverlays()).toEqual([]);
485+
486+
overlayRef.attach(componentPortal);
487+
expect(getAttachedOverlays()).toEqual([overlayRef]);
488+
489+
overlayRef.detach();
490+
expect(getAttachedOverlays()).toEqual([]);
491+
});
492+
493+
it('should track when an overlay is attached and disposed', () => {
494+
const overlayRef = createOverlayRef(injector);
495+
expect(getAttachedOverlays()).toEqual([]);
496+
497+
overlayRef.attach(componentPortal);
498+
expect(getAttachedOverlays()).toEqual([overlayRef]);
499+
500+
overlayRef.dispose();
501+
expect(getAttachedOverlays()).toEqual([]);
502+
});
503+
481504
describe('positioning', () => {
482505
let config: OverlayConfig;
483506

‎src/cdk/overlay/public-api.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export {
2020
CDK_CONNECTED_OVERLAY_DEFAULT_CONFIG,
2121
} from './overlay-directives';
2222
export {FullscreenOverlayContainer} from './fullscreen-overlay-container';
23-
export {OverlayRef, OverlaySizeConfig} from './overlay-ref';
23+
export {OverlayRef, OverlaySizeConfig, getAttachedOverlays} from './overlay-ref';
2424
export {ViewportRuler} from '../scrolling';
2525
export {ComponentType} from '../portal';
2626
export {OverlayPositionBuilder} from './position/overlay-position-builder';

0 commit comments

Comments
 (0)