Dialog

Promise-based modal interactions for alerts, confirmations, and user input collection

Overview

Dialogs are promise-based modal interactions that replace browser's native alert(), confirm(), and prompt() with styled, customisable alternatives. Perfect for user confirmations, alerts, and input collection.

Key Features

  • Promise-Based API - Modern async/await support
  • Three Types - Alert, confirm, and prompt dialogs
  • Customisable - Custom titles, button text, input types
  • Keyboard Support - Enter to confirm, Escape to cancel

Basic Usage

// Alert
await Domma.elements.alert('Operation successful!');

// Confirm
const confirmed = await Domma.elements.confirm('Delete this item?');

// Prompt
const name = await Domma.elements.prompt('Enter your name:');

Quick Start

Simple Alert

Simple Alert
<button type="button" id="quick-alert" class="btn btn-primary">Show Alert</button>
/**
 * Simple Alert - from public/showcase/elements/dialog.
 */
export function mount(root) {
    $(root).find('#quick-alert').on('click', async () => {
        await E.alert('This is an alert message!');
    });
}
$('#btn').on('click', async () => {
    await Domma.elements.alert('This is an alert message!');
    console.log('Alert closed');
});

Tutorial

Build a delete confirmation flow using dialogs.

Tutorial

Click "Delete Item" to start the flow

<div class="flex gap-4 justify-center">
    <button type="button" id="tutorial-delete" class="btn btn-danger">Delete Item</button>
</div>
<div id="tutorial-result" class="mt-4 p-4 bg-surface rounded dialog-min-h-60">
    <p data-bind-class="tone.value" data-bind-text="message.value">Click "Delete Item" to start the flow</p>
</div>
/**
 * Tutorial - from public/showcase/elements/dialog.
 *
 * The result panel binds to two observables - the message and its colour
 * class - so each step of the flow just sets them.
 */
export function mount(root) {
    const message = M.observable('Click "Delete Item" to start the flow');
    const tone = M.observable('text-muted');
    const show = (text, cls) => { message.value = text; tone.value = cls; };
    const handle = M.applyBindings({message, tone}, root.querySelector('#tutorial-result'));

    // Tutorial
    $(root).find('#tutorial-delete').on('click', async () => {
        show('Processing...', 'text-muted');

        const confirmed = await E.confirm(
            'Are you sure you want to delete this item?',
            {
                title: 'Confirm Deletion',
                confirmText: 'Delete',
                cancelText: 'Cancel'
            }
        );

        if (!confirmed) {
            show('Deletion cancelled by user.', 'text-warning');
            return;
        }

        const input = await E.prompt(
            'Type "DELETE" to confirm:',
            {
                title: 'Final Confirmation',
                inputPlaceholder: 'Type DELETE'
            }
        );

        if (input === 'DELETE') {
            show('✓ Item deleted successfully!', 'text-success');
        } else {
            show(`Deletion cancelled - you typed "${input || '(nothing)'}" instead of "DELETE".`, 'text-warning');
        }
    });

    return () => handle.dispose();
}
$('#delete-btn').on('click', async () => {
    // Step 1: Confirm deletion
    const confirmed = await Domma.elements.confirm(
        'Are you sure you want to delete this item?',
        {
            title: 'Confirm Deletion',
            confirmText: 'Delete',
            cancelText: 'Cancel'
        }
    );

    if (!confirmed) return;

    // Step 2: Prompt for confirmation text
    const input = await Domma.elements.prompt(
        'Type "DELETE" to confirm:',
        {
            title: 'Final Confirmation',
            inputPlaceholder: 'Type DELETE'
        }
    );

    if (input === 'DELETE') {
        await Domma.elements.alert('Item deleted successfully!', {
            title: 'Success'
        });
    } else {
        await Domma.elements.alert('Deletion cancelled - text did not match.', {
            title: 'Cancelled'
        });
    }
});

Examples

Alert Dialog

Alert Dialog
<button type="button" id="ex-alert" class="btn btn-primary">Show Alert</button>
/**
 * Alert Dialog - from public/showcase/elements/dialog.
 */
export function mount(root) {
        // Examples
    $(root).find('#ex-alert').on('click', async () => {
            await E.alert('Operation completed successfully!', {
                title: 'Success'
            });
        });
}

Confirm Dialog

Confirm Dialog

Result: -

<button type="button" id="ex-confirm" class="btn btn-warning">Show Confirm</button>
<p class="text-sm text-muted mt-2">Result: <span id="confirm-result">-</span></p>
/**
 * Confirm Dialog - from public/showcase/elements/dialog.
 */
export function mount(root) {
    $(root).find('#ex-confirm').on('click', async () => {
        const result = await E.confirm('Do you want to proceed?', {
            title: 'Confirm Action',
            confirmText: 'Yes',
            cancelText: 'No'
        });
      $(root).find('#confirm-result').text(result ? 'Confirmed' : 'Cancelled');
    });
}

Prompt Dialog (Text)

Prompt Dialog (Text)

Input: -

<button type="button" id="ex-prompt-text" class="btn btn-secondary">Show Text Prompt</button>
<p class="text-sm text-muted mt-2">Input: <span id="prompt-text-result">-</span></p>
/**
 * Prompt Dialog (Text) - from public/showcase/elements/dialog.
 */
export function mount(root) {
    $(root).find('#ex-prompt-text').on('click', async () => {
        const result = await E.prompt('What is your name?', {
            title: 'User Information',
            inputPlaceholder: 'Enter your name'
        });
      $(root).find('#prompt-text-result').text(result || '(cancelled)');
    });
}

Prompt Dialog (Email)

Prompt Dialog (Email)

Input: -

<button type="button" id="ex-prompt-email" class="btn btn-secondary">Show Email Prompt</button>
<p class="text-sm text-muted mt-2">Input: <span id="prompt-email-result">-</span></p>
/**
 * Prompt Dialog (Email) - from public/showcase/elements/dialog.
 */
export function mount(root) {
    $(root).find('#ex-prompt-email').on('click', async () => {
        const result = await E.prompt('Enter your email:', {
            title: 'Email Address',
            inputPlaceholder: 'you@example.com',
            inputType: 'email'
        });
      $(root).find('#prompt-email-result').text(result || '(cancelled)');
    });
}

Custom Button Text

Custom Button Text
<button type="button" id="ex-custom" class="btn btn-danger">Delete Account</button>
/**
 * Custom Button Text - from public/showcase/elements/dialog.
 */
export function mount(root) {
    $(root).find('#ex-custom').on('click', async () => {
        const confirmed = await E.confirm(
            'This action cannot be undone. Are you absolutely sure?',
            {
                title: 'Delete Account',
                confirmText: 'Yes, Delete My Account',
                cancelText: 'Cancel'
            }
        );
        if (confirmed) {
            await E.alert('Account deletion initiated.', {title: 'Account Deleted'});
        }
    });
}

Best Practices

Accessibility

  • Keyboard Support - Always enabled: Enter confirms, Escape cancels
  • Focus Management - Auto-focuses confirm button or input field
  • Clear Actions - Use descriptive button text ("Delete" not "OK")

UX Guidelines

  • Confirm Destructive Actions - Always confirm deletes, permanent changes
  • Provide Context - Use custom titles to clarify the action
  • Handle Cancellation - Check promise result and handle appropriately

Performance

  • Await Properly - Always use await or .then() to handle results
  • Error Handling - Wrap in try/catch for production environments

API Reference

Static Methods

Static Methods
Method Returns Description
alert(message, options) Promise Show alert with OK button
confirm(message, options) Promise Show confirmation dialog, returns true/false
prompt(message, options) Promise Show input dialog, returns value or null
<table class="api-table-accordion">
    <thead>
        <tr>
            <th>Method</th>
            <th>Returns</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>alert(message, options)</code></td>
            <td>Promise<void></void></td>
            <td>Show alert with OK button</td>
        </tr>
        <tr>
            <td><code>confirm(message, options)</code></td>
            <td>Promise<boolean></boolean></td>
            <td>Show confirmation dialog, returns true/false</td>
        </tr>
        <tr>
            <td><code>prompt(message, options)</code></td>
            <td>Promise<string|null></string|null></td>
                <td>Show input dialog, returns value or null</td>
            </tr>
        </tbody>
    </table>

Options

Option Type Default Description
title String null Dialog title
confirmText String 'OK' Confirm button text
cancelText String 'Cancel' Cancel button text
inputPlaceholder String '' Prompt input placeholder
inputValue String '' Prompt input default value
inputType String 'text' Input type (text, email, etc.)
animation Boolean true Enable animations
keyboard Boolean true Enable keyboard shortcuts

Config Engine

Dialogs are typically called programmatically, but you can attach them to buttons:

$.setup({
    '#delete-btn': {
        events: {
            click: async (e, $el) => {
                const confirmed = await Domma.elements.confirm(
                    'Delete this item?',
                    { confirmText: 'Delete', cancelText: 'Cancel' }
                );
                if (confirmed) {
                    // Perform deletion
                }
            }
        }
    }
});

CSS Customisation

Override these CSS variables to customise Dialog appearance and match your design system.

Variable Default Controls
--dm-surface var(--dm-white) Dialog background
--dm-radius-lg 0.5rem Dialog corner radius
--dm-border var(--dm-slate-300) Dialog border
--dm-primary var(--dm-blue-600) Confirm button colour

Example Override

:root {
    /* Same as Modal overrides */
    --dm-surface: #1e293b;
    --dm-text: #f1f5f9;
}

Full CSS Customisation Cheat-Sheet →

Related Elements

Related Elements
<div class="grid grid-cols-1 gap-4 grid-auto-fit-250"><a href="/showcase/elements/modal" class="card card-hover">
        <div class="card-body">
            <h3 class="card-title">Modal</h3>
            <p class="card-text">For custom modal content beyond simple dialogs</p>
        </div>
    </a>
    <a href="/showcase/elements/toast" class="card card-hover">
        <div class="card-body">
            <h3 class="card-title">Toast</h3>
            <p class="card-text">Non-blocking notifications</p>
        </div>
    </a>
</div>