Skip to the content
BooleanPress UI

Overlay

Alert dialog

A modal question that needs an answer before the page continues, such as confirming a deletion.

Import

import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger } from "@booleanpress/ui/alert-dialog"

Usage

Use an alert dialog when the person must confirm or cancel, and a dialog when they do something richer. Clicking the backdrop does not close it: only Cancel, the action, or Escape does. AlertDialogTitle names it and AlertDialogDescription describes it; both are read when it opens. Focus starts on Cancel, the least destructive choice.

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@booleanpress/ui/alert-dialog"
import { Button } from "@booleanpress/ui/button"

export function DeleteMailer() {
  return (
    <AlertDialog>
      <AlertDialogTrigger asChild>
        <Button variant="outline">Delete mailer</Button>
      </AlertDialogTrigger>
      <AlertDialogContent>
        <AlertDialogHeader>
          <AlertDialogTitle>Delete the Primary mailer?</AlertDialogTitle>
          <AlertDialogDescription>This cannot be undone.</AlertDialogDescription>
        </AlertDialogHeader>
        <AlertDialogFooter>
          <AlertDialogCancel>Cancel</AlertDialogCancel>
          <AlertDialogAction variant="destructive">Delete mailer</AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  )
}

AlertDialogAction and AlertDialogCancel render a button and take its variant and size: destructive for an action that removes something, outline for Cancel (the defaults). Both close the dialog; run the confirmed work in the action's onClick. size="sm" makes a narrow confirmation with the two buttons side by side. Control it with open and onOpenChange to open it from code.

If the action removes the row that held the trigger, focus has nowhere to return to. Pass returnFocusTo (a ref, or a function that returns an element) to AlertDialogContent.

Examples

Basic

A deletion confirmation with Cancel and a destructive action.

Small

size="sm" is narrow, and the two buttons share the row.

With an icon

AlertDialogMedia puts an icon beside the title; mark the icon aria-hidden.

Return focus

Deleting a row removes its trigger, so returnFocusTo sends focus to the list's heading.

Accessibility

Semantics
A div with role="alertdialog" and aria-modal="true", named by AlertDialogTitle and described by AlertDialogDescription. The rest of the page is hidden from assistive technology while it is open.
Labels
Every alert dialog needs a title and a description that says what will happen. Name the buttons by what they do ("Delete mailer"), not "OK". Several triggers of the same kind need names that differ, for example a visually hidden row name.
Focus
Focus moves to Cancel when it opens, Tab and Shift+Tab stay inside, and focus returns to the trigger when it closes. Without a trigger it returns to the element that had focus when the dialog opened, or to returnFocusTo when that element is gone.
Known limits
  • It has no × button and ignores clicks on the backdrop, on purpose. Always provide Cancel.
  • One dialog at a time: an alert dialog does not open a second dialog.

Keyboard

Keyboard
KeyBehaviour
EscapeCloses it without running the action.
TabMoves to the next button inside the dialog, wrapping from the last to the first.
ShiftTabMoves to the previous button, wrapping from the first to the last.
EnterSpacePresses the focused button.

API

AlertDialog

Renders Radix AlertDialog.Root and passes it every other prop.

AlertDialog props
PropTypeDefaultDescription
defaultOpenbooleanWhether it starts open, when it controls itself.
onOpenChange((open: boolean) => void)Called with true or false when it opens or closes.
openbooleanWhether it is open, when you control it. Pair it with onOpenChange.

AlertDialogAction

Renders Radix AlertDialog.Action and passes it every other prop.

AlertDialogAction props
PropTypeDefaultDescription
asChildbooleanRender the child element instead, with this part's behaviour and classes merged onto it.

AlertDialogCancel

Renders Radix AlertDialog.Cancel and passes it every other prop.

AlertDialogCancel props
PropTypeDefaultDescription
asChildbooleanRender the child element instead, with this part's behaviour and classes merged onto it.

AlertDialogContent

Renders Radix AlertDialog.Content and passes it every other prop.

AlertDialogContent props
PropTypeDefaultDescription
asChildbooleanRender the child element instead, with this part's behaviour and classes merged onto it.
deferPointerDownOutsidebooleanWhen true, a 'pointerdown' event outside of the layered element will wait for the interaction's click event before dispatching, allowing third-party code to stop propagation of later events and cancel dismissal.
forceMounttrueUsed to force mounting when more control is needed. Useful when controlling animation with React animation libraries.
onCloseAutoFocus((event: Event) => void)Event handler called when auto-focusing on close. Can be prevented.
onEscapeKeyDown((event: KeyboardEvent) => void)Event handler called when the escape key is down. Can be prevented.
onFocusOutside((event: FocusOutsideEvent) => void)Event handler called when the focus moves outside of the DismissableLayer. Can be prevented.
onOpenAutoFocus((event: Event) => void)Event handler called when auto-focusing on open. Can be prevented.
returnFocusToReturnFocusTargetWhere focus goes on close when the element that opened the overlay no longer exists — for example after the confirmed action deleted the row it sat in.
size"default" | "sm"defaultsm is a narrow, centred confirmation.

AlertDialogDescription

Renders Radix AlertDialog.Description and passes it every other prop.

AlertDialogDescription props
PropTypeDefaultDescription
asChildbooleanRender the child element instead, with this part's behaviour and classes merged onto it.

AlertDialogFooter

Renders a div and passes it every other prop.

AlertDialogHeader

Renders a div and passes it every other prop.

AlertDialogMedia

Renders a div and passes it every other prop.

AlertDialogOverlay

Renders Radix AlertDialog.Overlay and passes it every other prop.

AlertDialogOverlay props
PropTypeDefaultDescription
asChildbooleanRender the child element instead, with this part's behaviour and classes merged onto it.
forceMounttrueUsed to force mounting when more control is needed. Useful when controlling animation with React animation libraries.

AlertDialogPortal

Renders Radix AlertDialog.Portal and passes it every other prop.

AlertDialogPortal props
PropTypeDefaultDescription
containerElement | DocumentFragment | nullSpecify a container element to portal the content into.
forceMounttrueUsed to force mounting when more control is needed. Useful when controlling animation with React animation libraries.

AlertDialogTitle

Renders Radix AlertDialog.Title and passes it every other prop.

AlertDialogTitle props
PropTypeDefaultDescription
asChildbooleanRender the child element instead, with this part's behaviour and classes merged onto it.

AlertDialogTrigger

Renders Radix AlertDialog.Trigger and passes it every other prop.

AlertDialogTrigger props
PropTypeDefaultDescription
asChildbooleanRender the child element instead, with this part's behaviour and classes merged onto it.

Every part takes className, merged with its defaults by cn(), and ref, which reaches the element it renders.

Data attributes: data-slot="alert-dialog" (AlertDialog), data-slot="alert-dialog-action" (AlertDialogAction), data-slot="alert-dialog-cancel" (AlertDialogCancel), data-slot="alert-dialog-content" (AlertDialogContent), data-slot="alert-dialog-description" (AlertDialogDescription), data-slot="alert-dialog-footer" (AlertDialogFooter), data-slot="alert-dialog-header" (AlertDialogHeader), data-slot="alert-dialog-media" (AlertDialogMedia), data-slot="alert-dialog-overlay" (AlertDialogOverlay), data-slot="alert-dialog-portal" (AlertDialogPortal), data-slot="alert-dialog-title" (AlertDialogTitle), data-slot="alert-dialog-trigger" (AlertDialogTrigger), and data-size.

Theming

The panel is a floating surface, like menus and popovers: --popover and --popover-foreground. Its height stops below the WordPress admin bar (--wp-admin--admin-bar--height).

The tokens its classes read. Change their values in your theme, and it follows.

Theme tokens
TokenUsed for
--backgroundbackground
--mutedbackground
--muted-foregroundtext
--popoverbackground
--popover-foregroundtext