Custom Shadcn Timeline for React and Tailwind CSS. A visual representation of events in chronological order.
Browse 12 production-ready Shadcn Timeline components for dashboards, forms, and product UI. These examples use Base UI primitives from @base-ui/react and stay fully compatible with Shadcn Create so radius, color, and typography match your configured theme.
Browse all 12 Shadcn Timeline components for copy-ready layouts, dashboards, and forms built with Tailwind CSS in the ReUI library.
import {
Timeline,
TimelineContent,
TimelineDate,
TimelineHeader,
TimelineIndicator,
TimelineItem,
TimelineSeparator,
TimelineTitle,
} from "@/components/reui/timeline"<Timeline>
<TimelineItem step={1}>
<TimelineHeader>
<TimelineDate>March 2024</TimelineDate>
<TimelineTitle>Project Initialized</TimelineTitle>
</TimelineHeader>
<TimelineIndicator />
<TimelineSeparator />
<TimelineContent>
Successfully set up the project repository and initial architecture.
</TimelineContent>
</TimelineItem>
</Timeline>The root component for the timeline.
A single item in the timeline.
The date or time label for a timeline item.
The title for a timeline item.
The visual indicator (usually a dot) for a timeline item.
The line connecting timeline indicators.
A container for the date and title.
The main descriptive content for a timeline item.
import {
Timeline,
TimelineContent,
TimelineDate,
TimelineHeader,
TimelineIndicator,
TimelineItem,
TimelineSeparator,
TimelineTitle,
} from "@/components/reui/timeline"
export function Pattern() {
return (
<Timeline defaultValue={2} className="w-full max-w-md">
<TimelineItem step={1}>
<TimelineHeader>
<TimelineDate>March 2024</TimelineDate>
<TimelineTitle>Project Initialized</TimelineTitle>
</TimelineHeader>
<TimelineIndicator />
<TimelineSeparator />
<TimelineContent>
Successfully set up the project repository and initial architecture.
</TimelineContent>
</TimelineItem>
<TimelineItem step={2}>
<TimelineHeader>
<TimelineDate>April 2024</TimelineDate>
<TimelineTitle>Beta Release</TimelineTitle>
</TimelineHeader>
<TimelineIndicator />
<TimelineSeparator />
<TimelineContent>
Launched the beta version for early testers and feedback.
</TimelineContent>
</TimelineItem>
<TimelineItem step={3}>
<TimelineHeader>
<TimelineDate>June 2024</TimelineDate>
<TimelineTitle>Official Launch</TimelineTitle>
</TimelineHeader>
<TimelineIndicator />
<TimelineSeparator />
<TimelineContent>
The platform is now live for all users worldwide.
</TimelineContent>
</TimelineItem>
</Timeline>
)
}
import {
Timeline,
TimelineContent,
TimelineDate,
TimelineHeader,
TimelineIndicator,
TimelineItem,
TimelineSeparator,
TimelineTitle,
} from "@/components/reui/timeline"
const roadmap = [
{
id: 1,
date: "Jan 2025",
title: "AI Engine Integration",
description:
"Deep integration of advanced LLMs for real-time code generation and context-aware suggestions.",
},
{
id: 2,
date: "Feb 2025",
title: "Collaborative Editing",
description:
"Multi-user real-time collaboration with shared cursors and instant synchronization across workspaces.",
},
{
id: 3,
date: "Mar 2025",
title: "Visual Theme Builder",
description:
"Interactive interface for creating and managing custom design systems with automated CSS variable generation.",
},
{
id: 4,
date: "Apr 2025",
title: "Enterprise Security",
description:
"Role-based access control, SOC2 compliance audit, and enhanced data encryption protocols.",
},
]
export function Pattern() {
return (
<Timeline defaultValue={2} className="w-full max-w-md">
{roadmap.map((item) => (
<TimelineItem
key={item.id}
step={item.id}
className="sm:group-data-[orientation=vertical]/timeline:ms-32"
>
<TimelineHeader>
<TimelineSeparator />
<TimelineDate className="sm:group-data-[orientation=vertical]/timeline:absolute sm:group-data-[orientation=vertical]/timeline:-left-32 sm:group-data-[orientation=vertical]/timeline:w-20 sm:group-data-[orientation=vertical]/timeline:text-right">
{item.date}
</TimelineDate>
<TimelineTitle className="sm:-mt-0.5">{item.title}</TimelineTitle>
<TimelineIndicator />
</TimelineHeader>
<TimelineContent>{item.description}</TimelineContent>
</TimelineItem>
))}
</Timeline>
)
}
import {
Timeline,
TimelineContent,
TimelineDate,
TimelineHeader,
TimelineIndicator,
TimelineItem,
TimelineSeparator,
TimelineTitle,
} from "@/components/reui/timeline"
import { CheckIcon } from 'lucide-react'
const orderStatus = [
{
id: 1,
date: "Mar 15, 2024",
title: "Order Placed",
description: "Your order has been received and is being processed.",
},
{
id: 2,
date: "Mar 16, 2024",
title: "Payment Confirmed",
description: "Transaction successful. Preparing for shipment.",
},
{
id: 3,
date: "Mar 18, 2024",
title: "Shipped",
description: "Your package is on its way. Track your delivery.",
},
{
id: 4,
date: "Mar 20, 2024",
title: "Delivered",
description: "Package successfully delivered to the recipient.",
},
]
export function Pattern() {
return (
<Timeline defaultValue={3} className="w-full max-w-md">
{orderStatus.map((item) => (
<TimelineItem
key={item.id}
step={item.id}
className="group-data-[orientation=vertical]/timeline:ms-10"
>
<TimelineHeader>
<TimelineSeparator className="group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-6.5" />
<TimelineDate>{item.date}</TimelineDate>
<TimelineTitle>{item.title}</TimelineTitle>
<TimelineIndicator className="group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 items-center justify-center group-data-completed/timeline-item:border-none group-data-[orientation=vertical]/timeline:-left-7">
<CheckIcon className="size-4 group-not-data-completed/timeline-item:hidden" />
</TimelineIndicator>
</TimelineHeader>
<TimelineContent>{item.description}</TimelineContent>
</TimelineItem>
))}
</Timeline>
)
}
import {
Timeline,
TimelineContent,
TimelineDate,
TimelineHeader,
TimelineIndicator,
TimelineItem,
TimelineSeparator,
TimelineTitle,
} from "@/components/reui/timeline"
import { GitCompareArrowsIcon, GitForkIcon, GitMergeIcon, GitPullRequestArrowIcon } from 'lucide-react'
const gitActivity = [
{
id: 1,
date: "15 minutes ago",
title: "Forked Repository",
description:
"Forked the repository to create a new branch for development.",
icon: (
<GitForkIcon className="size-4" />
),
},
{
id: 2,
date: "10 minutes ago",
title: "Pull Request Submitted",
description:
"Submitted PR #342 with new feature implementation. Waiting for code review.",
icon: (
<GitPullRequestArrowIcon className="size-3.5" />
),
},
{
id: 3,
date: "5 minutes ago",
title: "Comparing Branches",
description:
"Received comments on PR. Minor adjustments needed in error handling.",
icon: (
<GitCompareArrowsIcon className="size-3.5" />
),
},
{
id: 4,
date: "Just now",
title: "Merged Branch",
description:
"Merged the feature branch into the main branch. Ready for deployment.",
icon: (
<GitMergeIcon className="size-3.5" />
),
},
]
export function Pattern() {
return (
<Timeline defaultValue={3} className="w-full max-w-md">
{gitActivity.map((item) => (
<TimelineItem
key={item.id}
step={item.id}
className="group-data-[orientation=vertical]/timeline:ms-10"
>
<TimelineHeader>
<TimelineSeparator className="group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-6.5" />
<TimelineTitle className="mt-0.5">{item.title}</TimelineTitle>
<TimelineIndicator className="bg-primary/10 group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 items-center justify-center border-none group-data-[orientation=vertical]/timeline:-left-7">
{item.icon}
</TimelineIndicator>
</TimelineHeader>
<TimelineContent>
{item.description}
<TimelineDate className="mt-2 mb-0">{item.date}</TimelineDate>
</TimelineContent>
</TimelineItem>
))}
</Timeline>
)
}
import {
Timeline,
TimelineDate,
TimelineHeader,
TimelineIndicator,
TimelineItem,
TimelineSeparator,
TimelineTitle,
} from "@/components/reui/timeline"
import { cn } from "@/lib/utils"
const milestones = [
{
id: 1,
date: "Jan 2024",
title: "Seed Funding",
},
{
id: 2,
date: "Mar 2024",
title: "Product MVP",
},
{
id: 3,
date: "May 2024",
title: "First Client",
},
{
id: 4,
date: "Jul 2024",
title: "Series A",
},
{
id: 5,
date: "Sep 2024",
title: "Global Expansion",
},
]
export function Pattern() {
return (
<Timeline defaultValue={3} className="w-full max-w-md">
{milestones.map((item) => (
<TimelineItem
key={item.id}
step={item.id}
className={cn(
"w-[calc(50%-1.5rem)] odd:ms-auto even:me-auto even:text-right even:group-data-[orientation=vertical]/timeline:ms-0 even:group-data-[orientation=vertical]/timeline:me-8",
"even:group-data-[orientation=vertical]/timeline:**:data-[slot=timeline-indicator]:-right-6 even:group-data-[orientation=vertical]/timeline:**:data-[slot=timeline-indicator]:left-auto",
"even:group-data-[orientation=vertical]/timeline:**:data-[slot=timeline-indicator]:translate-x-1/2 even:group-data-[orientation=vertical]/timeline:**:data-[slot=timeline-separator]:-right-6",
"even:group-data-[orientation=vertical]/timeline:**:data-[slot=timeline-separator]:left-auto even:group-data-[orientation=vertical]/timeline:**:data-[slot=timeline-separator]:translate-x-1/2"
)}
>
<TimelineHeader>
<TimelineSeparator />
<TimelineDate>{item.date}</TimelineDate>
<TimelineTitle>{item.title}</TimelineTitle>
<TimelineIndicator />
</TimelineHeader>
</TimelineItem>
))}
</Timeline>
)
}
import { Badge } from "@/components/reui/badge"
import {
Frame,
FrameHeader,
FramePanel,
} from "@/components/reui/frame"
import {
Timeline,
TimelineContent,
TimelineHeader,
TimelineIndicator,
TimelineItem,
TimelineSeparator,
TimelineTitle,
} from "@/components/reui/timeline"
import { cn } from "@/lib/utils"
import {
Avatar,
AvatarFallback,
AvatarImage,
} from "@/components/ui/avatar"
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible"
import { Spinner } from "@/components/ui/spinner"
import { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react'
const pipelineSteps = [
{
id: 1,
title: "Source Code Checkout",
duration: "12s",
status: "completed",
description: "Successfully fetched latest changes from the main branch.",
user: {
name: "Alex Johnson",
avatar:
"https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=96&h=96&dpr=2&q=80",
},
},
{
id: 2,
title: "Dependency Installation",
duration: "1m 45s",
status: "completed",
description: "All npm packages installed and cached for future builds.",
user: {
name: "Sarah Chen",
avatar:
"https://images.unsplash.com/photo-1519699047748-de8e457a634e?w=96&h=96&dpr=2&q=80",
},
},
{
id: 3,
title: "Unit & Integration Tests",
duration: "Running",
status: "active",
description: "Running 142 test suites across the entire codebase...",
user: {
name: "Michael Rodriguez",
avatar:
"https://images.unsplash.com/photo-1584308972272-9e4e7685e80f?w=96&h=96&dpr=2&q=80",
},
},
{
id: 4,
title: "Production Build",
duration: "Pending",
status: "pending",
description: "Optimizing assets and generating static site pages.",
user: {
name: "Emma Wilson",
avatar:
"https://images.unsplash.com/photo-1485893086445-ed75865251e0?w=96&h=96&dpr=2&q=80",
},
},
]
function StatusIcon({ status }: { status: string }) {
if (status === "completed")
return (
<CheckIcon className="size-3.5" />
)
if (status === "active") return <Spinner className="size-3.5" />
return (
<CircleIcon className="size-3.5" />
)
}
function StatusBadge({
status,
duration,
}: {
status: string
duration: string
}) {
const variant =
status === "completed"
? "success-light"
: status === "active"
? "info-light"
: "warning-light"
return (
<Badge variant={variant} size="sm">
{duration}
</Badge>
)
}
export function Pattern() {
return (
<div className="w-full max-w-lg">
<Timeline defaultValue={3}>
{pipelineSteps.map((step) => (
<TimelineItem key={step.id} step={step.id} className="ms-10 pb-10">
<TimelineHeader>
<TimelineSeparator className="group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-7" />
<div className="flex items-center gap-2">
<TimelineTitle className="text-sm font-semibold">
{step.title}
</TimelineTitle>
<StatusBadge status={step.status} duration={step.duration} />
</div>
<TimelineIndicator
className={cn(
"bg-muted text-muted-foreground group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 items-center justify-center border-none group-data-[orientation=vertical]/timeline:-left-7",
step.status === "active" && "ring-primary/20 ring-2"
)}
>
<StatusIcon status={step.status} />
</TimelineIndicator>
</TimelineHeader>
<TimelineContent className="mt-2">
<Frame stacked dense spacing="sm">
<Collapsible defaultOpen className="group/collapsible">
<CollapsibleTrigger className="flex w-full">
<FrameHeader className="flex grow flex-row items-center justify-between gap-2">
<div className="flex items-center gap-2">
<Avatar className="size-5">
<AvatarImage
src={step.user.avatar}
alt={step.user.name}
/>
<AvatarFallback>
{step.user.name.charAt(0)}
</AvatarFallback>
</Avatar>
<span className="text-muted-foreground text-xs font-medium">
{step.user.name}
</span>
</div>
<ChevronRightIcon className="text-muted-foreground size-4 transition-transform duration-200 group-data-open/collapsible:rotate-90" />
</FrameHeader>
</CollapsibleTrigger>
<CollapsibleContent>
<FramePanel>
<p className="text-muted-foreground text-sm leading-relaxed">
{step.description}
</p>
</FramePanel>
</CollapsibleContent>
</Collapsible>
</Frame>
</TimelineContent>
</TimelineItem>
))}
</Timeline>
</div>
)
}
import { Badge } from "@/components/reui/badge"
import {
Timeline,
TimelineContent,
TimelineDate,
TimelineHeader,
TimelineIndicator,
TimelineItem,
TimelineSeparator,
TimelineTitle,
} from "@/components/reui/timeline"
import { cn } from "@/lib/utils"
import { CheckIcon, XIcon } from 'lucide-react'
const deployments = [
{
id: 1,
title: "Production Deploy",
date: "2 minutes ago",
commit: "a1b2c3d",
branch: "main",
status: "success",
duration: "42s",
},
{
id: 2,
title: "Staging Deploy",
date: "15 minutes ago",
commit: "e4f5g6h",
branch: "staging",
status: "success",
duration: "38s",
},
{
id: 3,
title: "Preview Deploy",
date: "1 hour ago",
commit: "i7j8k9l",
branch: "feat/auth",
status: "failed",
duration: "1m 12s",
},
{
id: 4,
title: "Production Deploy",
date: "3 hours ago",
commit: "m0n1o2p",
branch: "main",
status: "success",
duration: "45s",
},
]
export function Pattern() {
return (
<div className="w-full max-w-xs">
<Timeline defaultValue={4}>
{deployments.map((deploy) => (
<TimelineItem
key={deploy.id}
step={deploy.id}
className="group-data-[orientation=vertical]/timeline:ms-10"
>
<TimelineHeader>
<TimelineSeparator className="bg-input! group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-6.5" />
<div className="flex items-center gap-2">
<TimelineTitle className="text-sm">
{deploy.title}
</TimelineTitle>
<Badge
variant={
deploy.status === "success"
? "success-light"
: "destructive-light"
}
size="sm"
>
{deploy.status}
</Badge>
</div>
<TimelineIndicator
className={cn(
"flex size-6 items-center justify-center border-none group-data-[orientation=vertical]/timeline:-left-7",
deploy.status === "success"
? "bg-emerald-500 text-white"
: "bg-destructive text-white"
)}
>
{deploy.status === "success" ? (
<CheckIcon className="size-3.5" />
) : (
<XIcon className="size-3.5" />
)}
</TimelineIndicator>
</TimelineHeader>
<TimelineContent>
<div className="text-muted-foreground flex items-center gap-3 text-xs">
<span className="font-mono">{deploy.commit}</span>
<span>·</span>
<span>{deploy.branch}</span>
<span>·</span>
<span>{deploy.duration}</span>
</div>
<TimelineDate className="mt-1 mb-0">{deploy.date}</TimelineDate>
</TimelineContent>
</TimelineItem>
))}
</Timeline>
</div>
)
}