{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "github-repo-card",
  "title": "GitHub Repo Card",
  "description": "A card component displaying GitHub repository information including name, description, stars, forks, and primary language.",
  "dependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/blocks/github/github-repo-card/components/elements/github-repo-card.tsx",
      "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\ninterface GitHubRepoCardProps extends React.HTMLAttributes<HTMLAnchorElement> {\n  owner: string;\n  repo: string;\n  staticData?: {\n    name: string;\n    description: string | null;\n    stargazers_count: number;\n    forks_count: number;\n    language: string | null;\n  };\n}\n\nfunction formatNumber(num: number): string {\n  if (num >= 1000000) {\n    return `${(num / 1000000).toFixed(1)}M`;\n  }\n  if (num >= 1000) {\n    return `${(num / 1000).toFixed(1)}K`;\n  }\n  return num.toString();\n}\n\nconst LANGUAGE_COLORS: Record<string, string> = {\n  TypeScript: \"#3178c6\",\n  JavaScript: \"#f1e05a\",\n  Python: \"#3572A5\",\n  Rust: \"#dea584\",\n  Go: \"#00ADD8\",\n  Java: \"#b07219\",\n  \"C++\": \"#f34b7d\",\n  C: \"#555555\",\n  Ruby: \"#701516\",\n  PHP: \"#4F5D95\",\n  Swift: \"#F05138\",\n  Kotlin: \"#A97BFF\",\n  Dart: \"#00B4AB\",\n  Vue: \"#41b883\",\n  CSS: \"#563d7c\",\n  HTML: \"#e34c26\",\n  Shell: \"#89e051\",\n  Scala: \"#c22d40\",\n  Elixir: \"#6e4a7e\",\n  Haskell: \"#5e5086\",\n  Lua: \"#000080\",\n  R: \"#198CE7\",\n  Julia: \"#a270ba\",\n  Clojure: \"#db5855\",\n  Zig: \"#ec915c\",\n};\n\nfunction StarIcon({ className }: { className?: string }) {\n  return (\n    <svg\n      className={className}\n      viewBox=\"0 0 16 16\"\n      fill=\"currentColor\"\n      aria-hidden=\"true\"\n    >\n      <path d=\"M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.75.75 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z\" />\n    </svg>\n  );\n}\n\nfunction ForkIcon({ className }: { className?: string }) {\n  return (\n    <svg\n      className={className}\n      viewBox=\"0 0 16 16\"\n      fill=\"currentColor\"\n      aria-hidden=\"true\"\n    >\n      <path d=\"M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z\" />\n    </svg>\n  );\n}\n\nfunction RepoIcon({ className }: { className?: string }) {\n  return (\n    <svg\n      className={className}\n      viewBox=\"0 0 16 16\"\n      fill=\"currentColor\"\n      aria-hidden=\"true\"\n    >\n      <path d=\"M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z\" />\n    </svg>\n  );\n}\n\nexport function GitHubRepoCard({\n  owner,\n  repo,\n  staticData,\n  className,\n  ...props\n}: GitHubRepoCardProps) {\n  const [data, setData] = useState(staticData || null);\n  const [loading, setLoading] = useState(!staticData);\n  const [error, setError] = useState<string | null>(null);\n\n  useEffect(() => {\n    if (staticData) return;\n\n    async function fetchData() {\n      try {\n        setLoading(true);\n        setError(null);\n\n        const response = await fetch(\n          `https://api.github.com/repos/${owner}/${repo}`\n        );\n\n        if (!response.ok) {\n          throw new Error(\"Failed to fetch repository\");\n        }\n\n        const repoData = await response.json();\n        setData({\n          name: repoData.name,\n          description: repoData.description,\n          stargazers_count: repoData.stargazers_count,\n          forks_count: repoData.forks_count,\n          language: repoData.language,\n        });\n      } catch (err) {\n        setError(err instanceof Error ? err.message : \"Unknown error\");\n      } finally {\n        setLoading(false);\n      }\n    }\n\n    fetchData();\n  }, [owner, repo, staticData]);\n\n  if (loading) {\n    return (\n      <div\n        data-slot=\"github-repo-card\"\n        className={cn(\n          \"flex flex-col gap-3 p-4 border border-border rounded-lg bg-card\",\n          className\n        )}\n      >\n        <div className=\"flex items-center gap-2\">\n          <div className=\"w-4 h-4 bg-muted rounded animate-pulse\" />\n          <div className=\"h-5 w-32 bg-muted rounded animate-pulse\" />\n        </div>\n        <div className=\"h-4 w-full bg-muted rounded animate-pulse\" />\n        <div className=\"flex items-center gap-4\">\n          <div className=\"h-4 w-16 bg-muted rounded animate-pulse\" />\n          <div className=\"h-4 w-12 bg-muted rounded animate-pulse\" />\n          <div className=\"h-4 w-12 bg-muted rounded animate-pulse\" />\n        </div>\n      </div>\n    );\n  }\n\n  if (error || !data) {\n    return (\n      <div\n        data-slot=\"github-repo-card\"\n        className={cn(\n          \"flex flex-col gap-3 p-4 border border-destructive/50 rounded-lg bg-destructive/10\",\n          className\n        )}\n      >\n        <p className=\"text-sm text-destructive\">{error || \"No data\"}</p>\n      </div>\n    );\n  }\n\n  const languageColor = data.language\n    ? LANGUAGE_COLORS[data.language] || \"#8b8b8b\"\n    : null;\n\n  return (\n    <a\n      data-slot=\"github-repo-card\"\n      href={`https://github.com/${owner}/${repo}`}\n      target=\"_blank\"\n      rel=\"noopener noreferrer\"\n      className={cn(\n        \"flex flex-col gap-3 p-4 border border-border rounded-lg bg-card\",\n        \"transition-colors hover:border-foreground/20 hover:bg-accent/50\",\n        className\n      )}\n      {...props}\n    >\n      <div className=\"flex items-center gap-2\">\n        <RepoIcon className=\"w-4 h-4 text-muted-foreground\" />\n        <span className=\"font-semibold text-sm text-foreground truncate\">\n          {owner}/{data.name}\n        </span>\n      </div>\n\n      {data.description && (\n        <p className=\"text-sm text-muted-foreground line-clamp-2\">\n          {data.description}\n        </p>\n      )}\n\n      <div className=\"flex items-center gap-4 text-xs text-muted-foreground\">\n        {languageColor && (\n          <span className=\"flex items-center gap-1.5\">\n            <span\n              className=\"w-3 h-3 rounded-full\"\n              style={{ backgroundColor: languageColor }}\n            />\n            {data.language}\n          </span>\n        )}\n\n        <span className=\"flex items-center gap-1\">\n          <StarIcon className=\"w-4 h-4\" />\n          {formatNumber(data.stargazers_count)}\n        </span>\n\n        <span className=\"flex items-center gap-1\">\n          <ForkIcon className=\"w-4 h-4\" />\n          {formatNumber(data.forks_count)}\n        </span>\n      </div>\n    </a>\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "docs": "Fetches repository data from GitHub API. Pass owner and repo props to display any public repository. Supports static data for SSR/demos.",
  "categories": [
    "github"
  ],
  "type": "registry:block"
}