Askr
UI & Components

Alert Dialog

Use alert dialog with the current published Askr packages.

  • @askrjs/ui/alert-dialog0.0.13
  • @askrjs/themes/alert-dialog0.0.13

How to use alert dialog

Alert Dialog should use the standard themed surface unless the application is deliberately implementing its own design system on top of @askrjs/ui.

  1. Import the themed component from @askrjs/themes/components; use @askrjs/ui directly only when building a custom visual system.
  2. Keep alert dialog labels, state, and application actions visible at the call site instead of styling internal DOM nodes.
  3. Verify keyboard behavior, focus movement or return, disabled state, and both standard themes.
import { Button, Dialog, DialogContent, DialogDescription, DialogTitle, DialogTrigger } from '@askrjs/themes/components';

<Dialog>
  <DialogTrigger asChild><Button>Edit project</Button></DialogTrigger>
  <DialogContent>
    <DialogTitle>Edit project</DialogTitle>
    <DialogDescription>Changes are visible immediately.</DialogDescription>
    <ProjectForm />
  </DialogContent>
</Dialog>

Purpose

Alert Dialog is Dialog configured for one job: forcing a decision. It's for destructive or hard-to-reverse actions — deleting a record, discarding unsaved changes — where you want to interrupt the user and make them explicitly confirm or back out rather than dismissing it accidentally with a stray click or Escape.

Install and import

Import behavior from `@askrjs/ui/alert-dialog` and styling from `@askrjs/themes/alert-dialog`, both real subpaths. Under the hood most of the pieces — `AlertDialogOverlay`, `AlertDialogTitle`, `AlertDialogDescription`, `AlertDialogAction`, `AlertDialogCancel` — are just `Dialog`'s corresponding parts re-exported under alert-dialog names, so anything you already know about Dialog's props carries over directly.

Live examples

Structure mirrors Dialog: `AlertDialog` wraps an `AlertDialogTrigger` and a portal containing `AlertDialogContent`, `AlertDialogTitle`, and `AlertDialogDescription`. The part that's actually distinct is the footer — pair `AlertDialogCancel` with `AlertDialogAction` so there's always an explicit way to back out alongside the destructive action.

Anatomy

`AlertDialogContent` is a dedicated component (not a Dialog re-export) that renders with `role="alertdialog"` baked in rather than the default `dialog` role. Everything else in the tree — trigger, portal, overlay, title, description — is Dialog's implementation reused as-is under an alert-dialog-flavored name, since the underlying interaction pattern doesn't need to differ.

State model

State is the same open/closed boolean as Dialog, since `AlertDialogProps` is literally `DialogProps` under a type alias — `open`, `defaultOpen`, and `onOpenChange` behave identically. The meaningful difference isn't in the state shape, it's in what the two footer actions are expected to do: `AlertDialogCancel` should always close without side effects, `AlertDialogAction` should perform the action and then close.

Keyboard and accessibility

The a11y contract calls for both a primary action and a cancel action to be present — `ALERT_DIALOG_A11Y_CONTRACT.ACTION_REQUIREMENTS` flags both as required, so don't ship an alert dialog with only a single button. `role="alertdialog"` combined with `aria-labelledby`/`aria-describedby` tells assistive tech this is an interruption that needs an explicit response, which is stronger messaging than a plain dialog gives.

Styling and tokens

Because the overlay, content surface, and animations are shared with Dialog, alert dialogs pick up the same `--ak-color-backdrop`, `--ak-color-bg`, `--ak-color-border`, and z-index tokens out of the box. The theme layer adds its own `alert-dialog.css` on top mainly to style the action row — typically rendering `AlertDialogAction` with a destructive-leaning button variant and `AlertDialogCancel` as a plain secondary button.

API

`AlertDialogAction` and `AlertDialogCancel` are both just `DialogClose` — button-like components with `onPress`/`disabled`, no special props of their own beyond what Dialog's close button already supports. `AlertDialogContent` supports the same `forceMount`, `onEscapeKeyDown`, `onPointerDownOutside`, `onInteractOutside`, and `onDismiss` props as `DialogContent`; there's no alert-dialog-specific prop surface beyond the role.

Edge cases

Because `AlertDialogCancel` and `AlertDialogAction` are both plain close buttons under the hood, nothing stops you from wiring `onPress` on `AlertDialogCancel` to do something other than a no-op cancel — resist that, since it breaks the pattern users expect from this component. If the destructive action can fail, keep the dialog open and surface the error inside `AlertDialogContent` rather than letting `AlertDialogAction` close it optimistically.

See Dialog for the full prop reference and the shared portal/overlay/content anatomy that Alert Dialog builds on. If the interruption doesn't need a confirm/cancel pair — just information the user can dismiss with a click anywhere — a plain Dialog or a Popover is a better fit.