Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Components

Free

Alert Dialog for React

Stop the page until the reader confirms or cancels a destructive step. For React with Base UI, when a click outside should not skip the choice.

Framework
UI library

A modal that asks the reader to cancel or continue.

Use it to confirm a destructive step, like deleting an account. A form, or anything they have to fill in, belongs in a Dialog. In React, Base UI doesn't close it on an outside click.

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.

Anatomy

Alert Dialog anatomy: content, title, description, cancel, action
AlertDialogTrigger
AlertDialogOverlay
AlertDialogContent
└── AlertDialogPositioner
AlertDialogTitle
AlertDialogDescription
AlertDialogAction

Usage

import {
  AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
  AlertDialogDescription, AlertDialogFooter, AlertDialogHeader,
  AlertDialogTitle, AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";
const AlertDialogDemo = () => (
  <AlertDialog>
    <AlertDialogTrigger render={<Button variant="outline" />}>
      Show Dialog
    </AlertDialogTrigger>
    <AlertDialogContent>
      <AlertDialogHeader>
        <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
        <AlertDialogDescription>
          This action cannot be undone. This will permanently delete your
          account from our servers.
        </AlertDialogDescription>
      </AlertDialogHeader>
      <AlertDialogFooter>
        <AlertDialogCancel>Cancel</AlertDialogCancel>
        <AlertDialogAction>Continue</AlertDialogAction>
      </AlertDialogFooter>
    </AlertDialogContent>
  </AlertDialog>
);

Accessibility

Enter
When focus is on the trigger, opens the dialog.
Tab
Moves focus to the next focusable element within the content. Focus is trapped within the dialog.
Shift+Tab
Moves focus to the previous focusable element. Focus is trapped within the dialog.
Escape
Closes the dialog and moves focus to trigger or the defined final focus element.
Space
Activate the focused control.

Demos

Basic

The plain confirmation is a question, one sentence about what is lost, and Cancel then Continue. The title asks if they are sure, and the description names the account and the data, at the default width. Use this when you do not need an icon or a tighter panel, and keep the safer action first so it is the one they reach before the commit.

Preview width

Small

A USB prompt does not need a wide panel. size set to sm tightens the content around one question, one sentence, and two short buttons, Don't allow and Allow. Use the small size for that kind of permission, and keep longer explanations on the default width so they are not scrolling inside a cramped box.

Preview width

Media

Sharing a project is easy to mix up with other confirms, so an icon in AlertDialogMedia sits above the title, ahead of the sentence about who gets the link. Hide the icon when the title already names the action. Reach for media when several dialogs would otherwise look identical, not as a replacement for the description.

Preview width

Small Media

Short copy and a thing people recognize from an icon can take both treatments. size is sm, a Bluetooth mark sits in AlertDialogMedia, and the buttons are Don't allow and Allow. Combine them for a device or a connection, and drop back to the default width, icon included, if the explanation grows into a paragraph.

Preview width

Destructive

Delete is the verb on the trigger, in the title, and on the action, with variant set to destructive so the button does not look like a safe continue. The trash icon is tinted the same way, inside a small dialog, and the description says the chat is gone for good. Save this treatment for steps that cannot be undone, and repeat the verb so the confirm matches the question.

Preview width

Rtl

Two confirms in Arabic, the wide account question and the small accessory question with a Bluetooth icon. dir is set to rtl on the wrapper and again on the content, because the panel does not inherit direction from the button that opened it. Title, description, and footer then follow the reading order, with cancel still the dismissal and the other button still the commit.

Preview width

FAQ

When should I use an Alert Dialog instead of a Dialog?

Use an Alert Dialog when the reader only confirms or cancels, such as deleting a file. If they have to type, pick a date or fill in a form, use a Dialog instead: the Alert Dialog is a short interruption, the Dialog a small page.

How do I keep the Alert Dialog open until my request finishes in React?

Here AlertDialogAction is a plain button that doesn't close the dialog, so control open and set it to false once the request settles. Pass isLoading to the action meanwhile to show a spinner.

Does the Alert Dialog close on Escape or on a click outside?

Escape closes it, but a click outside doesn't, so the choice stays explicit: the reader picks an action or cancels.

How do I style a delete confirmation in the Alert Dialog?

Pass variant="destructive" to AlertDialogAction and repeat the verb on it, such as Delete. Make the title the action and the object, and the description its consequence in one sentence. The Destructive demo shows the pattern.

Is the Base UI Alert Dialog accessible?

Yes. It renders with role="alertdialog", traps focus while open and returns it to the trigger when it closes. Always include AlertDialogTitle so screen readers announce what is being confirmed, and add AlertDialogDescription for the consequence.

How do I make a smaller Alert Dialog or add an icon?

Pass size="sm" to AlertDialogContent for a compact dialog, and put an icon in AlertDialogMedia above the title. The Small, Media and Small Media demos show each one.

How do I open an Alert Dialog without a trigger button?

Leave out AlertDialogTrigger and control whether it's open from your own state, for example after a form fails validation or from a menu item. Use open and onOpenChange.

How do I install the Alert Dialog in React?

Run the command in the Installation section above: it adds alert-dialog to your components/ui folder with the Button it uses. React and Solid use the shadcn CLI, Vue uses shadcn-vue and Svelte uses shadcn-svelte, each after its one-time setup.

API Reference

AlertDialog

data-slot="alert-dialog"

PropType
open?boolean

Whether the dialog is currently open.

defaultOpen?boolean

Whether the dialog is initially open. To render a controlled dialog, use the open prop instead.

Default
false
onOpenChange?(open: boolean, eventDetails: AlertDialogRoot.ChangeEventDetails) → void

Event handler called when the alert dialog is opened or closed.

Type
(open: boolean, eventDetails: AlertDialogRoot.ChangeEventDetails) → void
Parameters

open – boolean

eventDetails – AlertDialogRoot.ChangeEventDetails

Returns
void
actionsRef?React.RefObject<AlertDialogRoot.Actions | null>

A ref to imperative actions. - unmount: Ends the closing phase of the alert dialog after an externally controlled closing animation finishes. Call preventUnmountOnClose() in onOpenChange first, otherwise the alert dialog completes closing on its own. Whether it leaves the DOM is decided by keepMounted on the portal. - close: Closes the alert dialog imperatively when called.

Type
React.RefObject<AlertDialogRoot.Actions | null>
children?React.ReactNode | PayloadChildRenderFunction<Payload>

The content of the dialog. This can be a regular React node or a render function that receives the payload of the active trigger.

Type
React.ReactNode | PayloadChildRenderFunction<Payload>
defaultTriggerId?string | null

ID of the trigger that the dialog is associated with. This is useful in conjunction with the defaultOpen prop to create an initially open dialog.

Type
string | null
handle?AlertDialogHandle<Payload>

A handle to associate the alert dialog with a trigger. If specified, allows external triggers to control the alert dialog's open state. Can be created with the AlertDialog.createHandle() method.

Type
AlertDialogHandle<Payload>
onOpenChangeComplete?(open: boolean) → void

Event handler called after any animations complete when the dialog is opened or closed.

Parameters

open – boolean

Returns
void
triggerId?string | null

ID of the trigger that the dialog is associated with. This is useful in conjunction with the open prop to create a controlled dialog. There's no need to specify this prop when the dialog is uncontrolled (that is, when the open prop is not set).

Type
string | null
asChild?boolean

Use the provided child element as the default rendered element, combining their props and behavior.

render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)

AlertDialogTrigger

<button> data-slot="alert-dialog-trigger"

PropType
handle?AlertDialogHandle<Payload>

A handle to associate the trigger with an alert dialog. Can be created with the AlertDialog.createHandle() method.

Type
AlertDialogHandle<Payload>
id?string

ID of the trigger. In addition to being forwarded to the rendered element, it is also used to specify the active trigger for the dialog in controlled mode (with the DialogRoot triggerId prop).

nativeButton?boolean

Whether the component renders a native <button> element when replacing it via the render prop. Set to false if the rendered element is not a button (for example, <div>).

Default
true
payload?Payload

A payload to pass to the dialog when it is opened.

asChild?boolean

Use the provided child element as the default rendered element, combining their props and behavior.

render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)

AlertDialogPortal

data-slot="alert-dialog-portal"

PropType
asChild?boolean

Use the provided child element as the default rendered element, combining their props and behavior.

render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)

AlertDialogOverlay

data-slot="alert-dialog-overlay"

PropType
asChild?boolean

Use the provided child element as the default rendered element, combining their props and behavior.

render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

AlertDialogContent

data-slot="alert-dialog-content"

PropType
size?"default" | "sm"

The size.

Type
"default" | "sm"
Default
"default"
render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

AttributeType
data-size?string

Mirrors size.

AlertDialogHeader

<div> data-slot="alert-dialog-header"

PropType
description?string

The description of the alert dialog.

title?string

The title of the alert dialog.

render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

AlertDialogFooter

<div> data-slot="alert-dialog-footer"

PropType
render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

AlertDialogMedia

<div> data-slot="alert-dialog-media"

PropType
render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

AlertDialogTitle

data-slot="alert-dialog-title"

PropType
asChild?boolean

Use the provided child element as the default rendered element, combining their props and behavior.

render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

AlertDialogDescription

data-slot="alert-dialog-description"

PropType
asChild?boolean

Use the provided child element as the default rendered element, combining their props and behavior.

render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

AlertDialogAction

data-slot="alert-dialog-action"

PropType
clickEffect?boolean

Apply a click effect to the button.

Default
true
focusableWhenDisabled?boolean

Whether the button should be focusable when disabled.

Default
false
isLoading?boolean

Show a loading indicator.

Default
false
nativeButton?boolean

Whether the component renders a native <button> element when replacing it via the render prop. Set to false if the rendered element is not a button (for example, <div>).

Default
true
pill?boolean

Fully rounded corners.

Default
false
size?"icon-lg" | "icon-md" | "icon-sm" | "icon-xl" | "icon-xs" | "lg" | "md" | "sm" | "xl" | "xs"

The size.

Type
"icon-lg" | "icon-md" | "icon-sm" | "icon-xl" | "icon-xs" | "lg" | "md" | "sm" | "xl" | "xs"
Default
"md"
variant?"default" | "destructive" | "ghost" | "link" | "outline" | "secondary"

The visual style.

Type
"default" | "destructive" | "ghost" | "link" | "outline" | "secondary"
Default
"default"
render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

AlertDialogCancel

data-slot="alert-dialog-cancel"

PropType
asChild?boolean

Use the provided child element as the default rendered element, combining their props and behavior.

render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

With other components

  • Free

    Button

    Buttons

    Trigger and footer actions

  • Free

    Dialog

    Overlays

    When they need to type

  • Free

    Field

    Inputs

    Confirm after submit

  • Free

    Alert

    Feedback

    Inline, does not block

  • Free

    Sonner

    Feedback

    Toast after it succeeds

  • Free

    Card

    Layout

    Frame around the confirm

  • Free

    Sheet

    Overlays

    Slide-over confirm

  • Free

    Drawer

    Overlays

    Mobile-first overlay

  • Free

    Popover

    Overlays

    No focus trap

  • Free

    Hover Card

    Overlays

    Preview on hover

  • Free

    Tooltip

    Overlays

    A hint, not a choice

  • Free

    Toast

    Feedback

    A message after they confirm