Angular CDK understanding the overlay position system

undefined picture undefined · Sep 20, 2018 · Viewed 15.2k times · Source

I'm really trying to understand the overlay position parameter but without any luck. I also can't find any documentation about this topic.

What does the following code mean?

const positions = [
  new ConnectionPositionPair({ originX: 'start', originY: 'bottom' }, { overlayX: 'start', overlayY: 'top' }),
  new ConnectionPositionPair({ originX: 'start', originY: 'top' }, { overlayX: 'start', overlayY: 'bottom' })
];
this.positionStrategy = this._overlay.position()
.flexibleConnectedTo(this.getConnectedElement())
.withPositions(positions)
.withFlexibleDimensions(false)
.withPush(false);

Answer

David Rinck picture David Rinck · Oct 17, 2018

There still isn't much documentation about the Angular Overlay CDK. Most of what I've learned has come from their Github repo.

Global Position Strategy

This would be a global positioning strategy. The overlay you are creating would be positioned directly on the screen, not in relation to an element. This is good for a dialog popup or modal window.

  overlayConfig = this.overlay.position().global()
    .centerHorizontally().centerVertically();

Flexible Connected To Strategy

This is what you want to use for Toolbars, menu, things that pop out of a button. You'll have to pass in a reference to your button you want the overlay to be connected to:

<button id="toolbar-icons" cdkOverlayOrigin mat-button class="toolbar-button" (click)="this.showAppContext()">

and in your Component.ts

showAppContext() {
  const appOverlayRef: AppOverlayRef = 
    this.appOverlayService.open(this.origin);
}

ConnectionPositionPair - this is a list of preferred positions, from most to least desirable. So it will first try to use the first position you pass in.

originX: This will be 'start', 'end', or 'center'. It is the attachment point for your overlay. If you have passed in a button to your .flexibleConnectedTo function, this refers to the start, end and center of that element.

originY: this will be 'top', 'bottom' or 'center'. This refers to the top, bottom or center of the element passed in.

So { originX: 'start', originY: 'bottom' } would be the bottom left hand corner of the button.

overlayX and overlayY have the same options, but refer to the where the overlay will be attached to. { overlayX: 'start', overlayY: 'top' } is attaching the upper left hand corner of the overlay to the origin we have specified.

Then, as you can see in the array, we can pass multiple positions in. If the overlay doesn't fit in the first position, it will try the next position in the array. So, if the overlay doesn't fit on the screen the first way, it will automatically shift to the second position, which is defined here as connecting the upper-left hand of the bottom to the bottom left hand of the overlay.

const positions = [
  new ConnectionPositionPair(
   { originX: 'start', originY: 'bottom' },
   { overlayX: 'start', overlayY: 'top' }),
  new ConnectionPositionPair(
  { originX: 'start', originY: 'top' },
  { overlayX: 'start', overlayY: 'bottom' })];
];

withPush

You can set withPush to true, which will push the overlay on-screen if none of the provided positions fit.

The code is still the best place to see the documentation: https://github.com/angular/material2/blob/master/src/cdk/overlay/position/connected-position.ts