Mastering Angular Material Dialogs (mat-dialog) with Practical Examples

by Didin J. on Jul 07, 2025 Mastering Angular Material Dialogs (mat-dialog) with Practical Examples

Learn how to use Angular Material Dialog (mat-dialog) with real examples, forms, data passing, styling, animations, and reusable components.

Angular Material is a UI component library that provides modern, responsive, and accessible UI elements for Angular applications. One of its most powerful features is the mat-dialog service, which enables developers to create modal dialogs for user interactions such as confirmations, form inputs, alerts, and custom content popups.

In this tutorial, you’ll learn how to master the mat-dialog component with real-world examples. We’ll walk through creating a dialog, passing data to it, receiving results, and building reusable dialog components with various practical use cases.

Whether you’re building a confirmation popup, a form inside a modal, or a complex interactive dialog, this guide will help you use Angular Material dialogs effectively.

Prerequisites

Before you begin, make sure you have the following installed on your system:

  • Node.js (v18 or later)

  • Angular CLI (v20 or later)

  • Basic understanding of Angular components, services, and modules

You can check your versions by running:

node -v
ng version

If you don’t have Angular CLI installed:

npm install -g @angular/cli


Setting Up the Angular Project

1. Create a new Angular app

ng new angular-material-dialog-example

When prompted:

  • Add Angular routing: Yes

  • Choose stylesheet format: SCSS (or your preference)

Navigate into the project folder:

cd angular-material-dialog-example

2. Install Angular Material

ng add @angular/material

Select a theme (e.g., Indigo/Pink) and enable animations when prompted.

This will automatically:

  • Add @angular/material, @angular/cdk, and @angular/animations

  • Import a prebuilt theme into angular.json

  • Enable animations in app.module.ts

3. Run the App

Make sure everything is working by running:

ng serve

Visit http://localhost:4200/ in your browser. You should see the default Angular app homepage.

Mastering Angular Material Dialogs (mat-dialog) with Practical Examples - ng serve


Creating and Opening a Dialog Component

In Angular Material, dialogs are typically standalone components that are launched via the MatDialog service. In this section, we’ll create a basic dialog and show how to open it from a button click in the main component.

Step 1: Generate the Dialog Component

We’ll generate a separate component for the dialog content.

ng generate component confirm-dialog

This will create the confirm-dialog component in the src/app/ directory.

Step 2: Design the Confirm Dialog Component

Edit confirm-dialog.ts to make it a simple confirmation dialog:

import { CommonModule } from '@angular/common';
import { Component, Inject } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';

@Component({
  selector: 'app-confirm-dialog',
  imports: [
    CommonModule,
    MatDialogModule,
    MatButtonModule
  ],
  templateUrl: './confirm-dialog.html',
  styleUrl: './confirm-dialog.scss'
})
export class ConfirmDialog {
  constructor(
    public dialogRef: MatDialogRef<ConfirmDialog>,
    @Inject(MAT_DIALOG_DATA) public data: { message: string }
  ) { }

  onConfirm(): void {
    this.dialogRef.close(true);
  }

  onCancel(): void {
    this.dialogRef.close(false);
  }
}

Then edit the confirm-dialog.html:

<h2 mat-dialog-title>Confirm</h2>
<mat-dialog-content>{{ data.message }}</mat-dialog-content>
<mat-dialog-actions align="end">
  <button mat-button (click)="onCancel()">Cancel</button>
  <button mat-raised-button color="primary" (click)="onConfirm()">Confirm</button>
</mat-dialog-actions>

Step 3: Open the Dialog from AppComponent

Edit app.ts to open the dialog when a button is clicked:

import { Component } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { RouterOutlet } from '@angular/router';
import { ConfirmDialog } from './confirm-dialog/confirm-dialog';

@Component({
  selector: 'app-root',
  imports: [RouterOutlet],
  templateUrl: './app.html',
  styleUrl: './app.scss'
})
export class App {
  constructor(private dialog: MatDialog) { }

  openConfirmDialog(): void {
    const dialogRef = this.dialog.open(ConfirmDialog, {
      width: '350px',
      data: { message: 'Are you sure you want to proceed?' }
    });

    dialogRef.afterClosed().subscribe(result => {
      if (result) {
        console.log('User confirmed');
      } else {
        console.log('User cancelled');
      }
    });
  }
}

And update the app.html to include a trigger button:

<div style="text-align:center; margin-top: 100px;">
  <h1>Angular Material Dialog Example</h1>
  <button mat-raised-button color="primary" (click)="openConfirmDialog()">
    Open Confirm Dialog
  </button>
</div>

You now have a working confirmation dialog! Clicking the button opens the dialog, and the response is logged in the console.

Mastering Angular Material Dialogs (mat-dialog) with Practical Examples

Mastering Angular Material Dialogs (mat-dialog) with Practical Examples - dialog


Adding a Form Inside a Dialog

We’ll create a new dialog component that contains a simple form with fields like name and email, and then open it from the main component.

Step 1: Generate the Form Dialog Component

ng generate component form-dialog

This creates the form-dialog component inside src/app/.

Step 2: Create the Form in the Dialog Component

form-dialog.ts:

import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
import { MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';

@Component({
  selector: 'app-form-dialog',
  imports: [
    CommonModule,
    ReactiveFormsModule,
    MatDialogModule,
    MatFormFieldModule,
    MatInputModule
  ],
  templateUrl: './form-dialog.html',
  styleUrl: './form-dialog.scss'
})
export class FormDialog {
  form: FormGroup;

  constructor(
    private fb: FormBuilder,
    private dialogRef: MatDialogRef<FormDialog>
  ) {
    this.form = this.fb.group({
      name: ['', Validators.required],
      email: ['', [Validators.required, Validators.email]]
    });
  }

  onSubmit(): void {
    if (this.form.valid) {
      this.dialogRef.close(this.form.value);
    }
  }

  onCancel(): void {
    this.dialogRef.close();
  }
}

form-dialog.html:

<h2 mat-dialog-title>Enter Your Details</h2>
<mat-dialog-content [formGroup]="form">
  <mat-form-field appearance="fill" class="w-full">
    <mat-label>Name</mat-label>
    <input matInput formControlName="name" />
  </mat-form-field>

  <mat-form-field appearance="fill" class="w-full">
    <mat-label>Email</mat-label>
    <input matInput formControlName="email" />
  </mat-form-field>
</mat-dialog-content>

<mat-dialog-actions align="end">
  <button mat-button (click)="onCancel()">Cancel</button>
  <button
    mat-raised-button
    color="primary"
    (click)="onSubmit()"
    [disabled]="form.invalid"
  >
    Submit
  </button>
</mat-dialog-actions>

And style it a bit in form-dialog.scss (optional):

mat-form-field {
  width: 100%;
  margin-bottom: 12px;
}

Step 3: Open the Form Dialog from AppComponent

Update app.ts:

import { FormDialog } from './form-dialog/form-dialog';
  
  openFormDialog(): void {
    const dialogRef = this.dialog.open(FormDialog, {
      width: '400px'
    });

    dialogRef.afterClosed().subscribe(result => {
      if (result) {
        console.log('Form Data:', result);
      }
    });
  }

Update app.html:

<!-- Add a second button -->
<button mat-raised-button color="accent" (click)="openFormDialog()">
  Open Form Dialog
</button>

Now, when you click the "Open Form Dialog" button, a modal form will appear. After submitting valid input, it will close and return the form data to the main component.

Mastering Angular Material Dialogs (mat-dialog) with Practical Examples - form dialog


Reusable Dialog Component Tips

Instead of writing a new dialog for every use case, you can build flexible, reusable dialogs by designing them to accept dynamic data and return results.

Example: Reusable Confirmation Dialog

We'll refactor the ConfirmDialogComponent to be configurable and reusable across different parts of the app.

Step 1: Define a Confirmation Dialog Data Model

Create a file called confirm-dialog.model.ts:

export interface ConfirmDialogData {
  title?: string;
  message: string;
  confirmText?: string;
  cancelText?: string;
}

This lets you provide default or custom dialog content dynamically.

Step 2: Update ConfirmDialogComponent to Use the Model

Modify confirm-dialog.ts:

import { CommonModule } from '@angular/common';
import { Component, Inject } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { ConfirmDialogData } from './confirm-dialog.model';

@Component({
  selector: 'app-confirm-dialog',
  imports: [
    CommonModule,
    MatDialogModule,
    MatButtonModule
  ],
  templateUrl: './confirm-dialog.html',
  styleUrl: './confirm-dialog.scss'
})
export class ConfirmDialog {
  constructor(
    public dialogRef: MatDialogRef<ConfirmDialog>,
    @Inject(MAT_DIALOG_DATA) public data: ConfirmDialogData
  ) { }

  onConfirm(): void {
    this.dialogRef.close(true);
  }

  onCancel(): void {
    this.dialogRef.close(false);
  }
}

Update confirm-dialog.html:

<h2 mat-dialog-title>{{ data.title || 'Confirm' }}</h2>
<mat-dialog-content>{{ data.message }}</mat-dialog-content>
<mat-dialog-actions align="end">
  <button mat-button (click)="onCancel()">
    {{ data.cancelText || 'Cancel' }}
  </button>
  <button mat-raised-button color="primary" (click)="onConfirm()">
    {{ data.confirmText || 'Confirm' }}
  </button>
</mat-dialog-actions>

Step 3: Create a Centralized Dialog Service (Optional, but Recommended)

This service helps you reuse the confirmation dialog anywhere easily.

ng generate service dialog

Then in dialog.ts:

import { Injectable } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { ConfirmDialogData } from './confirm-dialog/confirm-dialog.model';
import { Observable } from 'rxjs';
import { ConfirmDialog } from './confirm-dialog/confirm-dialog';

@Injectable({
  providedIn: 'root'
})
export class Dialog {

  constructor(private dialog: MatDialog) { }

  confirm(data: ConfirmDialogData): Observable<boolean> {
    const dialogRef = this.dialog.open(ConfirmDialog, {
      width: '350px',
      data
    });

    return dialogRef.afterClosed();
  }
}

Step 4: Use the Dialog Anywhere with One Line

In any component (e.g. AppComponent), use the dialog like this:

import { Dialog } from './dialog';

constructor(private dialogService: Dialog) {}

showDeleteConfirm(): void {
  this.dialogService.confirm({
    title: 'Delete Item',
    message: 'Are you sure you want to delete this item?',
    confirmText: 'Delete',
    cancelText: 'Keep'
  }).subscribe(result => {
    if (result) {
      console.log('Item deleted');
    } else {
      console.log('Action canceled');
    }
  });
}

And in app.component.html:

<button mat-raised-button color="warn" (click)="showDeleteConfirm()">
  Open Reusable Confirm Dialog
</button>

Mastering Angular Material Dialogs (mat-dialog) with Practical Examples - resuable dialog

Benefits of This Approach

  • DRY (Don’t Repeat Yourself) principle

  • Centralized dialog logic for better maintainability

  • Easy to unit test

  • Flexible for multiple use cases: delete, logout, overwrite, etc.


Customizing mat-dialog Width, Height, Animations, and Styling

Angular Material’s MatDialog is highly configurable using the MatDialogConfig object, which lets you control the dialog's dimensions, position, backdrop, animations, and custom styles.

1. Set Custom Width and Height

You can define the width and height directly when opening a dialog.

Example:

this.dialog.open(FormDialogComponent, {
  width: '500px',
  height: '400px', // optional
  data: { /* ... */ }
});

Tip: Use CSS units like px, vw, vh, %, or even auto.

2. Set Custom Position

You can place dialogs in specific screen positions using position.

this.dialog.open(FormDialogComponent, {
  width: '400px',
  position: {
    top: '50px',
    right: '50px'
  }
});

3. Control Backdrop Behavior

  • Disable closing by clicking outside (backdrop click):

this.dialog.open(FormDialogComponent, {
  disableClose: true
});
  • Disable or remove the backdrop entirely:
this.dialog.open(FormDialogComponent, {
  hasBackdrop: false
});

4. Add Custom Dialog Animations

While Angular Material doesn’t expose dialog entrance/exit animations directly, you can animate the dialog content using Angular’s @angular/animations.

Example: Add a fade-in animation

Step 1 – Import animation modules in the component:

import {
  trigger,
  transition,
  style,
  animate
} from '@angular/animations';

Step 2 – Add animation metadata to the component:

@Component({
  ...,
  animations: [
    trigger('fadeIn', [
      transition(':enter', [
        style({ opacity: 0 }),
        animate('250ms ease-in', style({ opacity: 1 }))
      ])
    ])
  ]
})

Step 3 – Apply it in the dialog HTML root element:

<div [@fadeIn]>
  <!-- Your dialog content -->
</div>

🎯 You can also use scale, slideIn, or custom animations depending on your app’s design needs.

5. Style the Dialog with Custom CSS

Material dialogs have the wrapper class mat-dialog-container, but you can target your class for better isolation.

Option A – Use panelClass to add a custom class:

this.dialog.open(FormDialogComponent, {
  panelClass: 'custom-dialog-container'
});

Option B – Add this to styles.scss or component styles:

::ng-deep .custom-dialog-container {
  border-radius: 12px;
  padding: 24px;
  background: #f9f9f9;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
}

⚠️ ::ng-deep is deprecated but still works. For full encapsulation, move styles to a global stylesheet or use the ViewEncapsulation feature.None if necessary.

Combine Everything

Here’s a sample config that applies custom width, disables outside click, adds a CSS class, and sets position:

this.dialog.open(FormDialogComponent, {
  width: '450px',
  position: { top: '100px' },
  disableClose: true,
  panelClass: 'custom-dialog-container',
  data: { /* ... */ }
});


Conclusion

Angular Material's mat-dialog is a powerful and flexible tool for creating modal dialogs in Angular applications. Whether you're building simple confirmation popups or complex forms, MatDialog provides the structure, accessibility, and theming capabilities to do it all — cleanly and efficiently.

In this tutorial, you learned how to:

  • Set up Angular Material and integrate dialogs into your project

  • Create and open dialogs using the MatDialog service

  • Pass data to and receive results from dialogs

  • Add forms inside dialogs for user input

  • Customize dialog width, height, position, and backdrop behavior

  • Animate and style dialogs for a more polished UI

  • Build reusable dialogs using a central service and configuration model

These techniques allow you to reuse dialog components, standardize dialog interactions, and maintain a clean codebase as your Angular application scales.


Key Takeaways

  • Use MatDialog to handle modal dialogs in Angular Material.

  • Always separate dialogs into their components for reusability.

  • Pass data using MAT_DIALOG_DATA, and return values via MatDialogRef.afterClosed().

  • Customize appearance using panelClass, position, width, and custom animations.

  • Abstract confirmation dialogs using a dialog service to reduce repetition.

You can get the full source code on our GitHub.

If you don’t want to waste your time designing your front-end or your budget to spend by hiring a web designer, then Angular Templates is the best place to go. So, speed up your front-end web development with premium Angular templates. Choose your template for your front-end project here.

That's just the basics. If you need more deep learning about Angular, you can take the following cheap course:

Thanks!