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 follow the Radix UI implementation with accessible primitives from the Radix stack 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/r-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-[state=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>
)
}