{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "timeline",
  "title": "Timeline",
  "description": "Things that happened, in the order they happened, with each state said aloud.",
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/default/timeline/timeline.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"@/lib/utils\"\n\nexport type TimelineTone = \"done\" | \"active\" | \"todo\" | \"problem\"\n\nexport type TimelineEntry = {\n  id: string\n  title: string\n  time?: string\n  description?: React.ReactNode\n  tone?: TimelineTone\n}\n\nexport type TimelineProps = Omit<\n  React.HTMLAttributes<HTMLOListElement>,\n  \"children\"\n> & {\n  entries: readonly TimelineEntry[]\n  label?: string\n}\n\nconst DOT: Record<TimelineTone, string> = {\n  done: \"bg-foreground border-transparent\",\n  active: \"bg-primary border-transparent\",\n  todo: \"bg-background border-border\",\n  problem: \"bg-destructive border-transparent\",\n}\n\nconst SAID: Record<TimelineTone, string> = {\n  done: \"Finished\",\n  active: \"Happening now\",\n  todo: \"Not started\",\n  problem: \"Went wrong\",\n}\n\n/**\n * Things that happened, in the order they happened. The state of each entry is\n * said as well as coloured, so the line is not the only thing carrying it.\n */\nexport function Timeline({\n  entries,\n  label = \"Timeline\",\n  className,\n  ...rootProps\n}: TimelineProps) {\n  return (\n    <ol\n      data-slot=\"timeline\"\n      aria-label={label}\n      className={cn(\"relative grid\", className)}\n      {...rootProps}\n    >\n      {entries.map((entry, index) => {\n        const tone = entry.tone ?? \"done\"\n        const last = index === entries.length - 1\n\n        return (\n          <li\n            key={entry.id}\n            data-slot=\"timeline-entry\"\n            data-tone={tone}\n            className=\"relative grid grid-cols-[auto_1fr] gap-x-3 pb-6 last:pb-0\"\n          >\n            <div className=\"flex flex-col items-center\">\n              <span\n                aria-hidden=\"true\"\n                className={cn(\"mt-1 size-3 rounded-full border-2\", DOT[tone])}\n              />\n              {!last && (\n                <span\n                  aria-hidden=\"true\"\n                  className=\"bg-border mt-1 w-px flex-1\"\n                />\n              )}\n            </div>\n\n            <div className=\"min-w-0\">\n              <div className=\"flex flex-wrap items-baseline gap-x-2\">\n                <p className=\"text-sm font-semibold\">{entry.title}</p>\n                {entry.time && (\n                  <span className=\"text-muted-foreground text-xs\">\n                    {entry.time}\n                  </span>\n                )}\n                <span className=\"sr-only\">{SAID[tone]}</span>\n              </div>\n\n              {entry.description && (\n                <div className=\"text-muted-foreground mt-1 text-sm\">\n                  {entry.description}\n                </div>\n              )}\n            </div>\n          </li>\n        )\n      })}\n    </ol>\n  )\n}\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "timeline",
    "history",
    "layout",
    "status"
  ],
  "type": "registry:ui"
}