SABRAMAN

SABRAMAN DANYA YUDIN КАРТОН SABRAMAN DANYA YUDIN КАРТОН SABRAMAN DANYA YUDIN КАРТОН SABRAMAN DANYA YUDIN КАРТОН SABRAMAN DANYA YUDIN КАРТОН SABRAMAN DANYA YUDIN КАРТОН

Legacy Alert Dialog

Use this for confirmations, warnings, and high-attention decisions that need classic legacy chrome.

On this page
"use client";

import {
	LegacyAlertDialog,
	LegacyAlertDialogButton,
	LegacyAlertDialogClose,
	LegacyAlertDialogContent,
	LegacyAlertDialogDescription,
	LegacyAlertDialogFooter,
	LegacyAlertDialogHeader,
	LegacyAlertDialogTitle,
	LegacyAlertDialogTrigger,
} from "@/components/legacy-alert-dialog";
import { cn } from "@/lib/utils";

interface LegacyAlertDialogDemoProps {
	className?: string;
	compact?: boolean;
}

type AlertDialogVariant = "message" | "horizontal" | "vertical";

type AlertDialogExample = {
	description: string;
	title: string;
	triggerLabel: string;
	variant: AlertDialogVariant;
};

const ALERT_DIALOG_EXAMPLES: AlertDialogExample[] = [
	{
		description:
			"A simple notice with a title and message, without action buttons.",
		title: "Message",
		triggerLabel: "Message",
		variant: "message",
	},
	{
		description:
			"A confirmation alert with one default action and one primary action.",
		title: "Horizontal",
		triggerLabel: "Horizontal",
		variant: "horizontal",
	},
	{
		description:
			"A stacked alert with full-width actions for more emphatic decisions.",
		title: "Vertical",
		triggerLabel: "Vertical",
		variant: "vertical",
	},
] as const;

export function LegacyAlertDialogDemo({
	className,
	compact = false,
}: LegacyAlertDialogDemoProps) {
	return (
		<div className="flex w-full justify-center">
			<div
				className={cn(
					"flex w-full flex-wrap items-center justify-center",
					compact ? "max-w-[420px] gap-3" : "max-w-[520px] gap-4",
					className,
				)}
			>
				{ALERT_DIALOG_EXAMPLES.map((example) => (
					<LegacyAlertDialogExampleTrigger
						compact={compact}
						description={example.description}
						key={example.variant}
						title={example.title}
						triggerLabel={example.triggerLabel}
						variant={example.variant}
					/>
				))}
			</div>
		</div>
	);
}

function LegacyAlertDialogExampleTrigger({
	compact,
	description,
	title,
	triggerLabel,
	variant,
}: AlertDialogExample & {
	compact: boolean;
}) {
	return (
		<LegacyAlertDialog>
			<LegacyAlertDialogTrigger asChild>
				<LegacyAlertDialogButton
					className={cn("min-w-[108px]", compact ? "px-[10px]" : "px-[12px]")}
				>
					{triggerLabel}
				</LegacyAlertDialogButton>
			</LegacyAlertDialogTrigger>

			<LegacyAlertDialogContent>
				<LegacyAlertDialogHeader>
					<LegacyAlertDialogTitle>{title}</LegacyAlertDialogTitle>
					<LegacyAlertDialogDescription>
						{description}
					</LegacyAlertDialogDescription>
				</LegacyAlertDialogHeader>

				{variant === "horizontal" ? (
					<LegacyAlertDialogFooter>
						<LegacyAlertDialogClose asChild>
							<LegacyAlertDialogButton className="min-w-0 flex-1">
								Default
							</LegacyAlertDialogButton>
						</LegacyAlertDialogClose>
						<LegacyAlertDialogClose asChild>
							<LegacyAlertDialogButton
								className="min-w-0 flex-1"
								variant="primary"
							>
								Primary
							</LegacyAlertDialogButton>
						</LegacyAlertDialogClose>
					</LegacyAlertDialogFooter>
				) : null}

				{variant === "vertical" ? (
					<LegacyAlertDialogFooter className="flex-col sm:flex-col sm:justify-start">
						<LegacyAlertDialogClose asChild>
							<LegacyAlertDialogButton
								className="w-full min-w-0"
								variant="primary"
							>
								Primary
							</LegacyAlertDialogButton>
						</LegacyAlertDialogClose>
						<LegacyAlertDialogClose asChild>
							<LegacyAlertDialogButton
								className="w-full min-w-0"
								variant="primary"
							>
								Primary
							</LegacyAlertDialogButton>
						</LegacyAlertDialogClose>
						<LegacyAlertDialogClose asChild>
							<LegacyAlertDialogButton className="w-full min-w-0">
								Default
							</LegacyAlertDialogButton>
						</LegacyAlertDialogClose>
					</LegacyAlertDialogFooter>
				) : null}
			</LegacyAlertDialogContent>
		</LegacyAlertDialog>
	);
}

Why Use It

  • Best for destructive actions, permission prompts, and blocking notices.
  • Ships as composable dialog pieces, so you can build message-only, two-button, or stacked action layouts from the same API.
  • Keeps the glossy panel and button treatment without forcing a custom dialog state model.
  • Works well when you want the alert itself to carry the visual weight instead of the trigger button.

Installation

Install the component and the supporting dialog primitive from one registry item.

$ bunx --bun shadcn@latest add https://sabraman.ru/r/legacy-alert-dialog.json

Quick Start

Start with a standard confirm and cancel flow, then branch into alternate layouts if the action needs more context.

"use client";

import {
	LegacyAlertDialog,
	LegacyAlertDialogButton,
	LegacyAlertDialogClose,
	LegacyAlertDialogContent,
	LegacyAlertDialogDescription,
	LegacyAlertDialogFooter,
	LegacyAlertDialogHeader,
	LegacyAlertDialogTitle,
	LegacyAlertDialogTrigger,
} from "@/components/legacy-alert-dialog";

export function LegacyAlertDialogConfirmExample() {
	return (
		<LegacyAlertDialog>
			<LegacyAlertDialogTrigger asChild>
				<LegacyAlertDialogButton>Delete Draft</LegacyAlertDialogButton>
			</LegacyAlertDialogTrigger>

			<LegacyAlertDialogContent>
				<LegacyAlertDialogHeader>
					<LegacyAlertDialogTitle>Delete Draft</LegacyAlertDialogTitle>
					<LegacyAlertDialogDescription>
						This removes the note from the current device and cannot be undone.
					</LegacyAlertDialogDescription>
				</LegacyAlertDialogHeader>

				<LegacyAlertDialogFooter>
					<LegacyAlertDialogClose asChild>
						<LegacyAlertDialogButton className="min-w-0 flex-1">
							Cancel
						</LegacyAlertDialogButton>
					</LegacyAlertDialogClose>
					<LegacyAlertDialogClose asChild>
						<LegacyAlertDialogButton
							className="min-w-0 flex-1"
							variant="primary"
						>
							Delete
						</LegacyAlertDialogButton>
					</LegacyAlertDialogClose>
				</LegacyAlertDialogFooter>
			</LegacyAlertDialogContent>
		</LegacyAlertDialog>
	);
}

Examples

Confirm and Cancel

A simple confirm or cancel layout for the default destructive flow.

"use client";

import {
	LegacyAlertDialog,
	LegacyAlertDialogButton,
	LegacyAlertDialogClose,
	LegacyAlertDialogContent,
	LegacyAlertDialogDescription,
	LegacyAlertDialogFooter,
	LegacyAlertDialogHeader,
	LegacyAlertDialogTitle,
	LegacyAlertDialogTrigger,
} from "@/components/legacy-alert-dialog";

export function LegacyAlertDialogConfirmExample() {
	return (
		<LegacyAlertDialog>
			<LegacyAlertDialogTrigger asChild>
				<LegacyAlertDialogButton>Delete Draft</LegacyAlertDialogButton>
			</LegacyAlertDialogTrigger>

			<LegacyAlertDialogContent>
				<LegacyAlertDialogHeader>
					<LegacyAlertDialogTitle>Delete Draft</LegacyAlertDialogTitle>
					<LegacyAlertDialogDescription>
						This removes the note from the current device and cannot be undone.
					</LegacyAlertDialogDescription>
				</LegacyAlertDialogHeader>

				<LegacyAlertDialogFooter>
					<LegacyAlertDialogClose asChild>
						<LegacyAlertDialogButton className="min-w-0 flex-1">
							Cancel
						</LegacyAlertDialogButton>
					</LegacyAlertDialogClose>
					<LegacyAlertDialogClose asChild>
						<LegacyAlertDialogButton
							className="min-w-0 flex-1"
							variant="primary"
						>
							Delete
						</LegacyAlertDialogButton>
					</LegacyAlertDialogClose>
				</LegacyAlertDialogFooter>
			</LegacyAlertDialogContent>
		</LegacyAlertDialog>
	);
}

Message Only

A notice-only alert that relies on the close button instead of footer actions.

"use client";

import {
	LegacyAlertDialog,
	LegacyAlertDialogButton,
	LegacyAlertDialogContent,
	LegacyAlertDialogDescription,
	LegacyAlertDialogHeader,
	LegacyAlertDialogTitle,
	LegacyAlertDialogTrigger,
} from "@/components/legacy-alert-dialog";

export function LegacyAlertDialogMessageExample() {
	return (
		<LegacyAlertDialog>
			<LegacyAlertDialogTrigger asChild>
				<LegacyAlertDialogButton>System Notice</LegacyAlertDialogButton>
			</LegacyAlertDialogTrigger>

			<LegacyAlertDialogContent showCloseButton={true}>
				<LegacyAlertDialogHeader>
					<LegacyAlertDialogTitle>SIM Updated</LegacyAlertDialogTitle>
					<LegacyAlertDialogDescription>
						Carrier settings were refreshed. Signal bars may settle for a few
						seconds.
					</LegacyAlertDialogDescription>
				</LegacyAlertDialogHeader>
			</LegacyAlertDialogContent>
		</LegacyAlertDialog>
	);
}

Destructive Confirmation

A destructive trigger paired with stronger action wording inside the dialog.

"use client";

import {
	LegacyAlertDialog,
	LegacyAlertDialogButton,
	LegacyAlertDialogClose,
	LegacyAlertDialogContent,
	LegacyAlertDialogDescription,
	LegacyAlertDialogFooter,
	LegacyAlertDialogHeader,
	LegacyAlertDialogTitle,
	LegacyAlertDialogTrigger,
} from "@/components/legacy-alert-dialog";
import { LegacyBarButton } from "@/components/legacy-bar-button";

export function LegacyAlertDialogDestructiveExample() {
	return (
		<LegacyAlertDialog>
			<LegacyAlertDialogTrigger asChild>
				<LegacyBarButton label="Erase Phone" variant="destructive" />
			</LegacyAlertDialogTrigger>

			<LegacyAlertDialogContent>
				<LegacyAlertDialogHeader>
					<LegacyAlertDialogTitle>Erase All Content</LegacyAlertDialogTitle>
					<LegacyAlertDialogDescription>
						This clears photos, saved settings, and offline files from the
						device.
					</LegacyAlertDialogDescription>
				</LegacyAlertDialogHeader>

				<LegacyAlertDialogFooter>
					<LegacyAlertDialogClose asChild>
						<LegacyAlertDialogButton className="min-w-0 flex-1">
							Keep Data
						</LegacyAlertDialogButton>
					</LegacyAlertDialogClose>
					<LegacyAlertDialogClose asChild>
						<LegacyAlertDialogButton
							className="min-w-0 flex-1"
							variant="primary"
						>
							Erase
						</LegacyAlertDialogButton>
					</LegacyAlertDialogClose>
				</LegacyAlertDialogFooter>
			</LegacyAlertDialogContent>
		</LegacyAlertDialog>
	);
}

Stacked Actions

A stacked footer for flows that need multiple next steps instead of one primary decision.

"use client";

import {
	LegacyAlertDialog,
	LegacyAlertDialogButton,
	LegacyAlertDialogClose,
	LegacyAlertDialogContent,
	LegacyAlertDialogDescription,
	LegacyAlertDialogFooter,
	LegacyAlertDialogHeader,
	LegacyAlertDialogTitle,
	LegacyAlertDialogTrigger,
} from "@/components/legacy-alert-dialog";

export function LegacyAlertDialogStackedExample() {
	return (
		<LegacyAlertDialog>
			<LegacyAlertDialogTrigger asChild>
				<LegacyAlertDialogButton>Leave Call</LegacyAlertDialogButton>
			</LegacyAlertDialogTrigger>

			<LegacyAlertDialogContent>
				<LegacyAlertDialogHeader>
					<LegacyAlertDialogTitle>Call in Progress</LegacyAlertDialogTitle>
					<LegacyAlertDialogDescription>
						Pick the next step before disconnecting this line.
					</LegacyAlertDialogDescription>
				</LegacyAlertDialogHeader>

				<LegacyAlertDialogFooter className="flex-col sm:flex-col sm:justify-start">
					<LegacyAlertDialogClose asChild>
						<LegacyAlertDialogButton
							className="w-full min-w-0"
							variant="primary"
						>
							Hold and Exit
						</LegacyAlertDialogButton>
					</LegacyAlertDialogClose>
					<LegacyAlertDialogClose asChild>
						<LegacyAlertDialogButton
							className="w-full min-w-0"
							variant="primary"
						>
							Transfer Call
						</LegacyAlertDialogButton>
					</LegacyAlertDialogClose>
					<LegacyAlertDialogClose asChild>
						<LegacyAlertDialogButton className="w-full min-w-0">
							Stay Here
						</LegacyAlertDialogButton>
					</LegacyAlertDialogClose>
				</LegacyAlertDialogFooter>
			</LegacyAlertDialogContent>
		</LegacyAlertDialog>
	);
}

API Reference

LegacyAlertDialogContentProps controls the panel shell and layout. LegacyAlertDialogButtonProps covers the glossy action buttons used in triggers and footers.

Also inherits: React.ComponentProps<typeof DialogContent>

PropTypeRequired
showCloseButtonbooleanNo

Also inherits: React.ButtonHTMLAttributes<HTMLButtonElement>

PropTypeRequired
variantLegacyAlertDialogButtonVariantNo

Notes

  • Use showCloseButton when the alert should dismiss without dedicating space to footer actions.
  • The trigger, content, header, and footer exports can be composed around either controlled or uncontrolled dialog state.
  • LegacyAlertDialogButton exposes default and primary variants, so the action hierarchy stays consistent across layouts.