dialog
dialog copied to clipboard
👻 A simple to use, highly customizable, and powerful modal for Angular Applications
A simple to use, highly customizable, and powerful modal for Angular Applications
Features
✅ TemplateRef/Component Support
✅ Dialog Guards Support
✅ Resizable
✅ Draggable
✅ Multiple Dialogs Support
✅ Built-in Confirm/Success/Error Dialogs
✅ Customizable
Table of Contents
- Installation
- Usage
- Using a Component
- DialogRef API
- Using a TemplateRef
- Passing Data to Modal
- Modal Options
- Global Options
- Instance Options
- Built-in Confirm/Success/Error Modals
- Custom Sizes
- Styling
Installation
From your project folder, run:
ng add @ngneat/dialog
This command will import the DialogModule.forRoot() in your AppModule:
import { DialogModule } from '@ngneat/dialog';
@NgModule({
declarations: [AppComponent],
imports: [DialogModule.forRoot()],
bootstrap: [AppComponent]
})
export class AppModule {}
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>
`
changeDetection: ChangeDetectionStrategy.OnPush
})
export class HelloWorldComponent {
get title() {
if (!this.ref.data) return 'Hello world';
return this.ref.data.title;
}
constructor(public ref: DialogRef<Data, boolean>) {}
}
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
If you define the types for your DialogRef provider, the
afterClosed$andclose(params)will be typed automatically.
Now we can use the DialogService to open open the modal and display the component:
import { DialogService } from '@ngneat/dialog';
@Component({
template: `
<button (click)="open()">Open</button>
`
})
export class AppComponent implements OnInit {
constructor(private dialog: DialogService) {}
ngOnInit() {
const dialogRef = this.dialog.open(HelloWorldComponent);
}
}
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 aboolean, anobservable, or apromiseindicating whether the modal can be closed:
dialogRef.beforeClose(result => dialogCanBeClosed);
dialogRef.beforeClose(result => this.service.someMethod(result));
ref.data- A reference to thedatathat 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>
`
changeDetection: ChangeDetectionStrategy.OnPush
})
export class HelloWorldComponent {
constructor(public ref: DialogRef) {}
}
The library also provides the dialogClose directive helper, that you can use to close the modal:
import { DialogService, DialogRef } from '@ngneat/dialog';
@Component({
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',
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 {
constructor(private dialog: 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({
template: `
<button (click)="open()">Open</button>
`
})
export class AppComponent implements OnInit {
private id = '...';
constructor(private dialog: DialogService) {}
ngOnInit() {
const dialogRef = this.dialog.open(HelloWorldComponent, {
data: {
id: this.id
}
});
}
}
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 should close the modal (default is true).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. Usenonefor no constraint,bounceto have the modal bounce after it is released andconstrainto constrain while dragging (default isnone).size- Set the modal size according to your global custom sizes (default ismd).windowClass- Add a custom class to the modal container.width- Set a custom width (default unit ispx).height- Set a custom height (default unit ispx).minHeight- Set a custom min-height (default unit ispx).maxHeight- Set a custom max-height (default unit ispx).container- A custom element to which we append the modal (default isbody).
import { DialogModule } from '@ngneat/dialog';
@NgModule({
declarations: [AppComponent],
imports: [DialogModule.forRoot({
closeButton: boolean,
enableClose: boolean,
backdrop: boolean,
resizable: boolean,
draggable: boolean,
draggableConstraint: none | bounce | constrain,
size: sm | md | lg | fullScreen | string,
windowClass: string,
width: string | number,
height: string | number,
minHeight: string | number,
maxHeight: string | number
})],
bootstrap: [AppComponent]
})
export class AppModule {}
Instance Options
For each dialog instance you open you can specify all the global options and also the following 3 options.
id- The modal unique id (defaults to random id).vcr- A customViewContainerRefto use.data- Adataobject that will be passed to the modal template or component.
this.dialog.open(compOrTemplate, {
//...
// all global options
//...
id: string,
vcr: ViewContainerRef,
data: {}
});
Built-in Modals
The library provides built-in modals for common cases where we need to show a confirmation message, a success message, or an error message:
this.dialog
.confirm({
title: 'Are you sure?',
body: 'This action cannot be undone.'
})
.afterClosed$.subscribe(confirmed => console.log(confirmed));
this.dialog.success({
title: 'Hurray!',
body: '<h1>You Made It!!!</h1>'
});
this.dialog.error({
title: 'Oh no',
body: tpl
});
The body type can be a string, HTML string, or a <ng-template>.
Customization
You can customize the built-in dialogs in two ways. You can specify your own component and you can customize the text of the buttons in the default dialogs.
The confirm and cancel texts can either be of type string or Observable<string>. The last is useful in case you want a string that changes based on your language with something like Transloco.
import { DialogModule } from '@ngneat/dialog';
@NgModule({
declarations: [AppComponent],
imports: [
DialogModule.forRoot({
success: {
component: AppSuccessDialog,
confirmText: 'OK'
},
confirm: {
component: AppConfirmDialog,
confirmText: 'OK',
cancelText: 'Cancel'
},
error: {
component: AppErrorDialog,
confirmText: 'OK'
}
})
],
bootstrap: [AppComponent]
})
export class AppModule {}
Custom Sizes
You can define the modal sizes globally by using the sizes option:
import { DialogModule } from '@ngneat/dialog';
@NgModule({
declarations: [AppComponent],
imports: [
DialogModule.forRoot({
sizes: {
sm: {
width: 300, // 300px
minHeight: 250 // 250px
},
md: {
width: '60vw',
height: '60vh'
},
lg: {
width: '90vw',
height: '90vh'
},
fullScreen: {
width: '100vw',
height: '100vh'
},
stretch: {
minHeight: 500,
maxHeight: '85%'
}
}
})
],
bootstrap: [AppComponent]
})
export class AppModule {}
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
}
.ngneat-dialog-primary-btn,
.ngneat-dialog-secondary-btn {
// the default dialogs action buttons
}
}
}
}
Contributors ✨
Thanks goes to these wonderful people (emoji key):
Toni Villena 💻 🚇 ⚠️ |
Netanel Basal 📖 🤔 💻 |
Inbal Sinai 📖 |
Shahar Kazaz 💻 📖 |
beeman 💻 |
Ryan Hutchison 💻 🤔 |
Wybren Kortstra 💻 |
This project follows the all-contributors specification. Contributions of any kind welcome!
Logo made by itim2101 from www.flaticon.com