Skip to content
Dethink Components

ComponentsTimeline

Timeline

Show events in order with statuses and optional selection.

On this page

Use this component from the local workspace package. Follow the setup guide first. A public npm package and registry are not available yet.

View registry files

Import the component into your page or component file.

Usage
import {
  Timeline,
  type TimelineItemData,
} from "@dethink/components";

Try the examples, then open the code to use them in your app. Focus the track and use the arrow keys to move between items.

Events

Dated milestones with complete, current, and upcoming statuses.

  1. Status: Complete

    Research complete

    User needs and interaction model approved.

  2. Status: Current

    Private beta

    First teams using the component in dashboards.

  3. Status: Upcoming

    General availability

    Registry item, docs, and release notes ship.

Show sourceexamples/timeline/basic.tsx
examples/timeline/basic.tsx
"use client";

import { Timeline, type TimelineItemData } from "@dethink/components";

const milestones: TimelineItemData[] = [
  {
    id: "research",
    title: "Research complete",
    description: "User needs and interaction model approved.",
    datetime: "2026-01-12T09:00:00Z",
    dateLabel: "Jan 12",
    status: "complete",
  },
  {
    id: "beta",
    title: "Private beta",
    description: "First teams using the component in dashboards.",
    datetime: "2026-03-18T10:00:00Z",
    dateLabel: "Mar 18",
    status: "current",
  },
  {
    id: "ga",
    title: "General availability",
    description: "Registry item, docs, and release notes ship.",
    datetime: "2026-05-05T10:00:00Z",
    dateLabel: "May 5",
    status: "upcoming",
  },
];

export function TimelineBasic() {
  return <Timeline aria-label="Release milestones" items={milestones} />;
}

Progress

progress mode drops the dates for an evenly spaced step sequence — pipelines, wizards, order tracking.

  1. Status: Complete

    Queued

    Waiting for a build slot.

  2. Status: Current

    Building

    Compiling and running checks.

  3. Status: Upcoming

    Deploying

    Rolling out to the edge.

  4. Status: Upcoming

    Live

    Serving production traffic.

Show sourceexamples/timeline/progress.tsx
examples/timeline/progress.tsx
"use client";

import { Timeline, type TimelineItemData } from "@dethink/components";

const steps: TimelineItemData[] = [
  {
    id: "queued",
    title: "Queued",
    description: "Waiting for a build slot.",
    status: "complete",
  },
  {
    id: "building",
    title: "Building",
    description: "Compiling and running checks.",
    status: "current",
  },
  {
    id: "deploying",
    title: "Deploying",
    description: "Rolling out to the edge.",
    status: "upcoming",
  },
  {
    id: "live",
    title: "Live",
    description: "Serving production traffic.",
    status: "upcoming",
  },
];

export function TimelineProgress() {
  return (
    <Timeline
      aria-label="Deployment progress"
      mode="progress"
      scale="auto"
      layout="stacked"
      items={steps}
      defaultSelectedId="building"
    />
  );
}

Flow presentation with reveal

presentation="flow" swaps the pan/zoom viewport for a static document-flow list, and reveal="stagger" with the in-view trigger animates the items in one by one as they scroll into view. Reduced-motion users see everything immediately.

  1. Status: Complete

    Project kickoff

    Scope agreed and delivery squad assembled.

  2. Status: Complete

    Design review

    Flows approved with two accessibility follow-ups.

  3. Status: Current

    Build sprint

    Core screens implemented behind a feature flag.

  4. Status: Upcoming

    Launch

    Flag removed and rollout announced.

Show sourceexamples/timeline/flow-reveal.tsx
examples/timeline/flow-reveal.tsx
"use client";

import { Timeline, type TimelineItemData } from "@dethink/components";

const milestones: TimelineItemData[] = [
  {
    id: "kickoff",
    title: "Project kickoff",
    description: "Scope agreed and delivery squad assembled.",
    datetime: "2026-02-02T09:00:00Z",
    dateLabel: "Feb 2",
    status: "complete",
  },
  {
    id: "design",
    title: "Design review",
    description: "Flows approved with two accessibility follow-ups.",
    datetime: "2026-03-09T14:00:00Z",
    dateLabel: "Mar 9",
    status: "complete",
  },
  {
    id: "build",
    title: "Build sprint",
    description: "Core screens implemented behind a feature flag.",
    datetime: "2026-04-20T10:00:00Z",
    dateLabel: "Apr 20",
    status: "current",
  },
  {
    id: "launch",
    title: "Launch",
    description: "Flag removed and rollout announced.",
    datetime: "2026-06-01T10:00:00Z",
    dateLabel: "Jun 1",
    status: "upcoming",
  },
];

/**
 * presentation="flow" renders the same events data as a static document-flow
 * list — no pan/zoom viewport — and reveal="stagger" animates the items in
 * one by one as the timeline scrolls into view. Reduced-motion users see
 * every item immediately.
 */
export function TimelineFlowReveal() {
  return (
    <Timeline
      aria-label="Project milestones"
      items={milestones}
      presentation="flow"
      reveal="stagger"
      revealOptions={{ trigger: "in-view" }}
    />
  );
}

Streaming reveal

Appending to the items array animates only the new points in — built for live sources like agent runs, deploy logs, or activity feeds.

  1. Status: Complete
    12:04:01

    Run queued

    Agent run accepted and scheduled.

  2. Status: Complete
    12:04:07

    Plan drafted

    Task broken into three tool calls.

Show sourceexamples/timeline/reveal-streaming.tsx
examples/timeline/reveal-streaming.tsx
"use client";

import { useState } from "react";
import { Button, Timeline, type TimelineItemData } from "@dethink/components";

const runEvents: TimelineItemData[] = [
  {
    id: "queued",
    title: "Run queued",
    description: "Agent run accepted and scheduled.",
    dateLabel: "12:04:01",
    status: "complete",
  },
  {
    id: "plan",
    title: "Plan drafted",
    description: "Task broken into three tool calls.",
    dateLabel: "12:04:07",
    status: "complete",
  },
  {
    id: "search",
    title: "Search executed",
    description: "Indexed 42 documents, 6 strong matches.",
    dateLabel: "12:04:18",
    status: "complete",
  },
  {
    id: "draft",
    title: "Draft generated",
    description: "Summary produced from the top matches.",
    dateLabel: "12:04:31",
    status: "current",
  },
  {
    id: "review",
    title: "Awaiting review",
    description: "Draft handed off for human approval.",
    dateLabel: "12:04:32",
    status: "upcoming",
  },
];

/**
 * Growing the items array appends points live: only the new items animate in,
 * so a streaming source — an agent run, a deploy log, a support thread — can
 * push events onto the timeline one at a time.
 */
export function TimelineRevealStreaming() {
  const [count, setCount] = useState(2);
  const done = count >= runEvents.length;

  return (
    <div className="space-y-4">
      <div className="flex justify-center gap-2">
        <Button
          size="sm"
          disabled={done}
          onClick={() => setCount((current) => current + 1)}
        >
          Log next event
        </Button>
        <Button size="sm" variant="outline" onClick={() => setCount(2)}>
          Reset
        </Button>
      </div>
      <Timeline
        aria-label="Agent run events"
        items={runEvents.slice(0, count)}
        presentation="flow"
        reveal="stagger"
      />
    </div>
  );
}

Examples that combine components for common tasks.

LLM story

A publication-style vertical history showing how LLMs moved from research architecture to everyday product workflows.

  1. Status: Complete

    Attention changes the map

    The Transformer made attention the core primitive, giving language models a cleaner way to learn context at scale.

  2. Status: Complete

    Scale becomes the story

    Large pretrained models showed that more data, compute, and parameters could unlock useful few-shot behavior.

  3. Status: Complete

    Chat becomes the interface

    Conversational assistants made LLMs feel less like research demos and more like everyday software.

  4. Status: Current

    Models become teammates

    LLMs now read, write, see, call tools, and coordinate multi-step work across product workflows.

Show sourceexamples/timeline/recipe-origin-story.tsx
examples/timeline/recipe-origin-story.tsx
"use client";

import { Timeline, type TimelineItemData } from "@dethink/components";

type OriginMilestone = {
  year: string;
};

const originMilestones: TimelineItemData<OriginMilestone>[] = [
  {
    id: "transformer",
    title: "Attention changes the map",
    description:
      "The Transformer made attention the core primitive, giving language models a cleaner way to learn context at scale.",
    datetime: "2017-01-01T00:00:00Z",
    dateLabel: "2017",
    status: "complete",
    marker: <span className="font-mono text-[10px] font-bold">T</span>,
    data: { year: "2017" },
  },
  {
    id: "scale",
    title: "Scale becomes the story",
    description:
      "Large pretrained models showed that more data, compute, and parameters could unlock useful few-shot behavior.",
    datetime: "2020-01-01T00:00:00Z",
    dateLabel: "2020",
    status: "complete",
    marker: <span className="font-mono text-[10px] font-bold">S</span>,
    data: { year: "2020" },
  },
  {
    id: "chat",
    title: "Chat becomes the interface",
    description:
      "Conversational assistants made LLMs feel less like research demos and more like everyday software.",
    datetime: "2022-01-01T00:00:00Z",
    dateLabel: "2022",
    status: "complete",
    marker: <span className="font-mono text-[10px] font-bold">C</span>,
    data: { year: "2022" },
  },
  {
    id: "agents",
    title: "Models become teammates",
    description:
      "LLMs now read, write, see, call tools, and coordinate multi-step work across product workflows.",
    datetime: "2026-01-01T00:00:00Z",
    dateLabel: "2026",
    status: "current",
    marker: <span className="font-mono text-[10px] font-bold">A</span>,
    data: { year: "2026" },
  },
];

export function TimelineRecipeOriginStory() {
  return (
    <Timeline<OriginMilestone>
      aria-label="Story of LLMs"
      items={originMilestones}
      mode="story"
    />
  );
}

Deployment history

Statuses carry rollout health — including a rollback marked error — and controlled selection drives a details panel showing each deployment's commit and author from its typed payload.

  1. Status: Complete

    v1.4.0 → production

    Date suite components released.

  2. Status: Warning

    v1.4.1 → canary

    Latency regression flagged on p99.

  3. Status: Error

    v1.4.1 → production

    Rolled back after checkout error spike.

  4. Status: Complete

    v1.4.2 → production

    Hotfix for date parsing in Safari.

v1.4.1 → production

Commit 38385e3 · deployed by Miguel

Show sourceexamples/timeline/recipe-deploy-history.tsx
examples/timeline/recipe-deploy-history.tsx
"use client";

import { useState } from "react";
import { Timeline, type TimelineItemData } from "@dethink/components";

type DeployPayload = { sha: string; author: string };

const deploys: TimelineItemData<DeployPayload>[] = [
  {
    id: "d-2214",
    title: "v1.4.2 → production",
    description: "Hotfix for date parsing in Safari.",
    datetime: "2026-07-04T08:41:00Z",
    dateLabel: "Today 08:41",
    status: "complete",
    data: { sha: "f642257", author: "Dana" },
  },
  {
    id: "d-2213",
    title: "v1.4.1 → production",
    description: "Rolled back after checkout error spike.",
    datetime: "2026-07-03T16:20:00Z",
    dateLabel: "Yesterday 16:20",
    status: "error",
    data: { sha: "38385e3", author: "Miguel" },
  },
  {
    id: "d-2212",
    title: "v1.4.1 → canary",
    description: "Latency regression flagged on p99.",
    datetime: "2026-07-03T14:05:00Z",
    dateLabel: "Yesterday 14:05",
    status: "warning",
    data: { sha: "38385e3", author: "Miguel" },
  },
  {
    id: "d-2211",
    title: "v1.4.0 → production",
    description: "Date suite components released.",
    datetime: "2026-07-01T11:32:00Z",
    dateLabel: "Jul 1 11:32",
    status: "complete",
    data: { sha: "17f7ab3", author: "Priya" },
  },
];

/**
 * An interactive deployment history: statuses carry the health of each
 * rollout, and selecting an event surfaces its payload — commit and author —
 * in a details panel driven by the controlled selection.
 */
export function TimelineRecipeDeployHistory() {
  const [selectedId, setSelectedId] = useState<string | null>("d-2213");
  const selected = deploys.find((deploy) => deploy.id === selectedId);

  return (
    <div className="space-y-4">
      <Timeline
        aria-label="Deployment history"
        items={deploys}
        selectedId={selectedId}
        onSelectedIdChange={setSelectedId}
      />
      <div
        aria-live="polite"
        className="border-border mx-auto max-w-md rounded-lg border px-4 py-3 text-sm"
      >
        {selected ? (
          <>
            <p className="font-medium">{selected.title}</p>
            <p className="text-muted-foreground mt-0.5">
              Commit <span className="font-mono">{selected.data?.sha}</span> ·
              deployed by {selected.data?.author}
            </p>
          </>
        ) : (
          <p className="text-muted-foreground">
            Select a deployment for details.
          </p>
        )}
      </div>
    </div>
  );
}

Timeline is data-driven: items carry the content, and the component handles layout, scale, and interaction.

Timeline props
PropWhat it doesDefault
itemsTimelineItemData[]Event data: id, title, description, datetime/dateLabel, status, optional marker and typed payload via data.Not set
mode"events" | "progress" | "story"Dated event history, undated progress sequence, or static editorial story timeline."events"
status (per item)"neutral" | "complete" | "current" | "upcoming" | "warning" | "error"Health/progress tone of each item's marker and card."neutral"
orientation / layout"horizontal" | "vertical" / layout variantsAxis of the track and how item cards stack around it.horizontal
scale / ordertime scale / chronological orderHow datetimes map to track distance and which direction time flows.auto
selectedId / defaultSelectedId / onSelectedIdChangestring | null / string | null / (id) => voidControlled or uncontrolled selection; arrow keys move between items.Not set
presentation"canvas" | "flow"Pannable/zoomable plane, or a static document-flow list with markers, rail, and compact cards."canvas" ("flow" for story)
reveal / revealOptions"none" | "stagger" | "all" / trigger, interval, duration, initialDelayAnimated item entrance for the flow presentation — staggered or all at once, on mount, in view, or manually."none"
revealCount / onItemReveal / onRevealCompletenumber / (id, index) => void / () => voidControlled reveal progression for the manual trigger, plus per-item and completion callbacks. Appended items animate in as their own batch.Not set
interactivebooleanDisables selection for purely presentational timelines.true
viewportTimelineViewportOptionsZoom and pan options for long histories (defaultZoom, limits).Not set
renderItemTimelineItemRendererCustom item rendering with access to the typed payload.built-in card