{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "alert-dialog",
  "type": "registry:ui",
  "title": "Alert dialog",
  "description": "A question that must be answered: the dialog's plate and motion; a click outside shakes it once on the refusal spring instead of closing it, and focus starts on Cancel.",
  "dependencies": [
    "@base-ui/react@^1.8.0"
  ],
  "registryDependencies": [
    "https://metalui.dev/r/tokens.json"
  ],
  "files": [
    {
      "path": "packages/metalui/src/components/alert-dialog/alert-dialog.tsx",
      "type": "registry:ui",
      "target": "components/metalui/alert-dialog/alert-dialog.tsx",
      "content": "'use client';\n\nimport * as React from 'react';\nimport { AlertDialog as BaseAlertDialog } from '@base-ui/react/alert-dialog';\nimport { Surface } from '../surface/surface';\nimport { Button } from '../button/button';\nimport { refuse } from '../../motion/refuse';\n\n/* ─────────────────────────────────────────────────────────\n * ALERT DIALOG, a question that must be answered, on Base UI AlertDialog\n *\n *   open      the scrim fades and the plate rises a step on the surface spring (the dialog's\n *             own motion); focus starts on Cancel, the safe answer\n *   outside   a click on the scrim does not close it: the plate shakes once on the refusal\n *             spring, one nest (6) aside, ringing out against where it stands\n *   answer    Cancel or Esc closes with nothing done; the confirm button runs the thing and closes\n *   close     the plate leaves on the release spring; focus returns to what opened it\n * Reduce Motion: no shake (the refusal travel is zero); the rise is a crossfade.\n * The plate, scrim and layout are the dialog recipe's; this adds only the refusal and the answers.\n * Slots: AlertDialog.Root, Popup, Title, Description, Actions, Cancel, Confirm.\n * ───────────────────────────────────────────────────────── */\n\nconst SCRIM = 'mu-alert-dialog-scrim fixed inset-0 z-dialog-scrim-z bg-dialog-scrim-color backdrop-dialog-scrim-blur reduce-transparency:bg-dialog-scrim-opaque reduce-transparency:backdrop-blur-none transition-opacity ease-surface duration-surface data-starting-style:opacity-0 data-ending-style:opacity-0';\nconst POPUP = 'mu-alert-dialog mu-dialog dialog-frame fixed z-dialog-scrim-z dialog-top left-1/2 -translate-x-1/2 outline-none transition-dialog data-starting-style:dialog-enter data-ending-style:dialog-enter data-ending-style:duration-release data-ending-style:ease-release';\nconst DESCRIPTION = 'mu-alert-dialog-description alert-dialog-description type-body text-ink2';\n\ninterface Ctx { cancel: React.RefObject<HTMLButtonElement | null>; popup: React.RefObject<HTMLDivElement | null> }\nconst AlertCtx = React.createContext<Ctx | null>(null);\n\nexport interface AlertDialogRootProps {\n  open: boolean;\n  onOpenChange: (open: boolean) => void;\n  children: React.ReactNode;\n}\n\nfunction Root({ open, onOpenChange, children }: AlertDialogRootProps) {\n  const cancel = React.useRef<HTMLButtonElement>(null);\n  const popup = React.useRef<HTMLDivElement>(null);\n  return (\n    <AlertCtx.Provider value={{ cancel, popup }}>\n      <BaseAlertDialog.Root open={open} onOpenChange={(o) => onOpenChange(o)}>\n        <BaseAlertDialog.Portal>\n          <BaseAlertDialog.Backdrop className={SCRIM} onPointerDown={() => refuse(popup.current)} />\n          {children}\n        </BaseAlertDialog.Portal>\n      </BaseAlertDialog.Root>\n    </AlertCtx.Provider>\n  );\n}\n\nfunction Popup({ className, children, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n  const ctx = React.useContext(AlertCtx)!;\n  return (\n    <BaseAlertDialog.Popup ref={ctx.popup} initialFocus={ctx.cancel} {...props} className={className ? `${POPUP} ${className}` : POPUP} render={<Surface material=\"plate\" radius=\"card\" />}>\n      {children}\n    </BaseAlertDialog.Popup>\n  );\n}\n\n/** The question, in the title role: \"Delete 3 regions?\" */\nfunction Title({ className, ...props }: React.HTMLAttributes<HTMLHeadingElement>) {\n  return <BaseAlertDialog.Title {...props} className={className ? `mu-dialog-title type-title text-ink ${className}` : 'mu-dialog-title type-title text-ink'} />;\n}\n\n/** What happens if you say yes: \"Their notes move to the past for 30 days.\" */\nfunction Description({ className, ...props }: React.HTMLAttributes<HTMLParagraphElement>) {\n  return <BaseAlertDialog.Description {...props} className={className ? `${DESCRIPTION} ${className}` : DESCRIPTION} />;\n}\n\nfunction Actions({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n  return <div {...props} className={className ? `mu-dialog-actions dialog-actions ${className}` : 'mu-dialog-actions dialog-actions'} />;\n}\n\n/** The safe answer: closes with nothing done. Focus starts here. */\nfunction Cancel({ children = 'Cancel' }: { children?: React.ReactNode }) {\n  const ctx = React.useContext(AlertCtx)!;\n  return <BaseAlertDialog.Close ref={ctx.cancel} render={<Button />}>{children}</BaseAlertDialog.Close>;\n}\n\nexport interface AlertDialogConfirmProps {\n  children: React.ReactNode;\n  onClick: () => void;\n  /** destructive (the default) for a loss; primary for a weighty but safe yes. */\n  tone?: 'destructive' | 'primary';\n}\n\n/** The answer that does the thing, last; it closes after it runs. */\nfunction Confirm({ children, onClick, tone = 'destructive' }: AlertDialogConfirmProps) {\n  return <BaseAlertDialog.Close render={<Button cap={tone} />} onClick={onClick}>{children}</BaseAlertDialog.Close>;\n}\n\nexport const AlertDialog = Object.assign(Root, { Popup, Title, Description, Actions, Cancel, Confirm, Root });\n"
    }
  ],
  "docs": "Agent guide: https://metalui.dev/r/alert-dialog.md. SwiftUI: MetalAlertDialog in the MetalUI Swift package."
}
