93 / Blocks
Timeline
Things that happened, in the order they happened, with the state of each one said aloud rather than left in a coloured dot.
Pull request opened
09:14FinishedTwelve files changed.Checks passed
09:21FinishedWaiting on review
09:22Happening nowTwo reviewers asked.Merge
Not started
"use client"
import { Timeline } from "mischief-ui/timeline"
const entries = [
{
id: "opened",
title: "Pull request opened",
time: "09:14",
description: "Twelve files changed.",
tone: "done" as const,
},
{
id: "checks",
title: "Checks passed",
time: "09:21",
tone: "done" as const,
},
{
id: "review",
title: "Waiting on review",
time: "09:22",
description: "Two reviewers asked.",
tone: "active" as const,
},
{ id: "merge", title: "Merge", tone: "todo" as const },
]
export function TimelineDemo() {
return (
<div className="w-full max-w-md">
<Timeline entries={entries} label="Pull request history" />
</div>
)
}Installation
Copy the source into your project, or keep it behind a package.
npx shadcn@latest add Tinkerers-Labs/mischief-ui/timelineimport { Timeline } from "mischief-ui/timeline"Or paste it in yourself. The source imports the shared cn helper from @/lib/utils, so point that at your own copy.
"use client" import * as React from "react"import { cn } from "@/lib/utils" export type TimelineTone = "done" | "active" | "todo" | "problem" export type TimelineEntry = { id: string title: string time?: string description?: React.ReactNode tone?: TimelineTone}Usage
export function History({ events }) {
return <Timeline entries={events} label="Pull request history" />
}The dot is not the only thing carrying it
Each tone is drawn as a colour and also written out after the title: finished, happening now, not started, or went wrong. The colour is the quick version for anyone who can see it and the words are the actual record.
Time is taken already formatted rather than as a date, because how a time should be written depends on the locale, the timezone, and whether it is worth showing a year -- none of which a timeline component can work out on your behalf.
API
entriesTimelineEntry[]The events, oldest first.labelstringNames the list. Defaults to "Timeline".TimelineEntry
idstringIdentifies the entry.titlestringWhat happened.timestringWhen, already formatted.descriptionReactNodeAnything further.tone"done" | "active" | "todo" | "problem"Its state. Defaults to "done".Accessibility
A named ordered list, so the sequence is conveyed as a sequence rather than as a column of text. Each entry's state is announced after its title, and the dots and connecting line are hidden. Nothing animates.