Learn how to create an overlay with Angular Material CDK
- Installation
- Overlay component creation
- Parent component
- Passing data to overlay component
- Close overlay
-
npm install --save @angular/material @angular/cdk @angular/animations
-
Import
OverlayModule
in your app module:
import { OverlayModule } from '@angular/cdk/overlay';
@NgModule({
imports: [
...,
OverlayModule
],
...
})
export class AppModule { }
- Create a new component (ex: OverlayComponent):
ng generate component overlay
- Add cdkOverlayOrigin to an element of the template:
<button cdkOverlayOrigin (click)="displayOverlay()" #trigger="cdkOverlayOrigin">Click me!</button>
- Import the following:
import { CdkConnectedOverlay } from '@angular/cdk/overlay';
import { Component } from '@angular/core';
- Add overlay options inside parent component, and functions for displaying / hiding overlay
export class AppComponent {
public isOverlayDisplayed = false;
public readonly overlayOptions: Partial<CdkConnectedOverlay> = {
hasBackdrop: true,
positions: [
{ originX: 'end', originY: 'bottom', overlayX: 'start', overlayY: 'top'}
],
/* You can add to this object all of these options */
// backdropClass: '',
// flexibleDimensions: false,
// growAfterOpen: false,
// height: 'auto',
// width: 'auto',
// lockPosition: true,
// minHeight: 'unset',
// minWidth: 'unset',
// offsetX: 0,
// offsetY: 0,
// panelClass: '',
// positionStrategy,
// push,
// scrollStrategy,
// transformOriginSelector,
// viewportMargin,
};
constructor() { }
public displayOverlay(): void {
this.isOverlayDisplayed = true;
}
public hideOverlay(): void {
this.isOverlayDisplayed = false;
}
}
- Add overlay in parent template with optionnal configuration
<ng-template
#connectedOverlay="cdkConnectedOverlay"
cdkConnectedOverlay
[cdkConnectedOverlayOrigin]="trigger"
[cdkConnectedOverlayOpen]="isOverlayDisplayed"
[cdkConnectedOverlayHasBackdrop]="overlayOptions.hasBackdrop"
[cdkConnectedOverlayPositions]="overlayOptions.positions">
<app-overlay></app-overlay> <!-- Your overlay component -->
</ng-template>
- Create an input property inside overlay component
export class OverlayComponent {
@Input() data: { msg: string };
...
}
- Pass data through parent component
...
<app-overlay [data]="{msg: 'Your data'}"></app-overlay>
...
- Display it in the overlay template
<div class="overlay-container">
<p>This is the injected data: {{ data.msg }}</p>
</div>
- Option 1: On backdrop click When 'hasBackdrop' option is activated, a backdropClick event is emitted. We can get it in parent component as follow.
...
<ng-template
#connectedOverlay="cdkConnectedOverlay"
cdkConnectedOverlay
[cdkConnectedOverlayOrigin]="trigger"
[cdkConnectedOverlayOpen]="isOverlayDisplayed"
[cdkConnectedOverlayHasBackdrop]="overlayOptions.hasBackdrop"
[cdkConnectedOverlayPositions]="overlayOptions.positions"
(backdropClick)="hideOverlay()">
<app-overlay [data]="{msg: 'Your data'}"></app-overlay>
</ng-template>
...
- Option 2: From overlay component
In the parent component:
- listen to detach event, in order to update isOverlayDisplayed property
- pass connectedOverlay as an input of overlay component
...
<ng-template
#connectedOverlay="cdkConnectedOverlay"
cdkConnectedOverlay
[cdkConnectedOverlayOrigin]="trigger"
[cdkConnectedOverlayOpen]="isOverlayDisplayed"
[cdkConnectedOverlayHasBackdrop]="overlayOptions.hasBackdrop"
[cdkConnectedOverlayPositions]="overlayOptions.positions"
(backdropClick)="hideOverlay()"
(detach)="hideOverlay()">
<app-overlay [data]="{msg: 'Your data'}" [connectedOverlay]="connectedOverlay"></app-overlay>
</ng-template>
...
In the overlay component, add a button to close:
<div class="overlay-container">
<p>This is the injected data: {{ data.data }}</p>
<div>
<button mat-raised-button (click)="close()">Close me!</button>
</div>
</div>
And the associated controller:
export class OverlayComponent {
...
@Input() connectedOverlay: CdkConnectedOverlay;
...
public close(): void {
this.connectedOverlay.overlayRef.detach();
}
...