{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "artifact",
  "title": "Ai Artifact",
  "description": "TODO: Add description",
  "dependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/blocks/ai/ai-artifact/components/elements/ai-artifact.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  Check,\n  Copy,\n  Download,\n  FileCode,\n  Play,\n  RefreshCw,\n  Share2,\n  X,\n} from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\n\ninterface AiArtifactContextValue {\n  onClose?: () => void;\n}\n\nconst AiArtifactContext = React.createContext<AiArtifactContextValue | null>(\n  null,\n);\n\nfunction useArtifactContext() {\n  const context = React.useContext(AiArtifactContext);\n  if (!context) {\n    throw new Error(\"AiArtifact components must be used within <AiArtifact>\");\n  }\n  return context;\n}\n\ninterface AiArtifactProps {\n  onClose?: () => void;\n  children?: React.ReactNode;\n  className?: string;\n}\n\nfunction AiArtifact({ onClose, children, className }: AiArtifactProps) {\n  const contextValue = React.useMemo(() => ({ onClose }), [onClose]);\n\n  return (\n    <AiArtifactContext.Provider value={contextValue}>\n      <div\n        data-slot=\"ai-artifact\"\n        className={cn(\n          \"rounded-lg border border-border bg-card text-card-foreground shadow-lg overflow-hidden flex flex-col\",\n          className,\n        )}\n      >\n        {children}\n      </div>\n    </AiArtifactContext.Provider>\n  );\n}\n\ninterface AiArtifactHeaderProps {\n  children?: React.ReactNode;\n  className?: string;\n}\n\nfunction AiArtifactHeader({ children, className }: AiArtifactHeaderProps) {\n  return (\n    <div\n      data-slot=\"ai-artifact-header\"\n      className={cn(\n        \"flex items-center justify-between gap-4 border-b border-border px-4 py-3\",\n        className,\n      )}\n    >\n      <div className=\"flex items-center gap-3 min-w-0\">\n        <div className=\"flex size-8 shrink-0 items-center justify-center rounded-md bg-muted\">\n          <FileCode className=\"size-4 text-muted-foreground\" />\n        </div>\n        <div className=\"min-w-0\">{children}</div>\n      </div>\n    </div>\n  );\n}\n\ninterface AiArtifactTitleProps {\n  children?: React.ReactNode;\n  className?: string;\n}\n\nfunction AiArtifactTitle({ children, className }: AiArtifactTitleProps) {\n  return (\n    <h3\n      data-slot=\"ai-artifact-title\"\n      className={cn(\"font-semibold text-sm truncate\", className)}\n    >\n      {children}\n    </h3>\n  );\n}\n\ninterface AiArtifactDescriptionProps {\n  children?: React.ReactNode;\n  className?: string;\n}\n\nfunction AiArtifactDescription({\n  children,\n  className,\n}: AiArtifactDescriptionProps) {\n  return (\n    <p\n      data-slot=\"ai-artifact-description\"\n      className={cn(\"text-xs text-muted-foreground truncate\", className)}\n    >\n      {children}\n    </p>\n  );\n}\n\ninterface AiArtifactCloseProps {\n  className?: string;\n}\n\nfunction AiArtifactClose({ className }: AiArtifactCloseProps) {\n  const { onClose } = useArtifactContext();\n\n  if (!onClose) return null;\n\n  return (\n    <button\n      type=\"button\"\n      data-slot=\"ai-artifact-close\"\n      onClick={onClose}\n      className={cn(\n        \"shrink-0 rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n        className,\n      )}\n    >\n      <X className=\"size-4\" />\n      <span className=\"sr-only\">Close artifact</span>\n    </button>\n  );\n}\n\ninterface AiArtifactActionsProps {\n  children?: React.ReactNode;\n  className?: string;\n}\n\nfunction AiArtifactActions({ children, className }: AiArtifactActionsProps) {\n  const { onClose } = useArtifactContext();\n\n  return (\n    <div\n      data-slot=\"ai-artifact-actions\"\n      className={cn(\"flex items-center gap-1\", className)}\n    >\n      {children}\n      {onClose && <AiArtifactClose />}\n    </div>\n  );\n}\n\ntype ActionType = \"run\" | \"copy\" | \"regenerate\" | \"download\" | \"share\";\n\ninterface AiArtifactActionProps {\n  type: ActionType;\n  onClick?: () => void;\n  disabled?: boolean;\n  className?: string;\n}\n\nfunction AiArtifactAction({\n  type,\n  onClick,\n  disabled = false,\n  className,\n}: AiArtifactActionProps) {\n  const [showCheck, setShowCheck] = React.useState(false);\n  const timeoutRef = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n\n  React.useEffect(() => {\n    return () => {\n      if (timeoutRef.current) {\n        clearTimeout(timeoutRef.current);\n      }\n    };\n  }, []);\n\n  const handleClick = React.useCallback(() => {\n    onClick?.();\n    if (type === \"copy\") {\n      setShowCheck(true);\n      if (timeoutRef.current) {\n        clearTimeout(timeoutRef.current);\n      }\n      timeoutRef.current = setTimeout(() => setShowCheck(false), 1500);\n    }\n  }, [onClick, type]);\n\n  const actionConfig = React.useMemo(() => {\n    const configs: Record<\n      ActionType,\n      { icon: React.ReactNode; label: string }\n    > = {\n      run: { icon: <Play className=\"size-4\" />, label: \"Run\" },\n      copy: {\n        icon: showCheck ? (\n          <Check className=\"size-4 text-green-500\" />\n        ) : (\n          <Copy className=\"size-4\" />\n        ),\n        label: showCheck ? \"Copied!\" : \"Copy\",\n      },\n      regenerate: {\n        icon: <RefreshCw className=\"size-4\" />,\n        label: \"Regenerate\",\n      },\n      download: { icon: <Download className=\"size-4\" />, label: \"Download\" },\n      share: { icon: <Share2 className=\"size-4\" />, label: \"Share\" },\n    };\n    return configs[type];\n  }, [type, showCheck]);\n\n  return (\n    <button\n      type=\"button\"\n      data-slot=\"ai-artifact-action\"\n      data-action={type}\n      onClick={handleClick}\n      disabled={disabled}\n      title={actionConfig.label}\n      className={cn(\n        \"shrink-0 rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\",\n        className,\n      )}\n    >\n      {actionConfig.icon}\n      <span className=\"sr-only\">{actionConfig.label}</span>\n    </button>\n  );\n}\n\ninterface AiArtifactContentProps {\n  children?: React.ReactNode;\n  className?: string;\n}\n\nfunction AiArtifactContent({ children, className }: AiArtifactContentProps) {\n  return (\n    <div\n      data-slot=\"ai-artifact-content\"\n      className={cn(\"flex-1 overflow-auto\", className)}\n    >\n      {children}\n    </div>\n  );\n}\n\ninterface AiArtifactCodeProps {\n  code: string;\n  language?: string;\n  className?: string;\n}\n\nfunction AiArtifactCode({ code, language, className }: AiArtifactCodeProps) {\n  return (\n    <div data-slot=\"ai-artifact-code\" className={cn(\"relative\", className)}>\n      {language && (\n        <div className=\"absolute top-2 right-2 rounded bg-muted px-2 py-0.5 text-xs text-muted-foreground\">\n          {language}\n        </div>\n      )}\n      <pre className=\"p-4 overflow-x-auto text-sm font-mono bg-muted/30\">\n        <code>{code}</code>\n      </pre>\n    </div>\n  );\n}\n\ninterface AiArtifactPreviewProps {\n  children?: React.ReactNode;\n  className?: string;\n}\n\nfunction AiArtifactPreview({ children, className }: AiArtifactPreviewProps) {\n  return (\n    <div\n      data-slot=\"ai-artifact-preview\"\n      className={cn(\"p-4 bg-background\", className)}\n    >\n      {children}\n    </div>\n  );\n}\n\nexport {\n  AiArtifact,\n  AiArtifactHeader,\n  AiArtifactTitle,\n  AiArtifactDescription,\n  AiArtifactActions,\n  AiArtifactAction,\n  AiArtifactClose,\n  AiArtifactContent,\n  AiArtifactCode,\n  AiArtifactPreview,\n};\nexport type { AiArtifactProps, ActionType };\n",
      "type": "registry:component"
    }
  ],
  "docs": "TODO: Add documentation",
  "categories": [
    "ai"
  ],
  "type": "registry:ui"
}