registry/blocks/changelog-list.tsx
import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";
const releases = [
{
version: "2.4",
date: "2026-06-28",
title: "Edge functions everywhere",
items: [
"Functions now deploy to all 30 regions by default",
"Cold starts cut by 92% on the new runtime",
"Streaming responses out of beta",
],
},
{
version: "2.3",
date: "2026-06-02",
title: "Postgres branching",
items: [
"Copy-on-write database branches for every preview",
"One-click promote and rollback",
],
},
{
version: "2.2",
date: "2026-05-11",
title: "Quality of life",
items: [
"Audit log export (CSV and API)",
"Deploy comments notify the right people, finally",
"Dark mode for email notifications",
],
},
];
export default function ChangelogList() {
return (
<section className="bg-background">
<div className="mx-auto w-full max-w-3xl px-6 py-20 sm:py-24">
<div className="mb-12">
<h2 className="text-2xl font-semibold tracking-tight text-balance sm:text-3xl">
What's new
</h2>
<p className="mt-2 text-muted-foreground">
Every release, in order. No "minor fixes and improvements".
</p>
</div>
{releases.map((release, index) => (
<article key={release.version} className="relative flex gap-6 pb-12 last:pb-0">
{index < releases.length - 1 && (
<span
aria-hidden
className="absolute top-8 left-3.25 h-full w-px bg-border"
/>
)}
<span
aria-hidden
className={cn(
"mt-1.5 size-6.75 shrink-0 rounded-full border-8 border-background ring-1 ring-border",
index === 0 ? "bg-foreground" : "bg-muted-foreground/40",
)}
/>
<div className="min-w-0">
<div className="flex flex-wrap items-center gap-3">
<h3 className="text-lg font-semibold tracking-tight">
{release.title}
</h3>
<Badge variant="outline" className="font-mono text-xs">
v{release.version}
</Badge>
<time className="font-mono text-xs text-muted-foreground tabular-nums">
{release.date}
</time>
</div>
<ul className="mt-3 space-y-1.5">
{release.items.map((item) => (
<li key={item} className="flex gap-2.5 text-sm text-muted-foreground">
<span
aria-hidden
className="mt-2 size-1 shrink-0 rounded-full bg-muted-foreground/50"
/>
{item}
</li>
))}
</ul>
</div>
</article>
))}
</div>
</section>
);
}