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>
);
}
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.