Timeline
Ordered events: an audit trail, a deploy history, the life of a ticket. A marker column with a run of line down it, and a row built from slots.
Component behavior
Timeline is for events that already happened, in the order they happened. Every row carries a time, and the rail shows the order.
ActivityFeed combines Timeline with actor, action, target, relative timestamp, and day-group headings.
- Deployment, audit, status, or job history.
- Events displayed in chronological order.
- Events with different amounts of detail, including payloads.
ActivityFeed: rows use actor/action/target format with relative timestamps.
Stepper: the view shows current progress through a task.
List: rows do not have chronological order.
LogViewer: the content is a high-volume log stream.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | TimelineEvent[] | — | The events, newest first. Omit and write TimelineItem children instead. |
children | ReactNode | — | TimelineItem children, for the composed path. Ignored when items is given. |
variant | "rail" | "cards" | "minimal" | "rail" | Rail displays markers and connectors. Cards adds event frames. Minimal hides connectors and marker halos. |
density | "compact" | "normal" | "comfortable" | "normal" | Marker, type and row padding together. |
timePlacement | "inline" | "leading" | "none" | "inline" | Timestamp placement: inline, in a leading column, or hidden. |
timeWidth | number | string | 64 | Width of the leading time column. A number is px. |
markerSize | number | string | 18 (16 / 22 at compact / comfortable) | Marker diameter and marker-column width. Larger markers overflow the column while remaining centered. |
connector | boolean | true (false for minimal) | The run of line down the rail. |
tone | ToneProp | "neutral" | Default marker color for events without a tone. |
emptyState | ReactNode | — | Shown in place of the list when items is given and empty. |
onItemClick | (event: TimelineEvent, index: number) => void | — | Renders rows as buttons. Do not include links or other interactive children in button rows. |
renderItem | (event: TimelineEvent, state: TimelineItemState) => ReactNode | — | Custom content beside the marker. Retains the connector, row state, and click handling. |
renderMarker | (event: TimelineEvent, state: TimelineItemState) => ReactNode | — | Replaces the marker while retaining the row. |
TimelineEvent
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | — | Stable key. |
title | ReactNode | — | The headline. |
description | ReactNode | — | Secondary content below the title. |
time | ReactNode | — | Timestamp content. Use Timestamp or RelativeTime to format a date. |
meta | ReactNode | — | Monospace source text beside the title. |
tone | ToneProp | — | Colors this row's marker and its halo, and the detail block's edge. |
icon | ReactNode | — | Glyph inside the marker, in place of the dot. The marker becomes a tinted disc to hold it. |
marker | ReactNode | — | Replaces the event marker. |
detail | ReactNode | — | Framed detail content below the row. |
actions | ReactNode | — | Right-aligned controls on the title row. |
group | ReactNode | — | Section heading before this event. Consecutive events repeating it sit under one, and the line breaks between sections. |
active | boolean | — | Applies active styling with a tinted background and emphasized marker. |
dashed | boolean | — | Draws the run of line below this event dashed: history that is incomplete, or something still to come. |
TimelineItem
The composed row. It takes every TimelineEvent slot except id and group, and reads the enclosing timeline’s shape from context, so a hand-written row looks like a generated one.
| Prop | Type | Default | Description |
|---|---|---|---|
title | ReactNode | — | The headline. |
meta | ReactNode | — | Monospace source text beside the title. |
time | ReactNode | — | Timestamp content positioned according to the enclosing Timeline. |
description | ReactNode | — | Secondary content below the title. |
children | ReactNode | — | The description slot under another name, for the composed path. description wins if both are given. |
detail | ReactNode | — | Framed detail content below the row. |
actions | ReactNode | — | Right-aligned controls on the title row. |
tone | ToneProp | — | Colors this row's marker and its halo, and the detail block's edge. |
icon | ReactNode | — | Glyph inside the marker, in place of the dot. |
marker | ReactNode | — | Replaces the event marker. |
content | ReactNode | — | Replaces the row's slots entirely, keeping the rail, the state and the click. What Timeline's renderItem arrives as. |
active | boolean | — | Applies active styling with a tinted background and emphasized marker. |
dashed | boolean | — | Draws the run of line below this row dashed. |
onClick | (event: MouseEvent<HTMLElement>) => void | — | Makes the row a button. Lands on the row, not the <li>. |
Custom properties
Everything the component measures with is a custom property on the root, so density is tunable without restating a rule.
| Prop | Type | Default | Description |
|---|---|---|---|
--m-timeline-marker | length | 18px (16 / 22 at compact / comfortable) | Marker diameter and marker-column width. Also sets connector alignment. |
--m-timeline-dot | length | 8px | The dot inside the marker, when the event has no icon. |
--m-timeline-line | length | 1px | Connector thickness. |
--m-timeline-gap | length | var(--m-space-2) | Between the rail and the row. It is the row's inline padding, so the hover fill grows with it. |
--m-timeline-pad | length | var(--m-space-1_5) | Row padding-block. |
--m-timeline-font | length | var(--m-font-size-md) | Title size. Meta, time and detail keep their own fixed steps. |
--m-timeline-time-width | length | 64px | Leading timestamp column width. Set through timeWidth. |
import { Timeline, TimelineItem } from "@solarius/onset";
import type {
TimelineEvent,
TimelineItemState,
TimelineProps,
} from "@solarius/onset";Data and composition
Pass items to generate rows or provide TimelineItem children directly. Both forms render the same row component.
Variants
variant defaults to "rail". "cards" adds a frame around each event. "minimal" omits the connector and marker halo.
Density
density retunes the marker, the type and the row padding together. compact suits side panels; comfortable suits pages that are mostly timeline.
Timestamp placement
timePlacement="inline" displays timestamps at the end of the title row. "leading" adds a timestamp column before the marker. "none" hides timestamps.
The row's slots
Timeline slots are optional. title is the heading; meta is secondary source text; description is body text; detail contains framed content; and actions contains controls. icon renders in a tinted marker and marker replaces the marker.
Event groups
Consecutive events with the same group share a heading. Connectors break between groups. Set dashed on an event to use a dashed connector below it.
Selection and clicking
onItemClick renders event rows as buttons. Do not place links or other interactive elements inside button rows. active applies selected styling.
Empty
emptyState renders when an explicitly supplied items array is empty. It does not apply to the children composition form.