Timeline
UiTimeline renders an ordered list of events, each with a dot, icon, or image marker connected by a line. Use it for activity feeds, order/status history, or changelogs.
Basic timeline
Without icon or imageUrl, items render a plain dot marker.
<script setup lang="ts">
import type { ITimelineItem } from '@colorffy/ui'
const items: ITimelineItem[] = [
{ id: '1', title: 'Account created', text: 'Welcome to the platform', time: '3 days ago' },
{ id: '2', title: 'Profile verified', text: 'Documents approved', time: '2 days ago' },
{ id: '3', title: 'First project', text: 'Project Atlas started', time: '1 day ago' },
]
</script>
<template>
<UiTimeline :items="items" />
</template>
Icon markers
Set icon (a Material Symbols HTML entity) and optionally variant to color the marker with the shared semantic palette.
<script setup lang="ts">
import type { ITimelineItem } from '@colorffy/ui'
const items: ITimelineItem[] = [
{ id: '1', title: 'New deployment', text: 'Project Atlas v2.4.0 released', time: '3 days ago', icon: '', variant: 'success' },
{ id: '2', title: 'Usage alert', text: 'API reached 80% of its limit', time: '1 day ago', icon: '', variant: 'warning' },
]
</script>
<template>
<UiTimeline :items="items" />
</template>
Image markers
Set imageUrl (and imageAlt) to render an avatar-style marker instead of an icon. imageUrl takes precedence over icon.
<template>
<UiTimeline
:items="[
{ id: '1', title: 'Ana Morales', text: 'Approved the proposal', time: '4 hours ago', imageUrl: 'https://i.pravatar.cc/88?img=5', imageAlt: 'Photo of Ana Morales' },
]"
/>
</template>
Alternate alignment
Set align="alternate" to center the connector line and zig-zag content left/right (e.g. a company timeline or roadmap).
<template>
<UiTimeline :items="items" align="alternate" />
</template>
Custom item body
Provide a custom body for a specific item via the #item-<id> named slot, or handle every item the same way via the scoped #item slot ({ item }). Either slot overrides the default title/text/time markup.
<template>
<UiTimeline :items="items">
<template #item-release="{ item }">
<p class="subtitle-1 mb-1">{{ item.title }}</p>
<UiBadge text="Production" variant="tonal tonal-success" size="sm" />
</template>
</UiTimeline>
</template>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | ITimelineItem[] | [] | Array of timeline items to render. |
align | 'start' | 'alternate' | 'start' | Layout alignment. 'alternate' centers the connector line and alternates content left/right. |
size | 'sm' | 'lg' | — | Tighter (sm) or larger (lg) layout; unset is the standard size. |
customClass | string | string[] | Record<string, boolean> | null | — | Extra classes for the root element. |
ITimelineItem
| Property | Type | Description |
|---|---|---|
id | string | Unique identifier. Used as the render key and to target the #item-<id> slot. |
title | string | null | Title text displayed prominently. |
text | string | null | Supporting text. |
time | string | null | Timestamp/label rendered above the title. |
icon | string | null | Material Symbols icon code for the marker. |
imageUrl | string | null | Image URL rendered in place of the icon/dot marker. Takes precedence over icon. |
imageAlt | string | null | Alt text for the image. |
variant | ThemeColor | null | Semantic color applied to the dot/icon marker. |
Slots: #item-<id> per-item custom body (takes precedence); #item scoped slot ({ item }) applied to every item as a fallback; both fall back to the default title/text/time markup when unused.
UiListItem's icon wrapper, so a list and a timeline placed side by side stay visually aligned.CSS variables
Set these on :root, or on any wrapper to restyle only the timelines inside it. The sm and lg sizes keep their own spacing, dot, icon and text sizes (and lg its image size), and colored markers keep their palette.
:root {
--cffy-timeline-connector-color: var(--cffy-primary-a50);
--cffy-timeline-dot-color: var(--cffy-primary-a10);
}
| Variable | Default | Controls |
|---|---|---|
--cffy-timeline-gap | --cffy-space-16 | Space between the marker and the content |
--cffy-timeline-item-spacing | --cffy-space-24 | Space between items |
--cffy-timeline-connector-thickness / --cffy-timeline-connector-color | 2px / --cffy-outline-surface | Line between markers |
--cffy-timeline-dot-size / --cffy-timeline-dot-color | 0.75rem / --cffy-muted-a10 | Dot marker |
--cffy-timeline-icon-bg-color / --cffy-timeline-icon-color | --cffy-surface-container-lowest / --cffy-on-background | Icon marker |
--cffy-timeline-icon-size / --cffy-timeline-icon-padding / --cffy-timeline-icon-radius | --cffy-fs-lg / 0.625rem / --cffy-radius-md | Icon size, tile padding and corners |
--cffy-timeline-image-size / --cffy-timeline-image-radius | 2.75rem / --cffy-radius-md | Image marker |
--cffy-timeline-title-font-size / --cffy-timeline-title-font-weight | --cffy-fs-2xs / --cffy-fw-600 | Title |
--cffy-timeline-text-font-size / --cffy-timeline-text-color | --cffy-fs-3xs / --cffy-muted-a10 | Body text |
--cffy-timeline-time-color | --cffy-muted-a10 | Timestamp caption |