Skip to content
txbrendan/ui

Changelog

beta

A list of product releases for a changelog page, newest first: each with its date and version, a title, a short summary, an optional cover, and its changes marked New, Improved, Fixed, or Removed.

Built from Badge, Button, Glide Highlight, Panel Switch, and Tabs.

Preview

  1. Version 3.11

    Shared views

    Save a filtered view of any list and share it with your team. Everyone sees the same columns and order.

    • NewSave any filter as a view, and pin it to the sidebar.
    • NewShare a view with a link. People without access see a request page.
    • ImprovedColumn widths stay put when you switch views.
    • FixedSorting by date no longer puts empty dates first.
  2. Version 3.10

    Faster search

    Search now answers as you type, across every workspace you belong to.

    • ImprovedResults show as you type.
    • NewSearch across every workspace from one box.
    • FixedSearching for a word with an accent finds it without the accent too.
  3. Version 3.9

    API keys per project

    Make a key that only reaches one project, and see when each key was last used.

    • NewKeys that reach only one project.
    • ImprovedEach key shows when it was last used.
    • RemovedKeys with no project. Move them to a project by December 1.

one release, no cover

  1. Version 1.0

    The first release

    Lists, comments, and sharing, on the web and on phones.

    • NewLists you can share with a link.
    • NewComments on every item.

long title and words

  1. Version 0.9.12-beta.3

    Permissions for shared workspaces, guests, and outside reviewers across every project

    Give each person exactly the access they need, from a single page, and see who can reach what at a glance.

    • ImprovedFile names like annual-planning-notes-for-every-team-and-every-office-final.pdf now wrap instead of running out of the row.
    • FixedA guest who leaves a workspace loses access to its files at once, instead of at the next sign in.

no version: an id of your own, for #spring-update

  1. Spring update

    • ImprovedPages load faster on slow networks.
    • FixedPrinting a list keeps its columns.

narrow container: the date sits above each release

  1. Version 0.8

    Phone app

    Everything from the web, on iPhone and Android.

    • NewApps for iPhone and Android.
  2. Version 0.7

    Offline lists

    • NewLists open with no network, and sync when you are back.
    • FixedEdits made offline no longer show twice.

no releases yet

No releases yet.

Install

  1. 1. Add the registry to components.json, once per app. Without it, the shadcn CLI looks up @txbrendan in a public list that txbrendan/ui does not control.

    npx shadcn@latest registry add "@txbrendan=https://txbrendan.dev/r/{name}.json"
  2. 2. Add the theme, once per app. It replaces your color tokens with ones checked for contrast.

    npx shadcn@latest add @txbrendan/theme
  3. 3. Add the website component. It also adds every component it uses. Its own files go in your components folder, and they are yours to edit.

    npx shadcn@latest add @txbrendan/changelog

Use it for

  • The body of a changelog page, under a Headline as the page's h1. Each release title is an h2.
  • Pass `releases` newest first. Write each `date` as an ISO date, like "2026-10-28". It shows in words, like "October 28, 2026", the same on the server and in every browser.
  • Give a release a `version`, like "2.4", and it gets the id "2-4", so a link to /changelog#2-4 lands on it. With no version, pass an `id` of your own. Keep every id unique on the page.
  • A link to a release that is hidden, past the limit or out of the filter, still lands: the list shows it at once, then scrolls to it.
  • Mark each change with a `type`: "new" is green, "removed" is red, and "improved" and "fixed" stay gray, so the news stands out.
  • Set `limit` for a long list. It shows that many, then a Show older releases button that shows the rest in place and moves focus to the first one it showed.
  • Set `filter` to add tabs for each type of change in your releases. A tab shows only the releases with that type, and only those changes.
  • Pass a `cover` for a release worth a picture, like a drawing from our illustrations or a screenshot. It fills a 16:9 frame.
  • The dates stick below a floating navbar as you read, and a link scrolls each release to the same place. Both read `--changelog-offset`, 6rem by default. Set it in `className`, like `[--changelog-offset:1rem]`, when nothing floats over the page.

Avoid it for

  • An in-app feed of who did what, or the day's running order. Use Timeline, which keeps each item to one line on a rail.
  • Live updates or alerts inside an app. Use a Toast or an Alert.
  • Every commit or ticket. Group them into releases people can read, a few changes each.
  • Long change lines. Keep each to one sentence, and put the detail in the summary or a page of its own.

Props

  • releases

    The releases, newest first. date is an ISO date. version also gives the release its id, "2.4" as "2-4", unless you pass id. cover fills a 16:9 frame. Each change has a type and its words. With none, it says there are no releases yet.

    { date: string; version?: string; id?: string; title: ReactNode; summary?: ReactNode; cover?: ReactNode; changes?: { type: "new" | "improved" | "fixed" | "removed"; text: ReactNode }[] }[] · default []

  • limit

    Shows this many first, then a Show older releases button that shows the rest. With none, every release shows.

    number

  • filter

    Adds tabs over the list, All and one per type of change your releases have. It needs two types or more.

    boolean · default false

  • locale

    The language the dates are written in, like "en-GB" or "de-DE".

    string · default "en-US"

  • className

    Extra classes on the root, which holds the container query. The date column sits beside each release from 48rem of its own width, and above it when narrower. Set --changelog-offset here.

    string

  • ChangelogRelease

    Type. One release.

    { date: string; version?: string; id?: string; title: ReactNode; summary?: ReactNode; cover?: ReactNode; changes?: ChangelogChange[] }

  • ChangelogChange

    Type. One change in a release.

    { type: "new" | "improved" | "fixed" | "removed"; text: ReactNode }

Accessibility

  • The releases are an ordered list, newest first. Each is an article named by its title, an h2, so put the list under the page's h1.
  • Each date is a <time> with the ISO date in dateTime.
  • Each change's type is written on its badge, so it never rests on color alone.
  • The tabs are named "Type of change". Arrow keys move between them. When the list changes, screen readers hear how many releases are left.
  • Show older releases is a real button. Once pressed, it goes away and focus moves to the first release it showed, which sits where the button was.
  • The hover fill is for the pointer only. Nothing in a release takes focus by itself.
  • Reduced motion keeps the fades and drops the slides and the height glide.
  • In forced colors each cover keeps a border, since its fill is painted away.

Examples

Releases with versions, covers, and changes

<Changelog
  releases={[
    {
      date: "2026-10-28",
      version: "2.4",
      title: "Shared views",
      summary: "Save a filtered view of any list and share it with your team.",
      cover: <ThemeLayers />,
      changes: [
        { type: "new", text: "Save any filter as a view." },
        { type: "improved", text: "Column widths stay put when you switch views." },
        { type: "fixed", text: "Sorting by date no longer puts empty dates first." },
      ],
    },
    {
      date: "2026-10-14",
      version: "2.3",
      title: "Faster search",
      changes: [{ type: "improved", text: "Results show as you type." }],
    },
  ]}
/>

A long list that starts short, with tabs for each type of change

<Changelog releases={releases} limit={5} filter />

A changelog page under a floating navbar

<Navbar floating {...navbar} />
<main className="mx-auto flex max-w-7xl flex-col gap-16 px-4 pt-12">
  <Headline as="h1" align="start" title="Changelog" description="New features, improvements, and fixes." />
  <Changelog releases={releases} limit={5} filter />
</main>

Dates in British English, with nothing floating over the page

<Changelog releases={releases} locale="en-GB" className="[--changelog-offset:1rem]" />