Feed

Changelog

Release changelog on a timeline: each entry opens with a mono version and date, a Latest badge on the newest, a summary line, and New, Improved or Fixed badges against each change.

Free, MIT licenseOpen in Browse
import {
  Timeline,
  TimelineContent,
  TimelineDescription,
  TimelineIndicator,
  TimelineItem,
  TimelineLabel,
  TimelineTitle,
} from "@/components/editorial/timeline"
import { Badge } from "@/components/ui/badge"

// The copy: change text here, not in the markup.
const COPY = {
  title: "Changelog",
  body: "Every release, newest first.",
  latest: "Latest",
  kinds: { new: "New", improved: "Improved", fixed: "Fixed" },
} as const

type Kind = keyof typeof COPY.kinds

const RELEASES: {
  version: string
  date: string
  summary: string
  changes: { kind: Kind; text: string }[]
}[] = [
  {
    version: "2.4.0",
    date: "24 October 2026",
    summary: "Charts in both modes and a comparison table for pricing.",
    changes: [
      {
        kind: "new",
        text: "pricing-table-01, the plan comparison table as its own block.",
      },
      {
        kind: "improved",
        text: "Every chart block sets axis ink, so labels show on recharts 3.8.",
      },
      {
        kind: "fixed",
        text: "docs-nav-01 seam back on the left at every width.",
      },
    ],
  },
  {
    version: "2.3.2",
    date: "17 October 2026",
    summary: "Demos at realistic sizes.",
    changes: [
      {
        kind: "improved",
        text: "Loaders at 48 with ground around them; nimbus at 80.",
      },
      {
        kind: "fixed",
        text: "Eclipse void covers the paper rim in dark mode.",
      },
    ],
  },
  {
    version: "2.3.1",
    date: "10 October 2026",
    summary: "Milestones ships.",
    changes: [
      { kind: "new", text: "Four milestones blocks, two of them free." },
      { kind: "fixed", text: "cta-02 headline holds one line to 390." },
    ],
  },
]

const KIND_VARIANT: Record<Kind, "default" | "secondary" | "outline"> = {
  new: "default",
  improved: "secondary",
  fixed: "outline",
}

// A version heads each entry; the body line leads, so --timeline-lh is 1.5rem.
export default function Changelog() {
  return (
    <section className="mx-auto w-full max-w-2xl">
      <header className="mb-8">
        <h2 className="text-xl font-semibold tracking-tight">{COPY.title}</h2>
        <p className="mt-1 text-sm text-muted-foreground">{COPY.body}</p>
      </header>
      <Timeline className="[--timeline-lh:1.5rem]">
        {RELEASES.map((r, i) => (
          <TimelineItem key={r.version}>
            <TimelineIndicator />
            <TimelineContent className="pb-10">
              <div className="flex flex-wrap items-baseline gap-x-3 gap-y-1">
                <TimelineTitle className="font-mono text-base leading-6">
                  v{r.version}
                </TimelineTitle>
                <TimelineLabel className="text-sm/6">{r.date}</TimelineLabel>
                {i === 0 && <Badge variant="secondary">{COPY.latest}</Badge>}
              </div>
              <TimelineDescription className="text-base text-foreground">
                {r.summary}
              </TimelineDescription>
              <ul className="mt-4 space-y-2">
                {r.changes.map((c) => (
                  <li key={c.text} className="flex items-start gap-3 text-sm">
                    <Badge
                      variant={KIND_VARIANT[c.kind]}
                      className="mt-px w-20 shrink-0 justify-center"
                    >
                      {COPY.kinds[c.kind]}
                    </Badge>
                    <span className="text-muted-foreground">{c.text}</span>
                  </li>
                ))}
              </ul>
            </TimelineContent>
          </TimelineItem>
        ))}
      </Timeline>
    </section>
  )
}

Installation

pnpm dlx shadcn add @01orbital/changelog
npx shadcn add @01orbital/changelog
yarn shadcn add @01orbital/changelog
bunx --bun shadcn add @01orbital/changelog

Free under the MIT license. Add the @01orbital registry to components.json once (install guide), then run the command.

It lands at components/blocks/feed/changelog/index.tsx, as source you own and edit.

Usage

import Changelog from "@/components/blocks/feed/changelog"

export default function Example() {
  return <Changelog />
}

Dependencies

Registry pieces it installs with it: