Skip to content

Commit 9430986

Browse files
committed
refactor(cdk/overlay): allow connected overlays to stay in the overlay container
Adds an API that allows connected overlays to decide if they should be inline or in the overlay container when they're rendered out as popovers. (cherry picked from commit 1a92e22)
1 parent 2b2cb66 commit 9430986

File tree

5 files changed

+48
-22
lines changed

5 files changed

+48
-22
lines changed

goldens/cdk/overlay/index.api.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,6 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
7777
// (undocumented)
7878
static ngAcceptInputType_push: unknown;
7979
// (undocumented)
80-
static ngAcceptInputType_usePopover: unknown;
81-
// (undocumented)
8280
ngOnChanges(changes: SimpleChanges): void;
8381
// (undocumented)
8482
ngOnDestroy(): void;
@@ -98,7 +96,7 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
9896
push: boolean;
9997
scrollStrategy: ScrollStrategy;
10098
transformOriginSelector: string;
101-
usePopover: boolean;
99+
usePopover: FlexibleOverlayPopoverLocation | null;
102100
viewportMargin: ViewportMargin;
103101
width: number | string;
104102
// (undocumented)
@@ -150,7 +148,7 @@ export interface CdkConnectedOverlayConfig {
150148
// (undocumented)
151149
transformOriginSelector?: string;
152150
// (undocumented)
153-
usePopover?: boolean;
151+
usePopover?: FlexibleOverlayPopoverLocation | null;
154152
// (undocumented)
155153
viewportMargin?: ViewportMargin;
156154
// (undocumented)
@@ -286,7 +284,7 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy {
286284
// (undocumented)
287285
detach(): void;
288286
dispose(): void;
289-
getPopoverInsertionPoint(): Element;
287+
getPopoverInsertionPoint(): Element | null;
290288
_origin: FlexibleConnectedPositionStrategyOrigin;
291289
positionChanges: Observable<ConnectedOverlayPositionChange>;
292290
get positions(): ConnectionPositionPair[];
@@ -298,6 +296,7 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy {
298296
withFlexibleDimensions(flexibleDimensions?: boolean): this;
299297
withGrowAfterOpen(growAfterOpen?: boolean): this;
300298
withLockedPosition(isLocked?: boolean): this;
299+
withPopoverLocation(location: FlexibleOverlayPopoverLocation): this;
301300
withPositions(positions: ConnectedPosition[]): this;
302301
withPush(canPush?: boolean): this;
303302
withScrollableContainers(scrollables: CdkScrollable[]): this;
@@ -311,6 +310,9 @@ export type FlexibleConnectedPositionStrategyOrigin = ElementRef | Element | (Po
311310
height?: number;
312311
});
313312

313+
// @public
314+
export type FlexibleOverlayPopoverLocation = 'global' | 'inline';
315+
314316
// @public
315317
export class FullscreenOverlayContainer extends OverlayContainer implements OnDestroy {
316318
constructor(...args: unknown[]);

src/cdk/overlay/overlay-directives.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import {
3838
createFlexibleConnectedPositionStrategy,
3939
FlexibleConnectedPositionStrategy,
4040
FlexibleConnectedPositionStrategyOrigin,
41+
FlexibleOverlayPopoverLocation,
4142
} from './position/flexible-connected-position-strategy';
4243
import {createRepositionScrollStrategy, ScrollStrategy} from './scroll/index';
4344

@@ -127,7 +128,7 @@ export interface CdkConnectedOverlayConfig {
127128
growAfterOpen?: boolean;
128129
push?: boolean;
129130
disposeOnNavigation?: boolean;
130-
usePopover?: boolean;
131+
usePopover?: FlexibleOverlayPopoverLocation | null;
131132
matchWidth?: boolean;
132133
}
133134

@@ -251,8 +252,8 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
251252
disposeOnNavigation: boolean = false;
252253

253254
/** Whether the connected overlay should be rendered inside a popover element or the overlay container. */
254-
@Input({alias: 'cdkConnectedOverlayUsePopover', transform: booleanAttribute})
255-
usePopover: boolean = false;
255+
@Input({alias: 'cdkConnectedOverlayUsePopover'})
256+
usePopover: FlexibleOverlayPopoverLocation | null = null;
256257

257258
/** Whether the overlay should match the trigger's width. */
258259
@Input({alias: 'cdkConnectedOverlayMatchWidth', transform: booleanAttribute})
@@ -377,7 +378,7 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
377378
scrollStrategy: this.scrollStrategy,
378379
hasBackdrop: this.hasBackdrop,
379380
disposeOnNavigation: this.disposeOnNavigation,
380-
usePopover: this.usePopover,
381+
usePopover: !!this.usePopover,
381382
});
382383

383384
if (this.height || this.height === 0) {
@@ -423,7 +424,8 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
423424
.withGrowAfterOpen(this.growAfterOpen)
424425
.withViewportMargin(this.viewportMargin)
425426
.withLockedPosition(this.lockPosition)
426-
.withTransformOriginOn(this.transformOriginSelector);
427+
.withTransformOriginOn(this.transformOriginSelector)
428+
.withPopoverLocation(this.usePopover === 'global' ? 'global' : 'inline');
427429
}
428430

429431
/** Returns the position strategy of the overlay to be set on the overlay config */

src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2964,17 +2964,16 @@ describe('FlexibleConnectedPositionStrategy', () => {
29642964
originElement = createPositionedBlockElement();
29652965
document.body.appendChild(originElement);
29662966

2967-
positionStrategy = createFlexibleConnectedPositionStrategy(
2968-
injector,
2969-
originElement,
2970-
).withPositions([
2971-
{
2972-
overlayX: 'start',
2973-
overlayY: 'top',
2974-
originX: 'start',
2975-
originY: 'bottom',
2976-
},
2977-
]);
2967+
positionStrategy = createFlexibleConnectedPositionStrategy(injector, originElement)
2968+
.withPopoverLocation('inline')
2969+
.withPositions([
2970+
{
2971+
overlayX: 'start',
2972+
overlayY: 'top',
2973+
originX: 'start',
2974+
originY: 'bottom',
2975+
},
2976+
]);
29782977
});
29792978

29802979
afterEach(() => {

src/cdk/overlay/position/flexible-connected-position-strategy.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ export function createFlexibleConnectedPositionStrategy(
6363
);
6464
}
6565

66+
/** Supported locations in the DOM for connected overlays. */
67+
export type FlexibleOverlayPopoverLocation = 'global' | 'inline';
68+
6669
/**
6770
* A strategy for positioning overlays. Using this strategy, an overlay is given an
6871
* implicit position relative some origin element. The relative position is defined in terms of
@@ -158,6 +161,9 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy {
158161
/** Amount by which the overlay was pushed in each axis during the last time it was positioned. */
159162
private _previousPushAmount: {x: number; y: number} | null;
160163

164+
/** Configures where in the DOM to insert the overlay when popovers are enabled. */
165+
private _popoverLocation: FlexibleOverlayPopoverLocation = 'global';
166+
161167
/** Observable sequence of position changes. */
162168
positionChanges: Observable<ConnectedOverlayPositionChange> = this._positionChanges;
163169

@@ -511,8 +517,24 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy {
511517
return this;
512518
}
513519

520+
/**
521+
* Determines where in the DOM the overlay will be rendered when popover mode is enabled.
522+
* @param location Configures the location in the DOM. Supports the following values:
523+
* - `global` - The default which inserts the overlay inside the overlay container.
524+
* - `inline` - Inserts the overlay next to the trigger.
525+
*/
526+
withPopoverLocation(location: FlexibleOverlayPopoverLocation): this {
527+
this._popoverLocation = location;
528+
return this;
529+
}
530+
514531
/** @docs-private */
515-
getPopoverInsertionPoint(): Element {
532+
getPopoverInsertionPoint(): Element | null {
533+
// Return null so it falls back to inserting into the overlay container.
534+
if (this._popoverLocation === 'global') {
535+
return null;
536+
}
537+
516538
const origin = this._origin;
517539

518540
if (origin instanceof ElementRef) {

src/cdk/overlay/public-api.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export {
3232
createGlobalPositionStrategy,
3333
} from './position/global-position-strategy';
3434
export {
35+
FlexibleOverlayPopoverLocation,
3536
ConnectedPosition,
3637
FlexibleConnectedPositionStrategy,
3738
FlexibleConnectedPositionStrategyOrigin,

0 commit comments

Comments
 (0)