{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "changelog-2",
  "title": "Tabbed Change Filter",
  "description": "Changelog with tabs filtering release entries by All, Added, Improved, or Fixed, each showing version, date, badge, title, and description.",
  "dependencies": [
    "@base-ui/react"
  ],
  "registryDependencies": [
    "badge",
    "separator",
    "tabs"
  ],
  "files": [
    {
      "path": "registry/blocks/changelog/2/changelog-block.tsx",
      "content": "import { Badge } from \"@/components/ui/badge\"\nimport { Separator } from \"@/components/ui/separator\"\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"@/components/ui/tabs\"\n\ntype ChangeType = \"Added\" | \"Improved\" | \"Fixed\"\n\ntype Entry = {\n  version: string\n  date: string\n  type: ChangeType\n  title: string\n  description: string\n}\n\nconst entries: Entry[] = [\n  {\n    version: \"2.4.0\",\n    date: \"Jun 18, 2026\",\n    type: \"Added\",\n    title: \"Global command palette\",\n    description:\n      \"Press Command K anywhere to jump to projects, members, or files.\",\n  },\n  {\n    version: \"2.4.0\",\n    date: \"Jun 18, 2026\",\n    type: \"Improved\",\n    title: \"Faster billing page\",\n    description:\n      \"Large workspaces now load the billing view about twice as fast.\",\n  },\n  {\n    version: \"2.3.2\",\n    date: \"Jun 06, 2026\",\n    type: \"Fixed\",\n    title: \"Workspace rename sync\",\n    description: \"Resolved a rare error when renaming a busy workspace.\",\n  },\n  {\n    version: \"2.3.0\",\n    date: \"May 30, 2026\",\n    type: \"Added\",\n    title: \"Role-based access\",\n    description: \"Invite teammates as Admin, Editor, or Viewer.\",\n  },\n  {\n    version: \"2.3.0\",\n    date: \"May 30, 2026\",\n    type: \"Improved\",\n    title: \"Keyboard navigation\",\n    description: \"Dialogs and menus are now fully keyboard accessible.\",\n  },\n  {\n    version: \"2.2.1\",\n    date: \"May 12, 2026\",\n    type: \"Fixed\",\n    title: \"Sidebar layout shift\",\n    description: \"Toggling the sidebar no longer nudges page content.\",\n  },\n]\n\nconst typeVariant: Record<ChangeType, \"default\" | \"secondary\" | \"outline\"> = {\n  Added: \"default\",\n  Improved: \"secondary\",\n  Fixed: \"outline\",\n}\n\nconst tabs: { value: string; label: string; match?: ChangeType }[] = [\n  { value: \"all\", label: \"All\" },\n  { value: \"added\", label: \"Added\", match: \"Added\" },\n  { value: \"improved\", label: \"Improved\", match: \"Improved\" },\n  { value: \"fixed\", label: \"Fixed\", match: \"Fixed\" },\n]\n\nfunction EntryRow({ entry }: { entry: Entry }) {\n  return (\n    <div className=\"flex flex-col gap-2 sm:flex-row sm:items-start sm:gap-5\">\n      <div className=\"flex shrink-0 items-center gap-2.5 sm:w-32 sm:flex-col sm:items-start sm:gap-1\">\n        <span className=\"font-mono text-xs font-semibold tabular-nums\">\n          {entry.version}\n        </span>\n        <span className=\"text-xs text-muted-foreground tabular-nums\">\n          {entry.date}\n        </span>\n      </div>\n      <div className=\"flex flex-1 flex-col gap-1.5\">\n        <div className=\"flex items-center gap-2.5\">\n          <Badge variant={typeVariant[entry.type]}>{entry.type}</Badge>\n          <h3 className=\"font-heading text-sm font-semibold\">{entry.title}</h3>\n        </div>\n        <p className=\"text-sm/relaxed text-muted-foreground\">\n          {entry.description}\n        </p>\n      </div>\n    </div>\n  )\n}\n\nexport default function ChangelogBlock() {\n  return (\n    <section className=\"flex w-full items-center justify-center bg-muted/30 px-6 py-16 text-foreground\">\n      <div className=\"mx-auto w-full max-w-2xl\">\n        <div className=\"mb-8\">\n          <h2 className=\"font-heading text-2xl font-bold tracking-tight\">\n            Changelog\n          </h2>\n          <p className=\"mt-2 text-sm text-muted-foreground\">\n            Everything we have shipped, filterable by type.\n          </p>\n        </div>\n\n        <Tabs defaultValue=\"all\" className=\"gap-6\">\n          <TabsList>\n            {tabs.map((tab) => (\n              <TabsTrigger key={tab.value} value={tab.value}>\n                {tab.label}\n              </TabsTrigger>\n            ))}\n          </TabsList>\n\n          {tabs.map((tab) => {\n            const list = tab.match\n              ? entries.filter((e) => e.type === tab.match)\n              : entries\n            return (\n              <TabsContent key={tab.value} value={tab.value}>\n                <div className=\"flex flex-col\">\n                  {list.map((entry, i) => (\n                    <div key={`${entry.version}-${entry.title}`}>\n                      {i > 0 && <Separator className=\"my-5\" />}\n                      <EntryRow entry={entry} />\n                    </div>\n                  ))}\n                </div>\n              </TabsContent>\n            )\n          })}\n        </Tabs>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/blocks/changelog-2.tsx"
    }
  ],
  "meta": {
    "height": "782px",
    "tier": "free"
  },
  "categories": [
    "changelog"
  ],
  "type": "registry:block"
}