{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "terminal",
  "title": "Terminal",
  "description": "Terminal-style display for command output.",
  "dependencies": [
    "@vllnt/ui@^0.3.0"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/terminal/terminal.tsx",
      "content": "\"use client\";\n\nimport { Check, Copy, Terminal as TerminalIcon } from \"lucide-react\";\n\nimport { Button } from \"@vllnt/ui\";\nimport { useCopyToClipboard } 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\nfunction getCommandContents(lines: TerminalLine[]): string[] {\n  return lines.reduce<string[]>((commands, line) => {\n    if (line.type === \"command\") {\n      commands.push(line.content);\n    }\n    return commands;\n  }, []);\n}\n\nexport function Terminal({\n  copyable = true,\n  lines,\n  title = \"Terminal\",\n}: TerminalProps) {\n  const { copied, copy } = useCopyToClipboard();\n\n  const commands = getCommandContents(lines);\n\n  const handleCopy = () => {\n    void copy(commands.join(\"\\n\"));\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            aria-label={copied ? \"Copied\" : \"Copy commands\"}\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, copy } = useCopyToClipboard();\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 = getCommandContents(lines);\n\n  const handleCopy = () => {\n    void copy(commands.join(\"\\n\"));\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            aria-label={copied ? \"Copied\" : \"Copy commands\"}\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"
    }
  ],
  "type": "registry:component",
  "version": "0.3.0",
  "stability": "stable"
}
