Confirm Dialog
Promise-based dialogs on native <dialog>: confirm, prompt and type-to-confirm.
npm install @devix-labs/confirm-dialog
Promise-based dialogs built on the element the browser already ships: showModal() gives a real focus trap, a real inert background, Escape handling, the top layer and focus returning to the trigger — none of it re-implemented. A danger dialog is an alertdialog that opens on Cancel, ignores the backdrop and can demand the word typed out. Fields come with per-field validation and typed values, and onConfirm may be async: the dialog stays open, shows it is busy, and puts a thrown error inline.
What you get
The browser does the hard part
A native <dialog> with showModal(): focus trapped, background inert for screen readers too, Escape handled, top layer, focus returned to the trigger.
Destructive by design
A danger dialog is an alertdialog, opens on Cancel, ignores backdrop clicks, and can require “DELETE” typed out before the button wakes up.
Async confirms
onConfirm can do the work: the dialog stays open and busy, and a thrown error is shown inside it rather than lost behind a closed modal.
Prompts are forms
Text, number, email, textarea and checkbox fields with per-field validation, the first problem focused, and values handed back typed.
3.4 KB, no dependencies
A quarter of SweetAlert2 with its CSS, and no jQuery or Bootstrap the way bootbox needs.
Wears your design system
CSS variables for every value, classNames on every part, your icons and words, and a @layer stylesheet so your CSS wins without !important.
Confirm Dialog — overview
Why it exists
window.confirm blocks the page, cannot be styled or translated, and offers exactly two words. The
usual replacement is SweetAlert2 at 20 kB with its own focus trap. Meanwhile the browser has shipped
<dialog>: a real modal with a real focus trap, a real top layer and a real inert background.
What it does differently
- The browser does the hard part.
showModal()means focus containment, Escape, the top layer and the inert background are native — and focus returns to the trigger afterwards. - 3.4 kB gzip, no dependencies, a quarter of SweetAlert2.
- Destructive by design.
dangermakes it analertdialog, focuses Cancel, ignores the backdrop, and can require the words to be typed. - Async confirms.
onConfirmcan do the work: the dialog stays open and busy, and a thrown error is shown inline rather than lost. - Prompts are forms. Several fields, per-field validation, typed values back.
Shape of the package
| Entry | What |
|---|---|
@devix/confirm-dialog |
confirm, confirmDanger, alert, prompt, dialog, configure |
@devix/confirm-dialog/react, /vue, /svelte |
the same functions, plus useDialogs() |
@devix/confirm-dialog/styles.css, /styles.layer.css |
the theme, plain or inside @layer devix |
Not in 1.0
Drawers and sheets, multi-step wizards and a toast mode: the first two are their own products, and toasts are @devix/toast.
Demos
All demos →Confirm, alert, prompt
Three questions, three promises — on a native dialog, so Escape, focus and the top layer are the browser's.
Destructive by design
An alertdialog that opens on Cancel, ignores the backdrop, and can ask for the word to be typed.
A dialog with fields
Several inputs, per-field validation, and values handed back typed — numbers as numbers, checkboxes as boolean...
Work that takes a moment
onConfirm can be async: the dialog stays open and busy, and a failure is shown inside it instead of being lost...
How it compares
Questions
Why not just use window.confirm?
It blocks the page, cannot be styled or translated, offers exactly two words, and browsers are free to suppress it — some already do in cross-origin iframes and on repeat calls. This is a promise you can await, with your words and your styling.
Is the focus trap reliable?
It is the browser's. showModal() traps focus, makes the rest of the page inert for pointers and screen readers alike, handles Escape and returns focus to whatever opened the dialog. Nothing here re-implements any of it.
Can I keep the dialog open while saving?
Yes — that is what onConfirm is for. Return a promise and the dialog stays open with a busy button; throw and the message appears inside it, so the user can fix the problem without reopening anything.
Can I ask for more than yes or no?
Pass fields for a small form, or actions for your own set of buttons. Values come back typed, and each field can validate itself.
Does it stack?
Yes. Dialogs nest natively — a confirm inside an onConfirm opens above the first one, and the one below stays inert until it closes.
How do I make it look like my app?
Every value is a CSS variable, every part takes your own classes (globally through configure() or per dialog), icons and strings are replaceable, and the stylesheet also ships inside @layer devix.
More from Devix
All resources →Toast
UI component
Promise-aware toasts with stacking, swipe to dismiss and correct live regions.
Command Palette
UI component
A framework-free ⌘K palette with nested pages, async sources and shortcuts.
Cookie Consent
Plugin
Blocks scripts until consent, supports Consent Mode v2, GDPR and UAE PDPL.