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

async-modal

v1.0.2

Published

A Promise-based modal system that returns user selection, with support for confirmation checkboxes, auto-dismiss timeouts, customizable buttons, and built-in internationalization (i18n) for 13+ languages

Readme

async-modal

A Promise-based modal system that returns user selection, with support for confirmation checkboxes, auto-dismiss timeouts, and customizable buttons.

Screenshots

Basic Confirmation Modal

Danger Action Modal

Modal with Timeout

Timeout Continue Button

Features

  • ✅ Promise-based API - Use async/await for clean code
  • ✅ Multiple button types - Cancel, Continue, Settings, Help, Danger
  • ✅ Confirmation checkbox - Require user confirmation before proceeding
  • ✅ Auto-dismiss timeout - Automatically close modal after specified time
  • ✅ Customizable icons - Warning, danger, info, success, question
  • ✅ Sound notifications - Optional sound alerts
  • ✅ Responsive design - Works on mobile and desktop
  • ✅ Accessible - ARIA labels and keyboard navigation support
  • ✅ Multiple module systems - ES modules, CommonJS, and global support
  • ✅ XSS protection - HTML escaping for user input
  • ✅ Internationalization (i18n) - Built-in support for 13+ languages
  • ✅ Dark theme support - Automatic dark mode detection and manual theme control

Installation

Install using yarn:

yarn add async-modal

Or using npm:

npm install async-modal

Quick Start

Basic Usage

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="node_modules/@fortawesome/fontawesome-free/css/all.min.css">
  <link rel="stylesheet" href="node_modules/async-modal/src/async-modal.css">
</head>
<body>
  <script src="node_modules/async-modal/src/asyncModal.js"></script>
  <script>
    async function showModal() {
      const result = await window.asyncModal.show({
        title: 'Confirm Action',
        message: 'Are you sure you want to proceed?',
        showCancel: true,
        showContinue: true
      });
      
      if (result === 'continue') {
        console.log('User clicked Continue');
      } else {
        console.log('User clicked Cancel');
      }
    }
    
    showModal();
  </script>
</body>
</html>

ES Module Usage

import AsyncModal from 'async-modal';
import 'async-modal/src/async-modal.css';

const modal = new AsyncModal();

const result = await modal.show({
  title: 'Delete Item',
  message: 'This action cannot be undone.',
  showCancel: true,
  showContinue: true,
  icon: 'danger'
});

CommonJS Usage

const AsyncModal = require('async-modal');
require('async-modal/src/async-modal.css');

const modal = new AsyncModal();

const result = await modal.show({
  title: 'Save Changes',
  message: 'Do you want to save your changes?',
  showCancel: true,
  showContinue: true
});

API Reference

AsyncModal Class

Constructor

const modal = new AsyncModal(options);

Parameters:

  • options (Object, optional) - Configuration options
    • language (string, default: 'en') - Default language code
    • localePath (string, default: './locales') - Path to locale files
    • soundPath (string) - Default sound file path
    • darkTheme (boolean, default: auto-detect) - Enable dark theme (auto-detects system preference if not specified)

Example:

// Default (English)
const modal = new AsyncModal();

// With Turkish as default language
const modal = new AsyncModal({ language: 'tr' });

// With custom locale path
const modal = new AsyncModal({ 
  language: 'es',
  localePath: './custom-locales'
});

Methods

show(options)

Shows a modal and returns a Promise that resolves with the user's selection.

Parameters:

  • options (Object) - Configuration options
    • title (string, default: 'Confirmation Required') - Modal title
    • message (string, default: 'Are you sure you want to proceed?') - Modal message
    • showCancel (boolean, default: true) - Show cancel button
    • showContinue (boolean, default: true) - Show continue button
    • showSettings (boolean, default: false) - Show settings button
    • showHelp (boolean, default: false) - Show help button
    • showDanger (boolean, default: false) - Show danger button
    • disabled (boolean, default: false) - Disable all buttons initially
    • requireConfirmation (boolean, default: true) - Require confirmation checkbox
    • confirmationText (string, default: 'I confirm that I accept responsibility for this action') - Confirmation text
    • icon (string, default: 'question') - Icon type: 'warning', 'danger', 'info', 'success', 'question'
    • confirmButtonText (string, default: 'Continue') - Confirm button text
    • cancelButtonText (string, default: 'Cancel') - Cancel button text
    • playSound (boolean, default: false) - Play notification sound
    • autoDismissTimeout (boolean, default: false) - Enable auto dismiss timeout
    • autoDismissTimeoutSeconds (number, default: 15) - Timeout duration in seconds
    • soundPath (string) - Custom sound file path
    • language (string) - Language code (overrides global language for this modal - highest priority)
    • darkTheme (boolean) - Use dark theme for this modal (overrides global dark theme setting)

Returns: Promise<string> - Resolves with: 'continue', 'cancel', 'settings', 'help', or 'danger'

Example:

const result = await modal.show({
  title: 'Delete Account',
  message: 'This will permanently delete your account. This action cannot be undone.',
  showCancel: true,
  showContinue: true,
  requireConfirmation: true,
  confirmationText: 'I understand this action is irreversible',
  icon: 'danger',
  autoDismissTimeout: true,
  autoDismissTimeoutSeconds: 30
});
showConfirmation(messageOrOptions)

Shows a simple confirmation modal.

Parameters:

  • messageOrOptions (string|Object) - Confirmation message (string) or options object
    • message (string) - Confirmation message (uses localized default if not provided)
    • language (string) - Language code (overrides global language for this modal)

Returns: Promise<string>

Example:

// With string message
const result = await modal.showConfirmation('Do you want to save your changes?');

// With options object
const result = await modal.showConfirmation({ 
  message: 'Custom message',
  language: 'tr' // Turkish for this modal
});
showConfirmationWithResponsibility(message, confirmationText, options)

Shows a modal requiring responsibility confirmation.

Parameters:

  • message (string, optional) - Modal message (uses localized default if not provided)
  • confirmationText (string, optional) - Confirmation text (uses localized default if not provided)
  • options (Object, optional) - Additional options
    • language (string) - Language code (overrides global language for this modal)

Returns: Promise<string>

Example:

const result = await modal.showConfirmationWithResponsibility(
  'This action may have serious consequences.',
  'I accept full responsibility for this action',
  { language: 'fr' } // French for this modal
);
showDangerousAction(messageOrOptions)

Shows a modal for dangerous actions.

Parameters:

  • messageOrOptions (string|Object) - Warning message (string) or options object
    • message (string) - Warning message (uses localized default if not provided)
    • language (string) - Language code (overrides global language for this modal)

Returns: Promise<string>

Example:

// With string message
const result = await modal.showDangerousAction(
  'This will delete all data. Are you absolutely sure?'
);

// With options object
const result = await modal.showDangerousAction({ 
  message: 'Custom danger message',
  language: 'de' // German for this modal
});
showWorkingTimeViolation(options)

Shows a modal for working time violations.

Parameters:

  • options (Object, optional) - Configuration options
    • language (string) - Language code (overrides global language for this modal)
    • Other standard modal options

Returns: Promise<string>

Example:

const result = await modal.showWorkingTimeViolation({
  message: 'You are outside working hours. Proceed anyway?',
  language: 'es' // Spanish for this modal
});
setSoundPath(path)

Sets the default sound file path.

Parameters:

  • path (string) - Path to sound file

Example:

modal.setSoundPath('./custom-sound.wav');
setLanguage(lang)

Sets the current language for the modal. Supported languages: en, tr, es, fr, de, it, pt, ru, ja, zh, ko, ar, hi.

Parameters:

  • lang (string) - Language code

Returns: Promise<void>

Example:

await modal.setLanguage('tr'); // Turkish
await modal.setLanguage('es'); // Spanish
await modal.setLanguage('fr'); // French
setDarkTheme(enabled)

Sets the dark theme preference globally.

Parameters:

  • enabled (boolean) - Enable dark theme (true) or light theme (false)

Example:

modal.setDarkTheme(true);  // Enable dark theme
modal.setDarkTheme(false); // Disable dark theme (use light theme)
getDarkTheme()

Gets the current dark theme preference.

Returns: boolean - true if dark theme is enabled, false otherwise

Example:

const isDark = modal.getDarkTheme();
console.log('Dark theme enabled:', isDark);
close(action)

Closes the current modal programmatically.

Parameters:

  • action (string) - Action to return: 'continue', 'cancel', 'settings', 'help', or 'danger'

Example:

modal.close('cancel');

Examples

Basic Confirmation

const result = await modal.show({
  title: 'Save Changes',
  message: 'Do you want to save your changes before leaving?',
  showCancel: true,
  showContinue: true
});

if (result === 'continue') {
  // Save changes
  saveChanges();
}

With Confirmation Checkbox

const result = await modal.show({
  title: 'Delete Item',
  message: 'This will permanently delete the item.',
  requireConfirmation: true,
  confirmationText: 'I understand this action cannot be undone',
  icon: 'danger'
});

With Auto-Dismiss Timeout

const result = await modal.show({
  title: 'Session Expiring',
  message: 'Your session will expire in 30 seconds.',
  autoDismissTimeout: true,
  autoDismissTimeoutSeconds: 30,
  showCancel: true
});

// If timeout expires, result will be 'cancel'

Multiple Buttons

const result = await modal.show({
  title: 'Action Required',
  message: 'Choose an action:',
  showCancel: true,
  showContinue: true,
  showSettings: true,
  showHelp: true,
  showDanger: true
});

switch (result) {
  case 'continue':
    // Handle continue
    break;
  case 'settings':
    // Open settings
    break;
  case 'help':
    // Show help
    break;
  case 'danger':
    // Handle danger action
    break;
  case 'cancel':
    // Handle cancel
    break;
}

With Sound Notification

const result = await modal.show({
  title: 'Important Alert',
  message: 'Please review this important information.',
  playSound: true,
  soundPath: './custom-notification.wav' // Optional custom path
});

Internationalization (i18n)

async-modal includes built-in support for 13+ languages. All default messages, button texts, and titles are automatically localized.

Supported Languages:

  • English (en) - Default
  • Turkish (tr)
  • Spanish (es)
  • French (fr)
  • German (de)
  • Italian (it)
  • Portuguese (pt)
  • Russian (ru)
  • Japanese (ja)
  • Chinese (zh)
  • Korean (ko)
  • Arabic (ar)
  • Hindi (hi)

Language Priority (from highest to lowest):

  1. Function parameter (options.language) - Highest priority, overrides everything
  2. Global language (set via setLanguage() or constructor)
  3. Default ('en' - English)

Set Language in Constructor:

// Set default language when creating instance
const modal = new AsyncModal({ language: 'tr' }); // Turkish

Set Language Globally:

// Set language for all modals
await modal.setLanguage('tr'); // Turkish

// Now all modals will use Turkish translations (unless overridden)
const result = await modal.show({
  // title and message will be in Turkish if not specified
});

Set Language Per Modal (Highest Priority):

// Use specific language for one modal - overrides global language
const result = await modal.show({
  language: 'es', // Spanish - this modal will be in Spanish
  // Other options...
});

// Global language remains unchanged
const result2 = await modal.show({
  // This modal will use the global language (Turkish from setLanguage above)
});

Using Localized Helper Methods:

// Set language first
await modal.setLanguage('fr'); // French

// Helper methods automatically use localized strings
const result = await modal.showConfirmation(); // Uses French "Confirmation Requise"
const result2 = await modal.showDangerousAction(); // Uses French "Action Dangereuse"
const result3 = await modal.showWorkingTimeViolation(); // Uses French messages

// Override language for specific helper method calls
const result4 = await modal.showConfirmation({ language: 'es' }); // Spanish for this modal only
const result5 = await modal.showDangerousAction({ language: 'de' }); // German for this modal only

Available Localized Strings:

All default texts are automatically localized:

  • Button labels (Continue, Cancel, Settings, Help)
  • Default titles (Confirmation Required, Dangerous Action, etc.)
  • Default messages (working time violations, delete confirmations, etc.)
  • Confirmation checkbox text
  • Timeout labels (seconds, expired)

Custom Messages with Localization:

// You can still use custom messages, but buttons will be localized
const result = await modal.show({
  language: 'de', // German
  title: 'Custom Title', // Your custom title
  message: 'Custom Message', // Your custom message
  // Buttons will be in German: "Fortfahren", "Abbrechen", etc.
});

Dark Theme

The modal supports dark theme with automatic system preference detection. You can control the theme globally or per modal.

Automatic Dark Theme Detection

By default, the modal automatically detects your system's color scheme preference:

// Automatically uses dark theme if system preference is dark
const modal = new AsyncModal();
const result = await modal.show({
  title: 'Confirm Action',
  message: 'This modal will use dark theme if your system is set to dark mode'
});

Manual Dark Theme Control

You can manually control the theme:

// Set dark theme globally
const modal = new AsyncModal({ darkTheme: true });
modal.setDarkTheme(true);  // Or change it later

// Use dark theme for a specific modal only
const result = await modal.show({
  title: 'Dark Modal',
  message: 'This modal uses dark theme',
  darkTheme: true  // Overrides global setting
});

// Use light theme for a specific modal
const result2 = await modal.show({
  title: 'Light Modal',
  message: 'This modal uses light theme',
  darkTheme: false  // Overrides global setting
});

Theme Priority

  1. Function parameter (options.darkTheme in show() method) - Highest priority
  2. Global setting (set via setDarkTheme() or constructor) - Medium priority
  3. System preference (auto-detected via prefers-color-scheme) - Default fallback

Styling

The modal comes with default styles. You can customize it by overriding CSS classes:

  • .async-modal-overlay - Modal overlay/backdrop
  • .async-modal - Modal container
  • .async-modal-header - Modal header
  • .async-modal-title - Modal title
  • .async-modal-body - Modal body
  • .async-modal-btn - Button base styles
  • .async-modal-btn-cancel - Cancel button
  • .async-modal-btn-continue - Continue button
  • .async-modal-btn-settings - Settings button
  • .async-modal-btn-help - Help button
  • .async-modal-btn-danger - Danger button

Requirements

  • Font Awesome 6.x (for icons)
  • Modern browser with ES6+ support

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Changelog

1.0.0

  • Initial release
  • Promise-based API
  • Multiple button types
  • Confirmation checkbox support
  • Auto-dismiss timeout
  • Sound notifications
  • Responsive design
  • Accessibility features
  • Internationalization (i18n) support for 13+ languages