Skip to content

Commit 73d1ceb

Browse files
mertdeg2jelbourn
authored andcommitted
feat(cdk/overlay): accept PositionStrategy in cdkConnectedOverlay (#16374)
1 parent 49b6dbd commit 73d1ceb

File tree

3 files changed

+37
-4
lines changed

3 files changed

+37
-4
lines changed

src/cdk/overlay/overlay-directives.spec.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
dispatchEvent,
99
} from '@angular/cdk/testing/private';
1010
import {ESCAPE, A} from '@angular/cdk/keycodes';
11-
import {CdkConnectedOverlay, OverlayModule, CdkOverlayOrigin} from './index';
11+
import {Overlay, CdkConnectedOverlay, OverlayModule, CdkOverlayOrigin} from './index';
1212
import {OverlayContainer} from './overlay-container';
1313
import {
1414
ConnectedOverlayPositionChange,
@@ -18,6 +18,7 @@ import {FlexibleConnectedPositionStrategy} from './position/flexible-connected-p
1818

1919

2020
describe('Overlay directives', () => {
21+
let overlay: Overlay;
2122
let overlayContainer: OverlayContainer;
2223
let overlayContainerElement: HTMLElement;
2324
let fixture: ComponentFixture<ConnectedOverlayDirectiveTest>;
@@ -36,8 +37,9 @@ describe('Overlay directives', () => {
3637
fixture.detectChanges();
3738
});
3839

39-
beforeEach(inject([OverlayContainer], (oc: OverlayContainer) => {
40+
beforeEach(inject([OverlayContainer, Overlay], (oc: OverlayContainer, o: Overlay) => {
4041
overlayContainer = oc;
42+
overlay = o;
4143
overlayContainerElement = oc.getContainerElement();
4244
}));
4345

@@ -62,6 +64,27 @@ describe('Overlay directives', () => {
6264
expect(overlayContainerElement.textContent).toBe('');
6365
});
6466

67+
it('can change positionStrategy via input', () => {
68+
const expectedPositionStrategy =
69+
overlay.position()
70+
.flexibleConnectedTo(document.body)
71+
.withFlexibleDimensions(true)
72+
.withPositions([
73+
74+
{originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'top'},
75+
]);
76+
fixture.componentInstance.isOpen = true;
77+
fixture.componentInstance.positionStrategy = expectedPositionStrategy;
78+
fixture.detectChanges();
79+
80+
const testComponent: ConnectedOverlayDirectiveTest = fixture.debugElement.componentInstance;
81+
const overlayDirective = testComponent.connectedOverlayDirective;
82+
const actualPositionStrategy = overlayDirective.overlayRef.getConfig().positionStrategy as
83+
FlexibleConnectedPositionStrategy;
84+
85+
expect(expectedPositionStrategy).toBe(actualPositionStrategy);
86+
});
87+
6588
it('should destroy the overlay when the directive is destroyed', () => {
6689
fixture.componentInstance.isOpen = true;
6790
fixture.detectChanges();
@@ -575,6 +598,7 @@ describe('Overlay directives', () => {
575598
[cdkConnectedOverlayOpen]="isOpen"
576599
[cdkConnectedOverlayWidth]="width"
577600
[cdkConnectedOverlayHeight]="height"
601+
[cdkConnectedOverlayPositionStrategy]="positionStrategy"
578602
[cdkConnectedOverlayOrigin]="triggerOverride || trigger"
579603
[cdkConnectedOverlayHasBackdrop]="hasBackdrop"
580604
[cdkConnectedOverlayViewportMargin]="viewportMargin"
@@ -606,6 +630,7 @@ class ConnectedOverlayDirectiveTest {
606630
width: number | string;
607631
height: number | string;
608632
minWidth: number | string;
633+
positionStrategy: FlexibleConnectedPositionStrategy;
609634
minHeight: number | string;
610635
offsetX: number;
611636
offsetY: number;

src/cdk/overlay/overlay-directives.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,12 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
122122
/** Registered connected position pairs. */
123123
@Input('cdkConnectedOverlayPositions') positions: ConnectedPosition[];
124124

125+
/**
126+
* This input overrides the positions input if specified. It lets users pass
127+
* in arbitrary positioning strategies.
128+
*/
129+
@Input('cdkConnectedOverlayPositionStrategy') positionStrategy: FlexibleConnectedPositionStrategy;
130+
125131
/** The offset in pixels for the overlay connection point on the x-axis */
126132
@Input('cdkConnectedOverlayOffsetX')
127133
get offsetX(): number { return this._offsetX; }
@@ -287,7 +293,8 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
287293

288294
/** Builds the overlay config based on the directive's inputs */
289295
private _buildConfig(): OverlayConfig {
290-
const positionStrategy = this._position = this._createPositionStrategy();
296+
const positionStrategy = this._position =
297+
this.positionStrategy || this._createPositionStrategy();
291298
const overlayConfig = new OverlayConfig({
292299
direction: this._dir,
293300
positionStrategy,

tools/public_api_guard/cdk/overlay.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export declare class CdkConnectedOverlay implements OnDestroy, OnChanges {
2626
readonly overlayRef: OverlayRef;
2727
panelClass: string | string[];
2828
positionChange: EventEmitter<ConnectedOverlayPositionChange>;
29+
positionStrategy: FlexibleConnectedPositionStrategy;
2930
positions: ConnectedPosition[];
3031
push: boolean;
3132
scrollStrategy: ScrollStrategy;
@@ -40,7 +41,7 @@ export declare class CdkConnectedOverlay implements OnDestroy, OnChanges {
4041
static ngAcceptInputType_hasBackdrop: boolean | string | null | undefined;
4142
static ngAcceptInputType_lockPosition: boolean | string | null | undefined;
4243
static ngAcceptInputType_push: boolean | string | null | undefined;
43-
static ɵdir: i0.ɵɵDirectiveDefWithMeta<CdkConnectedOverlay, "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", ["cdkConnectedOverlay"], { 'origin': "cdkConnectedOverlayOrigin", 'positions': "cdkConnectedOverlayPositions", 'offsetX': "cdkConnectedOverlayOffsetX", 'offsetY': "cdkConnectedOverlayOffsetY", 'width': "cdkConnectedOverlayWidth", 'height': "cdkConnectedOverlayHeight", 'minWidth': "cdkConnectedOverlayMinWidth", 'minHeight': "cdkConnectedOverlayMinHeight", 'backdropClass': "cdkConnectedOverlayBackdropClass", 'panelClass': "cdkConnectedOverlayPanelClass", 'viewportMargin': "cdkConnectedOverlayViewportMargin", 'scrollStrategy': "cdkConnectedOverlayScrollStrategy", 'open': "cdkConnectedOverlayOpen", 'transformOriginSelector': "cdkConnectedOverlayTransformOriginOn", 'hasBackdrop': "cdkConnectedOverlayHasBackdrop", 'lockPosition': "cdkConnectedOverlayLockPosition", 'flexibleDimensions': "cdkConnectedOverlayFlexibleDimensions", 'growAfterOpen': "cdkConnectedOverlayGrowAfterOpen", 'push': "cdkConnectedOverlayPush" }, { 'backdropClick': "backdropClick", 'positionChange': "positionChange", 'attach': "attach", 'detach': "detach", 'overlayKeydown': "overlayKeydown" }, never>;
44+
static ɵdir: i0.ɵɵDirectiveDefWithMeta<CdkConnectedOverlay, "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", ["cdkConnectedOverlay"], { 'origin': "cdkConnectedOverlayOrigin", 'positions': "cdkConnectedOverlayPositions", 'positionStrategy': "cdkConnectedOverlayPositionStrategy", 'offsetX': "cdkConnectedOverlayOffsetX", 'offsetY': "cdkConnectedOverlayOffsetY", 'width': "cdkConnectedOverlayWidth", 'height': "cdkConnectedOverlayHeight", 'minWidth': "cdkConnectedOverlayMinWidth", 'minHeight': "cdkConnectedOverlayMinHeight", 'backdropClass': "cdkConnectedOverlayBackdropClass", 'panelClass': "cdkConnectedOverlayPanelClass", 'viewportMargin': "cdkConnectedOverlayViewportMargin", 'scrollStrategy': "cdkConnectedOverlayScrollStrategy", 'open': "cdkConnectedOverlayOpen", 'transformOriginSelector': "cdkConnectedOverlayTransformOriginOn", 'hasBackdrop': "cdkConnectedOverlayHasBackdrop", 'lockPosition': "cdkConnectedOverlayLockPosition", 'flexibleDimensions': "cdkConnectedOverlayFlexibleDimensions", 'growAfterOpen': "cdkConnectedOverlayGrowAfterOpen", 'push': "cdkConnectedOverlayPush" }, { 'backdropClick': "backdropClick", 'positionChange': "positionChange", 'attach': "attach", 'detach': "detach", 'overlayKeydown': "overlayKeydown" }, never>;
4445
static ɵfac: i0.ɵɵFactoryDef<CdkConnectedOverlay>;
4546
}
4647

0 commit comments

Comments
 (0)