Alert dialog <l-alert-dialog>
An interruptive confirmation dialog built on <l-dialog>. It renders its own cancel/confirm actions, exposes role="alertdialog", and closes when the user picks an action — unless you cancel the event. Use it to confirm a consequential action, not for generic content.
<l-alert-dialog>Options
Basic
Open with command="--show" on a trigger button. The cancel and confirm actions are rendered for you; label them with cancel-text and confirm-text. The dialog closes automatically when an action is picked.
Code
<button
type="button"
class="l-button"
command="--show"
commandfor="confirm-publish"
>
Publish article
</button>
<l-alert-dialog
id="confirm-publish"
title="Publish this article?"
confirm-text="Publish"
>
Once published, “Spring collection 2026” becomes visible to everyone on your storefront. You can
still edit it afterwards.
</l-alert-dialog>Danger
Add tone="danger" to render the confirm action as destructive — for delete, discard, or other irreversible actions.
Code
<button
type="button"
class="l-button"
data-variant="destructive"
command="--show"
commandfor="confirm-delete"
>
Delete project
</button>
<l-alert-dialog
id="confirm-delete"
tone="danger"
title="Delete this project?"
confirm-text="Delete"
>
This permanently deletes the <strong>Acme</strong> project and everything in it. This action
cannot be undone.
</l-alert-dialog>Custom actions
Slot your own confirm / cancel elements — a link, a button with an icon, any tone — to replace the built-in buttons. They still drive the confirm / cancel events. Keep the slotted element focusable.
Code
<button
type="button"
class="l-button"
command="--show"
commandfor="confirm-invite"
>
Invite collaborator
</button>
<l-alert-dialog
id="confirm-invite"
title="Send this invitation?"
confirm-text="Send invite"
>
Jane Cooper will get access to the Acme workspace and can edit all projects.
<a
slot="cancel"
class="l-button"
href="#confirm-invite"
>
Not now
</a>
<button
slot="confirm"
type="button"
class="l-button [--background-color:var(--l-color-bg-fill-success-strong)] [--background-color-hover:color-mix(in_oklab,var(--l-color-bg-fill-success-strong)_88%,black)] [--background-color-active:color-mix(in_oklab,var(--l-color-bg-fill-success-strong)_78%,black)] [--text-color:white] [--text-color-hover:white] [--border-color:transparent]"
>
<l-icon name="lucide:send"></l-icon>
Send invite
</button>
</l-alert-dialog>Examples
Reacting to the choice
Listen for confirm and cancel. Both fire on the user's intent; the dialog closes on its own afterwards.
const dialog = document.getElementById('confirm-delete');
dialog.addEventListener('confirm', () => deleteProject());
dialog.addEventListener('cancel', () => {
/* optional: the user backed out */
});Async confirmation
confirm is cancelable. Call preventDefault() to keep the dialog open while an async task runs, set loading to show a spinner on the confirm action, then close it once the work resolves. The cancel action stays operable throughout. Try it — the confirm button stays busy for ~1.8s:
Code
<button
type="button"
class="l-button"
data-variant="destructive"
command="--show"
commandfor="confirm-delete"
>
Delete account
</button>
<l-alert-dialog
id="confirm-delete"
tone="danger"
title="Are you absolutely sure?"
confirm-text="Delete account"
>
This action cannot be undone. This will permanently delete your account and remove your data from
our servers.
</l-alert-dialog>const dialog = document.getElementById('confirm-delete');
dialog.addEventListener('confirm', async (event) => {
event.preventDefault(); // keep the dialog open during the request
dialog.loading = true; // spinner on the confirm action
await deleteAccount();
dialog.loading = false;
dialog.open = false; // close once it's done
});Accessibility
Criteria
- Role
Rendered as a native
<dialog>withrole="alertdialog"— interruptive modal semanticsWCAG4.1.2RGAA7.1- Accessible description
The body content is wired as the dialog description via
aria-describedbyWCAG4.1.2- Focus management
Focus is trapped inside the modal and lands on the cancel action — the least destructive choice
WCAG2.4.3RGAA10.7- Focus restoration
Focus returns to the trigger element when the dialog closes
WCAG2.4.3- Motion
Respects
prefers-reduced-motionWCAG2.3.3
Keyboard interactions
API reference
Importing
import 'luxen-ui/alert-dialog';Attributes & Properties
confirm-textstringdefault:'Confirm'Property- Label for the confirm action.
cancel-textstringdefault:'Cancel'Property- Label for the cancel action.
tone'danger' | undefinedProperty- Visual tone.
dangerrenders the confirm action as destructive. loadingbooleandefault:falseProperty- Show a busy state on the confirm action (spinner +
aria-disabled); the cancel action stays operable as an escape hatch. titlestringProperty- Dialog title rendered in the header and used as the dialog's accessible name.
openbooleandefault:falseProperty- Whether the dialog is open.
light-dismissbooleandefault:falseProperty- Close when the backdrop is clicked.
without-headerbooleandefault:falseProperty- Hide the header entirely (title and close slot).
Commands
Open and close the dialog by toggling its open property, or via the Invoker Commands API from any light-DOM button. Custom commands must start with --.
--showCommand- Sets
open = true. --hideCommand- Sets
open = false.
Events
confirmcancelableEvent- Fired when the user accepts. Cancelable —
preventDefault()keeps it open for async work. cancelcancelableEvent- Fired when the user dismisses (cancel action, Escape). Cancelable —
preventDefault()keeps it open. showcancelableEvent- Fired when the dialog is about to open. Cancelable.
hidecancelableEvent- Fired when the dialog is about to close via the
openproperty. Cancelable. (The confirm, cancel, and Escape paths close natively and emitconfirm/cancelinstead ofhide.) after-showEvent- Fired after the open animation completes. Not cancelable.
after-hideEvent- Fired after the close animation completes. Not cancelable.
Slots
(default)Slot- Description text. Provides the dialog's accessible description.
titleSlot- Custom heading element. Overrides the default
<h2>rendered from thetitleproperty. Also provides the dialog's accessible name. cancelSlot- Replaces the built-in cancel action (e.g. a link). Keep it focusable.
confirmSlot- Replaces the built-in confirm action.
closeSlot- Close button (typically
<button class="l-close">). footerSlot- Footer actions.
CSS parts
dialogPart- The native
<dialog>element. headerPart- The header wrapper containing the title.
titlePart- The dialog title heading.
bodyPart- The body wrapper around the description.
footerPart- The footer wrapper around the actions.
buttonPart- Both built-in action buttons.
cancelPart- The built-in cancel button.
confirmPart- The built-in confirm button.
CSS custom properties
--widthdefault:31remCustom property- Dialog width.
--border-radiusdefault:6pxCustom property- Dialog border radius.
--paddingdefault:1.5remCustom property- Padding applied to the header, footer, and inline-padding of the body.
--show-durationdefault:200msCustom property- Open transition duration.
--hide-durationdefault:200msCustom property- Close transition duration.
--backdropCustom property- Backdrop color.
--backdrop-blurdefault:0Custom property- Backdrop blur amount (any CSS length).