{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "ai-conversation",
  "title": "AI: Conversation",
  "description": "A scroll container that sticks to the bottom while streaming, with a scroll-to-bottom control.",
  "dependencies": [
    "@untitledui/icons@^0.0.22",
    "use-stick-to-bottom@^1.1.6"
  ],
  "registryDependencies": [
    "@nx-ui/utils",
    "@nx-ui/button"
  ],
  "files": [
    {
      "path": "components/ai/conversation.tsx",
      "content": "\"use client\"\n\nimport type { ComponentProps } from \"react\"\nimport { useCallback } from \"react\"\nimport { ArrowDown } from \"@untitledui/icons\"\nimport { StickToBottom, useStickToBottomContext } from \"use-stick-to-bottom\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { cn } from \"@/lib/utils\"\n\nexport type ConversationProps = ComponentProps<typeof StickToBottom>\n\nexport const Conversation = ({ className, ...props }: ConversationProps) => (\n  <StickToBottom\n    className={cn(\"relative flex-1 overflow-y-hidden\", className)}\n    initial=\"smooth\"\n    resize=\"smooth\"\n    role=\"log\"\n    {...props}\n  />\n)\n\nexport type ConversationContentProps = ComponentProps<\n  typeof StickToBottom.Content\n>\n\nexport const ConversationContent = ({\n  className,\n  ...props\n}: ConversationContentProps) => (\n  <StickToBottom.Content\n    className={cn(\"flex flex-col gap-8 p-4\", className)}\n    {...props}\n  />\n)\n\nexport type ConversationEmptyStateProps = ComponentProps<\"div\"> & {\n  title?: string\n  description?: string\n  icon?: React.ReactNode\n}\n\nexport const ConversationEmptyState = ({\n  className,\n  title = \"No messages yet\",\n  description = \"Start a conversation to see messages here\",\n  icon,\n  children,\n  ...props\n}: ConversationEmptyStateProps) => (\n  <div\n    className={cn(\n      \"flex size-full flex-col items-center justify-center gap-3 p-8 text-center\",\n      className\n    )}\n    {...props}\n  >\n    {children ?? (\n      <>\n        {icon && <div className=\"text-muted-foreground\">{icon}</div>}\n        <div className=\"space-y-1\">\n          <h3 className=\"font-medium text-sm\">{title}</h3>\n          {description && (\n            <p className=\"text-muted-foreground text-sm\">{description}</p>\n          )}\n        </div>\n      </>\n    )}\n  </div>\n)\n\nexport type ConversationScrollButtonProps = ComponentProps<typeof Button>\n\nexport const ConversationScrollButton = ({\n  className,\n  ...props\n}: ConversationScrollButtonProps) => {\n  const { isAtBottom, scrollToBottom } = useStickToBottomContext()\n\n  const handleScrollToBottom = useCallback(() => {\n    scrollToBottom()\n  }, [scrollToBottom])\n\n  return (\n    !isAtBottom && (\n      <Button\n        className={cn(\n          \"absolute bottom-4 left-[50%] translate-x-[-50%] rounded-full\",\n          className\n        )}\n        onClick={handleScrollToBottom}\n        size=\"icon\"\n        type=\"button\"\n        variant=\"outline\"\n        {...props}\n      >\n        <ArrowDown className=\"size-4\" />\n      </Button>\n    )\n  )\n}\n",
      "type": "registry:ui",
      "target": "components/ai/conversation.tsx"
    }
  ],
  "type": "registry:ui"
}