{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "reasoning",
  "title": "Reasoning",
  "description": "The model's thinking, folded away. Open while it thinks, closed when the answer starts.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/manniche/reasoning/reasoning.tsx",
      "content": "import { Brain, ChevronRight } from 'lucide-react'\nimport { useEffect, useId, useRef, useState, type ReactNode } from 'react'\nimport { cn } from '@/lib/utils'\n\nexport type ReasoningProps = {\n  /** The model's reasoning so far. Plain text or your own markup. */\n  children: ReactNode\n  /** True while the model is still thinking. */\n  streaming?: boolean\n  /** How long the thinking took, in milliseconds. Shown once it is done. */\n  ms?: number\n  /** Start open. By default it is open while streaming and closes when done. */\n  defaultOpen?: boolean\n  className?: string\n}\n\nfunction seconds(ms: number) {\n  const s = Math.max(1, Math.round(ms / 1000))\n  return s === 1 ? '1 second' : `${s} seconds`\n}\n\n/**\n * The model's thinking, folded away by default. It opens while the model thinks and closes when the answer starts,\n * unless the reader has opened or closed it themselves; then their choice stands.\n */\nexport function Reasoning({ children, streaming = false, ms, defaultOpen, className }: ReasoningProps) {\n  const [open, setOpen] = useState(defaultOpen ?? streaming)\n  const touched = useRef(false)\n  const id = useId()\n\n  useEffect(() => {\n    if (!touched.current) setOpen(streaming)\n  }, [streaming])\n\n  const label = streaming ? 'Thinking' : ms !== undefined ? `Thought for ${seconds(ms)}` : 'Reasoning'\n\n  return (\n    <div className={cn('text-sm', className)}>\n      <button\n        type=\"button\"\n        aria-expanded={open}\n        aria-controls={id}\n        onClick={() => {\n          touched.current = true\n          setOpen((o) => !o)\n        }}\n        className=\"-ml-2 inline-flex min-h-11 items-center gap-2 rounded-xl px-2 text-muted-foreground transition-colors duration-150 hover:text-foreground\"\n      >\n        <Brain className={cn('size-4', streaming && 'animate-pulse motion-reduce:animate-none')} aria-hidden />\n        <span>{label}</span>\n        <ChevronRight className={cn('size-4 transition-transform duration-150 ease-out-quint', open && 'rotate-90')} aria-hidden />\n      </button>\n      <div\n        id={id}\n        hidden={!open}\n        className=\"mt-1 border-l-2 pl-4 leading-6 whitespace-pre-wrap text-muted-foreground animate-[manniche-reasoning_200ms_cubic-bezier(0.23,1,0.32,1)] motion-reduce:animate-none\"\n      >\n        <style href=\"manniche-reasoning\" precedence=\"default\">\n          {'@keyframes manniche-reasoning { from { opacity: 0; transform: translateY(-4px) } }'}\n        </style>\n        {children}\n      </div>\n    </div>\n  )\n}\n",
      "type": "registry:component"
    }
  ],
  "categories": [
    "agent"
  ],
  "type": "registry:component"
}