Manual UI Templates AlertDialog

AlertDialog

elements man ui/templates/alert-dialog

A modal that interrupts with something important and waits for an answer.

Example
import { AlertDialog, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, } from "@elements/ui/alert-dialog"; import { Button } from "@elements/ui/button"; <AlertDialog title="Delete project?" description="This permanently deletes the project and its files."> <Button slot="trigger" variant="danger">Delete project</Button> <AlertDialogFooter> <AlertDialogCancel>Cancel</AlertDialogCancel> <AlertDialogAction variant="danger" onclick={() => remove(project)}>Delete</AlertDialogAction> </AlertDialogFooter> </AlertDialog> <!-- controlled: open is two-way --> <AlertDialog open={state.confirming} title="Discard changes?">...</AlertDialog>

Parts

Part What it is
AlertDialog The root: owns open, renders the trigger slot and, while open, a modal <dialog role="alertdialog"> with its panel.
AlertDialogHeader Stacks media, title and description: centered on phones and in the sm size, left-aligned otherwise.
AlertDialogMedia An icon or image above the title (beside it at md from 40rem up). Decorative: aria-hidden.
AlertDialogTitle An <h2>; names the alert dialog (aria-labelledby).
AlertDialogDescription A <p>; the alert message (aria-describedby).
AlertDialogFooter The actions: right-aligned, stacked full width on phones, two equal columns in the sm size.
AlertDialogCancel An outline button that closes the dialog. It gets focus when the dialog opens.
AlertDialogAction A primary button that closes the dialog after its onclick, unless onclick calls e.preventDefault().

Attributes

AlertDialog

Attribute Type Default Description
open boolean (two-way) false Whether the dialog is open. Bind it to control it; the dialog writes false back when Escape, Cancel or Action closes it. Omit it and the trigger slot opens it.
title string "" Renders an AlertDialogTitle in a header and names the dialog.
description string "" Renders an AlertDialogDescription under the title and describes the dialog.
label string "" aria-label for a dialog with no visible title.
size "md" | "sm" "md" md is the theme's --dialog-width; sm is a narrow, centered layout with the actions side by side.
initialFocus DialogFocus "" CSS selector of the element to focus on open, or a function of the interaction type (keyboard, mouse, touch, pen) that returns an element, a selector, true for the default or false to leave focus. Default: the AlertDialogCancel button, else the panel.
returnFocus boolean true Return focus to the trigger (or whatever had focus) when the dialog closes.
finalFocus DialogFocus "" CSS selector of the element to focus on close, in place of the trigger, or a function of the interaction type that returns an element, a selector, true for the trigger or false to leave focus.
class string "" Extra classes on the panel.
onOpenChangeComplete (open: boolean) => void () => {} Called after the enter animation (true) or once the dialog has left the page after its exit (false).
onOpenChange (open: boolean, reason?: DialogChangeReason, details?: DialogChangeDetails) => void () => {} Called when the dialog opens or closes itself, with a reason: trigger-press, escape-key, close-press, close-watcher (a platform close request such as Android back), or none when the browser closed it. Not called for changes the caller makes. The third argument is an event details object: { reason, event (the DOM event behind the change, or null), trigger (the trigger element on trigger-press) }.
onOpenAutoFocus (e: Event) => void () => {} Called before focus moves in on open; e.preventDefault() leaves focus to the handler.
onCloseAutoFocus (e: Event) => void () => {} Called before focus returns on close; e.preventDefault() leaves focus to the handler.
onEscapeKeyDown (e: KeyboardEvent) => void () => {} Called on Escape before closing; e.preventDefault() keeps it open, and e.allowPropagation() lets the Escape reach the page's own key handlers too.

AlertDialogMedia

Attribute Type Default Description
variant "default" | "danger" "default" danger tints the media with the danger colors.

AlertDialogCancel

Attribute Type Default Description
variant ButtonVariant "outline" Button variant.

AlertDialogAction

Attribute Type Default Description
variant ButtonVariant "primary" Button variant; danger for a destructive action.
loading boolean false Shows a spinner over the label at the same size; clicks are ignored.
type "button" | "submit" | "reset" "button" The button type; submit makes the Action the submit button of a form inside the alert. A click still closes it.

AlertDialogCancel, AlertDialogAction

Attribute Type Default Description
size "xs" | "sm" | "md" | "lg" "md" Button size.
disabled boolean false Disables the button.
onclick (e: MouseEvent) => void () => {} Runs before the dialog closes; e.preventDefault() keeps it open.
attrs Record<string, string | number | boolean | undefined> {} Attributes for the <button> (id, name, form, data-testid).

every part

Attribute Type Default Description
class string "" Extra classes.

Slots

Slot Content
trigger The element that opens the dialog. It gets aria-haspopup, aria-expanded, aria-controls and data-state.
media An AlertDialogMedia shown in the header made by the title and description attributes.
default The content below the header, usually an AlertDialogFooter.

Keyboard

Keys Action
Space / Enter On the trigger: opens the dialog. On Cancel or Action: activates it, which closes the dialog.
Tab Moves to the next focusable element inside; wraps from the last to the first.
Shift + Tab Moves to the previous focusable element; wraps from the first to the last.
Escape Closes the dialog and returns focus to the trigger, unless onEscapeKeyDown prevents it.

Data attributes

Attribute Values On Description
data-open present .dialog-overlay, .alert-dialog While open; the same moment as data-state="open".
data-closed, data-ending-style present .dialog-overlay, .alert-dialog During the exit animation; the same moment as data-state="closed".
data-starting-style present .dialog-overlay, .alert-dialog For the first frame after the overlay mounts, so a CSS transition can start from it.
data-popup-open present trigger While open; the same moment as the trigger's data-state="open".
data-state "open" | "closed" trigger, .dialog-overlay, .alert-dialog closed during the exit animation.
data-size "md" | "sm" .alert-dialog
data-alert-dialog-cancel present AlertDialogCancel's <button> The default initial focus target.
data-alert-dialog-action present AlertDialogAction's <button>
data-scroll-locked present <body> While open.
data-nested present .alert-dialog The alert was opened inside another dialog's panel.
data-nested-dialog-open present the outer dialog's panel While a nested alert is open over it.
--nested-dialogs number the outer dialog's panel How many nested dialogs are open over it.

Accessibility

  • The overlay is a native <dialog> opened with showModal() and given role="alertdialog": it sits in the top layer and the page behind is inert.
  • aria-modal="true", aria-labelledby (the title) and aria-describedby (the description) are set on it; with no title, the label attribute becomes aria-label.
  • Focus moves to Cancel on open, so an accidental Enter does not confirm a destructive action. It is trapped while open and returns to the trigger on close.
  • A press outside does not close it: the user has to answer. Escape closes it, as Cancel would.
  • The trigger gets aria-haspopup="dialog", aria-expanded and aria-controls.

See also