Alert Dialog

A modal dialog that interrupts the user with important content and expects a confirm or cancel response.

Theme
<div class="flex justify-center">
    <sa-button variant="ButtonVariant.Outline" commandfor="--alert-dialog-intro" command="show-modal">
        Show Dialog
    </sa-button>
</div>
<sa-alert-dialog id="--alert-dialog-intro">
    <sa-alert-dialog-header>
        <sa-alert-dialog-title>Discard unsaved changes?</sa-alert-dialog-title>
        <sa-alert-dialog-description>
            You have unsaved changes to your itinerary for Trip #TRV-987. If you continue, your edits will be lost.
        </sa-alert-dialog-description>
    </sa-alert-dialog-header>
    <form method="dialog">
        <sa-alert-dialog-footer>
            <sa-alert-dialog-cancel>Keep editing</sa-alert-dialog-cancel>
            <sa-alert-dialog-action>Continue</sa-alert-dialog-action>
        </sa-alert-dialog-footer>
    </form>
</sa-alert-dialog>

Usage

<sa-alert-dialog> renders a standard HTML dialog element, styled as a centered confirmation modal. Open it with the Invoker Commands API by adding commandfor and command="show-modal" to a <sa-button>.

Unlike <sa-dialog>, an alert dialog is not light-dismissable: pressing Esc cancels it, but clicking the backdrop does nothing (closedby="closerequest" by default). Wrap the footer in a <form method="dialog"> and use <sa-alert-dialog-action> / <sa-alert-dialog-cancel> so the dialog closes with the correct returnValue.

<sa-button commandfor="--confirm" command="show-modal">
    Show Dialog
</sa-button>
<sa-alert-dialog id="--confirm">
    <sa-alert-dialog-header>
        <sa-alert-dialog-title>Cancel this booking?</sa-alert-dialog-title>
        <sa-alert-dialog-description>
            This action cannot be undone.
        </sa-alert-dialog-description>
    </sa-alert-dialog-header>
    <form method="dialog">
        <sa-alert-dialog-footer>
            <sa-alert-dialog-cancel>Keep booking</sa-alert-dialog-cancel>
            <sa-alert-dialog-action>Continue</sa-alert-dialog-action>
        </sa-alert-dialog-footer>
    </form>
</sa-alert-dialog>

<sa-alert-dialog-cancel> renders a submit button with value="cancel" and <sa-alert-dialog-action> one with value="confirm", so the wrapping method="dialog" form closes the dialog and sets returnValue accordingly.

Examples

Destructive action

Pass variant="ButtonVariant.Destructive" to <sa-alert-dialog-action> for irreversible operations such as deleting data.

Theme
<div class="flex justify-center">
    <sa-button variant="ButtonVariant.Destructive" commandfor="--alert-dialog-destructive" command="show-modal">
        Cancel Booking
    </sa-button>
</div>
<sa-alert-dialog id="--alert-dialog-destructive">
    <sa-alert-dialog-header>
        <sa-alert-dialog-title>Cancel this booking?</sa-alert-dialog-title>
        <sa-alert-dialog-description>
            This action cannot be undone. Your reservation for Trip #TRV-987 to Paris will be permanently cancelled and your seats released.
        </sa-alert-dialog-description>
    </sa-alert-dialog-header>
    <form method="dialog">
        <sa-alert-dialog-footer>
            <sa-alert-dialog-cancel>Keep booking</sa-alert-dialog-cancel>
            <sa-alert-dialog-action variant="ButtonVariant.Destructive">Cancel booking</sa-alert-dialog-action>
        </sa-alert-dialog-footer>
    </form>
</sa-alert-dialog>

Size

Use the size attribute (AlertDialogSize.Default or AlertDialogSize.Small) to switch between the wider, left-aligned default layout and the compact, centered small layout.

Theme
<div class="flex justify-center gap-2">
    <sa-button variant="ButtonVariant.Outline" commandfor="--alert-dialog-size-default" command="show-modal">
        Default
    </sa-button>
    <sa-button variant="ButtonVariant.Outline" commandfor="--alert-dialog-size-sm" command="show-modal">
        Small
    </sa-button>
</div>
<sa-alert-dialog id="--alert-dialog-size-default" size="AlertDialogSize.Default">
    <sa-alert-dialog-header>
        <sa-alert-dialog-title>Delete this itinerary?</sa-alert-dialog-title>
        <sa-alert-dialog-description>
            Your saved itinerary for Bangkok will be permanently deleted. On larger screens the default alert dialog is wider and left-aligns its content.
        </sa-alert-dialog-description>
    </sa-alert-dialog-header>
    <form method="dialog">
        <sa-alert-dialog-footer>
            <sa-alert-dialog-cancel>Cancel</sa-alert-dialog-cancel>
            <sa-alert-dialog-action variant="ButtonVariant.Destructive">Delete</sa-alert-dialog-action>
        </sa-alert-dialog-footer>
    </form>
</sa-alert-dialog>
<sa-alert-dialog id="--alert-dialog-size-sm" size="AlertDialogSize.Small">
    <sa-alert-dialog-header>
        <sa-alert-dialog-title>Delete this itinerary?</sa-alert-dialog-title>
        <sa-alert-dialog-description>
            Your saved Bangkok itinerary will be permanently deleted. The small alert dialog stays narrow and centers its content.
        </sa-alert-dialog-description>
    </sa-alert-dialog-header>
    <form method="dialog">
        <sa-alert-dialog-footer>
            <sa-alert-dialog-cancel>Cancel</sa-alert-dialog-cancel>
            <sa-alert-dialog-action variant="ButtonVariant.Destructive">Delete</sa-alert-dialog-action>
        </sa-alert-dialog-footer>
    </form>
</sa-alert-dialog>

Media

Add a <sa-alert-dialog-media> slot to the header to show a media element such as an icon or image above the title.

Theme
<div class="flex justify-center">
    <sa-button variant="ButtonVariant.Outline" commandfor="--alert-dialog-media" command="show-modal">
        Share Trip
    </sa-button>
</div>
<sa-alert-dialog id="--alert-dialog-media">
    <sa-alert-dialog-header>
        <sa-alert-dialog-media>
            <sa-icon name="circle-fading-plus"/>
        </sa-alert-dialog-media>
        <sa-alert-dialog-title>Share this trip?</sa-alert-dialog-title>
        <sa-alert-dialog-description>
            Anyone with the link will be able to view and edit your itinerary for Trip #TRV-987.
        </sa-alert-dialog-description>
    </sa-alert-dialog-header>
    <form method="dialog">
        <sa-alert-dialog-footer>
            <sa-alert-dialog-cancel>Cancel</sa-alert-dialog-cancel>
            <sa-alert-dialog-action>Share</sa-alert-dialog-action>
        </sa-alert-dialog-footer>
    </form>
</sa-alert-dialog>

Small with media

Combine size="AlertDialogSize.Small" with <sa-alert-dialog-media> for a compact, centered dialog that still leads with an icon.

Theme
<div class="flex justify-center">
    <sa-button variant="ButtonVariant.Outline" commandfor="--alert-dialog-small-media" command="show-modal">
        Show Dialog
    </sa-button>
</div>
<sa-alert-dialog id="--alert-dialog-small-media" size="AlertDialogSize.Small">
    <sa-alert-dialog-header>
        <sa-alert-dialog-media>
            <sa-icon name="map-pin"/>
        </sa-alert-dialog-media>
        <sa-alert-dialog-title>Enable location services?</sa-alert-dialog-title>
        <sa-alert-dialog-description>
            Voyager Travel uses your location to show flights and stays near you.
        </sa-alert-dialog-description>
    </sa-alert-dialog-header>
    <form method="dialog">
        <sa-alert-dialog-footer>
            <sa-alert-dialog-cancel>Not now</sa-alert-dialog-cancel>
            <sa-alert-dialog-action>Allow</sa-alert-dialog-action>
        </sa-alert-dialog-footer>
    </form>
</sa-alert-dialog>

JavaScript API

For the common "await a confirmation before acting" flow, use the window.stellarAdmin.alertDialog() helper. Its confirmAsync() method resolves to true when the user activates the action button and false on cancel or Esc.

alertDialog() is built on the same primitive as the dialog() helper. Use it whenever you want to drive a confirmation in an async/await style. See the alertDialog() documentation for the full API.

Theme
<sa-stack align="StackAlign.Start" class="min-w-md">
    <sa-button variant="ButtonVariant.Destructive" id="--alert-dialog-js-button">
        Remove from Wishlist
    </sa-button>
    <label class="text-sm font-bold">Result:</label>
    <div class="font-mono w-full rounded-md border border-border bg-muted p-3 text-foreground" id="--alert-dialog-js-result">-</div>
</sa-stack>
<sa-alert-dialog id="--alert-dialog-js">
    <sa-alert-dialog-header>
        <sa-alert-dialog-title>Remove from your wishlist?</sa-alert-dialog-title>
        <sa-alert-dialog-description>
            Kyoto will be removed from your saved destinations. You can add it back anytime.
        </sa-alert-dialog-description>
    </sa-alert-dialog-header>
    <form method="dialog">
        <sa-alert-dialog-footer>
            <sa-alert-dialog-cancel>Keep it</sa-alert-dialog-cancel>
            <sa-alert-dialog-action variant="ButtonVariant.Destructive">Remove</sa-alert-dialog-action>
        </sa-alert-dialog-footer>
    </form>
</sa-alert-dialog>
<script type="module">
    (function () {
        const alertDialog = window.stellarAdmin.alertDialog(document.getElementById("--alert-dialog-js"));
        const triggerButton = document.getElementById("--alert-dialog-js-button");
        const resultDisplay = document.getElementById("--alert-dialog-js-result");

        triggerButton.addEventListener("click", async () => {
            const confirmed = await alertDialog.confirmAsync();
            resultDisplay.innerHTML = confirmed ? "Removed from wishlist" : "Cancelled";
        });
    })();
</script>

Accessibility

<sa-alert-dialog> renders a native <dialog> element that is opened with showModal(), so focus is trapped inside it, the rest of the page is inert and focus returns to the trigger when it closes. The closedby attribute defaults to closerequest, so Escape closes the dialog without confirming but clicking outside it does nothing. The user has to choose an action explicitly.

Give <sa-alert-dialog-title> an id and reference it from aria-labelledby on <sa-alert-dialog> so the dialog is announced by its title, and do the same with aria-describedby and <sa-alert-dialog-description>. Add autofocus to <sa-alert-dialog-cancel> when the action is destructive so that pressing Enter by reflex does not confirm it.

API Reference

<sa-alert-dialog>

Renders a native <dialog> element which is opened and closed via the Invoker Commands API (command="show-modal" / command="close" on a button whose commandfor targets the dialog's id). The closedby attribute defaults to closerequest, so the dialog is not light-dismissable.

The dialog is wrapped in a <sel-dialog> web component that locks page scrolling while it is open. See JavaScript & Interactivity.

Prop

Type

<sa-alert-dialog-header>

Renders a <div> element that groups the media, title, and description.

<sa-alert-dialog-media>

Renders a <div> element for showing an icon or image above the title.

<sa-alert-dialog-title>

Renders an <h2> element containing the dialog's title.

<sa-alert-dialog-description>

Renders a <p> element containing the dialog's description.

Renders a <div> element that lays out the cancel and action buttons.

<sa-alert-dialog-cancel>

Renders a <button type="submit"> with value="cancel" (unless you supply your own value), so a wrapping <form method="dialog"> closes the dialog with that returnValue.

Prop

Type

<sa-alert-dialog-action>

Renders a <button type="submit"> with value="confirm" (unless you supply your own value), so a wrapping <form method="dialog"> closes the dialog with that returnValue.

Prop

Type

On this page