AlertDialog
A modal that only informs, with one OK button, on the browser's own <dialog> and no JavaScript.
Demo
Not closed yet.
Get it
It needs theme.qwe, as every component does; or take the whole kit, quillo-ui.qwe. Each component brings its own styles to the pages that show it.
$ curl -O https://quillolang.org/components/ui/theme.qwe$ curl -O https://quillolang.org/components/ui/alert_dialog.qwemain.qwe
import ui/theme.qwe use theme_cssuse ui/alert_dialog.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>Example
The code of the preview above.
demos/alert_dialog.qwe
component AlertDialogDemoLive() { state closed = 0 <div.demo-row> <AlertDialog id="alert-demo-live" title="Session ended" tone="warning" ok="Sign in again" trigger="Session ended" on_close={() => { closed += 1 }}> <p>You were signed out after an hour without activity.</p> </AlertDialog> <span.demo-note>{closed == 0 ? "Not closed yet." : `Closed ${closed} ${closed == 1 ? "time" : "times"}.`}</span> </div>}view AlertDialogDemo() = <div.demo-stack> <div.demo-row> <AlertDialog id="alert-demo-done" title="Export done" tone="success" trigger="Export done"> <p>Your file is on its way to you by email. It can take a few minutes.</p> </AlertDialog> <AlertDialog id="alert-demo-info" title="About" trigger="About"> <p>Quillo UI 1.0. Every component in one file, and each on its own.</p> </AlertDialog> <AlertDialog id="alert-demo-failed" title="Payment failed" tone="danger" ok="Try again" trigger="Payment failed"> <p>Your card was declined. Nothing was charged.</p> </AlertDialog> </div> <AlertDialogDemoLive/> </div>Source
ui/alert_dialog.qwe
// AlertDialog: a modal that only tells ("Your session has ended", "Export done")// and has one OK button. It is the browser's own <dialog>, opened by its trigger// button with the `command` attribute and closed by a `method="dialog"` form, so it// needs no JavaScript (Chrome 135, Firefox 144, Safari 26 and later; where the// button cannot open it, open it with Modal instead). Escape closes it too; focus// stays in it, and it is announced as an alert dialog.//// <AlertDialog id="done" title="Export done" trigger="Export">// <p>Your file is on its way to you by email.</p>// </AlertDialog>// <AlertDialog id="out" title="Session ended" tone="warning" ok="Sign in again" trigger="Show">...</AlertDialog>//// id (required): the dialog's id, unique on the page: the trigger opens it by it.// title: its heading, and its name for screen readers. children: the message.// trigger: the text of a button that opens it (styled as a Button when button_css is// on the page); null for none, to open it yourself (`document.getElementById(id).showModal()`).// ok ("OK"): the button's text. tone: "info" (default), "success", "warning" or// "danger", an icon and a colour. on_close(): inside one of your components,// called when it closes.import ui/theme.qwe use ui_clslet alert_dialog_css = css`.ui-alert-dialog-host { display: contents; }.ui-alert-dialog { width: min(400px, calc(100vw - 32px)); padding: 0; border: 1px solid var(--ui-border); border-radius: var(--ui-radius); background: var(--ui-surface); color: var(--ui-fg); box-shadow: var(--ui-shadow-lg); font: 15px/1.5 var(--ui-font); --t: var(--ui-info); --ts: var(--ui-info-soft);}.ui-alert-dialog-success { --t: var(--ui-success); --ts: var(--ui-success-soft); }.ui-alert-dialog-warning { --t: var(--ui-warning); --ts: var(--ui-warning-soft); }.ui-alert-dialog-danger { --t: var(--ui-danger); --ts: var(--ui-danger-soft); }.ui-alert-dialog::backdrop { background: var(--ui-overlay); }.ui-alert-dialog[open] { animation: ui-alert-dialog-in .16s ease-out; }@keyframes ui-alert-dialog-in { from { opacity: 0; transform: translateY(8px) scale(.98); } }.ui-alert-dialog-box { display: grid; gap: 8px; justify-items: center; padding: 24px 22px 20px; text-align: center; }.ui-alert-dialog-icon { display: grid; place-items: center; width: 44px; height: 44px; margin-bottom: 4px; border-radius: 50%; background: var(--ts); color: var(--t); }.ui-alert-dialog-icon svg { width: 24px; height: 24px; }.ui-alert-dialog-box h2 { margin: 0; font-size: 17px; font-weight: 600; line-height: 1.3; }.ui-alert-dialog-body { color: var(--ui-muted); }.ui-alert-dialog-body > :first-child { margin-top: 0; }.ui-alert-dialog-body > :last-child { margin-bottom: 0; }.ui-alert-dialog-box form { width: 100%; margin: 12px 0 0; }.ui-alert-dialog-ok { width: 100%; height: 38px; border: 0; border-radius: var(--ui-radius-sm); background: var(--ui-accent); color: var(--ui-accent-fg); font: 500 14px/1 var(--ui-font); cursor: pointer;}.ui-alert-dialog-ok:hover { background: color-mix(in srgb, var(--ui-accent) 88%, var(--ui-fg)); }.ui-alert-dialog-ok:focus-visible { outline: none; box-shadow: var(--ui-focus); }@media (prefers-reduced-motion: reduce) { .ui-alert-dialog[open] { animation: none; } }`fn alert_dialog_icon(tone: str) = match tone { "success" => "M20 6 9 17l-5-5" "warning" => "M12 9v4M12 17h.01M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0Z" "danger" => "M12 8v4M12 16h.01M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Z" _ => "M12 16v-4M12 8h.01M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Z" }view AlertDialog(id: str, title: str, trigger: str? = null, ok: str = "OK", tone: str = "info", on_close = null, class: str? = null, children) { style global alert_dialog_css <div.ui-alert-dialog-host> {trigger != null && <button.ui-btn.ui-btn-outline type="button" commandfor={id} command="show-modal" aria-haspopup="dialog">{trigger}</button>} <dialog class={ui_cls(["ui-alert-dialog", tone != "info" && `ui-alert-dialog-${tone}`, class])} id={id} role="alertdialog" aria-labelledby={`${id}-title`} aria-describedby={`${id}-body`} @close={() => { on_close && on_close() }}> <div.ui-alert-dialog-box> <div.ui-alert-dialog-icon aria-hidden="true"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d={alert_dialog_icon(tone)}/></svg> </div> <h2 id={`${id}-title`}>{title}</h2> <div.ui-alert-dialog-body id={`${id}-body`}>{children}</div> <form method="dialog"><button.ui-alert-dialog-ok type="submit" autofocus>{ok}</button></form> </div> </dialog> </div>}Related
FullscreenModalA dialog taking the whole window, with a bar holding close, its title and a main action, on the browser's <dialog>.5 views · 4 downloadsModalA dialog over the page, on the browser's own <dialog>: focus, Escape and screen readers handled.6 views · 8 downloadsPromptDialogA modal asking for one text value with OK and Cancel, on the browser's own <dialog>; Enter submits, Escape cancels.4 views · 5 downloadsQuickViewA Quick view button on a card that opens a preview of the item, its picture, price, text and actions, in a dialog.5 views · 6 downloadsSearchOverlayA full-screen search with results as one types, grouped and marked, from a list or a server, opened with /.7 views · 5 downloadsShareSheetA bottom sheet with the ways to share a link: copy it, email, X, LinkedIn, WhatsApp and more, and the system's own.6 views · 4 downloads
Thread
Thread 0 posts
On AlertDialog: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.