Timeline
Vertical chronological event feed for activity logs, audit trails, release notes, and notification streams. Pure semantic <ol>/<li> with a status-colored indicator and an optional icon override.
Installation
pnpm dlx @hex-core/cli add timelineUsage
import { Timeline } from "@/components/ui/timeline"Activity log
Three-entry vertical feed with mixed status colors
import { Timeline } from "@/components/ui/timeline";
export function Example() {
return (
<Timeline
aria-label="Activity"
events={[
{ id: "1", title: "Pull request opened", timestamp: "2 hours ago", status: "info" },
{ id: "2", title: "CI passed", timestamp: "1 hour ago", status: "success" },
{ id: "3", title: "Merged to main", timestamp: "12 minutes ago", description: "Squash + merge by @oscar", status: "success" },
]}
/>
);
}Custom icon
Override the default dot with a custom node
import { Timeline } from "@/components/ui/timeline";
export function Example() {
return (
<Timeline
aria-label="Release notes"
events={[
{ id: "v1", title: "v1.0", timestamp: "Apr 24", icon: <span>⚡</span> },
{ id: "v2", title: "v1.1", timestamp: "Apr 27", icon: <span>🐛</span>, status: "warning" },
]}
/>
);
}API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
eventsrequired | object | — | Ordered list of { id, title, timestamp?, description?, icon?, status? } events. |
size | string | md | Indicator size: 'sm' | 'md' |
aria-labelrequired | string | — | Required accessible name for the ordered list (e.g. 'Activity log', 'Release notes') |
AI Guidance
When to use
Use to show a chronological event feed: activity logs, audit trails, release notes, notification history, ticket events. Each event has a title and optional timestamp + description.
When not to use
Don't use for project schedules / Gantt charts (build a custom layout). Don't use for navigation between time periods (use Tabs or Stepper). Don't use for paginated data (use Table or DataTable). Don't use for >50 events without virtualization — Timeline renders every item.
Common mistakes
- Forgetting aria-label — the <ol> needs an accessible name to be understood as a feed
- Using duplicate event ids — breaks React keys and event reconciliation on re-render
- Stuffing the description with rich layouts that overflow the timeline rail — keep it short or move to a Card
- Setting status='error' on every event for emphasis — color loses meaning when overused
- Mixing controlled timestamps as Date objects without formatting — Timeline accepts ReactNode, so format upstream (date-fns) before passing in
Accessibility
Renders <ol> with the provided aria-label. The status-colored indicator and connector line are aria-hidden — meaning is carried entirely by the title/timestamp/description text. No aria-current; events are historical, not navigational. For >50 events consider a windowing solution outside Timeline.
Token budget: 1100