AlertDialog
A modal confirmation that requires a response. It does not close on outside press and focuses Cancel first.
Import
import { AlertDialog } from "@merid/react";<AlertDialog.Root>
<AlertDialog.Trigger asChild>
<Button variant="danger">Delete project</Button>
</AlertDialog.Trigger>
<AlertDialog.Content>
<AlertDialog.Title>Delete “Northwind”?</AlertDialog.Title>
<AlertDialog.Description>
The project and its 24 files are removed permanently. This cannot be undone.
</AlertDialog.Description>
<AlertDialog.Footer>
<AlertDialog.Cancel>Cancel</AlertDialog.Cancel>
<AlertDialog.Action tone="danger">Delete project</AlertDialog.Action>
</AlertDialog.Footer>
</AlertDialog.Content>
</AlertDialog.Root>Anatomy
<AlertDialog.Root>
<AlertDialog.Trigger />
<AlertDialog.Content>
<AlertDialog.Title />
<AlertDialog.Description />
<AlertDialog.Footer>
<AlertDialog.Cancel />
<AlertDialog.Action />
</AlertDialog.Footer>
</AlertDialog.Content>
</AlertDialog.Root>Root, Trigger, Title, Description and Footer are the same parts as Dialog. Cancel is a secondary Button that dismisses and receives initial focus; Action is a primary (or tone="danger") Button that confirms and closes. There is no icon close button.
Examples
Destructive confirmation
The example above is the canonical use: name the object, state the consequence, and repeat the verb on the Action button.
Keeping the dialog open while working
Call event.preventDefault() in the Action's onClick to keep the dialog open, then close it yourself with controlled state once the work finishes.
const [open, setOpen] = useState(false);
<AlertDialog.Root open={open} onOpenChange={setOpen}>
<AlertDialog.Content>
<AlertDialog.Title>Delete project?</AlertDialog.Title>
<AlertDialog.Footer>
<AlertDialog.Cancel>Cancel</AlertDialog.Cancel>
<AlertDialog.Action
onClick={async (event) => {
event.preventDefault();
await deleteProject();
setOpen(false);
}}
>
Delete
</AlertDialog.Action>
</AlertDialog.Footer>
</AlertDialog.Content>
</AlertDialog.Root>API reference
AlertDialog.Root
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | – | Controlled open state. |
defaultOpen | boolean | false | Initial open state when uncontrolled. |
onOpenChange | (open: boolean) => void | – | Called when the open state should change. |
children | ReactNode | – | Trigger, Content and anything else sharing this dialog's state. |
AlertDialog.Content
Accepts every <div> attribute except role. Outside press never closes it.
| Prop | Type | Default | Description |
|---|---|---|---|
closeOnEscape | boolean | true | Close on Escape. |
initialFocus | RefObject<HTMLElement | null> | – | Element to focus when opened; defaults to [data-autofocus] (the Cancel button), then the first tabbable element. |
container | Element | null | document.body | Portal target. `undefined` uses `document.body`; `null` renders nothing until the target exists. |
showClose | boolean | false | Render the standard top-right icon close button automatically. Skipped while you render your own icon `Close`. |
closeLabel | string | "Close" | Accessible name of the automatic close button. |
ref | Ref<HTMLDivElement> | – | Forwarded ref to the dialog element. |
AlertDialog.Action
Accepts every <button> attribute. Renders a Button styled by tone. Closes on click unless the handler calls event.preventDefault().
| Prop | Type | Default | Description |
|---|---|---|---|
tone | AlertDialogActionTone | "primary" | Button style: `primary`, or `danger` for destructive actions. `AlertDialogActionTone` is `"primary" | "danger"`. |
asChild | boolean | false | Render the single child element (e.g. your own `Button`) instead of a `<button>`, merging props, ref and handlers. |
ref | Ref<HTMLButtonElement> | – | Forwarded ref to the button. |
AlertDialog.Cancel
Accepts every <button> attribute. Renders a secondary Button and carries data-autofocus, so it receives initial focus.
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | Render the single child element (e.g. your own `Button`) instead of a `<button>`, merging props, ref and handlers. |
ref | Ref<HTMLButtonElement> | – | Forwarded ref to the button. |
Trigger (including asChild), Title, Description and Footer take the same props as their Dialog counterparts.
Styling
AlertDialog reuses the dialog classes (.mrd-dialog__backdrop, .mrd-dialog, .mrd-dialog__title, .mrd-dialog__description, .mrd-dialog__footer). The surface carries data-kind="alert", which narrows it to 440px, and data-state="open" while mounted. Cancel renders as .mrd-button with data-variant="secondary"; Action as .mrd-button with data-variant set from tone. AlertDialog.Content has no size prop.
Accessibility
Follows the WAI-ARIA Alert and Message Dialogs pattern. Content has role="alertdialog", aria-modal="true" and is labelled by the Title and described by the Description.
| Key | Action |
|---|---|
| SpaceEnter | On the trigger, opens the dialog; focus moves to Cancel. |
| Tab | Moves between Cancel, Action and other controls, wrapping inside the dialog. |
| ShiftTab | Moves focus backwards, wrapping inside the dialog. |
| Esc | Dismisses, like Cancel, and returns focus to the trigger. |
Guidelines
Do
Avoid
Do
Avoid