7.3 KiB
AlertDialog
(no submodules)
- alert-dialog.variants — `alertDialogOverlayVariants…-
alert-dialog.variants —
alertDialogOverlayVariants,alertDialogContentVariants,alertDialogHeaderVariants,alertDialogFooterVariants, `… -
alert-dialog.variants — `alertDialogOverlayVariants…
-
alert-dialog.variants —
alertDialogOverlayVariants,alertDialogContentVariants,alertDialogHeaderVariants,alertDialogFooterVariants, `… -
alert-dialog.variants — `alertDialogOverlayVariants…
-
alert-dialog.variants —
alertDialogOverlayVariants,alertDialogContentVariants,alertDialogHeaderVariants,alertDialogFooterVariants, `… -
alert-dialog.variants — `alertDialogOverlayVariants…
-
alert-dialog.variants —
alertDialogOverlayVariants,alertDialogContentVariants,alertDialogHeaderVariants,alertDialogFooterVariants, `… -
alert-dialog.variants —
alertDialogOverlayVariants,alertDialogContentVariants,alertDialogHeaderVariants,alertDialogFooterVariants, `…
Purpose
<AlertDialog> and its sub-components (<AlertDialogTrigger>, <AlertDialogPortal>, <AlertDialogOverlay>, <AlertDialogContent>, <AlertDialogHeader>, <AlertDialogFooter>, <AlertDialogTitle>, <AlertDialogDescription>, <AlertDialogAction>, <AlertDialogCancel>) are the chassis modal CONFIRMATION dialog primitives built on @radix-ui/react-alert-dialog.
The structural difference between <AlertDialog> and <Dialog> is the click-outside-suppression: an alert dialog CANNOT be dismissed by clicking the overlay backdrop — the user MUST press the <AlertDialogAction> or <AlertDialogCancel> button. Use <AlertDialog> for destructive operations (delete / discard / log out) where an accidental backdrop click could lose work; use <Dialog> for everything else.
Per the WAI-ARIA alertdialog pattern, every alert dialog MUST contain an <AlertDialogTitle> so the accessible name is announced. Use className="sr-only" if the visible UI does not need a heading. Radix renders role="alertdialog" (NOT role="dialog") so screen readers know to announce the prompt as a high-priority interrupt.
Features
role="alertdialog"(Radix-managed) so screen readers announce a high-priority prompt.- Click-outside dismissal SUPPRESSED — only Action / Cancel resolve the dialog.
- Escape closes (treated as cancel) — Radix-managed.
- Focus-trap on open; restore-focus to the trigger on close.
- Four content sizes (
sm,default,lg,xl) scale the panel max-width. <AlertDialogAction>defaults to Buttonvariant="default"styling (primary).<AlertDialogCancel>defaults to Buttonvariant="outline"styling (secondary).- Theme-driven cva overrides for every slot via
useThemedVariants("AlertDialog<Slot>"). - All sub-components forward refs.
motion-reduce:animate-nonecollapses animations underprefers-reduced-motion: reduce.
Usage: Basic Example
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@suaveplan/react-ui";
export function ConfirmDelete() {
return (
<AlertDialog>
<AlertDialogTrigger>Delete account</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Are you sure?</AlertDialogTitle>
<AlertDialogDescription>
This action cannot be undone.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction>Delete</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
}
Usage: Advanced Example
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@suaveplan/react-ui";
import { useState } from "react";
export function ConfirmDestructive({
title,
description,
onConfirm,
}: {
readonly title: string;
readonly description: string;
readonly onConfirm: () => Promise<void>;
}) {
const [open, setOpen] = useState(false);
const [busy, setBusy] = useState(false);
async function handleConfirm() {
setBusy(true);
try {
await onConfirm();
setOpen(false);
} finally {
setBusy(false);
}
}
return (
<AlertDialog open={open} onOpenChange={setOpen}>
<AlertDialogContent size="sm">
<AlertDialogHeader>
<AlertDialogTitle>{title}</AlertDialogTitle>
<AlertDialogDescription>{description}</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel disabled={busy}>Cancel</AlertDialogCancel>
<AlertDialogAction onClick={handleConfirm} disabled={busy}>
{busy ? "Working…" : "Confirm"}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
}
API Reference
<AlertDialog>
Wraps the Radix AlertDialog Root. Same lifecycle props as <Dialog> (open, defaultOpen, onOpenChange).
<AlertDialogContent>
| Prop | Type | Default | Description |
|---|---|---|---|
size |
"sm" | "default" | "lg" | "xl" |
"default" |
Visual variant scaling the panel max-width. |
<AlertDialogTitle>
REQUIRED for accessibility. Render className="sr-only" if no visible heading is needed.
<AlertDialogAction>, <AlertDialogCancel>
Renders as buttons with the default Button variant="default" and variant="outline" styling respectively. Activating either resolves the dialog (closes it).
<AlertDialogTrigger>, <AlertDialogPortal>, <AlertDialogOverlay>, <AlertDialogHeader>, <AlertDialogFooter>, <AlertDialogDescription>
Direct re-exports of the Radix sub-components with the chassis cva applied.
Implementation Notes
- The chassis NEVER assigns a numeric
z-index— Radix portals handle stacking. - The Action / Cancel button cva is INLINED into AlertDialog rather than reusing
<Button>so an ejected source copy stays self-contained (matches the shadcn upstreamalert-dialogrecipe). <AlertDialogContent>self-portals via<AlertDialogPortal>so consumers do not need to compose the portal manually.- The Cancel button uses
mt-2 sm:mt-0so it stacks beneath the Action on small screens (Action becomes the visually emphasised primary-end position) and aligns horizontally abovesm. - Radix's a11y warning fires when no
<AlertDialogDescription>is provided either — the chassis does not enforce this since some single-line confirmations only need a title; consumers can passaria-describedby={undefined}on<AlertDialogContent>if they want to suppress the warning explicitly.