Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@ngneat/dialog

ngneat21.1kMIT5.1.2TypeScript support: included

Simple to use, highly customizable, and powerful modal for Angular Apps

angular, dialog, modal, angular modal

readme


A simple to use, highly customizable, and powerful modal for Angular Applications

MIT commitizen PRs styled with prettier All Contributors ngneat spectator

Features

✅  TemplateRef/Component Support
✅  Dialog Guards Support
✅  Resizable
✅  Draggable
✅  Multiple Dialogs Support
✅  Customizable

Installation

npm i @ngneat/dialog

Usage

Using a Component

First, create the component to be displayed in the modal:

import { DialogService, DialogRef } from '@ngneat/dialog';

interface Data {
  title: string;
}

@Component({
  template: `
    <h1>{{ title }}</h1>
    <button (click)="ref.close(true)">Close</button>
  `,
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class HelloWorldComponent {
  ref: DialogRef<Data, boolean> = inject(DialogRef);

  get title() {
    if (!this.ref.data) return 'Hello world';
    return this.ref.data.title;
  }
}

Inside the component, you'll have access to a DialogRef provider. You can call its close() method to close the current modal. You can also pass data that'll be available for any subscribers to afterClosed$.

💡 Tip

A publicly accessible property of type DialogRef<Input, Output> on your component will be used to infer the input and output types of your component.

Now we can use the DialogService to open the modal and display the component:

import { DialogService } from '@ngneat/dialog';

@Component({
  standalone: true,
  template: ` <button (click)="open()">Open</button> `,
})
export class AppComponent implements OnInit {
  private dialog = inject(DialogService);

  ngOnInit() {
    const dialogRef = this.dialog.open(HelloWorldComponent, {
      // data is typed based on the passed generic
      data: {
        title: '',
      },
    });
  }
}

DialogRef API

The DialogRef instance exposes the following API:

  • afterClosed$ - An observable that emits after the modal closes:
const dialogRef = this.dialog.open(HelloWorldComponent);
dialogRef.afterClosed$.subscribe((result) => {
  console.log(`After dialog has been closed ${result}`);
});
  • backdropClick$ - An observable that emits when the user clicks on the modal backdrop:
const dialogRef = this.dialog.open(HelloWorldComponent);
dialogRef.backdropClick$.subscribe(() => {
  console.log('Backdrop has been clicked');
});
  • resetDrag - A method that can be called to reset the dragged modal to the middle of the screen. An offset can be given as the first parameter to position it different from the center:
dialogRef.resetDrag();
dialogRef.resetDrag({ x: 100, y: 0 });
  • beforeClose - A guard that should return a boolean, an observable, or a promise indicating whether the modal can be closed:
dialogRef.beforeClose((result) => dialogCanBeClosed);
dialogRef.beforeClose((result) => this.service.someMethod(result));
  • ref.data - A reference to the data that is passed by the component opened in the modal:
import { DialogService, DialogRef } from '@ngneat/dialog';

@Component({
  template: `
    <h1>{{ ref.data.title }}</h1>
    <button (click)="ref.close()">Close</button>
  `,
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class HelloWorldComponent {
  ref: DialogRef<Data> = inject(DialogRef);
}
  • ref.updateConfig - An update function for the config, a common use case would be a reusable component setting its own common properties:
import { DialogService, DialogRef } from '@ngneat/dialog';

@Component({
  template: `
    <h1>{{ ref.data.title }}</h1>
    <button (click)="ref.close()">Close</button>
  `,
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MyVeryCommonDialogComponent {
  ref: DialogRef<Data> = inject(DialogRef);

  constructor() {
    this.ref.updateConfig({
      height: '200px',
      width: '400px',
    });
  }
}

You can only update the config before the dialog is opened in the component's constructor.

The library also provides the dialogClose directive helper, that you can use to close the modal:

import { DialogService, DialogCloseDirective } from '@ngneat/dialog';

@Component({
  standalone: true,
  imports: [DialogCloseDirective],
  template: `
    <h1>Hello World</h1>
    <button dialogClose>Close</button>
    <button [dialogClose]="result">Close with result</button>
  `,
})
export class HelloWorldComponent {}

Using a TemplateRef

Sometimes it can be overkill to create a whole component. In these cases, you can pass a reference to an <ng-template>:

import { DialogService } from '@ngneat/dialog';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <ng-template #modalTpl let-ref>
      <h1>Hello World</h1>

      <button (click)="ref.close()">Close</button>
    </ng-template>

    <button (click)="open(modalTpl)">Open</button>
  `,
})
export class AppComponent {
  private dialog = inject(DialogService);

  open(tpl: TemplateRef<any>) {
    this.dialog.open(tpl);
  }
}

Note that in this case, you can access the ref object by using the $implicit context property.

Passing Data to the Modal Component

Sometimes we need to pass data from the opening component to our modal component. In these cases, we can use the data property, and use it to pass any data we need:

import { DialogService } from '@ngneat/dialog';

@Component({
  standalone: true,
  template: ` <button (click)="open()">Open</button> `,
})
export class AppComponent implements OnInit {
  private dialog = inject(DialogService);
  private title = 'Dialog title';

  open() {
    const dialogRef = this.dialog.open(HelloWorldComponent, {
      data: {
        title: this.title,
      },
    });
  }
}

Now we can access it inside our modal component or template, by using the ref.data property.

Dialog Options

Global Options

In the forRoot method when importing the dialog module in the app module you can specify the following options that will be globally applied to all dialog instances.

  • closeButton - Whether to display an 'X' for closing the modal (default is true).
  • enableClose - Whether a click on the backdrop, or press of the escape button, should close the modal (default is true), see enable close.
  • backdrop - Whether to show the backdrop element (default is true).
  • resizable - Whether the modal show be resizeable (default is false).
  • draggable - Whether the modal show be draggable (default is false).
  • draggableConstraint - When draggable true, whether the modal should be constraint to the window. Use none for no constraint, bounce to have the modal bounce after it is released and constrain to constrain while dragging (default is none).
  • size - Set the modal size according to your global custom sizes (default is md).
  • windowClass - Add a custom class to the modal container.
  • width - Set a custom width (default unit is px).
  • minWidth - Set a custom min-width (default unit is px).
  • maxWidth - Set a custom max-width (default unit is px).
  • height - Set a custom height (default unit is px).
  • minHeight - Set a custom min-height (default unit is px).
  • maxHeight - Set a custom max-height (default unit is px).
  • container - A custom element to which we append the modal (default is body).
import { provideDialogConfig } from '@ngneat/dialog';

bootstrapApplication(AppComponent, {
  providers: [
    provideDialogConfig({
      closeButton: boolean,
      enableClose:
        boolean |
        'onlyLastStrategy' |
        {
          escape: boolean | 'onlyLastStrategy',
          backdrop: boolean | 'onlyLastStrategy',
        },
      backdrop: boolean,
      resizable: boolean,
      draggable: boolean,
      overflow: boolean,
      draggableConstraint: none | bounce | constrain,
      sizes,
      size: sm | md | lg | fullScreen | string,
      windowClass: string,
      width: string | number,
      minWidth: string | number,
      maxWidth: string | number,
      height: string | number,
      minHeight: string | number,
      maxHeight: string | number,
    }),
  ],
});

Instance Options

For each dialog instance you open you can specify all the global options and also the following 3 options.

  • id - The modal's unique id, the defaults are:
    • If a component is passed - the component's name (e.g. MyCustomDialog).
    • Otherwise, a random id is given.

      [!Note]
      while not required, it is recommended to set an id in order to prevent unwanted multiple instances of the same dialog.

  • vcr - A custom ViewContainerRef to use.
  • data - A data object that will be passed to the modal template or component.
this.dialog.open(compOrTemplate, {
  //...
  // all global options expect sizes
  //...
  id: string,
  vcr: ViewContainerRef,
  data: {},
});

Enable close

The enableClose property can be configured for each dialog. It can either be an object with the keys escape and backdrop for more granular control, or one of the values described below directly. The latter will apply the set value to both close triggers (escape and backdrop).

If set to true, clicking on the backdrop or pressing the escape key will close the modal. If set to false, this behavior will be disabled.

Additionally, the property can be set to the string value 'onlyLastStrategy'. In this case, the behavior will only apply to the last dialog that was opened, and not to any other dialog. By default, this should be the top-most dialog and behave as true.

Custom Sizes

The default sizes config is:

{
  sizes: {
    sm: {
      height: 'auto',
        width: '400px',
    },
    md: {
      height: 'auto',
        width: '560px',
    },
    lg: {
      height: 'auto',
        width: '800px',
    },
    fullScreen: {
      height: '100%',
        width: '100%',
    },
  }
}

You can override it globally by using the sizes option:

bootstrapApplication(AppComponent, {
  providers: [
    provideDialogConfig({
      sizes: {
        sm: {
          width: 300, // 300px
          minHeight: 250, // 250px
        },
        md: {
          width: '60vw',
          height: '60vh',
        },
        lg: {
          width: '90vw',
          height: '90vh',
        },
        fullScreen: {
          width: '100vw',
          height: '100vh',
        },
      },
    }),
  ],
});

Styling

You can customize the styles with these classes:

ngneat-dialog {
  .ngneat-dialog-backdrop {
    // backdrop styles
    .ngneat-dialog-content {
      // dialog content, where your component/template is placed
      .ngneat-drag-marker {
        // draggable marker
      }
      .ngneat-close-dialog {
        // 'X' icon for closing the dialog
      }
    }
  }
}

changelog

Changelog

This file was generated using @jscutlery/semver.

5.1.2 (2024-12-02)

Bug Fixes

  • prevent dialog from closing when selecting elements from the dialog 54908f2, closes #129

5.1.1 (2024-07-15)

Bug Fixes

  • use component selector as default 3aee938, closes #123

5.1.0 (2024-07-05)

Bug Fixes

  • allow nullable values again 86f6605, closes #119 #81

Features

  • overflow functionality c3a710f

5.0.0 (2023-11-28)

Features

  • 🎸 allow updating the config via dialog ref 9e33a61
  • 🎸 update to new control flow b827e4e
  • 🎸 update to ng17 9bf838c

BREAKING CHANGES

  • 🧨 peer dep is angular 17

4.2.0 (2023-11-13)

Features

  • 🎸 allow updating the config via dialog ref (9e33a61)

4.1.1 (2023-09-11)

Bug Fixes

  • 🐛 ignore open dialogs instead of throwing an error (6779fc4)

4.1.0 (2023-08-02)

Features

  • config: split up backdrop+escape enableClose (5d8700d), closes #34
  • configure min-width and max-width sizes (fb7dd0c)

4.0.0 (2023-05-02)

⚠ BREAKING CHANGES

  • narrow result type definition

  • The Result generic is now infered based on the public ref property in the component

  • DialogRef.afterClosed$ will now use the infered result type
  • DialogRef.close will now use the infered resut type
  • DialogRef.beforeClose guard will now use the infered result type

Features

  • 🎸 add option to only enable close for last opened dialog (dba14e8), closes #96

Bug Fixes

  • expose return type of dialog ref (91a30d6), closes #86

3.6.0 (2023-04-24)

Features

3.5.0 (2023-02-26)

Features

  • 🎸 add CloseAllDialogsDirective (86704d0)

3.4.0 (2023-02-23)

Features

  • 🎸 add css variables (4e071aa)
  • 🎸 add more variables (1d7ca80)
  • add aria role attribute to dialog component (0733000), closes #90

Bug Fixes

  • 🐛 remove redundant top (f81a9b6)
  • draggable: move target instead of handle (490b28b), closes #84

3.3.0 (2023-01-05)

Features

  • 🎸 add more variables (b2be840)

3.2.1 (2023-01-05)

Bug Fixes

  • 🐛 remove redundant top (42638bb)

3.2.0 (2023-01-05)

Features

3.1.0 (2023-01-01)

Features

  • 🎸 expose dialog open statuses (030a68d)

3.0.2 (2022-12-12)

Bug Fixes

  • 🐛 allow nullable values (59cb603), closes #81

3.0.1 (2022-12-04)

⚠ BREAKING CHANGES

  • upgrade to standalone components

  • Remove DialogModule

  • Remove built-in dialogs
  • Sizes default height is now auto
  • Expose provideDialogConfig function
  • dialogClose should be imported when used
  • The data property type now inferred based on the public ref property in the component (see docs)

Features

  • customize confirm and cancel button texts of built-in dialogs (a7eab24), closes #47 #62
  • upgrade to standalone components (f5575f5)

Bug Fixes

  • 🐛 fix types (27c2621)
  • add reset location dialog component for demo (266a9eb)

Build System

  • fix the build script and add build test to ci (3f1f280)

3.0.0 (2022-11-24)

⚠ BREAKING CHANGES

  • upgrade to standalone components

  • Remove DialogModule

  • Remove built-in dialogs
  • Sizes default height is now auto
  • Expose provideDialogConfig function
  • dialogClose should be imported when used
  • The data property type now infered based on the public ref property in the component (see docs)

Bug Fixes

  • add reset location dialog component for demo (266a9eb)

Build System

  • fix the build script and add build test to ci (3f1f280)

2.1.1 (2022-06-14)

Bug Fixes

  • pass through offset parameters to resetDrag method (2fde3d1)
  • dialog-service: dialog invalid id (2722393), closes #63

2.1.0 (2022-03-31)

Features

Bug Fixes

  • fix dialog open config param default parameter (207cdf2)
  • fix dialog service open return typings (2e7b93f)

Tests

  • fix dialog.service.spec.ts type error (3f9791c)

2.0.1 (2022-01-04)

Bug Fixes

  • 🐛 clicking on element with ngIf closes the dialog (490ab3d)

2.0.0 (2021-11-24)

⚠ BREAKING CHANGES

  • Peer dep of v13

Features

1.7.0 (2021-10-18)

Features

  • add drag constraint and reset methods (feb39c4), closes #36
  • closeButton without backdrop click close (94e52e8)
  • move options to the global config (0a0c5c6), closes #37

1.6.0 (2021-03-21)

Features

  • allow multiple classes to be set from windowClass (5ac3297)
  • allow multiple classes to be set from windowClass (d60ee41)

1.5.0 (2021-03-16)

Features

  • add closeAll to dialog service (fa8cb92), closes #23

Bug Fixes

  • dialog-service: Remove 'ngneat-dialog-hidden' from body only after last dialog is closed (83477dd), closes ngneat/dialog#26
  • close dialog on backdrop click (efbdb11)
  • schematics: use correct folder (6e52e31)

1.4.1 (2021-02-02)

Bug Fixes

  • 🐛 replace close icon (b747695)

1.4.0 (2021-01-26)

Features

  • 🎸 support custom sizes (66e90ad)

Bug Fixes

  • 🐛 set deafult modal size to md (fc9c79a)

1.3.0 (2021-01-26)

Features

  • 🎸 add max height to config (d2f57ea)

Bug Fixes

  • dialog-component: use appendChild instead of append (IE) (e4e56e2)

1.2.1 (2020-12-01)

Bug Fixes

1.2.0 (2020-12-01)

Features

  • 🎸 add onopen and onclose to global config (cfc68ba)

Bug Fixes

  • 🐛 change modal animation (65c6d85)

1.0.4 (2020-12-19)

Bug Fixes

  • provide default value in forRoot() method (4ccc22d)

1.0.3 (2020-11-05)

Bug Fixes

  • 🐛 add dialog comp to entry (3674346)

1.0.2 (2020-08-26)

Bug Fixes

  • 🐛 expose config interfaces and config to dialogs (8e31702), closes #7

1.0.1 (2020-07-03)

Bug Fixes

  • 🐛 fix backdrop style (78babff)

1.0.0 (2020-06-30)

Features

  • 🎸 add min height support (f4c8f12)
  • 🎸 add x close button (546adcc)
  • add dialog playground (31fa872)
  • built-ins: add confirm, error and success (24d4188)
  • dialog-close: add dialog-close directive (28d3d49)
  • schematics: ng-add schematic (e2c3447)
  • 🎸 add dialog-service and most of features (13b8be4)
  • add beforeClose guards (3c9333e)
  • add dialog-cmp, add hooks and pass data (97e822a)
  • add resizable option (505b0f1)
  • allow pass an ElementRef as container (4718c20)
  • dialog-component: add open animation (2f5b9c8)
  • global config, sizes, vcr and draggable (7a1b4ca)

Bug Fixes

  • 🐛 dialog styles (a0dd1a3)
  • backdropClick$ is subscribable after open (4b1e979)
  • fullScreen is a size (a883c8a)
  • built-ins: add padding if there's title (7868be7)
  • built-ins: scope styles (7eba7ce)
  • dialog-component: bind right context (4398651)
  • dialog-component: hide backdrop (9e056c7)
  • dialog-component: set windowClass at host (63ba90e)
  • dialog-module: forRoot config is optional (e9c78d1)
  • dialog-ref: unwrap RefType (2f23abf)
  • dialog-service: add more-general overload (eb94617)
  • draggable-directive: move marker on init (25dc5dc)
  • afterClosed$ should emit result (4cf37f0)
  • clean-up only references (4a37b26)
  • dialog-service (aa647b1)
  • export DIALOG_DATA token (1b266b8)
  • dialog-module: sizes are optional (c8e851c)
  • set sizes from module (6232b7c)
  • dialog-service: use vcr with template-ref (a57660b)

Tests