Timeline
A vertical run of dated entries down a connecting line — a changelog, a version history, an audit log — each with a dot, icon or avatar marker, tags, and room for a body.
<UiTimeline :items="..." />Items
requireditems is the entries, in the order you want them shown — newest first for a changelog. Each is a title plus an optional description and date, and can also carry an icon, an avatar, tags, a to, its own color, or an active flag.
- PublishedMar 4, 2026
Made available to every workspace member
- ReviewedMar 2, 2026
Approved by two reviewers
- Draft createdFeb 27, 2026
Started from the blank template
Entries render in the order given — the component never sorts them. Newest-first is the convention for a changelog or an audit log; reverse the array for a history read top-down.
active adds a halo to the marker, for the version that's live or the newest deploy. It's an emphasis flag, not a state the component tracks — mark as many entries as you like, or none.
Variant
variant sets how much surface each entry carries. default is a bare title and description block; card wraps the content in a surface, leaving room for a changelog body; compact tightens it to one line per entry, for an audit log.
- v2.4.0 deployedMar 4, 2026, 9:12 AM
Production · eu-central-1
- Build failedMar 3, 2026, 6:20 PM
Type error in app/server/api/usage.ts
- v2.3.2 deployedMar 1, 2026, 8:02 AM
Production · eu-central-1
- v2.4.0 deployedMar 4, 2026, 9:12 AM
Production · eu-central-1
- Build failedMar 3, 2026, 6:20 PM
Type error in app/server/api/usage.ts
- v2.3.2 deployedMar 1, 2026, 8:02 AM
Production · eu-central-1
- v2.4.0 deployedProduction · eu-central-1Mar 4, 2026, 9:12 AM
- Build failedType error in app/server/api/usage.tsMar 3, 2026, 6:20 PM
- v2.3.2 deployedProduction · eu-central-1Mar 1, 2026, 8:02 AM
variant="compact" moves description onto the title's row and truncates it, keeping one audit-log entry to one line; variant="card" wraps each entry's content in a Card, which is the one that suits changelog bodies.
Color
color is the marker color for entries that don't set their own.
- Release notes v2.4.0Mar 4, 2026
What changed and how to upgrade
- Release notes v2.3.0Feb 18, 2026
Breaking: `Card`'s `type` prop is now `variant`
- Release notes v2.4.0Mar 4, 2026
What changed and how to upgrade
- Release notes v2.3.0Feb 18, 2026
Breaking: `Card`'s `type` prop is now `variant`
- Release notes v2.4.0Mar 4, 2026
What changed and how to upgrade
- Release notes v2.3.0Feb 18, 2026
Breaking: `Card`'s `type` prop is now `variant`
- Release notes v2.4.0Mar 4, 2026
What changed and how to upgrade
- Release notes v2.3.0Feb 18, 2026
Breaking: `Card`'s `type` prop is now `variant`
- Release notes v2.4.0Mar 4, 2026
What changed and how to upgrade
- Release notes v2.3.0Feb 18, 2026
Breaking: `Card`'s `type` prop is now `variant`
A marker is an avatar if the entry has one, otherwise its icon, otherwise a plain dot. color (per entry, falling back to the timeline's) fills the dot or tints the icon's disc; an avatar has no fill to tint, so it wears the color as a ring — and only when the entry sets color or active itself, so a colored timeline doesn't ring every face.
Date format
dateFormat sets how a Date, timestamp or ISO string is rendered. relative produces “4 minutes ago” and keeps updating — the right read for an activity feed.
- ALAda Lovelacerevoked API key prod-7f3aAug 17, 2026
- GHGrace Hopperinvited miles@acme.com as AdminAug 16, 2026
- ALAda Lovelacerevoked API key prod-7f3aAug 17, 2026, 12:04 AM
- GHGrace Hopperinvited miles@acme.com as AdminAug 16, 2026, 10:33 PM
- ALAda Lovelacerevoked API key prod-7f3a12:04 AM
- GHGrace Hopperinvited miles@acme.com as Admin10:33 PM
- ALAda Lovelacerevoked API key prod-7f3a4 minutes ago
- GHGrace Hopperinvited miles@acme.com as Admin2 hours ago
A date string is displayed verbatim unless it's ISO-8601 (2026-03-04, 2026-03-04T09:12:00Z); only ISO strings, Dates and timestamp numbers go through dateFormat. That's the escape hatch for a pre-formatted or non-date label like "3 days ago" or "Q1".
date-format="relative" is computed at render time and doesn't tick on its own — for a live audit log, re-render on your own interval.
Locale
locale sets which locale formats the dates. Defaults to the runtime's.
- PublishedMade available to every workspace memberMar 4, 2026
- ReviewedApproved by two reviewersMar 2, 2026
- PublishedMade available to every workspace member04.03.2026
- ReviewedApproved by two reviewers02.03.2026
- PublishedMade available to every workspace member2026/03/04
- ReviewedApproved by two reviewers2026/03/02
Line
line is the connecting line between markers. Drop it and the entries read as a list rather than a sequence.
- Release notes v2.4.0Mar 4, 2026
What changed and how to upgrade
- Release notes v2.3.0Feb 18, 2026
Breaking: `Card`'s `type` prop is now `variant`
- Release notes v2.4.0Mar 4, 2026
What changed and how to upgrade
- Release notes v2.3.0Feb 18, 2026
Breaking: `Card`'s `type` prop is now `variant`
Empty text
emptyText stands in for the list while items is empty. Say what would fill it rather than only reporting the emptiness.
No activity in the selected range
content slot
Replaces an entry's description with markup of your own — a changelog's bullet list, keyed off the item's value.
- v2.4.0LatestMar 4, 2026
- —Timeline component for changelogs and audit logs
- —Charts now accept a custom palette
- v2.3.0BreakingFeb 18, 2026
- —Renamed `Card`'s `type` prop to `variant`
- —Dropped the deprecated `Banner` component
- v2.2.0Jan 30, 2026
- —Form validation runs on blur as well as submit
The #content slot is written once but rendered for every entry, so key it off the scoped item (changes[item.value]). Entries whose slot renders nothing get no body spacing — or give just the entries that need one their own slot name and pass <template #that-name>.
API Reference
Generated from the component's source — props, slots and emits as the component actually declares them.
Props
itemsrequiredTimelineItem[]"default" | "card" | "compact"'default'"neutral" | "primary" | "secondary" | "success" | "error" | "warning" | "info" | "pending"'neutral'"date" | "datetime" | "time" | "relative"'date'Slots
item.slot ?? 'content'Types
type Color = "neutral" | "primary" | "secondary" | "success" | "error" | "warning" | "info" | "pending";type Variant = "default" | "card" | "compact";type DateFormat = "date" | "datetime" | "time" | "relative";interface TimelineTag {
/**
* The pill's text, e.g. 'Added', 'Breaking' or 'v2.4.0'.
*/
label: string;
/**
* @defaultValue 'neutral'
*/
color?: Color;
/**
* @defaultValue 'soft'
*/
variant?: "solid" | "soft";
/**
* Name of the icon displayed before the label.
*/
icon?: string;
}interface TimelineItem {
/**
* The entry's heading — a version number, an action, a deploy name.
*/
title?: string;
/**
* Secondary text under the title. `variant="compact"` keeps it on the title's row instead, and
* truncates it, so a long audit-log line stays one row tall.
*/
description?: string;
/**
* When the entry happened, shown at the end of the title row. A `Date` or a timestamp number is
* formatted per the timeline's `dateFormat`; a string is displayed verbatim (so a pre-formatted
* "3 days ago" passes straight through) unless it's ISO-8601 (`2026-03-04`,
* `2026-03-04T09:30:00Z`), which is formatted like the other two.
*/
date?: string | number | Date;
/**
* Name of the icon rendered inside this entry's marker, in place of the default dot.
*/
icon?: string;
/**
* Renders an avatar as this entry's marker instead of a dot or icon — for an audit log, where
* who did it is the first thing to read. Same fields as `Avatar`; takes precedence over `icon`.
*/
avatar?: { src?: string; firstName?: string; lastName?: string };
/**
* Colors this entry's marker, overriding the timeline's `color` — for typing entries by
* severity or kind (a failed deploy `error`, a release `success`). On an `avatar` marker, which
* has no fill to tint, it becomes a ring around the avatar instead.
*/
color?: Color;
/**
* Pills shown after the title, for change types ('Added', 'Fixed', 'Breaking') or labels.
*/
tags?: TimelineTag[];
/**
* Turns the title into a link to this URL or route — the release notes, the audited record.
*/
to?: string;
/**
* Marks the entry as the current one (the live version, the newest deploy), drawing a soft halo
* around its marker.
* @defaultValue false
*/
active?: boolean;
/**
* Unique value identifying this entry. Falls back to `title`, then its index.
*/
value?: string | number;
/**
* Name of the slot rendering this entry's body, instead of the shared `#content` slot.
*/
slot?: string;
}