Skip to main content
The Timeline component displays a sequence of events in chronological order with customizable markers.

Basic Usage

import { Timeline } from 'reshaped';

function App() {
  return (
    <Timeline>
      <Timeline.Item>First event</Timeline.Item>
      <Timeline.Item>Second event</Timeline.Item>
      <Timeline.Item>Third event</Timeline.Item>
    </Timeline>
  );
}

Custom Markers

Provide custom marker content:
import { Timeline, Icon, View } from 'reshaped';
import IconCheck from './icons/Check';

<Timeline>
  <Timeline.Item
    markerSlot={
      <View
        backgroundColor="positive"
        borderRadius="circular"
        padding={1}
      >
        <Icon svg={IconCheck} size={4} color="white" />
      </View>
    }
  >
    Completed step
  </Timeline.Item>
  <Timeline.Item
    markerSlot={
      <View
        backgroundColor="neutral"
        borderRadius="circular"
        width={3}
        height={3}
      />
    }
  >
    Active step
  </Timeline.Item>
</Timeline>

Without Markers

Create a timeline without markers:
<Timeline>
  <Timeline.Item markerSlot={null}>
    Full width content without marker
  </Timeline.Item>
  <Timeline.Item markerSlot={null}>
    Another full width item
  </Timeline.Item>
</Timeline>

Rich Content

Timeline items can contain any content:
import { Timeline, View, Text, Badge } from 'reshaped';

<Timeline>
  <Timeline.Item>
    <View gap={2}>
      <View direction="row" gap={2} align="center">
        <Text variant="body-2" weight="semibold">
          Project Created
        </Text>
        <Badge size="small" color="primary">New</Badge>
      </View>
      <Text variant="caption-1" color="neutral-faded">
        January 15, 2024 at 10:30 AM
      </Text>
      <Text variant="body-3">
        Initial project setup and configuration
      </Text>
    </View>
  </Timeline.Item>
</Timeline>

Complete Example

Order status timeline:
import { Timeline, View, Text, Icon } from 'reshaped';
import IconCheck from './icons/Check';
import IconTruck from './icons/Truck';
import IconPackage from './icons/Package';

function OrderTimeline({ order }) {
  const events = [
    {
      id: 1,
      title: 'Order Placed',
      description: 'Your order has been confirmed',
      timestamp: 'Jan 15, 2024 10:30 AM',
      completed: true,
      icon: IconCheck,
    },
    {
      id: 2,
      title: 'Order Packed',
      description: 'Your order is being prepared',
      timestamp: 'Jan 15, 2024 2:15 PM',
      completed: true,
      icon: IconPackage,
    },
    {
      id: 3,
      title: 'Out for Delivery',
      description: 'Your order is on the way',
      timestamp: 'Jan 16, 2024 8:00 AM',
      completed: false,
      icon: IconTruck,
    },
  ];

  return (
    <Timeline>
      {events.map(event => (
        <Timeline.Item
          key={event.id}
          markerSlot={
            <View
              backgroundColor={event.completed ? 'positive' : 'neutral-faded'}
              borderRadius="circular"
              padding={1.5}
            >
              <Icon 
                svg={event.icon} 
                size={4} 
                color={event.completed ? 'white' : 'neutral-faded'} 
              />
            </View>
          }
        >
          <View gap={1}>
            <Text 
              variant="body-2" 
              weight="semibold"
              color={event.completed ? 'neutral' : 'neutral-faded'}
            >
              {event.title}
            </Text>
            <Text 
              variant="body-3" 
              color={event.completed ? 'neutral' : 'neutral-faded'}
            >
              {event.description}
            </Text>
            <Text variant="caption-1" color="neutral-faded">
              {event.timestamp}
            </Text>
          </View>
        </Timeline.Item>
      ))}
    </Timeline>
  );
}

Activity Timeline

User activity feed:
import { Timeline, View, Text, Avatar } from 'reshaped';

function ActivityTimeline({ activities }) {
  return (
    <Timeline>
      {activities.map(activity => (
        <Timeline.Item
          key={activity.id}
          markerSlot={
            <Avatar
              src={activity.user.avatar}
              alt={activity.user.name}
              size={8}
            />
          }
        >
          <View gap={1}>
            <Text variant="body-3">
              <Text as="span" weight="semibold">
                {activity.user.name}
              </Text>{' '}
              {activity.action}
            </Text>
            <Text variant="caption-1" color="neutral-faded">
              {activity.timestamp}
            </Text>
          </View>
        </Timeline.Item>
      ))}
    </Timeline>
  );
}

Stepper Timeline

Multi-step process indicator:
import { Timeline, View, Text } from 'reshaped';

function StepperTimeline({ steps, currentStep }) {
  return (
    <Timeline>
      {steps.map((step, index) => {
        const isCompleted = index < currentStep;
        const isCurrent = index === currentStep;
        
        return (
          <Timeline.Item
            key={step.id}
            markerSlot={
              <View
                borderRadius="circular"
                width={8}
                height={8}
                backgroundColor={
                  isCompleted ? 'positive' : 
                  isCurrent ? 'primary' : 'neutral-faded'
                }
                attributes={{
                  style: {
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                  }
                }}
              >
                <Text 
                  variant="caption-1" 
                  weight="bold"
                  color="white"
                >
                  {index + 1}
                </Text>
              </View>
            }
          >
            <View gap={1} padding={1}>
              <Text 
                variant="body-2" 
                weight="semibold"
                color={isCompleted || isCurrent ? 'neutral' : 'neutral-faded'}
              >
                {step.title}
              </Text>
              <Text 
                variant="caption-1" 
                color="neutral-faded"
              >
                {step.description}
              </Text>
            </View>
          </Timeline.Item>
        );
      })}
    </Timeline>
  );
}

Props

Timeline

className
string
default:"undefined"
Additional classname for the root element.
attributes
object
default:"undefined"
Additional attributes for the root element.
children
ReactNode
default:"undefined"
Node for inserting children. Children are automatically wrapped in Timeline.Item if not already.

Timeline.Item

markerSlot
ReactNode
default:"undefined"
Node for rendering custom item markers. Set to null to remove the marker and make the item full width.
className
string
default:"undefined"
Additional classname for the item element.
attributes
object
default:"undefined"
Additional attributes for the item element.
children
ReactNode
default:"undefined"
Node for inserting children.

Build docs developers (and LLMs) love