# AlertDialog **Category**: react **URL**: https://heroui.com/en/docs/react/components/alert-dialog **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/react/components/(overlays)/alert-dialog.mdx > Modal dialog for critical confirmations requiring user attention and explicit action *** ## Usage ```tsx import { AlertDialog } from "@heroui/react"; ``` ```tsx "use client"; import {AlertDialog, Button} from "@heroui/react"; export function Default() { return ( Delete project permanently?

This will permanently delete My Awesome Project and all of its data. This action cannot be undone.

); } ``` ## Anatomy ```tsx import {AlertDialog, Button} from "@heroui/react"; export default () => ( {/* Optional: Close button */} {/* Optional: Status icon */} ); ``` ## Examples ### Statuses ```tsx "use client"; import {AlertDialog, Button} from "@heroui/react"; export function Statuses() { const examples = [ { actions: { cancel: "Stay Signed In", confirm: "Sign Out", }, body: "You'll need to sign in again to access your account. Any unsaved changes will be lost.", classNames: "bg-accent-soft text-accent-soft-foreground", header: "Sign out of your account?", status: "accent", trigger: "Sign Out", }, { actions: { cancel: "Not Yet", confirm: "Mark Complete", }, body: "This will mark the task as complete and notify all team members. The task will be moved to your completed list.", classNames: "bg-success-soft text-success-soft-foreground", header: "Complete this task?", status: "success", trigger: "Complete Task", }, { actions: { cancel: "Keep Editing", confirm: "Discard", }, body: "You have unsaved changes that will be permanently lost. Are you sure you want to discard them?", classNames: "bg-warning-soft text-warning-soft-foreground", header: "Discard unsaved changes?", status: "warning", trigger: "Discard Changes", }, { actions: { cancel: "Cancel", confirm: "Delete Account", }, body: "This will permanently delete your account and remove all your data from our servers. This action is irreversible.", classNames: "bg-danger-soft text-danger-soft-foreground", header: "Delete your account?", status: "danger", trigger: "Delete Account", }, ] as const; return (
{examples.map(({actions, body, classNames, header, status, trigger}) => ( {header}

{body}

))}
); } ``` ### Placements ```tsx "use client"; import {AlertDialog, Button} from "@heroui/react"; export function Placements() { const placements = ["auto", "top", "center", "bottom"] as const; return (
{placements.map((placement) => ( {placement === "auto" ? "Auto Placement" : `${placement.charAt(0).toUpperCase() + placement.slice(1)} Position`}

{placement === "auto" ? "Automatically positions at the bottom on mobile and center on desktop for optimal user experience." : `This dialog is positioned at the ${placement} of the viewport. Critical confirmations are typically centered for maximum attention.`}

))}
); } ``` ### Sizes ```tsx "use client"; import {Rocket} from "@gravity-ui/icons"; import {AlertDialog, Button} from "@heroui/react"; export function Sizes() { const sizes = ["xs", "sm", "md", "lg", "cover"] as const; return (
{sizes.map((size) => ( Size: {size.charAt(0).toUpperCase() + size.slice(1)}

{size === "cover" ? ( <> This alert dialog uses the cover size variant. It spans the full screen with margins: 16px on mobile and 40px on desktop. Maintains rounded corners and standard padding. Perfect for critical confirmations that need maximum width while preserving alert dialog aesthetics. ) : ( <> This alert dialog uses the {size} size variant. On mobile devices, all sizes adapt to near full-width for optimal viewing. On desktop, each size provides a different maximum width to suit various content needs. )}

))}
); } ``` ### Controlled State ```tsx "use client"; import {AlertDialog, Button, useOverlayState} from "@heroui/react"; import React from "react"; export function Controlled() { const [isOpen, setIsOpen] = React.useState(false); const state = useOverlayState(); return (

With React.useState()

Control the alert dialog using React's useState{" "} hook for simple state management. Perfect for basic use cases.

Status:{" "} {isOpen ? "open" : "closed"}

Controlled with useState()

This alert dialog is controlled by React's useState hook. Pass{" "} isOpen and onOpenChange props to manage the dialog state externally.

With useOverlayState()

Use the useOverlayState hook for a cleaner API with convenient methods like open(), close(), and{" "} toggle().

Status:{" "} {state.isOpen ? "open" : "closed"}

Controlled with useOverlayState()

The useOverlayState hook provides dedicated methods for common operations. No need to manually create callbacks—just use{" "} state.open(), state.close(), or{" "} state.toggle().

); } ``` ### Custom Icon ```tsx "use client"; import {LockOpen} from "@gravity-ui/icons"; import {AlertDialog, Button} from "@heroui/react"; export function CustomIcon() { return ( Reset your password?

We'll send a password reset link to your email address. You'll need to create a new password to regain access to your account.

); } ``` ### Custom Trigger ```tsx "use client"; import {TrashBin} from "@gravity-ui/icons"; import {AlertDialog, Button} from "@heroui/react"; export function CustomTrigger() { return (

Delete Item

Permanently remove this item

Delete this item?

Use AlertDialog.Trigger to create custom trigger elements beyond standard buttons. This example shows a card-style trigger with icons and descriptive text.

); } ``` ### Backdrop Variants ```tsx "use client"; import {AlertDialog, Button} from "@heroui/react"; export function BackdropVariants() { const variants = ["opaque", "blur", "transparent"] as const; return (
{variants.map((variant) => ( Backdrop: {variant.charAt(0).toUpperCase() + variant.slice(1)}

{variant === "opaque" ? "An opaque dark backdrop that completely obscures the background, providing maximum focus on the dialog." : variant === "blur" ? "A blurred backdrop that softly obscures the background while maintaining visual context." : "A transparent backdrop that keeps the background fully visible, useful for less critical confirmations."}

))}
); } ``` ### Custom Backdrop ```tsx "use client"; import {TriangleExclamation} from "@gravity-ui/icons"; import {AlertDialog, Button} from "@heroui/react"; export function CustomBackdrop() { return ( Permanently delete your account?

This action cannot be undone. All your data, settings, and content will be permanently removed from our servers. The dramatic red backdrop emphasizes the severity and irreversibility of this decision.

); } ``` ### Dismiss Behavior ```tsx "use client"; import {CircleInfo} from "@gravity-ui/icons"; import {AlertDialog, Button} from "@heroui/react"; export function DismissBehavior() { return (

isDismissable

Controls whether the alert dialog can be dismissed by clicking the overlay backdrop. Alert dialogs typically require explicit action, so this defaults to false. Set to{" "} true for less critical confirmations.

isDismissable = false

Clicking the backdrop won't close this alert dialog

Try clicking outside this alert dialog on the overlay - it won't close. You must use the action buttons to dismiss it.

isKeyboardDismissDisabled

Controls whether the ESC key can dismiss the alert dialog. Alert dialogs typically require explicit action, so this defaults to true. When set to false, the ESC key will be enabled.

isKeyboardDismissDisabled = true

ESC key is disabled

Press ESC - nothing happens. You must use the action buttons to dismiss this alert dialog.

); } ``` ### Close Methods ```tsx "use client"; import {AlertDialog, Button} from "@heroui/react"; export function CloseMethods() { return (

Using slot="close"

The simplest way to close a dialog. Add slot="close" to any Button component within the dialog. When clicked, it will automatically close the dialog.

Using slot="close"

Click either button below - both have slot="close" and will close the dialog automatically.

Using Dialog render props

Access the close method from the Dialog's render props. This gives you full control over when and how to close the dialog, allowing you to add custom logic before closing.

{(renderProps) => ( <> Using Dialog render props

The buttons below use the close method from render props. You can add validation or other logic before calling{" "} renderProps.close().

)}
); } ``` ### Custom Animations ```tsx "use client"; import {ArrowUpFromLine, Sparkles} from "@gravity-ui/icons"; import {AlertDialog, Button} from "@heroui/react"; import React from "react"; const iconMap: Record> = { "gravity-ui:arrow-up-from-line": ArrowUpFromLine, "gravity-ui:sparkles": Sparkles, }; export function CustomAnimations() { const animations = [ { classNames: { backdrop: [ "data-[entering]:duration-400", "data-[entering]:ease-[cubic-bezier(0.16,1,0.3,1)]", "data-[exiting]:duration-200", "data-[exiting]:ease-[cubic-bezier(0.7,0,0.84,0)]", ].join(" "), container: [ "data-[entering]:animate-in", "data-[entering]:fade-in-0", "data-[entering]:zoom-in-95", "data-[entering]:duration-400", "data-[entering]:ease-[cubic-bezier(0.16,1,0.3,1)]", "data-[exiting]:animate-out", "data-[exiting]:fade-out-0", "data-[exiting]:zoom-out-95", "data-[exiting]:duration-200", "data-[exiting]:ease-[cubic-bezier(0.7,0,0.84,0)]", ].join(" "), }, description: "Physics-based elastic scaling. Simulates a high-damping spring system with fast transient response and prolonged settling time. Ideal for Alert Dialogs and Modals.", icon: "gravity-ui:sparkles", name: "Kinematic Scale", }, { classNames: { backdrop: [ "data-[entering]:duration-500", "data-[entering]:ease-[cubic-bezier(0.25,1,0.5,1)]", "data-[exiting]:duration-200", "data-[exiting]:ease-[cubic-bezier(0.5,0,0.75,0)]", ].join(" "), container: [ "data-[entering]:animate-in", "data-[entering]:fade-in-0", "data-[entering]:slide-in-from-bottom-4", "data-[entering]:duration-500", "data-[entering]:ease-[cubic-bezier(0.25,1,0.5,1)]", "data-[exiting]:animate-out", "data-[exiting]:fade-out-0", "data-[exiting]:slide-out-to-bottom-2", "data-[exiting]:duration-200", "data-[exiting]:ease-[cubic-bezier(0.5,0,0.75,0)]", ].join(" "), }, description: "Simulates movement through a medium with fluid resistance. Eliminates mechanical linearity for a natural, grounded feel. Perfect for Bottom Sheets or Toasts.", icon: "gravity-ui:arrow-up-from-line", name: "Fluid Slide", }, ]; return (
{animations.map(({classNames, description, icon, name}) => { const IconComponent = iconMap[icon]; return ( {!!IconComponent && } {name} Animation

{description}

); })}
); } ``` ### Custom Portal ```tsx "use client"; import {AlertDialog, Button} from "@heroui/react"; import {useCallback, useRef, useState} from "react"; export function CustomPortal() { const portalRef = useRef(null); const [portalContainer, setPortalContainer] = useState(null); const setPortalRef = useCallback((node: HTMLDivElement | null) => { portalRef.current = node; setPortalContainer(node); }, []); return (

Render alert dialogs inside a custom container instead of document.body

Apply transform: translateZ(0) to the container to create a new stacking context.

{!!portalContainer && ( Custom Portal

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

)}
); } ``` ## Customization ### Tailwind CSS ```tsx "use client"; import {AlertDialog, Button} from "@heroui/react"; export function CustomStyles() { return (