Skip to content
Data Display

Timeline

An activity feed or an order's history: events in order, each on a rail with a dot or an icon, joined by the line that makes them read as one sequence rather than a list of unrelated rows.

Walkthrough

1. Basic

An order's history. Times are dates, written the way a person says them, with the exact moment in the tooltip; pending is the step that has not happened yet — its dot pulses and the line into it is dashed.

  1. Order placed

  2. Payment confirmed

    Visa ending 4242

  3. Shipped from Erbil

    Aramex AX-99120-IQ

  4. Out for delivery, In progress

<script lang="ts">	import { Timeline, TimelineItem } from 'omaris';​	const now = Date.now();	const MINUTE = 60_000;	const HOUR = 60 * MINUTE;</script>​<Timeline label="Order #4021" class="w-96 max-w-full">	<TimelineItem title="Order placed" time={now - 26 * HOUR} tone="neutral" />	<TimelineItem		title="Payment confirmed"		description="Visa ending 4242"		time={now - 26 * HOUR + 2 * MINUTE}		tone="neutral"	/>	<TimelineItem title="Shipped from Erbil" description="Aramex AX-99120-IQ" time={now - 5 * HOUR} />	<TimelineItem title="Out for delivery" time={now - 14 * MINUTE} pending /></Timeline>

2. Grouped

A feed grouped by day is one Timeline per group, each with a heading, which also names its list for a screen reader. compact is the dense variant for a feed rather than a history.

Today

  1. Ada merged #1042

  2. Grace commented on #1040

Yesterday

  1. Build failed on main

  2. Release 0.9.2 published

<script lang="ts">	import { Timeline, TimelineItem } from 'omaris';​	const now = Date.now();	const MINUTE = 60_000;	const HOUR = 60 * MINUTE;​	const GROUPS = [		{			heading: 'Today',			events: [				{ title: 'Ada merged #1042', at: now - 25 * MINUTE, tone: 'primary' },				{ title: 'Grace commented on #1040', at: now - 2 * HOUR, tone: 'neutral' }			]		},		{			heading: 'Yesterday',			events: [				{ title: 'Build failed on main', at: now - 30 * HOUR, tone: 'destructive' },				{ title: 'Release 0.9.2 published', at: now - 33 * HOUR, tone: 'success' }			]		}	] as const;</script>​<div class="flex w-96 max-w-full flex-col gap-6">	{#each GROUPS as group (group.heading)}		<Timeline heading={group.heading} variant="compact">			{#each group.events as event (event.title)}				<TimelineItem title={event.title} time={event.at} tone={event.tone} />			{/each}		</Timeline>	{/each}</div>

3. Icons and content

An icon puts the event in a tonal circle instead of a dot; children carry whatever the event needs underneath — a comment, a set of labels.

  1. Ada Lovelace commented

    The inner loop is twice as fast now. Can someone check the edge cases around zero?

  2. Labels added

    performance engine
  3. Opened

    by Ada Lovelace

<script lang="ts">	import { Avatar, Chip, Text, Timeline, TimelineItem } from 'omaris';​	const now = Date.now();	const MINUTE = 60_000;	const HOUR = 60 * MINUTE;</script>​<Timeline label="Activity on #1042" class="w-[28rem] max-w-full">	<TimelineItem title="Ada Lovelace commented" time={now - 40 * MINUTE}>		{#snippet icon()}<Avatar size="xs" name="Ada Lovelace" colorize />{/snippet}		<Text			variant="body-sm"			class="rounded-shape-md bg-surface-container-low p-3 text-surface-variant-foreground"		>			The inner loop is twice as fast now. Can someone check the edge cases around zero?		</Text>	</TimelineItem>	<TimelineItem title="Labels added" time={now - 3 * HOUR} tone="neutral">		{#snippet icon()}			...		{/snippet}		<div class="flex flex-wrap gap-2">			<Chip size="sm" variant="tonal" tone="tertiary">performance</Chip>			<Chip size="sm" variant="tonal">engine</Chip>		</div>	</TimelineItem>	<TimelineItem title="Opened" description="by Ada Lovelace" time={now - 26 * HOUR} tone="success">		{#snippet icon()}			...		{/snippet}	</TimelineItem></Timeline>

4. Overridden

relative={false} writes dates in dateFormat instead of counting; a time that is not a date is shown as given. classes reaches every part — here a primary line and square markers — and the caller's own attributes stay.

  1. API key rotated

  2. Admin added

    grace@example.com

  3. Next review, In progress

    Every quarter
<script lang="ts">	import { Timeline, TimelineItem } from 'omaris';​	const now = Date.now();	const DAY = 24 * 60 * 60_000;	const marker = { dot: 'rounded-xs', line: 'border-primary/40' };</script>​<Timeline	label="Audit log"	relative={false}	dateFormat={{ day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' }}	class="w-80 max-w-full"	data-log="audit">	<TimelineItem title="API key rotated" time={now - DAY} classes={marker} />	<TimelineItem		title="Admin added"		description="grace@example.com"		time={now - 9 * DAY}		classes={marker}	/>	<TimelineItem title="Next review" time="Every quarter" tone="neutral" pending classes={marker} /></Timeline>