Skip to main content
Gremorie

Alert Dialog

Interruptive confirmation dialog. Blocks the UI, has no overlay-close, and requires an explicit Action or Cancel.

Overview

AlertDialog is the interruptive cousin of Dialog. It is modal-blocking by default, the user cannot dismiss it by clicking the overlay, and it forces an explicit choice through AlertDialogAction or AlertDialogCancel. Reserve it for moments where doing nothing would be wrong: destructive confirmations, irreversible actions, account deletion, payment commits.

If your dialog is informational, dismissible, or part of a routine flow, use Dialog instead.

Preview

'use client';import { Button } from '@gremorie/rx-forms';import {  AlertDialog,  AlertDialogAction,  AlertDialogCancel,  AlertDialogContent,  AlertDialogDescription,  AlertDialogFooter,  AlertDialogHeader,  AlertDialogTitle,  AlertDialogTrigger,} from '@gremorie/rx-overlays';export function AlertDialogPreview() {  return (    <AlertDialog>      <AlertDialogTrigger asChild>        <Button variant="outline">Delete project</Button>      </AlertDialogTrigger>      <AlertDialogContent>        <AlertDialogHeader>          <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>          <AlertDialogDescription>            This action cannot be undone. The project and its data will be            permanently removed.          </AlertDialogDescription>        </AlertDialogHeader>        <AlertDialogFooter>          <AlertDialogCancel>Cancel</AlertDialogCancel>          <AlertDialogAction>Continue</AlertDialogAction>        </AlertDialogFooter>      </AlertDialogContent>    </AlertDialog>  );}

Anatomy

AlertDialog                       Radix root holding open state.
├─ AlertDialogTrigger             Element that opens the dialog.
└─ AlertDialogContent             Centered, portalled panel (size default | sm).
   ├─ AlertDialogHeader           Groups media, title and description.
   │  ├─ AlertDialogMedia         Optional icon container above the title.
   │  ├─ AlertDialogTitle         Accessible headline.
   │  └─ AlertDialogDescription   Body text.
   └─ AlertDialogFooter           Action row.
      ├─ AlertDialogCancel        Dismiss button (variant="outline").
      └─ AlertDialogAction        Confirm button (variant="default").

Installation

bash npx gremorie@latest add rx-alert-dialog

bash pnpm dlx gremorie@latest add rx-alert-dialog

bash yarn dlx gremorie@latest add rx-alert-dialog

bash bunx --bun gremorie@latest add rx-alert-dialog

Usage

import { Button } from "@gremorie/rx-forms";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@gremorie/rx-overlays";

export function Example() {
  return (
    <AlertDialog>
      <AlertDialogTrigger asChild>
        <Button variant="outline">Delete project</Button>
      </AlertDialogTrigger>
      <AlertDialogContent>
        <AlertDialogHeader>
          <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
          <AlertDialogDescription>
            This action cannot be undone.
          </AlertDialogDescription>
        </AlertDialogHeader>
        <AlertDialogFooter>
          <AlertDialogCancel>Cancel</AlertDialogCancel>
          <AlertDialogAction>Continue</AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  );
}

The Angular edition of this component ships from source today (see the workbench for the side-by-side); its registry entry is coming next.

API

<AlertDialog>

Extends Radix AlertDialog.Root. Same controlled API as Dialog (open, defaultOpen, onOpenChange).

<AlertDialogContent>

PropTypeDefaultDescription
size"default" | "sm""default"Compact variant. sm constrains width to max-w-xs and switches the footer to a two-column grid.

Wraps Radix AlertDialog.Content in a Portal with the overlay. Has no built-in X close button by design.

<AlertDialogAction>

PropTypeDefaultDescription
variantButton["variant"]"default"Forwarded to the wrapping Button. Use "destructive" for delete confirmations.
sizeButton["size"]"default"Forwarded to the wrapping Button.

Renders a Button with asChild wrapping a Radix AlertDialog.Action. Closes the dialog and runs your handler.

<AlertDialogCancel>

PropTypeDefaultDescription
variantButton["variant"]"outline"Forwarded to the wrapping Button.
sizeButton["size"]"default"Forwarded to the wrapping Button.

Closes the dialog and returns focus to the trigger.

<AlertDialogHeader>, <AlertDialogFooter>, <AlertDialogTitle>, <AlertDialogDescription>

Same shape as their Dialog counterparts. Header is centered on mobile, left-aligned at sm+. Footer is flex-col-reverse on mobile, flex-row justify-end on sm+ (or a two-column grid when size="sm").

<AlertDialogMedia>

Optional icon container above the header text. Square size-16 muted-background block; auto-sizes any SVG child to size-8.

<AlertDialogHeader>
  <AlertDialogMedia>
    <TrashIcon />
  </AlertDialogMedia>
  <AlertDialogTitle>Delete project?</AlertDialogTitle>
</AlertDialogHeader>

<AlertDialogTrigger>, <AlertDialogOverlay>, <AlertDialogPortal>

Pass-throughs over the Radix primitives with data-slot attributes.

Composition

  1. <AlertDialog> owns open/close state.
  2. <AlertDialogTrigger asChild> wraps the action that opens it.
  3. <AlertDialogContent> mounts via Portal with a non-dismissible overlay.
  4. Header carries title and description (both required by Radix).
  5. Footer must include at least one of AlertDialogAction or AlertDialogCancel.
  6. Optional AlertDialogMedia for an icon that frames the confirmation visually.

Variations

Destructive confirmation

The most common shape. Cancel uses the outline variant, action uses destructive. There is no overlay-dismiss and no X close, so the user must choose.

'use client';import { Button } from '@gremorie/rx-forms';import {  AlertDialog,  AlertDialogAction,  AlertDialogCancel,  AlertDialogContent,  AlertDialogDescription,  AlertDialogFooter,  AlertDialogHeader,  AlertDialogTitle,  AlertDialogTrigger,} from '@gremorie/rx-overlays';export function AlertDialogDestructivePreview() {  return (    <AlertDialog>      <AlertDialogTrigger asChild>        <Button variant="destructive">Delete account</Button>      </AlertDialogTrigger>      <AlertDialogContent>        <AlertDialogHeader>          <AlertDialogTitle>Delete account?</AlertDialogTitle>          <AlertDialogDescription>            This permanently removes your account and all associated data. There            is no undo.          </AlertDialogDescription>        </AlertDialogHeader>        <AlertDialogFooter>          <AlertDialogCancel>Cancel</AlertDialogCancel>          <AlertDialogAction variant="destructive">            Delete account          </AlertDialogAction>        </AlertDialogFooter>      </AlertDialogContent>    </AlertDialog>  );}

The same pattern in code:

<AlertDialog>
  <AlertDialogTrigger asChild>
    <Button variant="destructive">Delete account</Button>
  </AlertDialogTrigger>
  <AlertDialogContent>
    <AlertDialogHeader>
      <AlertDialogTitle>Delete account?</AlertDialogTitle>
      <AlertDialogDescription>
        This permanently removes your account and all data. There is no undo.
      </AlertDialogDescription>
    </AlertDialogHeader>
    <AlertDialogFooter>
      <AlertDialogCancel>Cancel</AlertDialogCancel>
      <AlertDialogAction variant="destructive" onClick={handleDelete}>
        Delete account
      </AlertDialogAction>
    </AlertDialogFooter>
  </AlertDialogContent>
</AlertDialog>

Compact with media icon

Use size="sm" for tighter confirmations and add an icon to soften the tone.

<AlertDialogContent size="sm">
  <AlertDialogHeader>
    <AlertDialogMedia>
      <ArchiveIcon />
    </AlertDialogMedia>
    <AlertDialogTitle>Archive 12 items?</AlertDialogTitle>
    <AlertDialogDescription>
      You can restore them within 30 days.
    </AlertDialogDescription>
  </AlertDialogHeader>
  <AlertDialogFooter>
    <AlertDialogCancel>Cancel</AlertDialogCancel>
    <AlertDialogAction>Archive</AlertDialogAction>
  </AlertDialogFooter>
</AlertDialogContent>

For high-stakes confirmations, restate the action verb on the primary button so the choice is unambiguous.

<AlertDialogFooter>
  <AlertDialogCancel>Keep project</AlertDialogCancel>
  <AlertDialogAction variant="destructive">
    Delete project forever
  </AlertDialogAction>
</AlertDialogFooter>

Accessibility

  • Role: role="alertdialog" with aria-modal="true". Screen readers announce it more assertively than a regular dialog.
  • Keyboard: Esc closes via the cancel path; Tab cycles between Cancel and Action only; focus trap is active.
  • Focus management: focus moves to the Cancel button on open (Radix default for alert dialogs) and returns to the trigger on close.
  • No overlay dismiss: clicking the overlay does nothing. The user must explicitly choose.
  • No X close button: by design, to prevent accidental dismissal of consequential choices.
  • Description: linked via aria-describedby. Both AlertDialogTitle and AlertDialogDescription are required by Radix.
  • Dialog - non-interruptive modal for routine flows.
  • Sheet - lateral panel for longer flows.
  • Sonner - non-blocking toast for soft confirmations and undo.

On this page