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

Package detail

ngx-light-modal

jihedhmida191MIT0.0.3TypeScript support: included

Lightweight and dependency-free Angular modal package using standalone components. Supports stacking, backdrops, dynamic injection, and custom content components.

angular, modal, dialog, popup, ngx, overlay, angular modal, standalone, lightweight, dynamic components, angular cdky-free

readme

Ngx Light Modal

npm version License: MIT

NgxLightModal is a lightweight, dependency-free Angular modal package built with standalone components and fully dynamic rendering. It supports modal stacking, backdrop control, custom content components, and complete lifecycle observables — without requiring a host component in your templates.


Features

  • No modal host required – Just call the service, and it works.
  • 🧩 Standalone Components Support – Built for modern Angular architecture.
  • 📦 Lightweight & Dependency-Free – Zero external dependencies, minimal size.
  • 📚 Dynamic Component Injection – Display any component dynamically as a modal.
  • 🔁 Stackable Modals – Open and manage multiple modals with ease.
  • 🌙 Backdrop & ESC Handling – Configurable dismissal via backdrop click or ESC key.
  • 🧠 Full Lifecycle Events – Hooks for open, close, submit, escape, and more.
  • 🎨 Customizable via modalClass and options

Installation

Install the package via npm:

npm install ngx-light-modal

ModalRef Lifecycle Methods

Once you open a modal using modalService.open(...), it returns a ModalRef<T> instance.
Here are all the lifecycle methods available on the ModalRef:

Method Description
afterClosed$ Emits once when the modal is closed, regardless of how
beforeClosed$ Emits right before the modal begins closing
afterOpened$ Emits once when the modal has been fully opened
onSubmitted() Emits when modal closes using CloseState.SUBMITTED
onEscaped() Emits when modal is closed using the ESC key
onBackdropDismiss() Emits when user clicks the backdrop to dismiss
onCancelled() Emits when modal closes using CloseState.CANCELLED
onStateClose(state: CloseState) Listen for a specific CloseState only
onUserDismissed() Emits when modal closes via ESC, backdrop, or close button
close(result?: any, state?: CloseState) Manually close modal with optional result and reason

CloseState Enum

enum CloseState {
  CLOSED = 'CLOSED',
  SUBMITTED = 'SUBMITTED',
  CANCELLED = 'CANCELLED',
  ESCAPED = 'ESCAPED',
  BACKDROP_DISMISS = 'BACKDROP_DISMISS',
  CLOSE_BUTTON = 'CLOSE_BUTTON',
  EXITED = 'EXITED',
}

Usage

Open a Modal from Any Component

import { Component, inject } from '@angular/core';
import { ModalService } from 'ngx-light-modal';
import { ExampleModalComponent } from './modal/example-modal/example-modal.component';

@Component({
  standalone: true,
  selector: 'app-root',
  template: `<button (click)="openModal()">Open Modal</button>`,
})
export class AppComponent {
  private modalService = inject(ModalService);

  openModal() {
    const modalRef = this.modalService.open(
      ExampleModalComponent,
      { message: 'Hello from parent!' },
      {
        showBackdrop: true,
        dismissOnBackdropClick: true,
        showCloseButton: true,
        modalClass: 'custom-modal-style',
      }
    );

    modalRef.afterClosed$.subscribe((result) => {
      console.log('Modal closed with:', result?.state);
    });

    modalRef.onSubmitted().subscribe((result) => {
      console.log('Submitted data:', result.data);
    });

    modalRef.onEscaped().subscribe(() => {
      console.log('User pressed ESC');
    });

    modalRef.afterOpened$.subscribe(() => {
      console.log('Modal opened');
    });

    modalRef.beforeClosed$.subscribe(() => {
      console.log('Modal will close');
    });

    modalRef.onBackdropDismiss().subscribe(() => console.log('Backdrop clicked'));
    modalRef.onCancelled().subscribe(() => console.log('Cancelled by user'));

    // More specific
    modalRef.onStateClose(CloseState.CLOSE_BUTTON).subscribe(() => console.log('Close button used'));

    // Aggregated
    modalRef.onUserDismissed().subscribe((result) => console.log('Dismissed by user:', result.state));
  }
}

Example Modal Component

import { Component } from '@angular/core';
import { ModalService } from 'ngx-light-modal';
import { CloseState } from 'ngx-light-modal';

@Component({
  selector: 'app-example-modal',
  template: `
    <h2>Custom Modal</h2>
    <p>Data received: {{ message }}</p>
    <p>Data received Signal: {{ messageSignal() }}</p>
    <button (click)="close()">Close</button>
    <button (click)="openForm()">Open Form Modal</button>
  `,
})
export class ExampleModalComponent {
  /**
   * Supports both plain data and Angular signals and it's type-safe
   */
  message: any;
  messageSignal = signal<string>('');

  constructor(private modalService: ModalService) {}

  close() {
    this.modalService.getModalRef(this)?.close(null, CloseState.CANCELLED);
  }

  openForm() {
    this.modalService.open(FormComponent, {
      data: { title: 'User Form', userId: 123 },
    });
  }
}

API

ModalService

open(component: Type<T>, data?: any, options?: ModalOptions): ModalRef<T>

Opens a modal component with the specified data and options.

getModalRef(component: object): ModalRef | null

Returns the ModalRef for a given component instance.


ModalRef

Handles lifecycle and communication.

Observables

  • afterClosed$: Emits when modal is closed.
  • beforeClosed$: Emits right before the modal is closed.
  • afterOpened$: Emits after the modal is rendered.
  • onSubmitted<T>(): Emits custom submit result.
  • onEscaped(): Emits if user hits ESC.

Methods

  • close(data?: any, state?: CloseState): Closes the modal manually.
  • submit<T>(data: T): Triggers the submit observable.
  • escape(): Simulates ESC key behavior.

ModalOptions

interface ModalOptions {
  showBackdrop?: boolean; // default: true
  dismissOnBackdropClick?: boolean; // default: true
  showCloseButton?: boolean; // default: true
  modalClass?: string; // optional CSS class for modal
}

CloseState

enum CloseState {
  CLOSED = 'CLOSED',
  SUBMITTED = 'SUBMITTED',
  CANCELLED = 'CANCELLED',
  ESCAPED = 'ESCAPED',
}

License

This project is licensed under the MIT License - see the LICENSE file for details.