{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "api-endpoint",
  "type": "registry:ui",
  "title": "ApiEndpoint",
  "description": "Machined HTTP/gRPC API specification block with method pill, copyable paths, parameters, and response tabs.",
  "registryDependencies": [
    "https://ui.arpitbhayani.me/r/aui.json"
  ],
  "files": [
    {
      "path": "ui/api-endpoint.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface ApiParam {\n  name: string;\n  type: string;\n  required?: boolean;\n  description: string;\n}\n\nexport interface ApiResponseTab {\n  status: number | string;\n  label?: string;\n  body: string;\n}\n\nexport interface ApiEndpointProps extends React.HTMLAttributes<HTMLDivElement> {\n  method: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\" | string;\n  path: string;\n  description?: string;\n  badge?: React.ReactNode;\n  curl?: string;\n  params?: ApiParam[];\n  responses?: ApiResponseTab[];\n}\n\nexport function ApiEndpoint({\n  method,\n  path,\n  description,\n  badge,\n  curl,\n  params,\n  responses,\n  className,\n  children,\n  ...props\n}: ApiEndpointProps) {\n  const [copiedPath, setCopiedPath] = React.useState(false);\n  const [copiedCurl, setCopiedCurl] = React.useState(false);\n  const [activeTab, setActiveTab] = React.useState(0);\n\n  const methodUpper = method.toUpperCase();\n  const getMethodStyle = () => {\n    switch (methodUpper) {\n      case \"GET\":\n        return \"bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border-emerald-500/20\";\n      case \"POST\":\n        return \"bg-blue-500/10 text-blue-600 dark:text-blue-400 border-blue-500/20\";\n      case \"PUT\":\n        return \"bg-amber-500/10 text-amber-600 dark:text-amber-400 border-amber-500/20\";\n      case \"PATCH\":\n        return \"bg-purple-500/10 text-purple-600 dark:text-purple-400 border-purple-500/20\";\n      case \"DELETE\":\n        return \"bg-rose-500/10 text-rose-600 dark:text-rose-400 border-rose-500/20\";\n      default:\n        return \"bg-muted text-muted-foreground border-border\";\n    }\n  };\n\n  const handleCopyPath = () => {\n    navigator.clipboard.writeText(path);\n    setCopiedPath(true);\n    setTimeout(() => setCopiedPath(false), 1600);\n  };\n\n  const handleCopyCurl = () => {\n    const curlCmd = curl || `curl -X ${methodUpper} \"https://api.example.com${path}\"`;\n    navigator.clipboard.writeText(curlCmd);\n    setCopiedCurl(true);\n    setTimeout(() => setCopiedCurl(false), 1600);\n  };\n\n  return (\n    <div\n      className={cn(\n        \"rounded-lg border border-border bg-card text-card-foreground overflow-hidden my-4 shadow-xs\",\n        className\n      )}\n      {...props}\n    >\n      <div className=\"flex flex-wrap items-center justify-between gap-3 px-4 py-3 bg-muted/30 border-b border-border\">\n        <div className=\"flex items-center gap-2.5 flex-wrap min-w-0\">\n          <span\n            className={cn(\n              \"font-mono text-[11px] font-medium tracking-wider px-2 py-0.5 rounded border uppercase\",\n              getMethodStyle()\n            )}\n          >\n            {methodUpper}\n          </span>\n          <span className=\"font-mono text-sm font-medium text-foreground break-all\">\n            {path}\n          </span>\n          {badge && <span>{badge}</span>}\n        </div>\n        <div className=\"flex items-center gap-1.5\">\n          <button\n            type=\"button\"\n            onClick={handleCopyPath}\n            className=\"inline-flex items-center gap-1.5 px-2 py-1 rounded border border-border bg-card hover:bg-muted font-mono text-xs text-muted-foreground hover:text-foreground transition-colors cursor-pointer\"\n          >\n            {copiedPath ? (\n              <span className=\"text-emerald-500 font-semibold\">Copied</span>\n            ) : (\n              <span>Path</span>\n            )}\n          </button>\n          <button\n            type=\"button\"\n            onClick={handleCopyCurl}\n            className=\"inline-flex items-center gap-1.5 px-2 py-1 rounded border border-border bg-card hover:bg-muted font-mono text-xs text-muted-foreground hover:text-foreground transition-colors cursor-pointer\"\n          >\n            {copiedCurl ? (\n              <span className=\"text-emerald-500 font-semibold\">Copied</span>\n            ) : (\n              <span>cURL</span>\n            )}\n          </button>\n        </div>\n      </div>\n\n      <div className=\"p-4 space-y-4\">\n        {description && (\n          <p className=\"text-sm text-muted-foreground leading-relaxed\">\n            {description}\n          </p>\n        )}\n\n        {params && params.length > 0 && (\n          <div>\n            <div className=\"font-mono text-xs uppercase tracking-wider font-medium text-muted-foreground mb-2\">\n              Parameters\n            </div>\n            <div className=\"rounded border border-border overflow-x-auto\">\n              <table className=\"w-full text-left text-xs border-collapse\">\n                <thead className=\"bg-muted/40 font-mono text-muted-foreground uppercase border-b border-border\">\n                  <tr>\n                    <th className=\"px-3 py-2\">Option</th>\n                    <th className=\"px-3 py-2\">Type</th>\n                    <th className=\"px-3 py-2\">Status</th>\n                    <th className=\"px-3 py-2\">Description</th>\n                  </tr>\n                </thead>\n                <tbody className=\"divide-y divide-border\">\n                  {params.map((p, idx) => (\n                    <tr key={idx} className=\"hover:bg-muted/30\">\n                      <td className=\"px-3 py-2 font-mono font-medium text-foreground\">\n                        {p.name}\n                      </td>\n                      <td className=\"px-3 py-2 font-mono text-muted-foreground\">\n                        {p.type}\n                      </td>\n                      <td className=\"px-3 py-2\">\n                        {p.required ? (\n                          <span className=\"font-mono text-[10px] uppercase font-medium text-primary bg-primary/10 px-1.5 py-0.5 rounded\">\n                            req\n                          </span>\n                        ) : (\n                          <span className=\"font-mono text-[10px] text-muted-foreground bg-muted px-1.5 py-0.5 rounded\">\n                            opt\n                          </span>\n                        )}\n                      </td>\n                      <td className=\"px-3 py-2 text-muted-foreground\">\n                        {p.description}\n                      </td>\n                    </tr>\n                  ))}\n                </tbody>\n              </table>\n            </div>\n          </div>\n        )}\n\n        {responses && responses.length > 0 && (\n          <div>\n            <div className=\"font-mono text-xs uppercase tracking-wider font-medium text-muted-foreground mb-2\">\n              Responses\n            </div>\n            <div className=\"flex border-b border-border gap-1 mb-2\">\n              {responses.map((res, i) => (\n                <button\n                  key={i}\n                  type=\"button\"\n                  onClick={() => setActiveTab(i)}\n                  className={cn(\n                    \"px-3 py-1 font-mono text-xs border-b-2 font-medium cursor-pointer transition-colors\",\n                    activeTab === i\n                      ? \"border-primary text-foreground font-semibold\"\n                      : \"border-transparent text-muted-foreground hover:text-foreground\"\n                  )}\n                >\n                  {res.status} {res.label ? `· ${res.label}` : \"\"}\n                </button>\n              ))}\n            </div>\n            <pre className=\"p-3 bg-muted/50 rounded border border-border font-mono text-xs text-foreground overflow-x-auto\">\n              <code>{responses[activeTab]?.body}</code>\n            </pre>\n          </div>\n        )}\n\n        {children}\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:ui"
    }
  ]
}