← All proposals

Timeline

Net-new, in two parts.

Net-new componentOpen in Storybook

proposals/Timeline/context.md44 lines · View on GitHub

Timeline

Problem

PDS has no pattern for a log of events over time: deploys, checks, approvals, an agent joining and working. Teams draw the rail, the timestamps and the status icons by hand. Two proposals here already cover half of it: AgentStep (one row of agent work) and ChainOfThought (a collapsible list of those rows), both written for agent runs only. An agent run is really one region inside a larger event log, so the pieces should be generic and the agent flavor should be a modifier.

Proposal

Net-new, in two parts. Both generalize the existing proposals instead of duplicating them.

  • TimelineItem (the row): optional status or custom icon, label with inline emphasis, quiet secondary text, a right-aligned time, optional expandable detail and an always-visible children slot. isAgentic switches the icon and accents from neutral to the agent color, the same boolean convention as Button, IconButton and MenuButton. This is AgentStep made generic.
  • Timeline (the list): an ol that owns list semantics, spacing and an optional vertical rail (hasRail) connecting the icons. Children can be items, LabeledDividers, a ChainOfThought or a ThinkingState, and the rail runs through all of them.

The full event log with an agent in it is a recipe, not a component: a documented story composing the parts below (see Recipe).

ChainOfThought keeps its summary line, isOpen and expandWhenActive, and renders a Timeline for its body.

Recipe: event log with agent engagement

A story and Usage section, not an API. Shows a neutral Timeline log, then an agentic LabeledDivider ("Zappy engaged"), then isAgentic items, a ChainOfThought row (its steps nest one level in and use the parent's rail), a ThinkingState as the live last row, and a closing agentic LabeledDivider. Where the agent starts and stops, what the dividers say and which rows are agentic are screen decisions, so they stay out of the components. Promote to a TimelineGroup only if the same region keeps being rebuilt.

Source

Two screenshots from Erika (2026-10-16): a deploy and check log with a "Zappy engaged" divider and an agent sandbox investigation below it, and a plain all-neutral log of the same incident. Plus the existing AgentStep, ChainOfThought, ThinkingState and LabeledDivider proposals. The screenshots' small left-aligned divider is ignored; the current centered LabeledDivider is the design.

Constraints

  • Tokens only; light and dark. Reuse PDS components first (Icon, Spinner, Tag, Button for the chevron).
  • Semantics: Timeline is an ol with li children. A divider child is a separator li. The rail is decorative and aria-hidden.
  • Times are strings formatted by the consumer (translatable, same as ThinkingState.time). Prefer a time element when a machine-readable value is passed.
  • Status text stays visually hidden for screen readers and translatable, as in AgentStep.
  • Settled conventions apply: isAgentic boolean, controls over extra stories, no hardcoded content, no inline styles.
  • AgentStep and ChainOfThought already have HANDOFF.md and the ready-for-dev tag. Do not change them, or the tag, until the designer decides how to handle the rename.

Open questions

  • Names: Timeline and TimelineItem (recommended), or ActivityLog / ActivityItem? And does AgentStep get renamed, or stay as a thin isAgentic wrapper over TimelineItem?
  • Rail: optional (hasRail) with Chain of Thought nested items using the parent's rail? Is a plain Chain of Thought still railless?
  • Tone: per-item isAgentic first, or also a TimelineGroup isAgentic that tints a region between two dividers?
  • Live tail: is ThinkingState a child of Timeline as-is, or does TimelineItem get an active look ("Rolling out... now")?
  • Time column: always right-aligned and always optional? How does it behave on narrow widths?
  • Collapsing old items: does a long log need a "Show N earlier events" row, and does that belong here?
  • Nesting depth: one level (Chain of Thought inside a region) or arbitrary?