{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "document-toast",
  "title": "document-toast",
  "files": [
    {
      "path": "components/extend/ui-toast.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { createPortal } from \"react-dom\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype ToastTone = \"error\" | \"info\" | \"success\"\ntype ToastItem = {\n  id: number\n  createdAt: number\n  title: React.ReactNode\n  type?: ToastTone\n}\nfunction createToastManager() {\n  let nextId = 1\n  let items: ToastItem[] = []\n  const listeners = new Set<() => void>()\n  const emit = () => listeners.forEach((listener) => listener())\n  return {\n    add(item: Omit<ToastItem, \"id\" | \"createdAt\">) {\n      const id = nextId++\n      items = [...items, { ...item, id, createdAt: Date.now() }]\n      emit()\n      return id\n    },\n    getSnapshot: () => items,\n    remove(id: number) {\n      items = items.filter((item) => item.id !== id)\n      emit()\n    },\n    subscribe(listener: () => void) {\n      listeners.add(listener)\n      return () => listeners.delete(listener)\n    },\n  }\n}\nexport const ToastPrimitive = { createToastManager }\ntype ToastManager = ReturnType<typeof createToastManager>\nexport function ToastProvider({\n  children,\n  limit = 3,\n  portalProps,\n  timeout = 5000,\n  toastManager,\n  viewportProps,\n}: {\n  children: React.ReactNode\n  limit?: number\n  portalProps?: {\n    container?: Element | DocumentFragment | null\n  }\n  timeout?: number\n  toastManager: ToastManager\n  viewportProps?: React.ComponentProps<\"div\">\n}) {\n  const items = React.useSyncExternalStore(\n    toastManager.subscribe,\n    toastManager.getSnapshot,\n    toastManager.getSnapshot\n  )\n  React.useEffect(() => {\n    const timers = items.map((item) =>\n      window.setTimeout(\n        () => toastManager.remove(item.id),\n        Math.max(0, item.createdAt + timeout - Date.now())\n      )\n    )\n    return () => timers.forEach((timer) => window.clearTimeout(timer))\n  }, [items, limit, timeout, toastManager])\n  const viewport = (\n    <div\n      {...viewportProps}\n      className={cn(\n        \"pointer-events-none absolute right-3 bottom-3 z-50 flex w-80 max-w-[calc(100%-1.5rem)] flex-col gap-2\",\n        viewportProps?.className\n      )}\n    >\n      {items.slice(-limit).map((item) => (\n        <div\n          key={item.id}\n          role={item.type === \"error\" ? \"alert\" : \"status\"}\n          className=\"pointer-events-auto rounded-lg border bg-popover px-3 py-2 text-sm text-popover-foreground shadow-lg\"\n        >\n          {item.title}\n        </div>\n      ))}\n    </div>\n  )\n  const container = portalProps?.container\n  return (\n    <>\n      {children}\n      {container ? createPortal(viewport, container) : viewport}\n    </>\n  )\n}\n",
      "type": "registry:ui",
      "target": "@components/extend/ui-toast.tsx"
    }
  ],
  "type": "registry:ui",
  "dependencies": [],
  "registryDependencies": [
    "utils"
  ]
}
