{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "ai-chat-interface-shadcnui",
  "type": "registry:component",
  "title": "AI Chat Interface",
  "description": "Chat input with attachments, model selector, and accessible controls",
  "registryDependencies": [
    "button"
  ],
  "dependencies": [
    "framer-motion",
    "react"
  ],
  "files": [
    {
      "path": "@uitripled/react-shadcn/src/components/components/chat/ai-chat-interface.tsx",
      "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Textarea } from \"@/components/ui/textarea\";\nimport { AnimatePresence, motion, useReducedMotion } from \"framer-motion\";\nimport {\n  ArrowUpRight,\n  ChevronDown,\n  Clock,\n  Link2,\n  Mail,\n  MessageSquare,\n  Share2,\n  Sparkles,\n  Star,\n  Zap,\n} from \"lucide-react\";\nimport { useEffect, useRef, useState } from \"react\";\n\ntype DropdownType = \"share\" | \"quick\" | \"history\" | \"magic\" | \"model\" | null;\n\ntype ActionOption = {\n  icon: typeof Link2;\n  label: string;\n  action: string;\n};\n\nconst shareOptions: ActionOption[] = [\n  { icon: Link2, label: \"Copy link\", action: \"copy-link\" },\n  { icon: Mail, label: \"Email\", action: \"email\" },\n  { icon: MessageSquare, label: \"Slack\", action: \"slack\" },\n];\n\nconst quickOptions: ActionOption[] = [\n  { icon: Sparkles, label: \"Summarize\", action: \"summarize\" },\n  { icon: Sparkles, label: \"Improve\", action: \"improve\" },\n  { icon: Sparkles, label: \"Translate\", action: \"translate\" },\n];\n\nconst historyOptions: ActionOption[] = [\n  { icon: Clock, label: \"Last hour\", action: \"history-1h\" },\n  { icon: Clock, label: \"Today\", action: \"history-today\" },\n  { icon: Clock, label: \"This week\", action: \"history-week\" },\n];\n\nconst magicOptions: ActionOption[] = [\n  { icon: Sparkles, label: \"Auto-complete\", action: \"magic-complete\" },\n  { icon: Sparkles, label: \"Storyboard\", action: \"magic-storyboard\" },\n  { icon: Sparkles, label: \"Rephrase\", action: \"magic-rephrase\" },\n];\n\nconst models = [\"GPT 5.0\", \"GPT 4.5 Turbo\", \"GPT 4.0\", \"Claude 3.5 Sonnet\"];\n\nexport function AIChatInterface() {\n  const [inputValue, setInputValue] = useState(\"\");\n  const [isFocused, setIsFocused] = useState(false);\n  const [activeDropdown, setActiveDropdown] = useState<DropdownType>(null);\n  const [selectedModel, setSelectedModel] = useState(models[0]);\n  const prefersReducedMotion = useReducedMotion();\n  const textareaRef = useRef<HTMLTextAreaElement>(null);\n  const dropdownRef = useRef<HTMLDivElement>(null);\n\n  const shouldAnimate = !prefersReducedMotion;\n\n  useEffect(() => {\n    function handleClickOutside(event: MouseEvent) {\n      if (\n        dropdownRef.current &&\n        !dropdownRef.current.contains(event.target as Node)\n      ) {\n        setActiveDropdown(null);\n      }\n    }\n\n    document.addEventListener(\"mousedown\", handleClickOutside);\n    return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n  }, []);\n\n  const handleTextareaChange = (\n    event: React.ChangeEvent<HTMLTextAreaElement>\n  ) => {\n    setInputValue(event.target.value);\n\n    if (textareaRef.current) {\n      textareaRef.current.style.height = \"auto\";\n      textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;\n    }\n  };\n\n  const renderDropdown = (\n    type: DropdownType,\n    options: ActionOption[],\n    align: \"left\" | \"right\" = \"left\"\n  ) => (\n    <AnimatePresence>\n      {activeDropdown === type && (\n        <motion.div\n          key={type}\n          initial={{ opacity: 0, y: -8 }}\n          animate={{ opacity: 1, y: 0 }}\n          exit={{ opacity: 0, y: -8 }}\n          transition={{ duration: 0.18, ease: \"easeOut\" }}\n          className={`absolute ${align === \"right\" ? \"right-0\" : \"left-0\"} mt-3 w-56 rounded-2xl border border-border/40 bg-background/85 py-2 shadow-[0_24px_60px_rgba(15,23,42,0.24)] backdrop-blur-xl`}\n          role=\"menu\"\n        >\n          {options.map((option) => (\n            <Button\n              key={option.action}\n              onClick={() => {\n                console.log(`Action: ${option.action}`);\n                setActiveDropdown(null);\n              }}\n              className=\"flex w-full justify-start items-center gap-3 px-4 py-2 text-sm text-foreground/85 transition-all hover:bg-foreground/[0.05] hover:text-foreground\"\n              role=\"menuitem\"\n              type=\"button\"\n              variant=\"ghost\"\n            >\n              <option.icon size={16} className=\"text-foreground/60\" />\n              <span>{option.label}</span>\n            </Button>\n          ))}\n        </motion.div>\n      )}\n    </AnimatePresence>\n  );\n\n  return (\n    <motion.section\n      initial={shouldAnimate ? { opacity: 0, y: 20 } : { opacity: 1, y: 0 }}\n      animate={{ opacity: 1, y: 0 }}\n      transition={shouldAnimate ? { duration: 0.5 } : { duration: 0 }}\n      className=\"relative w-full\"\n    >\n      <div className=\"space-y-8\">\n        <div\n          className={`relative rounded-[28px] border border-border/50 bg-background/70 px-6 py-6 backdrop-blur-xl transition w-full z-10 ${\n            isFocused ? \"shadow-[0_28px_80px_rgba(15,23,42,0.24)]\" : \"\"\n          }`}\n        >\n          <div className=\"pointer-events-none absolute inset-0 bg-gradient-to-br from-primary/20/20 via-transparent to-transparent\" />\n          <div className=\"relative space-y-5\">\n            <div className=\"flex flex-col gap-1 text-left\">\n              <span className=\"text-xs font-semibold uppercase tracking-[0.32em] text-foreground/45\">\n                Prompt\n              </span>\n              <p className=\"text-sm text-foreground/60\">\n                Share goals, context, tone, and desired output.\n              </p>\n            </div>\n            <label htmlFor=\"chat-input\" className=\"sr-only\">\n              Ask AI anything\n            </label>\n            <Textarea\n              id=\"chat-input\"\n              ref={textareaRef}\n              value={inputValue}\n              onChange={handleTextareaChange}\n              placeholder=\"Ask AI anything...\"\n              className=\"w-full resize-none bg-transparent text-base text-foreground/90 placeholder:text-foreground/40 focus:outline-none\"\n              onFocus={() => setIsFocused(true)}\n              onBlur={() => setIsFocused(false)}\n              rows={1}\n              aria-label=\"Chat input\"\n            />\n\n            <div\n              className=\"flex flex-wrap items-center gap-2 border-t border-border/25 pt-3\"\n              ref={dropdownRef}\n            >\n              <div className=\"relative\">\n                <Button\n                  onClick={() =>\n                    setActiveDropdown(\n                      activeDropdown === \"share\" ? null : \"share\"\n                    )\n                  }\n                  className=\"group rounded-xl p-2 bg-background/80 transition-all hover:bg-foreground/[0.05] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/40\"\n                  aria-label=\"Share options\"\n                  aria-expanded={activeDropdown === \"share\"}\n                  aria-haspopup=\"menu\"\n                  type=\"button\"\n                >\n                  <Share2\n                    size={18}\n                    className=\"text-foreground/50 group-hover:text-foreground\"\n                    strokeWidth={2}\n                  />\n                </Button>\n                {renderDropdown(\"share\", shareOptions)}\n              </div>\n\n              <div className=\"relative\">\n                <Button\n                  onClick={() =>\n                    setActiveDropdown(\n                      activeDropdown === \"quick\" ? null : \"quick\"\n                    )\n                  }\n                  className=\"group rounded-xl p-2 bg-background/80 transition-all hover:bg-foreground/[0.05] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/40\"\n                  aria-label=\"Quick actions\"\n                  aria-expanded={activeDropdown === \"quick\"}\n                  aria-haspopup=\"menu\"\n                  type=\"button\"\n                >\n                  <Zap\n                    size={18}\n                    className=\"text-foreground/50 group-hover:text-foreground\"\n                    strokeWidth={2}\n                  />\n                </Button>\n                {renderDropdown(\"quick\", quickOptions)}\n              </div>\n\n              <div className=\"relative\">\n                <Button\n                  onClick={() =>\n                    setActiveDropdown(\n                      activeDropdown === \"history\" ? null : \"history\"\n                    )\n                  }\n                  className=\"group rounded-xl p-2 bg-background/80 transition-all hover:bg-foreground/[0.05] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/40\"\n                  aria-label=\"History\"\n                  aria-expanded={activeDropdown === \"history\"}\n                  aria-haspopup=\"menu\"\n                  type=\"button\"\n                >\n                  <Clock\n                    size={18}\n                    className=\"text-foreground/50 group-hover:text-foreground\"\n                    strokeWidth={2}\n                  />\n                </Button>\n                {renderDropdown(\"history\", historyOptions)}\n              </div>\n\n              <div className=\"relative\">\n                <Button\n                  onClick={() =>\n                    setActiveDropdown(\n                      activeDropdown === \"magic\" ? null : \"magic\"\n                    )\n                  }\n                  className=\"group rounded-xl p-2 bg-background/80 transition-all hover:bg-foreground/[0.05] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/40\"\n                  aria-label=\"Magic options\"\n                  aria-expanded={activeDropdown === \"magic\"}\n                  aria-haspopup=\"menu\"\n                  type=\"button\"\n                >\n                  <Sparkles\n                    size={18}\n                    className=\"text-foreground/50 group-hover:text-foreground\"\n                    strokeWidth={2}\n                  />\n                </Button>\n                {renderDropdown(\"magic\", magicOptions)}\n              </div>\n\n              <div className=\"relative ml-auto\">\n                <Button\n                  onClick={() =>\n                    setActiveDropdown(\n                      activeDropdown === \"model\" ? null : \"model\"\n                    )\n                  }\n                  className=\"flex items-center gap-2 rounded-xl border border-border/30 bg-background/80 px-3 py-1.5 text-sm font-medium text-foreground/80 transition hover:border-border/40 hover:bg-background/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/40\"\n                  aria-label=\"Select AI model\"\n                  aria-expanded={activeDropdown === \"model\"}\n                  aria-haspopup=\"listbox\"\n                  type=\"button\"\n                >\n                  <span>{selectedModel}</span>\n                  <ChevronDown size={16} className=\"text-foreground/50\" />\n                </Button>\n\n                <AnimatePresence>\n                  {activeDropdown === \"model\" && (\n                    <motion.div\n                      key=\"model-dropdown\"\n                      initial={{ opacity: 0, y: -8 }}\n                      animate={{ opacity: 1, y: 0 }}\n                      exit={{ opacity: 0, y: -8 }}\n                      transition={{ duration: 0.18, ease: \"easeOut\" }}\n                      className=\"absolute right-0 mt-3 w-56 rounded-2xl border border-border/40 bg-background/85 py-2 shadow-[0_24px_60px_rgba(15,23,42,0.24)] backdrop-blur-xl z-50\"\n                      role=\"listbox\"\n                    >\n                      {models.map((model) => (\n                        <Button\n                          key={model}\n                          onClick={() => {\n                            setSelectedModel(model);\n                            setActiveDropdown(null);\n                          }}\n                          className={`flex w-full items-center justify-between px-4 py-2 text-sm transition-all ${\n                            selectedModel === model\n                              ? \"bg-primary/15 font-medium text-primary hover:bg-primary/20\"\n                              : \"text-foreground/80 hover:bg-foreground/[0.05]\"\n                          }`}\n                          role=\"option\"\n                          aria-selected={selectedModel === model}\n                          type=\"button\"\n                          variant={\n                            selectedModel === model ? \"default\" : \"ghost\"\n                          }\n                        >\n                          {model}\n                          {selectedModel === model && (\n                            <Star size={14} className=\"text-primary/80\" />\n                          )}\n                        </Button>\n                      ))}\n                    </motion.div>\n                  )}\n                </AnimatePresence>\n              </div>\n\n              <Button\n                type=\"button\"\n                size=\"lg\"\n                className=\"inline-flex items-center gap-2 rounded-full px-5 text-xs uppercase tracking-[0.28em]\"\n                onClick={() => console.log(\"Action: send-message\")}\n              >\n                Send\n                <ArrowUpRight className=\"h-4 w-4\" />\n              </Button>\n            </div>\n          </div>\n        </div>\n      </div>\n    </motion.section>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/uitripled/ai-chat-interface-shadcnui.tsx"
    }
  ]
}