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
<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.
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
<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
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)
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)
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
<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
awaitor.then()to handle results - Error Handling - Wrap in try/catch for production environments
API Reference
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
<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>