{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "ai-message-bubble",
  "title": "AI Message Bubble",
  "description": "Chat bubble for assistant, user, tool, and system messages using the current design system surfaces.",
  "dependencies": [
    "@vllnt/ui@^0.3.0",
    "class-variance-authority"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/ai-message-bubble/ai-message-bubble.tsx",
      "content": "import { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@vllnt/ui\";\nimport { Avatar, AvatarFallback } from \"@vllnt/ui\";\nimport { Badge } from \"@vllnt/ui\";\n\nconst bubbleVariants = cva(\n  \"rounded-2xl border px-4 py-3 shadow-sm transition-colors\",\n  {\n    defaultVariants: {\n      messageRole: \"assistant\",\n    },\n    variants: {\n      messageRole: {\n        assistant: \"border-border bg-card text-card-foreground\",\n        system: \"border-border/80 bg-muted/60 text-foreground\",\n        tool: \"border-border bg-muted/40 text-foreground\",\n        user: \"border-primary/20 bg-primary/10 text-foreground\",\n      },\n    },\n  },\n);\n\nfunction AIMessageMeta({\n  author,\n  isUser,\n  status,\n  timestamp,\n}: {\n  author?: string;\n  isUser: boolean;\n  status?: string;\n  timestamp?: string;\n}) {\n  return (\n    <div\n      className={cn(\n        \"flex flex-wrap items-center gap-2 text-xs text-muted-foreground\",\n        isUser ? \"justify-end\" : \"justify-start\",\n      )}\n    >\n      {author ? (\n        <span className=\"font-medium text-foreground\">{author}</span>\n      ) : null}\n      {timestamp ? <span>{timestamp}</span> : null}\n      {status ? (\n        <Badge\n          className=\"rounded-full px-2 py-0 text-[10px]\"\n          variant=\"secondary\"\n        >\n          {status}\n        </Badge>\n      ) : null}\n    </div>\n  );\n}\n\nexport type AIMessageBubbleProps = React.ComponentPropsWithoutRef<\"div\"> &\n  VariantProps<typeof bubbleVariants> & {\n    /** Optional short label describing the speaker. */\n    author?: string;\n    /** Bubble body content. */\n    children: React.ReactNode;\n    /** Optional status badge for the message. */\n    status?: string;\n    /** Optional timestamp or relative time label. */\n    timestamp?: string;\n  };\n\nconst AIMessageBubble = ({\n  author,\n  children,\n  className,\n  messageRole = \"assistant\",\n  ref,\n  status,\n  timestamp,\n  ...props\n}: AIMessageBubbleProps & { ref?: React.Ref<HTMLDivElement> }) => {\n  const resolvedMessageRole = messageRole ?? \"assistant\";\n  const isUser = resolvedMessageRole === \"user\";\n  const fallbackLabel = (author ?? resolvedMessageRole).charAt(0).toUpperCase();\n\n  return (\n    <div\n      className={cn(\"flex w-full\", isUser ? \"justify-end\" : \"justify-start\")}\n    >\n      <div\n        className={cn(\n          \"flex w-full max-w-3xl gap-3\",\n          isUser ? \"flex-row-reverse text-right\" : \"flex-row\",\n        )}\n      >\n        <Avatar className=\"mt-0.5 size-8 border border-border/70\">\n          <AvatarFallback className=\"bg-muted text-[11px] font-medium uppercase text-muted-foreground\">\n            {fallbackLabel}\n          </AvatarFallback>\n        </Avatar>\n\n        <div\n          className={cn(\n            \"min-w-0 space-y-2\",\n            isUser ? \"items-end\" : \"items-start\",\n          )}\n        >\n          <AIMessageMeta\n            author={author}\n            isUser={isUser}\n            status={status}\n            timestamp={timestamp}\n          />\n\n          <div\n            className={cn(\n              bubbleVariants({ messageRole: resolvedMessageRole }),\n              className,\n            )}\n            ref={ref}\n            {...props}\n          >\n            <div className=\"text-sm leading-6 whitespace-pre-wrap\">\n              {children}\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n};\n\nAIMessageBubble.displayName = \"AIMessageBubble\";\n\nexport { AIMessageBubble };\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component",
  "version": "0.3.0",
  "stability": "stable"
}
