{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "terminal",
  "type": "registry:component",
  "title": "Terminal",
  "description": "Terminal-style display for command output.",
  "dependencies": [
    "@vllnt/ui@^0.2.1"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/terminal/terminal.tsx",
      "content": "\"use client\";\n\nimport { useState } from \"react\";\n\nimport { Check, Copy, Terminal as TerminalIcon } from \"lucide-react\";\n\nimport { Button } from \"@vllnt/ui\";\n\nexport type TerminalLine = {\n  content: string;\n  type: \"command\" | \"comment\" | \"output\";\n};\n\nexport type TerminalProps = {\n  copyable?: boolean;\n  lines: TerminalLine[];\n  title?: string;\n};\n\nexport function Terminal({\n  copyable = true,\n  lines,\n  title = \"Terminal\",\n}: TerminalProps) {\n  const [copied, setCopied] = useState(false);\n\n  const commands = lines\n    .filter((l) => l.type === \"command\")\n    .map((l) => l.content);\n\n  const handleCopy = async () => {\n    await navigator.clipboard.writeText(commands.join(\"\\n\"));\n    setCopied(true);\n    setTimeout(() => {\n      setCopied(false);\n    }, 2000);\n  };\n\n  return (\n    <div className=\"my-6 rounded-lg border bg-zinc-950 dark:bg-zinc-900 overflow-hidden\">\n      <div className=\"flex items-center justify-between px-4 py-2 bg-zinc-900 dark:bg-zinc-800 border-b border-zinc-800\">\n        <div className=\"flex items-center gap-2\">\n          <TerminalIcon className=\"size-4 text-zinc-400\" />\n          <span className=\"text-sm font-medium text-zinc-300\">{title}</span>\n        </div>\n        <div className=\"flex items-center gap-1.5\">\n          <div className=\"size-3 rounded-full bg-red-500\" />\n          <div className=\"size-3 rounded-full bg-yellow-500\" />\n          <div className=\"size-3 rounded-full bg-green-500\" />\n        </div>\n      </div>\n      <div className=\"relative\">\n        <div className=\"p-4 font-mono text-sm space-y-1 overflow-x-auto\">\n          {lines.map((line) => (\n            <div\n              className=\"flex items-start\"\n              key={`${line.type}-${line.content}`}\n            >\n              {line.type === \"command\" && (\n                <>\n                  <span className=\"text-green-400 mr-2 select-none\">$</span>\n                  <span className=\"text-zinc-100\">{line.content}</span>\n                </>\n              )}\n              {line.type === \"output\" && (\n                <span className=\"text-zinc-400\">{line.content}</span>\n              )}\n              {line.type === \"comment\" && (\n                <span className=\"text-zinc-600 italic\"># {line.content}</span>\n              )}\n            </div>\n          ))}\n        </div>\n        {copyable && commands.length > 0 ? (\n          <Button\n            className=\"absolute top-2 right-2 size-8 bg-zinc-800 hover:bg-zinc-700 text-zinc-300\"\n            onClick={handleCopy}\n            size=\"icon\"\n            variant=\"ghost\"\n          >\n            {copied ? (\n              <Check className=\"size-3\" />\n            ) : (\n              <Copy className=\"size-3\" />\n            )}\n          </Button>\n        ) : null}\n      </div>\n    </div>\n  );\n}\n\nexport type SimpleTerminalProps = {\n  children: string;\n  title?: string;\n};\n\nexport function SimpleTerminal({\n  children,\n  title = \"Terminal\",\n}: SimpleTerminalProps) {\n  const [copied, setCopied] = useState(false);\n\n  const lines = children\n    .trim()\n    .split(\"\\n\")\n    .map((line): TerminalLine => {\n      if (line.startsWith(\"$ \")) {\n        return { content: line.slice(2), type: \"command\" };\n      }\n      if (line.startsWith(\"# \")) {\n        return { content: line.slice(2), type: \"comment\" };\n      }\n      return { content: line, type: \"output\" };\n    });\n\n  const commands = lines\n    .filter((l) => l.type === \"command\")\n    .map((l) => l.content);\n\n  const handleCopy = async () => {\n    await navigator.clipboard.writeText(commands.join(\"\\n\"));\n    setCopied(true);\n    setTimeout(() => {\n      setCopied(false);\n    }, 2000);\n  };\n\n  return (\n    <div className=\"my-6 rounded-lg border bg-zinc-950 dark:bg-zinc-900 overflow-hidden\">\n      <div className=\"flex items-center justify-between px-4 py-2 bg-zinc-900 dark:bg-zinc-800 border-b border-zinc-800\">\n        <div className=\"flex items-center gap-2\">\n          <TerminalIcon className=\"size-4 text-zinc-400\" />\n          <span className=\"text-sm font-medium text-zinc-300\">{title}</span>\n        </div>\n        <div className=\"flex items-center gap-1.5\">\n          <div className=\"size-3 rounded-full bg-red-500\" />\n          <div className=\"size-3 rounded-full bg-yellow-500\" />\n          <div className=\"size-3 rounded-full bg-green-500\" />\n        </div>\n      </div>\n      <div className=\"relative\">\n        <div className=\"p-4 font-mono text-sm space-y-1 overflow-x-auto\">\n          {lines.map((line) => (\n            <div\n              className=\"flex items-start\"\n              key={`${line.type}-${line.content}`}\n            >\n              {line.type === \"command\" && (\n                <>\n                  <span className=\"text-green-400 mr-2 select-none\">$</span>\n                  <span className=\"text-zinc-100\">{line.content}</span>\n                </>\n              )}\n              {line.type === \"output\" && (\n                <span className=\"text-zinc-400\">{line.content}</span>\n              )}\n              {line.type === \"comment\" && (\n                <span className=\"text-zinc-600 italic\"># {line.content}</span>\n              )}\n            </div>\n          ))}\n        </div>\n        {commands.length > 0 && (\n          <Button\n            className=\"absolute top-2 right-2 size-8 bg-zinc-800 hover:bg-zinc-700 text-zinc-300\"\n            onClick={handleCopy}\n            size=\"icon\"\n            variant=\"ghost\"\n          >\n            {copied ? (\n              <Check className=\"size-3\" />\n            ) : (\n              <Copy className=\"size-3\" />\n            )}\n          </Button>\n        )}\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "version": "0.2.1",
  "stability": "stable"
}
