Overlay · astro-ui · AlertDialog

AlertDialogJS

role=alertdialog modal that interrupts for a decision.

AlertDialog is a modal that interrupts for a decision — role=“alertdialog” tells assistive tech to announce the message immediately. Structure mirrors Dialog (native <dialog>, platform modality/focus containment, zero JS in the component) with an action-oriented footer: cancel buttons are plain <form method=“dialog”> submissions, so dismissal needs no JS. The dialog’s returnValue receives the submitting button’s value, so the app can tell which action dismissed it.

Features

  • role="alertdialog" — announced immediately by assistive tech
  • Native <dialog> modality, focus containment, Escape-to-close
  • Zero-JS dismissal via <form method="dialog"> (returnValue tells you which action)
  • xs / sm / md / lg panel sizes; auto title/description labelling

Usage

---
import { Button, AlertDialog } from "astro-ui";
---

<Button id="open-delete">Delete project</Button>
<AlertDialog id="delete">
  <h2 slot="title">Delete project?</h2>
  <p slot="description">This cannot be undone.</p>
  <Fragment slot="footer">
    <form method="dialog"><Button variant="outline">Cancel</Button></form>
    <form method="dialog">
      <Button variant="destructive" value="confirm">Delete</Button>
    </form>
  </Fragment>
</AlertDialog>

<script>
  document.getElementById("open-delete")?.addEventListener("click", () => {
    document.getElementById("delete")?.showModal();
  });
</script>

Demos

Confirm a destructive action

Delete project?

This cannot be undone.

<Button id="open-delete" variant="destructive">Delete project</Button>
<AlertDialog id="delete">
  <h2 slot="title">Delete project?</h2>
  <p slot="description">This cannot be undone.</p>
  <Fragment slot="footer">
    <form method="dialog"><Button variant="outline">Cancel</Button></form>
    <form method="dialog"><Button variant="destructive" value="confirm">Delete</Button></form>
  </Fragment>
</AlertDialog>

Sizes

Extra small

20rem panel for short confirmations.

Large

32rem panel when the message needs room.

<Button id="open-xs">Open xs</Button>
<AlertDialog id="xs" size="xs">
  <h2 slot="title">Extra small</h2>
  <p slot="description">20rem panel for short confirmations.</p>
</AlertDialog>
<Button id="open-lg">Open lg</Button>
<AlertDialog id="lg" size="lg">
  <h2 slot="title">Large</h2>
  <p slot="description">32rem panel when the message needs room.</p>
</AlertDialog>

API

Props

PropTypeDefaultDescription
size"xs" | "sm" | "md" | "lg""sm"Panel width scale.
idstring—Required for automatic title/description labelling (and the trigger script).
classstring—Merged via cn(); Tailwind classes welcome.
idstring—Element id.

Slots

SlotDescription
titleHeading (auto-wired to aria-labelledby).
descriptionSupporting copy (auto-wired to aria-describedby).
defaultExtra body content.
footerAction buttons — wrap each in <form method="dialog"> for zero-JS close.

Accessibility

Implemented accessibility features — semantics, ARIA wiring, and keyboard behavior that ship with the component.

  • Native <dialog> with role="alertdialog" — interruptive semantics announced as an alert
  • aria-labelledby / aria-describedby auto-wired to the title and description slots
  • Focus is contained while open; Escape closes via the platform

FAQ

How do I know which button closed it?

The dialog's returnValue receives the submitting button's value — listen for the close event and read dialog.returnValue === "confirm".

Does the component ship JS?

No — only the app-level trigger (showModal()) is yours; modality, focus containment, and Escape all come from native <dialog>.

Changelog

Version history mentioning AlertDialog.

v0.1.0 — 2026-11-11
added
  • Overlay (8): Dialog, AlertDialog, Sheet, Tooltip, Popover, HoverCard, Lightbox, Menu.
  • Native-first interactive behavior: Dialog, AlertDialog, and Sheet on <dialog>; Accordion and Collapsible on <details>; Tabs, Menu, Tree, and Combobox with WAI-ARIA roles and scoped keyboard scripts.
fixed
  • Dialog, Lightbox, Sheet, and AlertDialog backdrops, Progress stripes, Carousel shadows, and Chart SVG shadows resolve through tokens instead of hard-coded colors.