AlertDialog
FeedbackAn interrupting confirmation with safe focus and explicit actions.
Responsive viewport — resize the window to explore. Direction and density apply only to this preview. Theme applies to the docs too.
"use client";
import {
AlertDialog,
AlertDialogTrigger,
AlertDialogContent,
AlertDialogTitle,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogCancel,
AlertDialogAction,
} from "@/components/ui/alert-dialog";
import { Button } from "@dashboardpack/core/components/ui/button";
import { useState } from "react";
export default function AlertDialogExample() {
const [message, setMessage] = useState("No workspace has been deleted.");
return (
<div className="space-y-3">
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant="destructive">Delete workspace</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogTitle>Delete this workspace?</AlertDialogTitle>
<AlertDialogDescription>
This preview changes only the message below. In your application,
explain exactly which records will be removed.
</AlertDialogDescription>
<AlertDialogFooter>
<AlertDialogCancel>Keep workspace</AlertDialogCancel>
<AlertDialogAction
variant="destructive"
onClick={() => setMessage("Workspace deleted in preview.")}
>
Delete workspace
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<p role="status" className="text-sm text-muted-foreground">
{message}
</p>
</div>
);
}Usage
Use AlertDialogTitle, AlertDialogDescription, AlertDialogCancel, and AlertDialogAction inside the content. Radix actions close immediately by default. For an asynchronous write, prevent the action default and control open until success.
import {
AlertDialog,
AlertDialogTrigger,
AlertDialogContent,
AlertDialogTitle,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogCancel,
AlertDialogAction,
} from "@/components/ui/alert-dialog";Shipped as editable source in src/components/ui/alert-dialog.tsx in both apps. Copy the implementation below when moving it to another project. Copy the complete example from Source code for all imports and state. Add "use client" when using hooks or event handlers. See installation and theming for project setup.
Component source
The complete implementation is included in both apps. It uses the React, Radix, Lucide, and shared-core dependencies already installed in Apex. Keep your project’s semantic theme tokens when reusing it.
src/components/ui/alert-dialog.tsx
"use client";
import type { ComponentProps } from "react";
import { cn } from "@dashboardpack/core/lib/utils";
import { AlertDialog as Primitive } from "radix-ui";
import { buttonVariants } from "@dashboardpack/core/components/ui/button";
export const AlertDialog = Primitive.Root;
export const AlertDialogTrigger = Primitive.Trigger;
export function AlertDialogContent({
className,
children,
...props
}: ComponentProps<typeof Primitive.Content>) {
return (
<Primitive.Portal>
<Primitive.Overlay className="fixed inset-0 z-50 bg-black/50" />
<Primitive.Content
className={cn(
"fixed start-1/2 top-1/2 z-50 grid max-h-[90dvh] w-[calc(100%-2rem)] max-w-md -translate-y-1/2 gap-4 overflow-y-auto rounded-xl border bg-background p-6 shadow-lg ltr:-translate-x-1/2 rtl:translate-x-1/2",
className,
)}
{...props}
>
{children}
</Primitive.Content>
</Primitive.Portal>
);
}
export function AlertDialogTitle({
className,
...props
}: ComponentProps<typeof Primitive.Title>) {
return (
<Primitive.Title
className={cn("text-lg font-semibold", className)}
{...props}
/>
);
}
export function AlertDialogDescription({
className,
...props
}: ComponentProps<typeof Primitive.Description>) {
return (
<Primitive.Description
className={cn("text-sm leading-relaxed text-muted-foreground", className)}
{...props}
/>
);
}
export function AlertDialogFooter({
className,
...props
}: ComponentProps<"div">) {
return (
<div
className={cn("flex flex-wrap justify-end gap-2 pt-2", className)}
{...props}
/>
);
}
export function AlertDialogAction({
className,
variant = "default",
...props
}: ComponentProps<typeof Primitive.Action> & {
variant?: "default" | "destructive";
}) {
return (
<Primitive.Action
className={cn(buttonVariants({ variant }), className)}
{...props}
/>
);
}
export function AlertDialogCancel({
className,
...props
}: ComponentProps<typeof Primitive.Cancel>) {
return (
<Primitive.Cancel
className={cn(buttonVariants({ variant: "outline" }), className)}
{...props}
/>
);
}API reference
Common props and defaults. Slot-specific props are named below; native elements also accept their standard HTML attributes. The component TypeScript definitions are the complete type reference.
| Prop | Type / Default | Description |
|---|---|---|
| open / defaultOpen | booleanDefault: false | Controlled or initial visibility. |
| onOpenChange | (open: boolean) => voidDefault: — | Respond to dismissal or opening. |
| variant (AlertDialogAction) | default | destructiveDefault: default | Confirmation button appearance. |
| asChild (AlertDialogTrigger) | booleanDefault: false | Use your own single trigger child. |