skrewww

Content & Data

Timeline

Timeline is a vertical, chronological event list built on Content/Timeline Item rows — Default outlined-ring or Highlighted solid-dot markers, connector suppression purely positional.

Composed from Timeline Item rows — no top-level variants of its own

betaReact AvailableFigma AvailableDocs Partial
React last updated
2026-07-19
Documentation last updated
2026-07-19
Accessibility target
WCAG 2.2 AA (target)
Version
0.1.0-beta

Known open questions

  • Exact marker/connector pixel sizing, using one shared marker color across both states, and the Timestamp/Description secondary-text token choice are this implementation's own decisions where the given facts didn't specify them.
  • No truncation is applied anywhere (Title, Timestamp, or Description) — Alert and Card don't truncate their titles either, and Figma's own reference shows the Description wrapping, not truncating, at 220px. List Item does truncate, but its single-line row density isn't comparable to Timeline's larger content blocks.
  • An empty data array renders nothing (null) — no other collection component in this codebase (Table, Tree View, Bar Chart, Line Chart) has an established empty-state convention to follow instead.

Order status history

Default items use an outlined ring; Highlighted items use a larger solid dot. The connector line is suppressed purely by list position (only the last event), independent of state — and its length adapts to the longer, wrapping description in the second event.

Order #48213

  1. Order placedJan 3, 9:14 AM

    Order #48213 received.

  2. Payment confirmedJan 3, 9:16 AM

    The customer's original order was flagged for manual review after the automated fraud detection system detected an unusual shipping address mismatch. A support representative confirmed the details directly with the customer before the charge was captured.

  3. ShippedJan 4, 11:02 AM

    Left the fulfillment center.

  4. DeliveredJan 6, 2:41 PM

    Left at front door.

Purpose

A vertical, chronological list of events for activity feeds, order status history, or audit logs, composed from Content/Timeline Item rows.

Anatomy

An <ol> of Timeline Item rows. Each row is a CSS grid of two columns: a marker column (a circular marker — outlined ring for Default, larger solid dot for Highlighted — plus a connector line beneath it) and a content column (Title + Timestamp on one line, Description wrapping below). The connector's length is computed via CSS (flex: 1 inside a grid row stretched to the taller of its two columns), not a fixed pixel value, so it reaches the next item's marker regardless of how tall the current row's description makes it. Connector visibility is purely positional — only the last row omits it — entirely independent of each row's own state.

Variants and states

default · highlighted

When to use

Sequential, time-stamped events where chronological order itself is meaningful and each event needs its own title, timestamp, and description.

When not to use

A fixed, known-length linear process with progress state — use Step Item. An empty list of events — Timeline renders nothing for zero items; there's no established empty-state convention for collection components in this codebase to fall back to.

Accessibility

Renders as a real ordered list (role="list"/<ol>); each event's timestamp is real visible text, not just implied by position or by the marker's visual state.

Keyboard behavior

Purely presentational — Timeline has no interactive elements and captures no keyboard input of its own.

Common mistakes

Coupling connector-line visibility to state === "highlighted" instead of actual list position — the two are independent: a Default item can be last (and must suppress its connector), and a Highlighted item can be in the middle (and must keep its connector). Introducing truncation or an invented empty-state pattern that no comparable component in this codebase actually uses.

Properties

data ({ title, timestamp, description, state? }[] — state defaults to "default"; "highlighted" is a larger solid dot instead of an outlined ring).

Why is connector visibility based on position, not state?

They're independent concerns. A Default (outlined-ring) item can be the last event in the list and must suppress its connector for that reason alone — not because it's unhighlighted. A Highlighted item can sit in the middle of the list and must keep its connector. Coupling the two would produce a visibly broken timeline the moment a Default item happens to be last, or a Highlighted item happens to not be.

How does the connector reach the next item's marker when a description is long?

The connector is a flex: 1 element inside a flex column (the marker column) that's stretched by CSS Grid to match the height of the row's taller column — usually the content column, which grows with description length. This is computed by the browser's layout engine, not a fixed pixel height copied from one Figma example.

Why no truncation on Title, Timestamp, or Description?

Checked precedent first: List Item does truncate its title/description to a single line, but Alert and Card — the more structurally comparable "content block with a title" components — don't truncate at all. Figma's own Timeline reference also shows the Description wrapping to 2 lines rather than truncating. Given that mixed signal, this implementation defaults to natural wrapping everywhere, matching the majority precedent and the literal Figma behavior, rather than inventing truncation Timeline alone would need to justify.

What happens with an empty data array?

Renders nothing. No other collection component in this codebase (Table, Tree View, Bar Chart, Line Chart) auto-composes an empty-state pattern for zero items — EmptyState is always a separate, consumer-composed choice. Inventing a Timeline-specific empty-state behavior would be inconsistent with every sibling component.

Tokens used

semantic/action/primarysemantic/border/defaultsemantic/text/primary

Component API

PropTypeDefaultDescription
data{ title: string; timestamp: string; description: string; state?: "default" | "highlighted" }[]Chronological list of events, in display order. state defaults to "default".

React example

Copy React example
import { Timeline } from "@/components/ui";

const events = [
  { title: "Order placed", timestamp: "Jan 3, 9:14 AM", description: "Order #48213 received." },
  {
    title: "Payment confirmed",
    timestamp: "Jan 3, 9:16 AM",
    description: "Charge captured successfully.",
    state: "highlighted",
  },
  { title: "Delivered", timestamp: "Jan 6, 2:41 PM", description: "Left at front door." },
];

export function Example() {
  return <Timeline data={events} />;
}