Alert Dialog
A modal question before something hard to undo: delete, disconnect, leave, or discard. Outside clicks do not close it. Focus stays inside until the person answers, then returns to where it was.
No change made.
Usage
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogTitle,
} from "@tulipfarm/sprout/alert-dialog";
<AlertDialog open={confirmStop} onOpenChange={(value) => { if (!busy) setConfirmStop(value); }}>
<AlertDialogContent>
<AlertDialogTitle>Stop this plan?</AlertDialogTitle>
<AlertDialogDescription>
Unfinished tasks are cancelled and saved agents pause. Finished work is kept.
</AlertDialogDescription>
{error && <p role="alert" className="text-sprout-danger">{error}</p>}
<AlertDialogFooter>
<AlertDialogCancel disabled={busy}>Keep running</AlertDialogCancel>
<AlertDialogAction variant="destructive" disabled={busy} aria-busy={busy} onClick={stop}>
{busy ? "Stopping…" : "Stop plan"}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>AlertDialog works controlled with open and onOpenChange, uncontrolled with AlertDialogTrigger, or mounted only while open with open fixed to true. Ignore the change in onOpenChange to block Escape while work is pending.
AlertDialogCancel closes the dialog. AlertDialogAction is a Button and does not close it, so close it yourself on success and keep it open to show progress or an error.
Sizes
size is "default" (20rem, 24rem from 640px) or "sm" (20rem). With AlertDialogHeader, a default dialog puts AlertDialogMedia beside the text from 640px; sm always centers it and splits the footer into two equal buttons.
Sizes
Both sizes with AlertDialogHeader and AlertDialogMedia. Below 640px both center their header.
Confirmations
Most confirmations place the title and description straight in the content without a header. Cancel can run its own onClick, for example to clear a pending choice.
Confirmations
Title and description sit straight in the content. Cancel closes; the action closes the dialog itself before starting the change.
Pending and errors
Disable both buttons and set aria-busy on the action while work runs. Show errors as a role="alert" paragraph or an Alert inside the dialog. When the result is known, hide the action and let Cancel's label say what happens next.
Pending and errors
While work runs, both buttons disable, the action says what is happening, and Escape is ignored. Errors stay inside the dialog.
Progress
A plain Button in the footer can start work that runs inside the dialog, with a role="status" count.
Progress
A plain Button starts the work without closing. The dialog then reports progress, and Cancel's label follows the state.
Review changes
Pick the action variant from what confirming does, and disable it when the review is out of date.
Review changes
The action variant follows what confirming does: default when nothing is lost, destructive when input is cleared. A stale review disables it.
Unsaved changes
Guard navigation away from a dirty draft. Pass finalFocus a function when focus should land somewhere other than the trigger.
Unsaved changes
Switching teams or leaving with a dirty draft asks first. finalFocus sends focus to the team that ends up selected.
API
AlertDialog, AlertDialogTrigger, AlertDialogPortal, AlertDialogOverlay, AlertDialogTitle, and AlertDialogDescription wrap the Base UI alert dialog parts and take their props, including render. AlertDialogHeader, AlertDialogFooter, and AlertDialogMedia render a div and accept render.
AlertDialogContent takes size, container, and every Base UI popup prop such as initialFocus and finalFocus. AlertDialogAction takes every Button prop. AlertDialogCancel takes Base UI close props plus variant (default "outline") and size. alertDialogSizeNames lists the sizes.
Accessibility
The popup has role="alertdialog", is named by AlertDialogTitle, and described by AlertDialogDescription. Tab and Shift+Tab stay inside, Escape closes it unless you ignore the change, and outside clicks never close it.
Opening fades and scales in over 180ms; closing takes 120ms. Both turn off when reduced motion is requested.
Theme tokens
Alert dialogs use --sprout-overlay, --sprout-surface, --sprout-canvas, --sprout-secondary, --sprout-line, --sprout-text, --sprout-muted, --sprout-shadow-overlay, and --sprout-radius-panel. They need no brand color, so neutral and TulipFarm themes look alike in light and dark mode.