Version history

Pro

Live, draft and past versions of something editable (an agent's settings, a knowledge page), newest first, with who changed it and why. Publish a draft, or restore a past version as a new draft — history is never rewritten.

Markdown

Preview

Install

With the Candor CLI

First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/version-history

Brings in: badge, button, know, locale, relative-time, utils · npm: lucide-react@^1.67.0

Usage

TSX · The example above
"use client"

import * as React from "react"
import type { Version } from "@/lib/know"
import { VersionHistory } from "@/components/version-history"

const ago = (d: number) => new Date(Date.now() - d * 86_400_000).toISOString()

const initial: Version[] = [
  { id: "v5", label: "Version 5", state: "draft", at: ago(0), by: "You", note: "Dev agent may apply migrations on Staging without asking." },
  { id: "v4", label: "Version 4", state: "live", at: ago(3), by: "Priya", note: "Dev agent asks before applying migrations." },
  { id: "v3", label: "Version 3", state: "past", at: ago(12), by: "Maya", note: "Moved the Dev agent to a faster model." },
]

export default function Example() {
  const [versions, setVersions] = React.useState(initial)
  return (
    <VersionHistory
      className="max-w-xl"
      versions={versions}
      onPublish={(id) => setVersions((vs) => vs.map((v) => (v.id === id ? { ...v, state: "live", at: new Date().toISOString() } : v.state === "live" ? { ...v, state: "past" } : v)))}
      onRestore={(id) => {
        const from = versions.find((v) => v.id === id)!
        setVersions((vs) => {
          const n = Math.max(...vs.map((v) => Number(v.id.slice(1)))) + 1
          return [{ id: `v${n}`, label: `Version ${n}`, state: "draft", at: new Date().toISOString(), by: "You", note: `Restored from ${from.label}.` }, ...vs.filter((v) => v.state !== "draft")]
        })
      }}
    />
  )
}

<VersionHistory>

PropTypeDefaultDescription
versionsrequiredVersion[]—Every version: live, draft or past, with who changed it, when and why.
activeIdstring | undefined—The version being viewed, highlighted.
onSelect((id: string) => void) | undefined—Makes each version's name a button; called with its id.
onPublish((id: string) => void) | undefined—Shows Publish on the draft; called with its id.
onRestore((id: string) => void) | undefined—Shows Restore on past versions; called with the version's id to copy into a new draft.
classNamestring | undefined—Extra classes for the outer element.

Strings

The fixed words, in English by default. Change any of them under versionHistory in <LocaleProvider strings={{ … }}>; the table is exported as versionHistoryStrings.

KeyEnglish
versionsVersions
liveLive
draftDraft
publishPublish
restoreRestore as draft