npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@belomonte/async-modal-ngx

v21.0.0

Published

angular customizable modal that allows to asynchronously wait for user action and receive return data

Downloads

63

Readme

Matthew 5

[43] Ye have heard that it hath been said, Thou shalt love thy neighbour, and hate thine enemy. [44] But I say unto you, Love your enemies, bless them that curse you, do good to them that hate you, and pray for them which despitefully use you, and persecute you; [45] that ye may be the children of your Father which is in heaven: for he maketh his sun to rise on the evil and on the good, and sendeth rain on the just and on the unjust.

Asynchronous Modal for Angular (AsyncModalNgx)

npm version Npm Total Downloads Npm Monthly Downloads

This library will give you the means to present an angular component on the screen with the possibility of sending data to it before rendering and will also provide an observable to receive data from this component and know when the interaction with it has been completed.

This library will not offer you style structures, an appearance for the component that will host your modals must be customized in your project.

Run example

Open example app

Installation

npm install @belomonte/async-modal-ngx --save

How to use

You must import AsyncModalModule where you gonna render . You can put it in AppModule or you can create a module for a complex and customized modal.

import { AsyncModalModule } from '@belomonte/async-modal-ngx';

@NgModule({
  imports: [
    CommonModule,
    AsyncModalModule
  ]
})
export class AppModule { }

To create a modal you must extends ModalableDirective as the example below:

import { ModalableDirective } from '@belomonte/async-modal-ngx';

@Component({
  selector: 'app-my-modal',
  templateUrl: './my-modal.component.html',
  styleUrl: './my-modal.component.scss'
})
export class MyModalComponent extends ModalableDirective<{ name: string }, boolean> {

  name!: string;

  override response = new Subject<boolean | void>();
  
  override onInjectData(data: { name: string }): void {
    this.name = data.name;
  }

  ok(): void {
    this.response.next(true);
    //  close method will complete the response observable
    this.close();
  }

  cancel(): void {
    this.response.next(false);
    this.close();
  }
}

After you set in your template to render the modal, you can open it like this:

import { AsyncModalModule, ModalService } from '@belomonte/async-modal-ngx';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [
    CommonModule,
    RouterOutlet,
    AsyncModalModule
  ],
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss'
})
export class AppComponent {

  pressed: boolean | null = null;

  constructor(
    private modalService: ModalService,
    private router: Router
  ) { }

  open(): void {
    this.modalService
      .createModal(MyModalComponent)
      //  the data send here will be received in onInjectData method
      .setData({ name: 'user' })
      //  optional, this will close modal when route changes
      .setBindToRoute(this.router)
      //  you can add css classes to modal root
      .setRootCssClasses([
        'my-custom-css-class-for-this-specific-instance',
        'another-class'
      ])
      .build()
      .subscribe({
        next: response => {
          this.pressed = response || null;
          console.info('data received: ', response);
        },
        error: error => console.error(error),
        complete: () => console.info('modal was closed')
      });
  }
}

Also you can open with a small set of configurations:

import { AsyncModalModule, ModalService } from '@belomonte/async-modal-ngx';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [
    CommonModule,
    AsyncModalModule
  ],
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss'
})
export class AppComponent {

  pressed: boolean | null = null;

  constructor(
    private modalService: ModalService
  ) { }

  open(): void {
    this.modalService
      .createModal(MyModalComponent)
      .build()
      .subscribe({
        next: response => {
          this.pressed = response || null;
          console.info('data received: ', response);
        }
      });
  }
}

Customize a main modal wrapping ModalOutletComponent

Instead put the directly in app.component, you can create a component to work as your main modal and embed each modal component inside it, as the example below:

import { Component, HostListener, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { ModalBuilder, ModalOutletComponent } from '@belomonte/async-modal-ngx';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-main-modal',
  templateUrl: './main-modal.component.html',
  styleUrls: ['./main-modal.component.scss']
})
export class MainModalComponent implements OnInit, OnDestroy {
  
  @ViewChild(ModalOutletComponent)
  modal!: ModalOutletComponent;

  title = '';
  isOpen = false;

  private subscriptions = new Subscription();

  ngOnInit(): void {
    this.subscribeModalData();
  }

  ngOnDestroy(): void {
    this.subscriptions.unsubscribe();
  }
  
  private subscribeModalData(): void {
    this.subscriptions.add(ModalBuilder.modalInject$.subscribe({
      next: metadata => {
        //  casting from unknown
        const data = Object(metadata.data);
        if ('title' in data) {
          this.title = data.title;
        }
      }
    }));
  }

  @HostListener('document:keydown.escape')
  close(): void {
    this.modal.close();
  }
}
<section [class.hidden]="!isOpen" class="modal">
  <header>
    <button tabindex="1" (click)="close()" type="button">
      x
    </button>
    <h1>{{title}}</h1>
  </header>
  <div>
    <modal-outlet
      name="headedModal"
      (closed)="isOpen = false"
      (opened)="isOpen = true"
      showingDisplay="flex"
    ></modal-outlet>
  </div>
</section>

And then you can call it like this:

  this.modalService
    .createModal(MainModalComponent)
    .setOutletName('headedModal')
    .build();

CSS Suggestion

You can full customize your modal style, but this is a suggestion from working example app:

modal-outlet {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(0,0,0,.1);
  border: 1px solid;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 500;

  > * {
    margin: 0 auto;
    display: block;
    min-width: 200px;
    background-color: white;
    border-radius: 15px;
    padding: 1rem;
    box-sizing: border-box;
  }
}

Donate

Help me continue working on tools like this one. There's still a lot of work to do.

Lighting donate: lightning:[email protected]

zap me

Bitcoin onchain donate: bc1qrm99lmmpwk7zsh7njpgthw87yvdm38j2lzpq7q

zap me