{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "toast",
  "title": "TIS Toast",
  "author": "TIS Experience Engineering",
  "description": "Toast React com composição shadcn e manager Base UI, preservando tipos, estilos, anatomia e tokens públicos do DS TIS.",
  "dependencies": [
    "@base-ui/react@1.6.0",
    "clsx@2.1.1",
    "lucide-react@1.28.0",
    "tailwind-merge@3.6.0",
    "ds-tis@github:tis-experience/ds-tis#dd4c906943847cb7664a72a0c7637a378b39adcc"
  ],
  "files": [
    {
      "path": "registry/tis/toast.tsx",
      "content": "import * as React from \"react\"\nimport { Toast as ToastPrimitive } from \"@base-ui/react/toast\"\nimport {\n  CircleAlertIcon,\n  CircleCheckIcon,\n  InfoIcon,\n  TriangleAlertIcon,\n  XIcon,\n} from \"lucide-react\"\n\nimport { cn } from \"./tis-utils\"\n\ntype ToastType = \"error\" | \"info\" | \"success\" | \"warning\"\ntype ToastStyle = \"solid\" | \"subtle\"\ntype ToastData = { style?: ToastStyle }\n\ntype ShowToastOptions = {\n  actionLabel?: React.ReactNode\n  description?: React.ReactNode\n  duration?: number\n  id?: string\n  onAction?: (detail: { id: string; type: ToastType }) => void\n  style?: ToastStyle\n  title: React.ReactNode\n  type?: ToastType\n}\n\nconst DEFAULT_DURATION = 5000\nconst iconByType = {\n  error: CircleAlertIcon,\n  info: InfoIcon,\n  success: CircleCheckIcon,\n  warning: TriangleAlertIcon,\n}\n\nfunction normalizeType(type?: ToastType): ToastType {\n  return type && iconByType[type] ? type : \"info\"\n}\n\nfunction normalizeStyle(style?: ToastStyle): ToastStyle {\n  return style === \"solid\" ? \"solid\" : \"subtle\"\n}\n\nconst toastManager = ToastPrimitive.createToastManager<ToastData>()\n\nfunction showToast(options: ShowToastOptions) {\n  if (options.title === null || options.title === undefined || options.title === \"\") {\n    throw new Error(\"showToast requires options.title\")\n  }\n\n  const type = normalizeType(options.type)\n  const style = normalizeStyle(options.style)\n  let id = options.id ?? \"\"\n  const actionProps = options.actionLabel\n    ? {\n        children: options.actionLabel,\n        onClick: () => options.onAction?.({ id, type }),\n      }\n    : undefined\n\n  id = toastManager.add({\n    actionProps,\n    data: { style },\n    description: options.description,\n    id: options.id,\n    priority: type === \"error\" ? \"high\" : \"low\",\n    timeout: options.duration ?? (actionProps ? 0 : DEFAULT_DURATION),\n    title: options.title,\n    type,\n  })\n  return id\n}\n\nfunction dismissToast(id?: string) {\n  toastManager.close(id)\n}\n\nfunction ToastProvider({\n  children,\n  limit = 5,\n  manager = toastManager,\n  timeout = DEFAULT_DURATION,\n}: Omit<ToastPrimitive.Provider.Props, \"toastManager\"> & {\n  manager?: ReturnType<typeof ToastPrimitive.createToastManager<ToastData>>\n}) {\n  return (\n    <ToastPrimitive.Provider limit={limit} timeout={timeout} toastManager={manager}>\n      {children}\n      <ToastPrimitive.Portal data-slot=\"toast-portal\">\n        <ToastPrimitive.Viewport\n          className=\"ds-toast-region ds-tis-toast__viewport\"\n          data-slot=\"toast-viewport\"\n        >\n          <ToastList />\n        </ToastPrimitive.Viewport>\n      </ToastPrimitive.Portal>\n    </ToastPrimitive.Provider>\n  )\n}\n\nfunction ToastList() {\n  const { toasts } = ToastPrimitive.useToastManager<ToastData>()\n\n  return toasts.map((toast) => {\n    const type = normalizeType(toast.type as ToastType)\n    const style = normalizeStyle(toast.data?.style)\n    const Icon = iconByType[type]\n    return (\n      <ToastPrimitive.Root\n        aria-hidden={false}\n        className={cn(\n          \"ds-toast\",\n          `ds-toast--${type}`,\n          `ds-toast--${style}`,\n          \"ds-tis-toast\",\n        )}\n        data-slot=\"toast\"\n        key={toast.id}\n        swipeDirection={[\"down\", \"right\"]}\n        toast={toast}\n      >\n        <ToastPrimitive.Content className=\"ds-tis-toast__content\" data-slot=\"toast-content\">\n          <span className=\"ds-toast__icon\" aria-hidden=\"true\">\n            <Icon className=\"ds-icon\" />\n          </span>\n          <div className=\"ds-toast__content\">\n            <ToastPrimitive.Title className=\"ds-toast__title\" data-slot=\"toast-title\" />\n            {toast.description ? (\n              <ToastPrimitive.Description\n                className=\"ds-toast__description\"\n                data-slot=\"toast-description\"\n              />\n            ) : null}\n            {toast.actionProps ? (\n              <div className=\"ds-toast__actions\">\n                <ToastPrimitive.Action\n                  className={cn(\n                    \"ds-button ds-button--ghost ds-button--sm\",\n                    toast.actionProps.className,\n                  )}\n                  data-slot=\"toast-action\"\n                />\n              </div>\n            ) : null}\n          </div>\n          <ToastPrimitive.Close\n            aria-hidden={false}\n            aria-label=\"Dispensar\"\n            className=\"ds-toast__close\"\n            data-slot=\"toast-close\"\n          >\n            <XIcon className=\"ds-icon\" aria-hidden=\"true\" />\n          </ToastPrimitive.Close>\n        </ToastPrimitive.Content>\n      </ToastPrimitive.Root>\n    )\n  })\n}\n\nexport {\n  dismissToast,\n  showToast,\n  toastManager,\n  ToastList,\n  ToastProvider,\n}\n",
      "type": "registry:ui",
      "target": "@ui/toast.tsx"
    },
    {
      "path": "registry/tis/tis-utils.ts",
      "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n",
      "type": "registry:lib",
      "target": "@ui/tis-utils.ts"
    }
  ],
  "css": {
    "@import \"ds-tis/css\"": {},
    ".ds-tis-toast__content": {
      "display": "contents"
    },
    ".ds-tis-toast__viewport, .ds-tis-toast": {
      "box-sizing": "border-box"
    },
    ".ds-tis-toast": {
      "transition": "opacity var(--ds-motion-duration-fast) var(--ds-motion-ease-out)"
    },
    ".ds-tis-toast[data-starting-style], .ds-tis-toast[data-ending-style]": {
      "opacity": "0"
    },
    ".ds-tis-toast[data-limited]": {
      "display": "none"
    }
  },
  "meta": {
    "provider": "Base UI",
    "providerRole": "output-provider",
    "status": "beta",
    "wave": "feedback"
  },
  "docs": "Monte ToastProvider uma vez no app, chame showToast para feedback transitório e preserve @import \"ds-tis/css\" como o primeiro import global.",
  "type": "registry:ui"
}