{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "toast",
  "title": "Toast",
  "description": "macOS notifications: glass banners at the top right that slide in and stack.",
  "dependencies": [
    "@base-ui/react",
    "lucide-react"
  ],
  "registryDependencies": [
    "@cupertinoui/macos-theme",
    "@cupertinoui/button",
    "@cupertinoui/spinner"
  ],
  "files": [
    {
      "path": "registry/macos/ui/toast.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Toast as ToastPrimitive } from \"@base-ui/react/toast\"\nimport { CircleCheckIcon, InfoIcon, OctagonXIcon, TriangleAlertIcon, XIcon } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/macos/ui/button\"\nimport { Spinner } from \"@/registry/macos/ui/spinner\"\n\n// macOS notifications: glass banners in the top-right corner that slide in\n// from the side and stack, newest on top. Call toast.add({ title,\n// description, type }) from anywhere under <Toaster />.\nconst toast = ToastPrimitive.createToastManager()\n\nfunction ToastProvider({ ...props }: ToastPrimitive.Provider.Props) {\n  return <ToastPrimitive.Provider {...props} />\n}\n\nfunction ToastPortal({ ...props }: ToastPrimitive.Portal.Props) {\n  return <ToastPrimitive.Portal data-slot=\"toast-portal\" {...props} />\n}\n\nfunction ToastViewport({ className, ...props }: ToastPrimitive.Viewport.Props) {\n  return (\n    <ToastPrimitive.Viewport\n      data-slot=\"toast-viewport\"\n      className={cn(\"pointer-events-none fixed top-[38px] right-3 z-50 w-[calc(100%-24px)] max-w-[356px] outline-none\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction Toast({ className, ...props }: ToastPrimitive.Root.Props) {\n  return (\n    <ToastPrimitive.Root\n      data-slot=\"toast\"\n      className={cn(\n        \"group/toast pointer-events-auto absolute top-0 right-0 z-[calc(1000-var(--toast-index))] w-full origin-top rounded-[20px] text-mac-label shadow-mac-popover mac-material-popover will-change-transform outline-none select-none focus-visible:mac-focus-ring\",\n        \"[--gap:0.5rem] [--height:var(--toast-frontmost-height,var(--toast-height))] [--offset-y:calc(var(--toast-offset-y)+(var(--toast-index)*var(--gap))+var(--toast-swipe-movement-y))] [--peek:0.5rem] [--scale:calc(max(0,1-(var(--toast-index)*0.05)))] [--shrink:calc(1-var(--scale))]\",\n        \"h-(--height) [transform:translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--toast-swipe-movement-y)+(var(--toast-index)*var(--peek))+(var(--shrink)*var(--height))))_scale(var(--scale))] [transition:transform_500ms_cubic-bezier(0.22,1,0.36,1),opacity_500ms,height_150ms]\",\n        \"after:absolute after:bottom-full after:left-0 after:h-[calc(var(--gap)+1px)] after:w-full after:content-['']\",\n        \"data-expanded:h-(--toast-height) data-expanded:[transform:translateX(var(--toast-swipe-movement-x))_translateY(var(--offset-y))]\",\n        \"data-limited:opacity-0 data-starting-style:[transform:translateX(calc(100%+24px))]\",\n        \"[&[data-ending-style]:not([data-limited]):not([data-swipe-direction])]:[transform:translateX(calc(100%+24px))]\",\n        \"data-ending-style:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+100%+24px))_translateY(var(--offset-y))]\",\n        \"data-ending-style:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))]\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction ToastContent({ className, ...props }: ToastPrimitive.Content.Props) {\n  return (\n    <ToastPrimitive.Content\n      data-slot=\"toast-content\"\n      className={cn(\n        \"flex h-full items-center gap-3 overflow-hidden py-3 pr-3 pl-3.5 transition-opacity duration-250 ease-[cubic-bezier(0.22,1,0.36,1)] data-behind:opacity-0 data-expanded:opacity-100\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction ToastTitle({ className, ...props }: ToastPrimitive.Title.Props) {\n  return <ToastPrimitive.Title data-slot=\"toast-title\" className={cn(\"text-mac-body leading-4 font-semibold\", className)} {...props} />\n}\n\nfunction ToastDescription({ className, ...props }: ToastPrimitive.Description.Props) {\n  return <ToastPrimitive.Description data-slot=\"toast-description\" className={cn(\"text-mac-body leading-4 text-mac-label-secondary\", className)} {...props} />\n}\n\nfunction ToastAction({ className, render = <Button variant=\"secondary\" size=\"sm\" />, ...props }: ToastPrimitive.Action.Props) {\n  return <ToastPrimitive.Action data-slot=\"toast-action\" render={render} className={cn(\"shrink-0\", className)} {...props} />\n}\n\n// The close button appears on the top-left corner while the pointer is on\n// the notification, as in Notification Center.\nfunction ToastClose({ className, children, ...props }: ToastPrimitive.Close.Props) {\n  return (\n    <ToastPrimitive.Close\n      data-slot=\"toast-close\"\n      aria-label=\"Close notification\"\n      className={cn(\n        \"absolute -top-1.5 -left-1.5 flex size-5 cursor-default items-center justify-center rounded-full text-mac-label-secondary opacity-0 shadow-mac-popover mac-material-popover transition-opacity outline-none group-hover/toast:opacity-100 hover:text-mac-label focus-visible:opacity-100 focus-visible:mac-focus-ring\",\n        className\n      )}\n      {...props}\n    >\n      {children ?? <XIcon className=\"size-3\" strokeWidth={2.5} aria-hidden=\"true\" />}\n    </ToastPrimitive.Close>\n  )\n}\n\nfunction ToastIcon({ type }: { type: string | undefined }) {\n  const icons: Record<string, React.ReactNode> = {\n    success: <CircleCheckIcon className=\"text-mac-green\" />,\n    info: <InfoIcon className=\"text-mac-blue\" />,\n    warning: <TriangleAlertIcon className=\"text-mac-orange\" />,\n    error: <OctagonXIcon className=\"text-mac-red\" />,\n    loading: <Spinner className=\"size-5\" />,\n  }\n  const icon = type ? icons[type] : null\n  if (!icon) return null\n  return (\n    <span\n      data-slot=\"toast-icon\"\n      className=\"flex size-9 shrink-0 items-center justify-center rounded-[9px] bg-mac-window shadow-[0_0_0_0.5px_rgb(0_0_0/0.1)] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-5\"\n    >\n      {icon}\n    </span>\n  )\n}\n\nfunction ToastList() {\n  const { toasts } = ToastPrimitive.useToastManager()\n  return toasts.map((item) => (\n    <Toast key={item.id} toast={item}>\n      <ToastContent>\n        <ToastIcon type={item.type} />\n        <div className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n          <ToastTitle />\n          <ToastDescription />\n        </div>\n        <ToastAction />\n        <ToastClose />\n      </ToastContent>\n    </Toast>\n  ))\n}\n\nfunction Toaster({ children, toastManager = toast, ...props }: ToastPrimitive.Provider.Props) {\n  return (\n    <ToastProvider toastManager={toastManager} {...props}>\n      {children}\n      <ToastPortal>\n        <ToastViewport>\n          <ToastList />\n        </ToastViewport>\n      </ToastPortal>\n    </ToastProvider>\n  )\n}\n\nconst createToastManager = ToastPrimitive.createToastManager\nconst useToastManager = ToastPrimitive.useToastManager\n\nexport {\n  Toaster,\n  Toast,\n  ToastAction,\n  ToastClose,\n  ToastContent,\n  ToastDescription,\n  ToastPortal,\n  ToastProvider,\n  ToastTitle,\n  ToastViewport,\n  createToastManager,\n  toast,\n  useToastManager,\n}\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}