Timeline

A flexible timeline component with vertical and horizontal layouts, status indicators, and CSS grid alignment. Each example now renders from the same source shown in the code snippet.

Add the component

npx shadcn-svelte@latest add https://shadcn-svelte-timeline.vercel.app/r/timeline.json

Basic

Default vertical timeline with icon indicators.

curtisss requested a review from james_rob · 4 days ago

curtisss added tag feature

james_rob approved these changes · 3 days ago

Source

Svelte

<Timeline.Root>
	<Timeline.Item>
		<Timeline.Indicator>
			<svg
				class="size-3 text-background"
				viewBox="0 0 16 16"
				fill="currentColor"
			>
				<path
					d="M8 3C4.5 3 1.5 5.5 1.5 8S4.5 13 8 13s6.5-2.5 6.5-5S11.5 3 8 3zm0 8a3 3 0 110-6 3 3 0 010 6z"
				/>
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-medium">
				curtisss
				<span class="font-normal text-muted-foreground"
					>requested a review from</span
				>
				james_rob
				<span class="font-normal text-muted-foreground">· 4 days ago</span>
			</p>
		</Timeline.Content>
	</Timeline.Item>
	<Timeline.Item>
		<Timeline.Indicator>
			<svg
				class="size-3 text-background"
				viewBox="0 0 16 16"
				fill="currentColor"
			>
				<path
					d="M2 2h5.586l6 6a2 2 0 010 2.828l-2.758 2.758a2 2 0 01-2.828 0L2 7.586V2zm3 3a1 1 0 100-2 1 1 0 000 2z"
				/>
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-medium">
				curtisss
				<span class="font-normal text-muted-foreground">added tag</span>
				<span
					class="inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium"
				>
					feature
				</span>
			</p>
		</Timeline.Content>
	</Timeline.Item>
	<Timeline.Item>
		<Timeline.Indicator class="bg-green-500">
			<svg
				class="size-3 text-white"
				viewBox="0 0 16 16"
				fill="none"
				stroke="currentColor"
				stroke-width="2.5"
				stroke-linecap="round"
				stroke-linejoin="round"
			>
				<path d="M3 8l3.5 3.5L13 4" />
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-medium">
				james_rob
				<span class="font-normal text-muted-foreground"
					>approved these changes · 3 days ago</span
				>
			</p>
		</Timeline.Content>
	</Timeline.Item>
</Timeline.Root>

Large

Use `size="lg"` for numbered steps or more prominent indicators.

1

Submit

Complete the form and provide all necessary assets.

2

Review

Verify your data and approve the final draft for accuracy.

3

Publish

Finalize your settings and push your content live.

Source

Svelte

<Timeline.Root size="lg">
	<Timeline.Item>
		<Timeline.Indicator>1</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-semibold">Submit</p>
			<p class="text-sm text-muted-foreground">
				Complete the form and provide all necessary assets.
			</p>
		</Timeline.Content>
	</Timeline.Item>
	<Timeline.Item>
		<Timeline.Indicator>2</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-semibold">Review</p>
			<p class="text-sm text-muted-foreground">
				Verify your data and approve the final draft for accuracy.
			</p>
		</Timeline.Content>
	</Timeline.Item>
	<Timeline.Item>
		<Timeline.Indicator>3</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-semibold">Publish</p>
			<p class="text-sm text-muted-foreground">
				Finalize your settings and push your content live.
			</p>
		</Timeline.Content>
	</Timeline.Item>
</Timeline.Root>

Horizontal

Use `horizontal` to render the timeline horizontally.

Order confirmed

On its way

Delivered

Source

Svelte

<Timeline.Root horizontal>
	<Timeline.Item>
		<Timeline.Indicator>
			<svg
				class="size-3 text-background"
				viewBox="0 0 16 16"
				fill="currentColor"
			>
				<rect x="1" y="3" width="14" height="10" rx="1.5" />
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-xs font-medium">Order confirmed</p>
		</Timeline.Content>
	</Timeline.Item>
	<Timeline.Item>
		<Timeline.Indicator>
			<svg
				class="size-3 text-background"
				viewBox="0 0 16 16"
				fill="currentColor"
			>
				<path
					d="M1 3a1 1 0 011-1h8a1 1 0 011 1v7H1V3zm9 0v7h1.5L13 7.5V6l-2-3H10zm-7 9a1.5 1.5 0 100 3 1.5 1.5 0 000-3zm8 0a1.5 1.5 0 100 3 1.5 1.5 0 000-3z"
				/>
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-xs font-medium">On its way</p>
		</Timeline.Content>
	</Timeline.Item>
	<Timeline.Item>
		<Timeline.Indicator>
			<svg
				class="size-3 text-background"
				viewBox="0 0 16 16"
				fill="currentColor"
			>
				<path d="M8 1L1 7v8h5V11h4v4h5V7L8 1z" />
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-xs font-medium">Delivered</p>
		</Timeline.Content>
	</Timeline.Item>
</Timeline.Root>

Status

Use `status` on timeline items to indicate progress.

Order confirmed

On its way

Delivered

Source

Svelte

<Timeline.Root horizontal>
	<Timeline.Item status="complete">
		<Timeline.Indicator>
			<svg
				class="size-3 text-primary-foreground"
				viewBox="0 0 16 16"
				fill="none"
				stroke="currentColor"
				stroke-width="2.5"
				stroke-linecap="round"
				stroke-linejoin="round"
			>
				<path d="M3 8l3.5 3.5L13 4" />
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-xs font-medium">Order confirmed</p>
		</Timeline.Content>
	</Timeline.Item>
	<Timeline.Item status="current">
		<Timeline.Indicator>
			<svg
				class="size-3 text-primary-foreground"
				viewBox="0 0 16 16"
				fill="currentColor"
			>
				<path
					d="M1 3a1 1 0 011-1h8a1 1 0 011 1v7H1V3zm9 0v7h1.5L13 7.5V6l-2-3H10zm-7 9a1.5 1.5 0 100 3 1.5 1.5 0 000-3zm8 0a1.5 1.5 0 100 3 1.5 1.5 0 000-3z"
				/>
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-xs font-medium">On its way</p>
		</Timeline.Content>
	</Timeline.Item>
	<Timeline.Item status="incomplete">
		<Timeline.Indicator>
			<svg
				class="size-3 text-muted-foreground"
				viewBox="0 0 16 16"
				fill="currentColor"
			>
				<path d="M8 1L1 7v8h5V11h4v4h5V7L8 1z" />
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-xs font-medium text-muted-foreground">Delivered</p>
		</Timeline.Content>
	</Timeline.Item>
</Timeline.Root>

Indicator colors

Use indicator classes to set a custom colored background.

Build failed

Tests did not pass

Warning issued

Deprecated API usage detected

Deployed successfully

Production v2.4.1 is live

Source

Svelte

<Timeline.Root>
	<Timeline.Item>
		<Timeline.Indicator class="bg-red-500">
			<svg
				class="size-3 text-white"
				viewBox="0 0 16 16"
				fill="none"
				stroke="currentColor"
				stroke-width="2.5"
				stroke-linecap="round"
			>
				<path d="M4 4l8 8M12 4l-8 8" />
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-medium">Build failed</p>
			<p class="text-xs text-muted-foreground">Tests did not pass</p>
		</Timeline.Content>
	</Timeline.Item>
	<Timeline.Item>
		<Timeline.Indicator class="bg-amber-500">
			<svg class="size-3 text-white" viewBox="0 0 16 16" fill="currentColor">
				<path
					d="M8 2l1.5 4.5H14l-3.5 2.5 1.5 4.5L8 11l-4 2.5 1.5-4.5L2 6.5h4.5L8 2z"
				/>
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-medium">Warning issued</p>
			<p class="text-xs text-muted-foreground">Deprecated API usage detected</p>
		</Timeline.Content>
	</Timeline.Item>
	<Timeline.Item>
		<Timeline.Indicator class="bg-green-500">
			<svg
				class="size-3 text-white"
				viewBox="0 0 16 16"
				fill="none"
				stroke="currentColor"
				stroke-width="2.5"
				stroke-linecap="round"
				stroke-linejoin="round"
			>
				<path d="M3 8l3.5 3.5L13 4" />
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-medium">Deployed successfully</p>
			<p class="text-xs text-muted-foreground">Production v2.4.1 is live</p>
		</Timeline.Content>
	</Timeline.Item>
</Timeline.Root>

Bare indicator

Use `variant="bare"` for larger standalone icon indicators.

Draft created · 2 days ago

Edits made · 1 day ago

Published · just now

Source

Svelte

<Timeline.Root>
	<Timeline.Item>
		<Timeline.Indicator variant="bare">
			<svg
				class="size-6 text-muted-foreground/60"
				viewBox="0 0 24 24"
				fill="none"
				stroke="currentColor"
				stroke-width="1.5"
			>
				<path
					stroke-linecap="round"
					stroke-linejoin="round"
					d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z"
				/>
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-medium">
				Draft created
				<span class="font-normal text-muted-foreground">· 2 days ago</span>
			</p>
		</Timeline.Content>
	</Timeline.Item>
	<Timeline.Item>
		<Timeline.Indicator variant="bare">
			<svg
				class="size-6 text-muted-foreground/60"
				viewBox="0 0 24 24"
				fill="none"
				stroke="currentColor"
				stroke-width="1.5"
			>
				<path
					stroke-linecap="round"
					stroke-linejoin="round"
					d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10"
				/>
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-medium">
				Edits made
				<span class="font-normal text-muted-foreground">· 1 day ago</span>
			</p>
		</Timeline.Content>
	</Timeline.Item>
	<Timeline.Item>
		<Timeline.Indicator variant="bare">
			<svg
				class="size-6 text-green-500"
				viewBox="0 0 24 24"
				fill="none"
				stroke="currentColor"
				stroke-width="1.5"
			>
				<path
					stroke-linecap="round"
					stroke-linejoin="round"
					d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
				/>
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-medium">
				Published
				<span class="font-normal text-muted-foreground">· just now</span>
			</p>
		</Timeline.Content>
	</Timeline.Item>
</Timeline.Root>

Block item

Use `Timeline.Block` for full-width content blocks spanning both columns.

curtisss requested a review · 4 days ago

JR

james_rob replied to your message · 4 days ago

Looks good to me! Just a few minor nits to address.

curtisss added tag feature

james_rob approved these changes · 3 days ago

Source

Svelte

<Timeline.Root>
	<Timeline.Item>
		<Timeline.Indicator>
			<svg
				class="size-3 text-background"
				viewBox="0 0 16 16"
				fill="currentColor"
			>
				<path
					d="M8 3C4.5 3 1.5 5.5 1.5 8S4.5 13 8 13s6.5-2.5 6.5-5S11.5 3 8 3zm0 8a3 3 0 110-6 3 3 0 010 6z"
				/>
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-medium">
				curtisss
				<span class="font-normal text-muted-foreground"
					>requested a review · 4 days ago</span
				>
			</p>
		</Timeline.Content>
	</Timeline.Item>
	<Timeline.Item>
		<Timeline.Block>
			<div class="col-span-full rounded-xl border bg-card p-4">
				<div class="flex items-start gap-3">
					<div
						class="flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-xs font-semibold"
					>
						JR
					</div>
					<div class="space-y-1">
						<p class="text-sm font-medium">
							james_rob
							<span class="font-normal text-muted-foreground"
								>replied to your message · 4 days ago</span
							>
						</p>
						<p class="text-sm text-muted-foreground">
							Looks good to me! Just a few minor nits to address.
						</p>
					</div>
				</div>
				<div class="mt-3 flex gap-2">
					<button
						class="rounded-md border px-3 py-1.5 text-xs font-medium hover:bg-accent"
					>
						View message
					</button>
					<button
						class="rounded-md px-3 py-1.5 text-xs font-medium text-muted-foreground hover:bg-accent hover:text-foreground"
					>
						Reply
					</button>
				</div>
			</div>
		</Timeline.Block>
	</Timeline.Item>
	<Timeline.Item>
		<Timeline.Indicator>
			<svg
				class="size-3 text-background"
				viewBox="0 0 16 16"
				fill="currentColor"
			>
				<path
					d="M2 2h5.586l6 6a2 2 0 010 2.828l-2.758 2.758a2 2 0 01-2.828 0L2 7.586V2zm3 3a1 1 0 100-2 1 1 0 000 2z"
				/>
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-medium">
				curtisss
				<span class="font-normal text-muted-foreground">added tag</span>
				<span
					class="inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium"
				>
					feature
				</span>
			</p>
		</Timeline.Content>
	</Timeline.Item>
	<Timeline.Item>
		<Timeline.Indicator class="bg-green-500">
			<svg
				class="size-3 text-white"
				viewBox="0 0 16 16"
				fill="none"
				stroke="currentColor"
				stroke-width="2.5"
				stroke-linecap="round"
				stroke-linejoin="round"
			>
				<path d="M3 8l3.5 3.5L13 4" />
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-medium">
				james_rob
				<span class="font-normal text-muted-foreground"
					>approved these changes · 3 days ago</span
				>
			</p>
		</Timeline.Content>
	</Timeline.Item>
</Timeline.Root>

Block subgrid

Use `Timeline.Subgrid` inside a block to align avatars and content to the timeline's column tracks.

curtisss requested a review · 4 days ago

JR

james_rob commented · 4 days ago

Contrast slider goes a bit wild at the top end...

ME

james_rob approved these changes · 3 days ago

Source

Svelte

<Timeline.Root>
	<Timeline.Item>
		<Timeline.Indicator>
			<svg
				class="size-3 text-background"
				viewBox="0 0 16 16"
				fill="currentColor"
			>
				<path
					d="M8 3C4.5 3 1.5 5.5 1.5 8S4.5 13 8 13s6.5-2.5 6.5-5S11.5 3 8 3zm0 8a3 3 0 110-6 3 3 0 010 6z"
				/>
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-medium">
				curtisss
				<span class="font-normal text-muted-foreground"
					>requested a review · 4 days ago</span
				>
			</p>
		</Timeline.Content>
	</Timeline.Item>
	<Timeline.Item>
		<div class="col-span-full grid auto-rows-auto grid-cols-subgrid">
			<Timeline.Block
				class="overflow-hidden rounded-xl border bg-card after:h-0"
			>
				<Timeline.Subgrid class="bg-muted/30 p-3">
					<div
						class="flex size-6 shrink-0 items-center justify-center rounded-full bg-muted text-[10px] font-semibold"
					>
						JR
					</div>
					<div class="space-y-1">
						<p class="text-sm font-medium">
							james_rob
							<span class="font-normal text-muted-foreground"
								>commented · 4 days ago</span
							>
						</p>
						<p class="text-sm text-muted-foreground">
							Contrast slider goes a bit wild at the top end...
						</p>
					</div>
				</Timeline.Subgrid>
				<div class="col-span-full border-t"></div>
				<Timeline.Subgrid class="bg-background p-3">
					<div
						class="flex size-6 shrink-0 items-center justify-center rounded-full bg-primary text-[10px] font-semibold text-primary-foreground"
					>
						ME
					</div>
					<div>
						<input
							type="text"
							placeholder="Leave a reply..."
							class="w-full rounded-md border bg-background px-3 py-1.5 text-sm outline-none focus:ring-2 focus:ring-ring"
						>
					</div>
				</Timeline.Subgrid>
			</Timeline.Block>
			<div aria-hidden="true" class="col-span-full h-6"></div>
		</div>
	</Timeline.Item>
	<Timeline.Item>
		<Timeline.Indicator class="bg-green-500">
			<svg
				class="size-3 text-white"
				viewBox="0 0 16 16"
				fill="none"
				stroke="currentColor"
				stroke-width="2.5"
				stroke-linecap="round"
				stroke-linejoin="round"
			>
				<path d="M3 8l3.5 3.5L13 4" />
			</svg>
		</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-medium">
				james_rob
				<span class="font-normal text-muted-foreground"
					>approved these changes · 3 days ago</span
				>
			</p>
		</Timeline.Content>
	</Timeline.Item>
</Timeline.Root>

Alignment start

Use `align="start"` to anchor indicators to the top of each item row.

1

Start align

Place the indicator at the start edge of the item row.

2

Second item

Another item using the same indicator placement.

Source

Svelte

<Timeline.Root size="lg" align="start">
	<Timeline.Item>
		<Timeline.Indicator>1</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-semibold">Start align</p>
			<p class="text-sm text-muted-foreground">
				Place the indicator at the start edge of the item row.
			</p>
		</Timeline.Content>
	</Timeline.Item>
	<Timeline.Item>
		<Timeline.Indicator>2</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-semibold">Second item</p>
			<p class="text-sm text-muted-foreground">
				Another item using the same indicator placement.
			</p>
		</Timeline.Content>
	</Timeline.Item>
</Timeline.Root>

Alignment baseline

Use `align="baseline"` to match the default vertical placement. It currently renders the same as `start`.

2

Baseline align

Place the indicator at the baseline edge of the item row.

3

Second item

Another item using the same indicator placement.

Source

Svelte

<Timeline.Root size="lg" align="baseline">
	<Timeline.Item>
		<Timeline.Indicator>2</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-semibold">Baseline align</p>
			<p class="text-sm text-muted-foreground">
				Place the indicator at the baseline edge of the item row.
			</p>
		</Timeline.Content>
	</Timeline.Item>
	<Timeline.Item>
		<Timeline.Indicator>3</Timeline.Indicator>
		<Timeline.Content>
			<p class="text-sm font-semibold">Second item</p>
			<p class="text-sm text-muted-foreground">
				Another item using the same indicator placement.
			</p>
		</Timeline.Content>
	</Timeline.Item>
</Timeline.Root>