Skip to content

Documentation

neelam-ui

Search documentation

Getting Started
Forms
Overlays
Navigation
Data Display
Layout
AI & Chat
Blocks
GitHub repository

Alert Dialog

A confirmation modal that cannot be dismissed by accident — the same native <dialog> foundation as Dialog, with every dismissal path that isn't an explicit choice switched off.

Delete this project?

This permanently deletes the project and all of its deployments. This action cannot be undone.

Usage#

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "neelam-ui";
 
<AlertDialog>
  <AlertDialogTrigger>Delete project</AlertDialogTrigger>
  <AlertDialogContent>
    <AlertDialogHeader>
      <AlertDialogTitle>Delete this project?</AlertDialogTitle>
      <AlertDialogDescription>This cannot be undone.</AlertDialogDescription>
    </AlertDialogHeader>
    <AlertDialogFooter>
      <AlertDialogCancel>Cancel</AlertDialogCancel>
      <AlertDialogAction variant="destructive">Delete</AlertDialogAction>
    </AlertDialogFooter>
  </AlertDialogContent>
</AlertDialog>

How it differs from Dialog#

Mechanically it is a Dialog — same native <dialog>, same focus trapping, same top-layer stacking. Three deliberate subtractions make it an alert dialog:

  • No outside-click dismissal. Not a prop that defaults to off — simply never available. A stray click silently discarding a destructive confirmation is exactly what this component exists to prevent.
  • No Escape. A native <dialog> fires a cancelable cancel event before Escape closes it, so onCancel calls preventDefault() on it. The close is stopped before it starts, rather than closing and reopening.
  • No corner close button. Every way out should read as a deliberate choice between the two footer buttons, not a third, easier-to-misclick escape hatch.

Reserve it for consequences

An alert dialog takes away every casual way out. That is correct for deleting an account and hostile for "you have unsaved changes". If dismissing is a reasonable thing to want, use Dialog.

AlertDialogTrigger, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, and AlertDialogFooter are the exact same components as their Dialog counterparts, re-exported under alert-flavoured names. Only AlertDialogContent, AlertDialogAction, and AlertDialogCancel are new.

Action and Cancel#

Both close the dialog. They differ only in default styling, so the pair reads as primary/secondary without either needing an explicit variant:

  • AlertDialogAction defaults to variant="default".
  • AlertDialogCancel defaults to variant="outline".

Both accept Button's full variant and size set, which is the whole affordance for a destructive confirmation:

<AlertDialogAction variant="destructive">Delete</AlertDialogAction>

Calling preventDefault() in your own onClick stops the dialog closing — the hook for keeping it open while an async delete is in flight.

Keyboard#

Keyboard shortcuts
KeyBehaviour
EnterSpaceOpens the dialog from the trigger; activates the focused footer button when open.
TabShift+TabCycles focus within the dialog and cannot leave it.
EscapeDeliberately does nothing. Cancel is the way out.

Escape doing nothing is a real trade-off

It breaks a convention users rely on. That is the point — but it means the cancel button must always be visible and obvious, never scrolled out of view on a small screen.

Accessibility#

  • The panel carries role="alertdialog" rather than the <dialog> element's implicit dialog role, which is what tells assistive tech this one requires an immediate, explicit response.
  • AlertDialogTitle supplies the accessible name via aria-labelledby and is required. AlertDialogDescription is wired up with aria-describedby.
  • Focus moves into the dialog on open and returns to the trigger on close.
  • Background content is made inert by the platform, so it is removed from the accessibility tree rather than merely covered.
  • Transitions are dropped under prefers-reduced-motion.

API reference#

AlertDialog#

Props for AlertDialog
PropTypeDefault
defaultOpen

Initial open state when uncontrolled. Defaults to `false`.

boolean
onOpenChange

Called whenever the open state changes, whether from `DialogTrigger`, `DialogClose`, the built-in close button, Escape, or an outside click.

((open: boolean) => void)
open

Controls the open state. Omit to let the dialog manage its own state.

boolean

AlertDialogContent#

Props for AlertDialogContent
PropTypeDefault
onCancelReactEventHandler<HTMLDialogElement>

AlertDialogAction#

Props for AlertDialogAction
PropTypeDefault
size"sm" | "md" | "lg" | "icon" | null
variant"link" | "default" | "secondary" | "outline" | "destructive" | "ghost" | nulloutline

AlertDialogCancel#

Props for AlertDialogCancel
PropTypeDefault
size"sm" | "md" | "lg" | "icon" | null
variant"link" | "default" | "secondary" | "outline" | "destructive" | "ghost" | nulloutline