Skip to content

Confirmation dialog

wu-confirm-modal asks the user to confirm one action. It builds on wu-modal for opening, closing, the backdrop and the motion, and on wu-btn for the actions. Both classes go on the <dialog>.

How to make a confirm dialog without JavaScript

Section titled “How to make a confirm dialog without JavaScript”

Use a small dialog with a question and two buttons. The button that opens it needs no script, and the buttons inside close it and report which one was pressed. This uses the browser’s built-in dialog element, as in the modal. The full demo is under Default.

<button class="wu-btn" type="button" commandfor="ask" command="show-modal">Remove</button>
<dialog class="wu-modal wu-confirm-modal" id="ask" role="alertdialog" aria-label="Remove item">
<p class="wu-confirm-modal-message">Remove this item?</p>
<form class="wu-confirm-modal-actions" method="dialog">
<button class="wu-btn" value="cancel" autofocus>Cancel</button>
<button class="wu-btn danger" value="confirm">Remove</button>
</form>
</dialog>
Class, attribute or variable Effect
wu-modal wu-confirm-modal Root, on <dialog role="alertdialog">. Compact padded panel
wu-confirm-modal-title Part. Large semibold title; link it with aria-labelledby
wu-confirm-modal-subject Part, optional. Names the object the action applies to, in semibold text; add its id to aria-describedby
wu-confirm-modal-message Part. Muted message; link it with aria-describedby
wu-confirm-modal-actions Part, on <form method="dialog">. End-aligned buttons
danger The message reads in regular text at body size, for actions that cannot be undone. Give the action wu-btn danger
animated The modal’s fade and scale, opt-in
--wu-confirm-modal--Width Width, 26rem by default

Publish the report?

Everyone in the workspace will see it.

<button class="wu-btn" type="button" commandfor="confirm-publish" command="show-modal">Publish</button>
<dialog class="wu-modal wu-confirm-modal" id="confirm-publish" role="alertdialog" aria-labelledby="confirm-publish-title" aria-describedby="confirm-publish-message">
<h2 class="wu-confirm-modal-title" id="confirm-publish-title">Publish the report?</h2>
<p class="wu-confirm-modal-message" id="confirm-publish-message">Everyone in the workspace will see it.</p>
<form class="wu-confirm-modal-actions" method="dialog">
<button class="wu-btn" value="cancel" autofocus>Cancel</button>
<button class="wu-btn brand" value="confirm">Publish</button>
</form>
</dialog>

Delete project?

Website redesign

The project, its tasks and its files are deleted for everyone. This cannot be undone.

<button class="wu-btn" type="button" commandfor="confirm-delete" command="show-modal">Delete project</button>
<dialog class="wu-modal wu-confirm-modal danger animated" id="confirm-delete" role="alertdialog" aria-labelledby="confirm-delete-title" aria-describedby="confirm-delete-subject confirm-delete-message">
<h2 class="wu-confirm-modal-title" id="confirm-delete-title">Delete project?</h2>
<p class="wu-confirm-modal-subject" id="confirm-delete-subject">Website redesign</p>
<p class="wu-confirm-modal-message" id="confirm-delete-message">The project, its tasks and its files are deleted for everyone. This cannot be undone.</p>
<form class="wu-confirm-modal-actions" method="dialog">
<button class="wu-btn" value="cancel" autofocus>Cancel</button>
<button class="wu-btn danger" value="confirm">Delete</button>
</form>
</dialog>

danger on the dialog gives the message full weight, the subject names what is deleted, and wu-btn danger on the action gives it the danger fill. This example also carries animated, so it fades and scales in under prefers-reduced-motion: no-preference.

dialog.returnValue holds the value of the button that closed the dialog. Esc does not set it, so clear it after reading.

const dialog = document.getElementById('confirm-delete');
dialog.addEventListener('close', () => {
if (dialog.returnValue === 'confirm') deleteProject();
dialog.returnValue = '';
});
  • role="alertdialog" tells screen readers the dialog needs an answer; aria-labelledby and aria-describedby read the title, then the subject and the message.
  • autofocus on Cancel puts focus on the safe choice, so Enter does not confirm by accident.
  • The examples leave out closedby="any", so a stray click outside does not dismiss it. Esc still closes it.
  • Page scroll is not locked while it is open: that needs JavaScript.
@use "@wovenui/components/confirm-modal";

The confirm modal needs the modal and the button. The entry loads all three; in the bundle, switching modal or button off while confirm-modal is on stops the compile with an error.