{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "alert-dialog",
  "title": "Alert-dialog",
  "description": "A alert-dialog component.",
  "dependencies": [
    "@hugeicons/react",
    "@hugeicons/core-free-icons"
  ],
  "registryDependencies": [
    "@cubby-ui/button",
    "@cubby-ui/scroll-area",
    "@cubby-ui/elevated"
  ],
  "files": [
    {
      "path": "registry/default/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 { cn } from \"@/lib/utils\";\nimport { Button } from \"@/registry/default/button/button\";\nimport {\n  elevatedSurface,\n  type SurfaceLevel,\n} from \"@/registry/default/lib/elevated\";\nimport {\n  ScrollArea,\n  type ScrollAreaProps,\n} from \"@/registry/default/scroll-area/scroll-area\";\n\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport Cancel01Icon from \"@hugeicons/core-free-icons/Cancel01Icon\";\nconst AlertDialog = BaseAlertDialog.Root;\n\nconst createAlertDialogHandle = BaseAlertDialog.createHandle;\n\nfunction AlertDialogPortal({ ...props }: BaseAlertDialog.Portal.Props) {\n  return <BaseAlertDialog.Portal data-slot=\"alert-dialog-portal\" {...props} />;\n}\n\nfunction AlertDialogTrigger({ ...props }: BaseAlertDialog.Trigger.Props) {\n  return (\n    <BaseAlertDialog.Trigger data-slot=\"alert-dialog-trigger\" {...props} />\n  );\n}\n\nfunction AlertDialogClose({ ...props }: BaseAlertDialog.Close.Props) {\n  return <BaseAlertDialog.Close data-slot=\"alert-dialog-close\" {...props} />;\n}\n\nfunction AlertDialogBackdrop({\n  className,\n  ...props\n}: BaseAlertDialog.Backdrop.Props) {\n  return (\n    <BaseAlertDialog.Backdrop\n      className={cn(\n        \"ease-out-expo fixed inset-0 min-h-dvh bg-black/40 transition-all duration-200 supports-[-webkit-touch-callout:none]:absolute\",\n        \"backdrop-blur-sm data-ending-style:opacity-0 data-starting-style:opacity-0\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction AlertDialogViewport({\n  className,\n  ...props\n}: BaseAlertDialog.Viewport.Props) {\n  return (\n    <BaseAlertDialog.Viewport\n      data-slot=\"alert-dialog-viewport\"\n      className={cn(\n        \"fixed inset-0 flex items-center justify-center overflow-hidden px-4 py-6\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction AlertDialogContent({\n  className,\n  children,\n  showCloseButton = false,\n  variant = \"default\",\n  level = 5,\n  shadowLevel = 5,\n  ...props\n}: BaseAlertDialog.Popup.Props & {\n  showCloseButton?: boolean;\n  variant?: \"default\" | \"inset\";\n  /** Surface elevation level for the dialog bg (1-8). Defaults to 5. Bump to 7 for a critical/destructive confirmation that needs extra gravity. */\n  level?: SurfaceLevel;\n  /** Shadow weight (1-8). Pinned to 5 by default. */\n  shadowLevel?: SurfaceLevel;\n}) {\n  return (\n    <AlertDialogPortal>\n      <AlertDialogBackdrop />\n      <AlertDialogViewport>\n        <BaseAlertDialog.Popup\n          data-slot=\"alert-dialog-content\"\n          data-variant={variant}\n          data-level={level}\n          className={cn(\n            \"text-popover-foreground relative z-50 flex max-h-full min-h-0 w-full max-w-full min-w-0 flex-col overflow-hidden\",\n            \"rounded-2xl sm:max-w-lg\",\n            // Surface elevation — bg + shadow + rim overlay (rim uses ::after at z-[2])\n            elevatedSurface(level, shadowLevel),\n            // Nested dialog offset\n            \"-translate-y-[calc(1.25rem*var(--nested-dialogs))]\",\n            // Scale effect for nested dialogs\n            \"scale-[calc(1-0.1*var(--nested-dialogs))]\",\n            // Animation duration\n            \"ease-out-expo transition-all duration-200\",\n            // Animations: scale and fade\n            \"data-starting-style:translate-y-[calc(1.25rem)] data-starting-style:scale-95 data-starting-style:opacity-0\",\n            \"data-ending-style:translate-y-[calc(1.25rem)] data-ending-style:scale-95 data-ending-style:opacity-0\",\n            // Nested dialog overlay — uses ::before (not ::after, that's the rim) at z-3 so it paints above content AND above the rim\n            \"before:pointer-events-none before:absolute before:inset-0 before:z-3 before:hidden before:rounded-[inherit] before:bg-black/5 before:opacity-0 before:transition-[opacity,display] before:transition-discrete before:duration-200\",\n            \"data-nested-dialog-open:before:block data-nested-dialog-open:before:opacity-100\",\n            \"starting:data-nested-dialog-open:before:opacity-0\",\n            className,\n          )}\n          {...props}\n        >\n          {children}\n          {showCloseButton && (\n            <AlertDialogClose\n              aria-label=\"Close\"\n              className=\"absolute end-2 top-2\"\n              render={<Button size=\"icon_sm\" variant=\"ghost\" />}\n            >\n              <HugeiconsIcon icon={Cancel01Icon} strokeWidth={2} />\n            </AlertDialogClose>\n          )}\n        </BaseAlertDialog.Popup>\n      </AlertDialogViewport>\n    </AlertDialogPortal>\n  );\n}\n\n// Slot-presence padding uses ancestor `:has()` on `[data-slot=alert-dialog-content]`\n// so header/body/footer can be wrapped in forms, ErrorBoundaries, or fragments\n// without breaking spacing — adjacent-sibling selectors wouldn't reach through.\nfunction AlertDialogHeader({\n  className,\n  ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n  return (\n    <div\n      data-slot=\"alert-dialog-header\"\n      className={cn(\n        \"flex flex-col gap-2 px-6 pt-6 pb-3\",\n        // Header alone with footer (no body anywhere in content)\n        \"in-[[data-slot=alert-dialog-content]:not(:has([data-slot=alert-dialog-body])):has([data-slot=alert-dialog-footer])]:pb-6\",\n        // Header alone (no body, no footer)\n        \"in-[[data-slot=alert-dialog-content]:not(:has([data-slot=alert-dialog-body])):not(:has([data-slot=alert-dialog-footer]))]:pb-6\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction AlertDialogBody({\n  className,\n  nativeScroll = false,\n  fadeEdges = true,\n  scrollbarGutter = false,\n  persistScrollbar,\n  hideScrollbar,\n  children,\n  ...props\n}: React.HTMLAttributes<HTMLDivElement> & {\n  nativeScroll?: boolean;\n} & Pick<\n    ScrollAreaProps,\n    \"fadeEdges\" | \"scrollbarGutter\" | \"persistScrollbar\" | \"hideScrollbar\"\n  >) {\n  return (\n    <div\n      data-slot=\"alert-dialog-body\"\n      className={cn(\n        \"flex min-h-0 flex-1 flex-col overflow-hidden\",\n        // No header anywhere in content → body needs its own top padding\n        \"in-[[data-slot=alert-dialog-content]:not(:has([data-slot=alert-dialog-header]))]:pt-5\",\n        // No footer anywhere in content → body needs its own bottom padding\n        \"in-[[data-slot=alert-dialog-content]:not(:has([data-slot=alert-dialog-footer]))]:pb-5\",\n        // Inset variant: still need bottom padding when a footer follows so the\n        // body's content doesn't crowd the footer's top border\n        \"in-data-[variant=inset]:in-[[data-slot=alert-dialog-content]:has([data-slot=alert-dialog-footer])]:pb-5\",\n      )}\n    >\n      <ScrollArea\n        className=\"flex-1\"\n        fadeEdges={fadeEdges}\n        scrollbarGutter={scrollbarGutter}\n        persistScrollbar={persistScrollbar}\n        hideScrollbar={hideScrollbar}\n        nativeScroll={nativeScroll}\n      >\n        <div className={cn(\"px-6 py-1\", className)} {...props}>\n          {children}\n        </div>\n      </ScrollArea>\n    </div>\n  );\n}\n\nfunction AlertDialogFooter({\n  className,\n  ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n  return (\n    <div\n      data-slot=\"alert-dialog-footer\"\n      className={cn(\n        \"flex flex-col-reverse gap-2 px-6 pt-4 pb-6 sm:flex-row sm:justify-end\",\n        // No header AND no body → footer alone, needs its own top padding\n        \"in-[[data-slot=alert-dialog-content]:not(:has([data-slot=alert-dialog-header])):not(:has([data-slot=alert-dialog-body]))]:pt-6\",\n        // Reduce top padding when body is present\n        \"not-in-data-[variant=inset]:in-[[data-slot=alert-dialog-content]:has([data-slot=alert-dialog-body])]:pt-3\",\n        // Inset variant: muted background with top border for separation\n        \"in-data-[variant=inset]:border-border in-data-[variant=inset]:bg-muted in-data-[variant=inset]:rounded-b-2xl in-data-[variant=inset]:border-t in-data-[variant=inset]:pt-4 in-data-[variant=inset]:pb-4\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction AlertDialogTitle({\n  className,\n  ...props\n}: BaseAlertDialog.Title.Props) {\n  return (\n    <BaseAlertDialog.Title\n      className={cn(\n        \"text-foreground text-lg leading-none font-semibold tracking-tight text-balance\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction AlertDialogDescription({\n  className,\n  ...props\n}: BaseAlertDialog.Description.Props) {\n  return (\n    <BaseAlertDialog.Description\n      className={cn(\"text-muted-foreground text-sm text-pretty\", className)}\n      {...props}\n    />\n  );\n}\n\nexport {\n  AlertDialog,\n  createAlertDialogHandle,\n  AlertDialogPortal,\n  AlertDialogBackdrop,\n  AlertDialogViewport,\n  AlertDialogContent,\n  AlertDialogTrigger,\n  AlertDialogClose,\n  AlertDialogHeader,\n  AlertDialogBody,\n  AlertDialogFooter,\n  AlertDialogTitle,\n  AlertDialogDescription,\n};\n",
      "type": "registry:ui",
      "target": "components/ui/cubby-ui/alert-dialog.tsx"
    }
  ],
  "type": "registry:ui"
}