maximelafarie / ngx-smart-modal

Modal/Dialog component crafted for Angular (Ivy-compatible)
https://maximelafarie.com/ngx-smart-modal/
MIT License
325 stars 85 forks source link
angular angular-cli angular-ivy dialog hacktoberfest library modal modal-dialogs modals ngx-smart-modal npm npm-module npm-package yarn

ngx-smart-modal

Join the chat at https://gitter.im/ngx-smart-modal/Lobby ci npm version npm downloads codecov

ngx-smart-modal is a lightweight and very complete Angular library for managing modals inside any Angular project.

No external library, pure Angular! 🤘

To avoid having to download a CSS library when using this package, simply use our built-in SCSS/CSS file with custom animations and overloadable variables. So you don't have to use a CSS library you don't want! What's more, it doesn't use jQuery either!

CSS-framework-agnostic

Because we want to be as neutral as we can, we made it very flexible for you to style it with any CSS framework. So if your project uses a framework which is shipped with some modal styles, you simply have to pick up its class names and set the main class in the [customClass]="'modal'" (e.g.: bootstrap). And the rest of the modal DOM elements has just to be set into the ngx-smart-modal component (e.g.: modal-dialog, modal-content, modal-header, etc.).

Features

How it works

Basically, imagine that the component is based on a service that stores any modals you create in order to let you pick them up and manage them anywhere in your app at any time. sequence diagram

Browsers Support

Chrome Firefox Edge Safari Opera
> 75 > 60 > 17 > 5.1 > 60

Based on browserl.ist

Installation

npm i ngx-smart-modal --save

Which version should I use?

If your project uses a version of Angular lower than 14 (or non-Ivy), use version <=7.4.1. Otherwise, use the latest version >=14.x.

How to use

Import the module

Add NgxSmartModalModule (with .forRoot() or .forChild() depending if the module which you import the library into is the main module of your project or a nested module) and NgxSmartModalService to your project NgModule

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { NgxSmartModalModule } from 'ngx-smart-modal';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    NgxSmartModalModule.forRoot()
  ],
  providers: [
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Import the styles

And import ngx-smart-modal.scss or ngx-smart-modal.css in a global style file (e.g. styles.scss or styles.css in classic Angular projects or any other scss/css file it imports). Example with styles.scss:

/* You can add global styles to this file, and also import other style files */
@import "~ngx-smart-modal/styles/ngx-smart-modal"

Manipulate modals

from the template

You can use modals directly in your component's template like this:

<ngx-smart-modal #myModal identifier="myModal">
  <h1>Title</h1>
  <p>Some stuff...</p>

  <button (click)="myModal.close()">Close</button>
</ngx-smart-modal>

At this point, the modal instance is stored in the NgxSmartModalService. You can do absolutely what you want with it, anywhere in your app. For example, from a component :

import { Component } from '@angular/core';
import { NgxSmartModalService } from 'ngx-smart-modal';

@Component({
  // ...
})
export class AppComponent {
  constructor(public ngxSmartModalService: NgxSmartModalService) {
  }
}

Then in the AppComponent view you can open any modal with no need to be in the same view:

<button (click)="ngxSmartModalService.getModal('myModal').open()">Open myModal</button>

with class reference (since 7.2.0)

import { Component } from '@angular/core';

import { MyComponent } from 'xxxx';

import { NgxSmartModalService } from 'ngx-smart-modal';

@Component({
  // ...
})
export class AppComponent {
  // If Angular < 8
  // @ViewChild(TemplateRef) tpl: TemplateRef<any>;

  // If Angular >= 8
  @ViewChild(TemplateRef, { static: false }) tpl: TemplateRef<any>;

  constructor(private ngxSmartModalService: NgxSmartModalService, private vcr: ViewContainerRef) {
    // simple text content
    this.ngxSmartModalService.create('myModal1', 'content', vcr).open();

    // component
    this.ngxSmartModalService.create('myModal2', MyComponent, vcr).open();

    // or templateRef
    this.ngxSmartModalService.create('myModal3', this.tpl, vcr).open();
  }
}

Manipulate data

You can associate data with any created modal. To do that, use the setModalData() from the NgxSmartModalService:

import { AfterViewInit, Component } from '@angular/core';
import { NgxSmartModalService } from 'ngx-smart-modal';

@Component({
  // ...
})
export class AppComponent implements AfterViewInit {
  constructor(public ngxSmartModalService: NgxSmartModalService) {
  }

  ngAfterViewInit() {
    const obj: Object = {
      prop1: 'test',
      prop2: true,
      prop3: [{a: 'a', b: 'b'}, {c: 'c', d: 'd'}],
      prop4: 327652175423
    };

    this.ngxSmartModalService.setModalData(obj, 'myModal');
  }
}

After that, you can retrieve the modal data directly from the view with the getData() modal property. To avoid any errors with unavailable data, you can use the hasData() modal property (It's dynamic. If data comes after a certain time its value will automatically change to true):

<ngx-smart-modal #myModal identifier="myModal">
  <div *ngIf="myModal.hasData()">
    <pre>{{ myModal.getData() | json }}</pre>
  </div>

  <button (click)="myModal.close()">Close</button>
</ngx-smart-modal>

Handle events

ngx-smart-modal comes with several built-in events:

You can handle events directly from the view...

<ngx-smart-modal #myModal identifier="myModal" (onOpen)="log('Modal opened!')" (onClose)="log('Modal closed!')" (onDismiss)="log('Modal dismissed!')">
  <h1>Title</h1>
  <p>Some stuff...</p>

  <button (click)="myModal.close()">Close</button>
</ngx-smart-modal>

...and execute component's functions:

@Component({
  // ...
})
export class AppComponent {
  constructor() {
  }

  public log(msg: string) {
    console.log(msg);
  }
}

Or you can declare modal in any template (e.g.: the Rickroll demo modal)...

<ngx-smart-modal #videoModal identifier="videoModal" customClass="medium-modal">
  <h1>Hey, I Rickrolled You!</h1>
  <iframe #rickroll width="1280" height="720"
          src="https://www.youtube.com/embed/dQw4w9WgXcQ?rel=0&autoplay=1&controls=0&showinfo=0&ecver=1&enablejsapi=1"
          frameborder="0" allowfullscreen></iframe>

  <button class="button -dark" (click)="videoModal.close()">Close</button>
</ngx-smart-modal>

... and listen to its events from any component:

export class AppComponent implements AfterViewInit {
  // ...
  constructor(public ngxSmartModalService: NgxSmartModalService) {
  }

  ngAfterViewInit() {
    this.ngxSmartModalService.getModal('videoModal').onOpen.subscribe((modal: NgxSmartModalComponent) => {
      console.log('Rickroll modal opened!', modal);
    });
  }
}

Parameters (INgxSmartModalOptions)

ngx-smart-modal comes with some parameters / options in order to make it fit your needs. The following parameters / options needs to be used like this: <ngx-smart-modal [parameter-or-option-name]="value"></ngx-smart-modal>

The below documentation will use the following pattern:

parameter/option name (type) | default value | required? ― description

API

ngx-smart-modal also comes with the NgxSmartModalService that you can use in any component like this:

import { Component } from '@angular/core';
import { NgxSmartModalService } from 'ngx-smart-modal';

@Component({
  // ...
})
export class AppComponent {
  constructor(public ngxSmartModalService: NgxSmartModalService) {
  }
}

List of available methods:

Style & customization

ngx-smart-modal provides built-in SCSS variables that you can override easily like it (assuming you imported ngx-smart-modal.scss as explained above):

/* You can add global styles to this file, and also import other style files */
/* NgxSmartModal variables override */
$color-overlay: rgba(0, 0, 0, .7);
$dialog-position-top: 20%;

@import "~ngx-smart-modal/ngx-smart-modal";
// ...

Note that variables needs to be overridden before @import!

Available SCSS variables

The below documentation will use the following pattern:

parameter/option name (type) | default value | description

Built-in effects

ngx-smart-modal can understand several built-in classes to open differently with a sexy effect:

To change this effect, you can use the customClass option (see below) but you also can define your own class names with dedicated effect and pass them to customClass!

Contributors

Many thanks to our awesome contributors! ♥️ Still not on the list? Let's contribute!