For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to documentation URLs. Homepage markdown is available at /llms.md/content.md. An agent skill is available at /.well-known/agent-skills/site-skill.md.

Alert Dialog

The Alert Dialog component from this design system, built on Base UI.

Installation

$ pnpm dlx shadcn@latest add @cobalt/alert-dialog

Source

"use client";

import { AlertDialog as AlertDialogPrimitive } from "@base-ui/react/alert-dialog";
import { cn } from "cn";
import * as React from "react";

import { Button } from "@/components/ui/button";

function AlertDialog({ ...props }: AlertDialogPrimitive.Root.Props) {
  return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...props} />;
}

function AlertDialogTrigger({ ...props }: AlertDialogPrimitive.Trigger.Props) {
  return (
    <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />
  );
}

function AlertDialogPortal({ ...props }: AlertDialogPrimitive.Portal.Props) {
  return (
    <AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} />
  );
}

// Black/70 behind the panel, fading over 300ms. The fade is kept under reduced
// motion; only the panel's scale and blur are dropped there.
function AlertDialogOverlay({
  className,
  ...props
}: AlertDialogPrimitive.Backdrop.Props) {
  return (
    <AlertDialogPrimitive.Backdrop
      data-slot="alert-dialog-overlay"
      className={cn(
        "fixed inset-0 isolate z-50 bg-black/70 transition-opacity duration-300 ease-out data-ending-style:opacity-0 data-starting-style:opacity-0",
        className
      )}
      {...props}
    />
  );
}

function AlertDialogContent({
  className,
  size = "default",
  ...props
}: AlertDialogPrimitive.Popup.Props & {
  size?: "default" | "sm";
}) {
  return (
    <AlertDialogPortal>
      <AlertDialogOverlay />
      <AlertDialogPrimitive.Popup
        data-slot="alert-dialog-content"
        data-size={size}
        className={cn(
          // Centred in the viewport with the same 16px / 24px gutter as the
          // source overlay. The panel fades and sharpens from scale 0.85 and a
          // 4px blur over 300ms on the iOS sheet curve.
          "fixed top-1/2 left-1/2 z-50 flex max-h-[calc(100dvh-2rem)] w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 flex-col gap-4 overflow-y-auto overscroll-contain rounded-[24px] border border-[color:var(--surface-strong,var(--border))] bg-[var(--surface-overlay,var(--popover))] p-6 text-sm text-popover-foreground shadow-[shadow:var(--shadow-control,0_1px_2px_0_rgb(0_0_0/0.05))] outline-none transition-[opacity,scale,filter] duration-300 ease-[cubic-bezier(0.32,0.72,0,1)] data-ending-style:opacity-0 data-starting-style:opacity-0 motion-safe:data-ending-style:scale-[0.85] motion-safe:data-ending-style:blur-[4px] motion-safe:data-starting-style:scale-[0.85] motion-safe:data-starting-style:blur-[4px] motion-reduce:transition-[opacity] data-[size=default]:max-w-[480px] data-[size=sm]:max-w-[400px] sm:max-h-[calc(100dvh-3rem)] sm:w-[calc(100%-3rem)]",
          className
        )}
        {...props}
      />
    </AlertDialogPortal>
  );
}

function AlertDialogHeader({
  className,
  ...props
}: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="alert-dialog-header"
      className={cn("flex flex-col", className)}
      {...props}
    />
  );
}

function AlertDialogFooter({
  className,
  ...props
}: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="alert-dialog-footer"
      className={cn(
        // Stacked on phones (primary action on top, 8px extra over the panel
        // gap), a trailing row from sm up.
        "mt-2 flex shrink-0 flex-col-reverse gap-2 sm:flex-row sm:items-center sm:justify-end",
        className
      )}
      {...props}
    />
  );
}

function AlertDialogMedia({
  className,
  variant = "default",
  ...props
}: React.ComponentProps<"div"> & {
  /** `destructive` tints the icon circle for destructive confirmations. */
  variant?: "default" | "destructive";
}) {
  return (
    <div
      data-slot="alert-dialog-media"
      data-variant={variant}
      className={cn(
        "mb-4 inline-flex size-10 shrink-0 items-center justify-center rounded-full [&_svg:not([class*='size-'])]:size-5",
        variant === "destructive"
          ? "bg-[var(--notification-error-background,color-mix(in_oklch,var(--destructive)_15%,transparent))] text-[color:var(--notification-error-foreground,var(--destructive))]"
          : "bg-[var(--surface-strong,var(--muted))] text-[color:var(--icon-foreground,var(--muted-foreground))]",
        className
      )}
      {...props}
    />
  );
}

function AlertDialogTitle({
  className,
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {
  return (
    <AlertDialogPrimitive.Title
      data-slot="alert-dialog-title"
      className={cn("text-lg leading-[1.625rem] font-medium", className)}
      {...props}
    />
  );
}

function AlertDialogDescription({
  className,
  ...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {
  return (
    <AlertDialogPrimitive.Description
      data-slot="alert-dialog-description"
      className={cn(
        "mt-1 text-sm leading-[1.25rem] text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
        className
      )}
      {...props}
    />
  );
}

function AlertDialogAction({
  className,
  ...props
}: React.ComponentProps<typeof Button>) {
  return (
    <Button
      data-slot="alert-dialog-action"
      className={cn(className)}
      {...props}
    />
  );
}

function AlertDialogCancel({
  className,
  variant = "outline",
  size = "default",
  ...props
}: AlertDialogPrimitive.Close.Props &
  Pick<React.ComponentProps<typeof Button>, "variant" | "size">) {
  return (
    <AlertDialogPrimitive.Close
      data-slot="alert-dialog-cancel"
      className={cn(className)}
      render={<Button variant={variant} size={size} />}
      {...props}
    />
  );
}

export {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogMedia,
  AlertDialogOverlay,
  AlertDialogPortal,
  AlertDialogTitle,
  AlertDialogTrigger,
};