Building a custom slide-over with the Angular CDK Dialog

Building a custom slide-over with the Angular CDK Dialog
Photo by Edge2Edge Media / Unsplash

This is part 1 of a three-part series.

  1. Building a custom slide-over with the Angular CDK Dialog
  2. Animating a custom Angular CDK slide-over dialog
  3. Customisation options to the Angular CDK slide-over dialog

The Angular Component Development Kit (CDK) is

a set of behaviour primitives for building UI components

based on commonly used interaction patterns in a page such as dialogs, menus, overlays, scrolling and many more.

Using the Angular CDK simplifies the process of creating custom components, providing a rich set of features at your disposal.

With this in mind, let us build a custom slide-over component, on top of the Angular CDK Dialog, to see how well we can utilise it to develop custom modal dialogs and services.

This slide-over component will have the standard header, body and footer layout. The body will contain a registration form while the footer will contain two actions, Cancel and Save.

Custom slide-over using Angular CDK Dialog
ℹ️
The project used here was created using the latest versions of Angular (v16, as of the time of writing), Angular CDK and TailwindCSS.

Getting started

We begin by installing the Angular CDK into our project,

$ npm i @angular/cdk@latest

then importing the DialogModule into our component.

import { DialogModule } from '@angular/cdk/dialog';

As part of the initial setup, the prebuilt css styles need to be imported into the application's global stylesheet so the CDK modal dialog shows up correctly.

@import '@angular/cdk/overlay-prebuilt.css';

Import the prebuilt css to style a CDK modal dialog

Once set up, the CDK modal dialog is activated using the open function of the Dialog service. It accepts as first parameter, the component (or template) to show in the dialog.

import { Dialog } from '@angular/cdk/dialog';


#dialog = inject(Dialog);

openSlideOverSimple() {
  this.#dialog.open(UiSlideOverContentSimple);
}

Activating a CDK modal dialog

By default, an activated modal dialog is positioned globally in the middle of the page on top of a slightly opaque backdrop. Moreover, the html page scrolling is disabled too.

Default dialog content

Customisations

The second parameter of the open function exposes a DialogConfig, which allow customisations to the modal dialog, such as:

  • content data
  • scroll management
  • positioning
  • accessibility
  • and many more

We update the panelClass property with a custom css class or classes to, for example, define the space that the modal dialog can occupy in the page.

...
panelClass: ['w-72']
...

Customising the dialog panel

We update the positionStrategy property to specify a location for the dialog in the page.

...
positionStrategy: this.#overlay.position().global().end()
...

Customising the dialog position using the Overlay service

ℹ️
We use the OverlayPositionBuilder of the Angular CDK Overlay service to help us reposition the dialog, so make sure to import it.
import { Overlay } from '@angular/cdk/overlay';

Dialog data

Most of the time, a dialog needs data from various sources in order to present information effectively.

These are specified in the data property.

data: {
  registrationData: {
    username: 'dracula87',
    password: 'sup3rSecret!',
    rememberMe: true
  }
}

Customising the dialog data

To access and consume this data, we inject the DIALOG_DATA injection token into our dialog content component where these can be derived or use in a initialisation step.

import { DIALOG_DATA } from '@angular/cdk/dialog';

#dialogData = inject(DIALOG_DATA);

registrationData: {
  username: string;
  password: string;
  rememberMe: boolean;
} = {
  username: '',
  password: '',
  rememberMe: false
};

ngOnInit() {
  this.registrationData = {
    ...this.registrationData,
    ...this.#dialogData.registrationData
  };
}

Dialog result

In some cases, we need to receive and act on data resulting from the user's interaction with the dialog.

In order to do that, we need to inject the DialogRef and use its close method to pass the result to the calling function of the dialog.

In the calling component, we assign the dialogRef returned by the Dialog service's open method to a local variable and subscribe to its observable property closed to process the dialog result.

// in dialog content component .ts file

import { DialogRef } from '@angular/cdk/dialog'

#dialogRef = inject(DialogRef);

cancel() {
  this.#dialogRef.close();
}

save(registrationForm: NgForm) {
  if (registrationForm.invalid) {
    return;
  }
  this.#dialogRef.close(this.registrationData);
}


// in calling component .ts file
const dialogRef = this.#dialog.open(UiSlideOverContent, ...);

dialogRef.closed.pipe(take(1)).subscribe((result) => {
  if (!!result) {
    console.log("User's answers: " + JSON.stringify(result));
  } else {
    console.log('The user cancelled.');
  }
});

That's it. A custom slide-over component has now been created, powered by the Angular CDK Dialog, enabling us to present a custom component in a modal dialog and the ability to process the inputted form data afterwards.

The completed solution is provided below for your reference.

Reference

This post is heavily inspired by this article, Custom Overlays with Angular's CDK by Dominic Elm. This gave me clarity as to the power of the Angular CDK.

Next steps

In the next articles, we will add further capabilities to the custom slide-over like animation, templated dialog sections and many others, by exploring a few more of the Dialog's APIs.

Lhar Gil

Lhar Gil

Tech-savvy software developer and street photography enthusiast. Exploring the world through code and candid shots of daily life. 📸 All opinions are my own.
England