Components

Timeline

Vertical timeline with status indicators, alternate layout, animated entrance, and custom content slots.

Client Only

Installation

pnpm dlx @docyrus/cli add @docyrus/ui-timeline
Required Packages(1 package)
pnpm add motion

Usage

import { Timeline, type TimelineItem } from "@docyrus/ui/components/timeline";

const items: TimelineItem[] = [
  { title: "Order placed", description: "Confirmed", time: "10:00 AM", status: "completed" },
  { title: "Shipped", description: "On the way", time: "2:00 PM", status: "active" },
  { title: "Delivered", time: "—", status: "pending" },
];

<Timeline items={items} size="md" layout="left" />

Variants

VariantDescription
defaultFilled dot — bg-primary
outlineOutlined dot — border-2 border-primary bg-transparent

Sizes

SizeDotStatus DotText
sm10px20pxtext-sm / text-xs
md12px24pxtext-sm / text-sm
lg16px28pxtext-base / text-sm

Layouts

LayoutDescription
leftContent on the right side of the timeline (default)
alternateContent alternates left and right
rightContent on the left side of the timeline

Status Indicators

When TimelineItem.status is set, the dot renders a status icon instead of a plain dot.

StatusAppearanceLine Style
completedGreen circle with check iconSolid primary
activePrimary circle with inner ringDashed primary
pendingSmall muted circle (opacity 50%)Dashed muted
errorRed circle with X iconSolid destructive

Line Styles

StyleDescription
solidContinuous line (default for completed/error)
dashedDashed line (default for active/pending)

Line style can be set globally via lineStyle prop or per-item via TimelineItem.lineStyle.

Custom Content

Each item supports a content slot for arbitrary React nodes below the description:

const items: TimelineItem[] = [
  {
    title: "Shipped",
    status: "active",
    content: (
      <span className="inline-flex rounded-full bg-primary/10 px-2.5 py-0.5 text-xs font-semibold text-primary">
        In Transit
      </span>
    ),
  },
];

Custom Icons

Use the icon slot to render a custom icon instead of the default dot:

import { Rocket } from "lucide-react";

const items: TimelineItem[] = [
  {
    title: "Launch",
    icon: <Rocket className="size-4 text-primary" />,
  },
];

Custom Dot Colors

Use dotColor to override the dot color for individual items (works with both default and outline variants):

const items: TimelineItem[] = [
  { title: "Warning", dotColor: "hsl(var(--warning))" },
  { title: "Success", dotColor: "hsl(var(--success))" },
];

Animation

Set animated to enable staggered fade-in entrance with framer-motion:

<Timeline items={items} animated />

API Reference

TimelineProps

PropTypeDefaultDescription
itemsTimelineItem[]—Array of timeline events (required)
size'sm' | 'md' | 'lg''md'Size of dots, text, and spacing
variant'default' | 'outline''default'Dot style (filled or outlined)
lineStyle'solid' | 'dashed'—Global line style (overridden by item.lineStyle or status)
layout'left' | 'alternate' | 'right''left'Content placement relative to timeline
animatedbooleanfalseEnable staggered entrance animation
onItemClick(item: TimelineItem, index: number) => void—Click handler for items
titleClassNamestring—Custom class for title text
descriptionClassNamestring—Custom class for description text
timeClassNamestring—Custom class for time text
classNamestring—Container className

TimelineItem

PropertyTypeDefaultDescription
titlestring—Item title (required)
descriptionstring—Item description text
timestring—Time label
iconReactNode—Custom icon replacing the dot
dotColorstring—Override dot color
status'completed' | 'active' | 'pending' | 'error'—Status indicator (replaces dot with icon)
contentReactNode—Custom content below description
lineStyle'solid' | 'dashed'—Per-item line style override

Type Exports

TypeDescription
TimelinePropsProps for the Timeline component
TimelineItemIndividual timeline item configuration
TimelineSize'sm' | 'md' | 'lg'
TimelineVariant'default' | 'outline'
TimelineStatus'completed' | 'active' | 'pending' | 'error'
TimelineLineStyle'solid' | 'dashed'
TimelineLayout'left' | 'alternate' | 'right'

On this page