Timeline

A timeline is an ordered list with a rule down the side. Build it from items, or from timelineItem() children when the entries are not uniform enough to come from an array.

Basic timeline

  1. March 2026

    Component library

    sitelo-ui ships with ninety components.

  2. January 2026

    Server islands

    Static pages with regions rendered at request time.

  3. October 2025

    First release

    File-based routing and a build command.

timeline({
  items: [
    { time: 'March 2026', title: 'Component library', description: 'sitelo-ui ships with ninety components.' },
    { time: 'January 2026', title: 'Server islands', description: 'Static pages with regions rendered at request time.' },
    { time: 'October 2025', title: 'First release', description: 'File-based routing and a build command.' },
  ],
})

Colored markers

  1. 12:04

    Deploy succeeded

    204 pages published.

  2. 12:03

    Lighthouse passed

    All thresholds met.

  3. 12:01

    Link check warned

    One external link timed out.

  4. 12:00

    Build started

timeline({
  items: [
    { time: '12:04', title: 'Deploy succeeded', description: '204 pages published.', color: 'success' },
    { time: '12:03', title: 'Lighthouse passed', description: 'All thresholds met.', color: 'success' },
    { time: '12:01', title: 'Link check warned', description: 'One external link timed out.', color: 'warning' },
    { time: '12:00', title: 'Build started', color: 'neutral' },
  ],
})

With icons

  1. Just now

    Published

  2. 2 minutes ago

    Building

timeline(
  timelineItem({
    time: 'Just now',
    title: 'Published',
    color: 'success',
    icon: icon('check', { 'stroke-width': 3.4 }),
  }),
  timelineItem({
    time: '2 minutes ago',
    title: 'Building',
    color: 'primary',
  }),
)

Rich entries

Children of an item go under its description.

  1. v2.7.0

    Page sections

    herofooterstatstepstimelinemockup
  2. v2.6.3

    Maintenance

    Dependency bumps and a link-checker fix.

timeline(
  timelineItem({ time: 'v2.7.0', title: 'Page sections', color: 'primary' },
    stack({ direction: 'row', gap: 'xs', wrap: true, style: 'margin-top: 0.5rem' },
      chip({ size: 'sm' }, 'hero'),
      chip({ size: 'sm' }, 'footer'),
      chip({ size: 'sm' }, 'stat'),
      chip({ size: 'sm' }, 'steps'),
      chip({ size: 'sm' }, 'timeline'),
      chip({ size: 'sm' }, 'mockup'),
    ),
  ),
  timelineItem({ time: 'v2.6.3', title: 'Maintenance', description: 'Dependency bumps and a link-checker fix.' }),
)

From data

The usual shape on a static site: a changelog file loaded by data(), mapped straight to items.

  1. 2026-03-01

    v2.7.0

    Page sections

  2. 2026-02-14

    v2.6.3

    Maintenance

  3. 2026-01-20

    v2.6.0

    Server islands

return (() => {
  const releases = [
    { version: '2.7.0', date: '2026-03-01', summary: 'Page sections' },
    { version: '2.6.3', date: '2026-02-14', summary: 'Maintenance' },
    { version: '2.6.0', date: '2026-01-20', summary: 'Server islands' },
  ]

  return timeline({
    items: releases.map((release) => ({
      time: release.date,
      title: 'v' + release.version,
      description: release.summary,
      color: 'primary',
    })),
  })
})()

Timeline or steps?

A timeline records what happened, newest or oldest first, and has no current position. steps() shows progress through a flow with one step in progress and the rest ahead of or behind it.

Props

timeline():

PropTypeDefaultDescription
itemsArray[]Objects with the timelineItem props below.

timelineItem():

PropTypeDefaultDescription
timeChildWhen it happened — a date, a version, a clock time.
titleChildWhat happened.
descriptionChildThe detail under it.
iconChildMarkup inside the marker.
color'primary' | 'neutral' | 'success' | 'warning' | 'danger'Marker colour.

Children of an item render under its description.