Skip to content
bahtuiv0.18.8

Dialog & toast service

Most confirms, notices and “Saved.” toasts do not deserve their own <baht-modal> in the template. bank20baht-ui/overlay mounts one for you, resolves a Promise with the answer and removes it again. Under the hood it is the same <baht-modal> and <baht-toast> elements, so every style below is one CSS class away.

import { dialog, toast } from 'bank20baht-ui/overlay';
const ok = await dialog.confirm('Delete this workflow?', { tone: 'danger' });
await dialog.error('Import failed.', { detail: err.message });
const name = await dialog.prompt('Workflow name?');
toast.success('Saved.');
dialogconfirm()alert()error()prompt()3 queued
toastsuccessinfowarningdangersticky + dismiss
// results land here

Every call returns a Promise. Dialogs queue: one is visible at a time, the next opens when the current one settles. Focus goes back to whatever was focused before the dialog opened.

Call Resolves Default title Buttons
dialog.confirm(message, options?) boolean — true only on explicit confirm “Are you sure?” Cancel · Confirm
dialog.alert(message, options?) void when acknowledged “Notice” OK
dialog.error(message, options?) void when acknowledged “Something went wrong” OK — tone: 'danger' preset
dialog.prompt(message, options?) string, or null on cancel / Escape / scrim “Input needed” Cancel · OK — Enter submits
Option Type Default Notes
title string per call the modal heading (accessible name)
tone 'info' | 'success' | 'warning' | 'danger' — left accent on the body; danger also turns the confirm button red
confirmText string 'Confirm' / 'OK'
cancelText string 'Cancel'
detail string — monospace block under the message — error text, a payload, a path
dismissible boolean true false removes the Escape path; only the buttons settle it (a scrim click never does)
placeholder string — prompt only
value string '' prompt only — initial input value

The resolved dialog reports why it closed. confirm/alert/error/prompt collapse that into their return value; the underlying reasons are 'confirm' | 'cancel' | 'escape' | 'scrim' | 'detached'. detached means the modal was torn out of the DOM (route change, host re-render) — the Promise still settles as cancelled, so the queue never wedges.

Useful when you style it, or build the same body inside your own <baht-modal>:

<baht-modal heading="Are you sure?">
<div class="baht-dialog baht-dialog--danger">
<p class="baht-dialog-message">Delete this workflow?</p>
<pre class="baht-dialog-detail">…only with { detail }</pre>
<input class="baht-control baht-dialog-input" /> <!-- prompt only -->
<div class="baht-dialog-actions">
<baht-button class="baht-dialog-cancel" variant="secondary" label="Cancel"></baht-button>
<baht-button class="baht-dialog-confirm" variant="danger" label="Confirm"></baht-button>
</div>
</div>
</baht-modal>

.baht-dialog--info | --success | --warning | --danger draw the 3px tone border on the left; .baht-dialog-actions right-aligns the buttons. The <baht-modal> page shows the same classes inside a hand-written modal.

The first call mounts a single <baht-toast> at the end of <body> (or reuses one already on the page). Every call returns the toast id, so a sticky toast can be dismissed later.

Call Notes
toast.show(message, { tone?, duration? }) tone: 'neutral' | 'success' | 'info' | 'warning' | 'danger' (default neutral). duration ms, 0 = sticky, default is the host’s duration (4000)
toast.success(message, { duration? }) shorthand, same for .info, .warning, .danger
toast.dismiss(id) removes one toast; fires baht-dismiss on the host

danger and warning toasts use role="alert" (screen readers interrupt); the rest ride the polite live region. Copy stays short and dry — “Saved.”, not “Successfully saved your changes!”.

Reach for a hand-written <baht-modal> when the body is a form or anything with state that must survive open/close (modal children stay mounted while closed), when you need the baht-close event to block closing mid-save, or when the layout is more than message + buttons. The service is for the 80% case: a question, a notice, a line of text.