cortexcn

Alert Dialog

A modal dialog that interrupts the user with important content and expects a response.

Loading…
import {  AlertDialog,  AlertDialogAction,  AlertDialogCancel,  AlertDialogContent,  AlertDialogDescription,  AlertDialogFooter,  AlertDialogHeader,  AlertDialogTitle,  AlertDialogTrigger,} from "@/components/ui/alert-dialog";import { Button } from "@/components/ui/button";export default function AlertDialogDemo() {  return (    <AlertDialog>      <AlertDialogTrigger asChild>        <Button variant="outline">Show Dialog</Button>      </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>  );}

Installation

npx shadcn@latest add @cortexcn/alert-dialog
Install the following dependencies:
npm install radix-ui
Copy and paste the following code into your project.
components/ui/alert-dialog.tsx
"use client";import * as React from "react";import { AlertDialog as AlertDialogPrimitive } from "radix-ui";import { cn } from "@/lib/utils";import { Button } from "@/components/ui/button";function AlertDialog({  ...props}: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {  return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...props} />;}function AlertDialogTrigger({  ...props}: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {  return (    <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />  );}function AlertDialogPortal({  ...props}: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) {  return (    <AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} />  );}function AlertDialogOverlay({  className,  ...props}: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) {  return (    <AlertDialogPrimitive.Overlay      data-slot="alert-dialog-overlay"      className={cn(        "fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",        className,      )}      {...props}    />  );}function AlertDialogContent({  className,  size = "default",  ...props}: React.ComponentProps<typeof AlertDialogPrimitive.Content> & {  size?: "default" | "sm";}) {  return (    <AlertDialogPortal>      <AlertDialogOverlay />      <AlertDialogPrimitive.Content        data-slot="alert-dialog-content"        data-size={size}        className={cn(          "group/alert-dialog-content fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 data-[size=sm]:max-w-xs data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[size=default]:sm:max-w-lg",          className,        )}        {...props}      />    </AlertDialogPortal>  );}function AlertDialogHeader({  className,  ...props}: React.ComponentProps<"div">) {  return (    <div      data-slot="alert-dialog-header"      className={cn(        "grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-6 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]",        className,      )}      {...props}    />  );}function AlertDialogFooter({  className,  ...props}: React.ComponentProps<"div">) {  return (    <div      data-slot="alert-dialog-footer"      className={cn(        "flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end",        className,      )}      {...props}    />  );}function AlertDialogTitle({  className,  ...props}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {  return (    <AlertDialogPrimitive.Title      data-slot="alert-dialog-title"      className={cn(        "text-lg font-semibold sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",        className,      )}      {...props}    />  );}function AlertDialogDescription({  className,  ...props}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {  return (    <AlertDialogPrimitive.Description      data-slot="alert-dialog-description"      className={cn("text-sm text-muted-foreground", className)}      {...props}    />  );}function AlertDialogMedia({  className,  ...props}: React.ComponentProps<"div">) {  return (    <div      data-slot="alert-dialog-media"      className={cn(        "mb-2 inline-flex size-16 items-center justify-center rounded-md bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-8",        className,      )}      {...props}    />  );}function AlertDialogAction({  className,  variant = "default",  size = "default",  ...props}: React.ComponentProps<typeof AlertDialogPrimitive.Action> &  Pick<React.ComponentProps<typeof Button>, "variant" | "size">) {  return (    <Button variant={variant} size={size} asChild>      <AlertDialogPrimitive.Action        data-slot="alert-dialog-action"        className={cn(className)}        {...props}      />    </Button>  );}function AlertDialogCancel({  className,  variant = "outline",  size = "default",  ...props}: React.ComponentProps<typeof AlertDialogPrimitive.Cancel> &  Pick<React.ComponentProps<typeof Button>, "variant" | "size">) {  return (    <Button variant={variant} size={size} asChild>      <AlertDialogPrimitive.Cancel        data-slot="alert-dialog-cancel"        className={cn(className)}        {...props}      />    </Button>  );}export {  AlertDialog,  AlertDialogAction,  AlertDialogCancel,  AlertDialogContent,  AlertDialogDescription,  AlertDialogFooter,  AlertDialogHeader,  AlertDialogMedia,  AlertDialogOverlay,  AlertDialogPortal,  AlertDialogTitle,  AlertDialogTrigger,};
Update the import paths to match your project setup.

Usage

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
<AlertDialog>
  <AlertDialogTrigger asChild>
    <Button variant="outline">Show Dialog</Button>
  </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>

Composition

Use the following composition to build an AlertDialog:

AlertDialog
├── AlertDialogTrigger
└── AlertDialogContent
    ├── AlertDialogHeader
    │   ├── AlertDialogMedia
    │   ├── AlertDialogTitle
    │   └── AlertDialogDescription
    └── AlertDialogFooter
        ├── AlertDialogCancel
        └── AlertDialogAction

Examples

Basic

A basic alert dialog with a title, description, and cancel and continue buttons.

Loading…
import {  AlertDialog,  AlertDialogAction,  AlertDialogCancel,  AlertDialogContent,  AlertDialogDescription,  AlertDialogFooter,  AlertDialogHeader,  AlertDialogTitle,  AlertDialogTrigger,} from "@/components/ui/alert-dialog";import { Button } from "@/components/ui/button";export default function AlertDialogBasic() {  return (    <AlertDialog>      <AlertDialogTrigger asChild>        <Button variant="outline">Show Dialog</Button>      </AlertDialogTrigger>      <AlertDialogContent>        <AlertDialogHeader>          <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>          <AlertDialogDescription>            This action cannot be undone. This will permanently delete your            account and remove your data from our servers.          </AlertDialogDescription>        </AlertDialogHeader>        <AlertDialogFooter>          <AlertDialogCancel>Cancel</AlertDialogCancel>          <AlertDialogAction>Continue</AlertDialogAction>        </AlertDialogFooter>      </AlertDialogContent>    </AlertDialog>  );}

Small

Use the size="sm" prop to make the alert dialog smaller.

Loading…
import {  AlertDialog,  AlertDialogAction,  AlertDialogCancel,  AlertDialogContent,  AlertDialogDescription,  AlertDialogFooter,  AlertDialogHeader,  AlertDialogTitle,  AlertDialogTrigger,} from "@/components/ui/alert-dialog";import { Button } from "@/components/ui/button";export default function AlertDialogSmall() {  return (    <AlertDialog>      <AlertDialogTrigger asChild>        <Button variant="outline">Show Dialog</Button>      </AlertDialogTrigger>      <AlertDialogContent size="sm">        <AlertDialogHeader>          <AlertDialogTitle>Allow accessory to connect?</AlertDialogTitle>          <AlertDialogDescription>            Do you want to allow the USB accessory to connect to this device?          </AlertDialogDescription>        </AlertDialogHeader>        <AlertDialogFooter>          <AlertDialogCancel>Don&apos;t allow</AlertDialogCancel>          <AlertDialogAction>Allow</AlertDialogAction>        </AlertDialogFooter>      </AlertDialogContent>    </AlertDialog>  );}

Media

Use the AlertDialogMedia component to add a media element such as an icon or image to the alert dialog.

Loading…
import { CircleFadingPlusIcon } from "lucide-react";import {  AlertDialog,  AlertDialogAction,  AlertDialogCancel,  AlertDialogContent,  AlertDialogDescription,  AlertDialogFooter,  AlertDialogHeader,  AlertDialogMedia,  AlertDialogTitle,  AlertDialogTrigger,} from "@/components/ui/alert-dialog";import { Button } from "@/components/ui/button";export default function AlertDialogWithMedia() {  return (    <AlertDialog>      <AlertDialogTrigger asChild>        <Button variant="outline">Share Project</Button>      </AlertDialogTrigger>      <AlertDialogContent>        <AlertDialogHeader>          <AlertDialogMedia>            <CircleFadingPlusIcon />          </AlertDialogMedia>          <AlertDialogTitle>Share this project?</AlertDialogTitle>          <AlertDialogDescription>            Anyone with the link will be able to view and edit this project.          </AlertDialogDescription>        </AlertDialogHeader>        <AlertDialogFooter>          <AlertDialogCancel>Cancel</AlertDialogCancel>          <AlertDialogAction>Share</AlertDialogAction>        </AlertDialogFooter>      </AlertDialogContent>    </AlertDialog>  );}

Small with Media

Combine size="sm" with AlertDialogMedia for a compact dialog with an icon.

Loading…
import { BluetoothIcon } from "lucide-react";import {  AlertDialog,  AlertDialogAction,  AlertDialogCancel,  AlertDialogContent,  AlertDialogDescription,  AlertDialogFooter,  AlertDialogHeader,  AlertDialogMedia,  AlertDialogTitle,  AlertDialogTrigger,} from "@/components/ui/alert-dialog";import { Button } from "@/components/ui/button";export default function AlertDialogSmallWithMedia() {  return (    <AlertDialog>      <AlertDialogTrigger asChild>        <Button variant="outline">Show Dialog</Button>      </AlertDialogTrigger>      <AlertDialogContent size="sm">        <AlertDialogHeader>          <AlertDialogMedia>            <BluetoothIcon />          </AlertDialogMedia>          <AlertDialogTitle>Allow accessory to connect?</AlertDialogTitle>          <AlertDialogDescription>            Do you want to allow the USB accessory to connect to this device?          </AlertDialogDescription>        </AlertDialogHeader>        <AlertDialogFooter>          <AlertDialogCancel>Don&apos;t allow</AlertDialogCancel>          <AlertDialogAction>Allow</AlertDialogAction>        </AlertDialogFooter>      </AlertDialogContent>    </AlertDialog>  );}

Destructive

Use the variant="destructive" prop on AlertDialogAction to add a destructive action button.

Loading…
import { Trash2Icon } from "lucide-react";import {  AlertDialog,  AlertDialogAction,  AlertDialogCancel,  AlertDialogContent,  AlertDialogDescription,  AlertDialogFooter,  AlertDialogHeader,  AlertDialogMedia,  AlertDialogTitle,  AlertDialogTrigger,} from "@/components/ui/alert-dialog";import { Button } from "@/components/ui/button";export default function AlertDialogDestructive() {  return (    <AlertDialog>      <AlertDialogTrigger asChild>        <Button variant="destructive">Delete Chat</Button>      </AlertDialogTrigger>      <AlertDialogContent size="sm">        <AlertDialogHeader>          <AlertDialogMedia className="bg-destructive/10 text-destructive dark:bg-destructive/20 dark:text-destructive">            <Trash2Icon />          </AlertDialogMedia>          <AlertDialogTitle>Delete chat?</AlertDialogTitle>          <AlertDialogDescription>            This will permanently delete this chat conversation. View{" "}            <a href="#">Settings</a> to delete any memories saved during this            chat.          </AlertDialogDescription>        </AlertDialogHeader>        <AlertDialogFooter>          <AlertDialogCancel variant="outline">Cancel</AlertDialogCancel>          <AlertDialogAction variant="destructive">Delete</AlertDialogAction>        </AlertDialogFooter>      </AlertDialogContent>    </AlertDialog>  );}

RTL

Alert dialogs respect the document direction — pass dir="rtl" to flip the layout.

Loading…
"use client";import * as React from "react";import { BluetoothIcon } from "lucide-react";import {  AlertDialog,  AlertDialogAction,  AlertDialogCancel,  AlertDialogContent,  AlertDialogDescription,  AlertDialogFooter,  AlertDialogHeader,  AlertDialogMedia,  AlertDialogTitle,  AlertDialogTrigger,} from "@/components/ui/alert-dialog";import { Button } from "@/components/ui/button";const content = {  ltr: {    dir: "ltr" as const,    smallTitle: "Allow accessory to connect?",    smallDescription:      "Do you want to allow the USB accessory to connect to this device?",    dontAllow: "Don't allow",    allow: "Allow",    trigger: "Show Dialog",  },  rtl: {    dir: "rtl" as const,    smallTitle: "السماح للملحق بالاتصال؟",    smallDescription: "هل تريد السماح لملحق USB بالاتصال بهذا الجهاز؟",    dontAllow: "عدم السماح",    allow: "السماح",    trigger: "إظهار الحوار",  },};export default function AlertDialogRtl() {  const [mode, setMode] = React.useState<"rtl" | "ltr">("rtl");  const t = content[mode];  return (    <div className="flex flex-col items-center gap-6">      <Button        variant="ghost"        size="sm"        onClick={() => setMode((m) => (m === "rtl" ? "ltr" : "rtl"))}      >        Toggle dir ({mode})      </Button>      <div dir={t.dir}>        <AlertDialog>          <AlertDialogTrigger asChild>            <Button variant="outline">{t.trigger}</Button>          </AlertDialogTrigger>          <AlertDialogContent size="sm" dir={t.dir}>            <AlertDialogHeader>              <AlertDialogMedia>                <BluetoothIcon />              </AlertDialogMedia>              <AlertDialogTitle>{t.smallTitle}</AlertDialogTitle>              <AlertDialogDescription>                {t.smallDescription}              </AlertDialogDescription>            </AlertDialogHeader>            <AlertDialogFooter>              <AlertDialogCancel>{t.dontAllow}</AlertDialogCancel>              <AlertDialogAction>{t.allow}</AlertDialogAction>            </AlertDialogFooter>          </AlertDialogContent>        </AlertDialog>      </div>    </div>  );}

API Reference

size

Use the size prop on the AlertDialogContent component to control the size of the alert dialog.

PropTypeDefault
size"default" | "sm""default"

For the remaining components and their props, see the Radix UI documentation.

On this page