Timeline

Material Design 3 timeline component for displaying chronological events and milestones

Timeline

Timelines display a list of events in chronological order, helping users understand the sequence of events and milestones. @duskmoon-dev/core provides a flexible Material Design 3-inspired timeline component.

Basic Usage

Basic Timeline

2 hours ago

Project Started

The project has been initialized and setup is complete.

1 hour ago

First Commit

Initial code structure and dependencies added.

30 minutes ago

Tests Passing

All unit tests are now passing successfully.

Layouts

Vertical Timeline (Default)

The default layout displays events vertically with a connecting line:

Vertical Timeline

January 15, 2025

Planning Phase

Initial project planning and requirements gathering.

February 1, 2025

Development Begins

Started coding the core features.

Horizontal Timeline

Display events horizontally for a different perspective:

Horizontal Timeline

Q1 2025

Phase 1

Initial development

Q2 2025

Phase 2

Feature expansion

Q3 2025

Phase 3

Launch preparation

Alternate Layout (Zigzag)

Create a zigzag pattern with alternating sides:

Alternate Layout Timeline

Step 1

Discovery

Understanding user needs and requirements.

Step 2

Design

Creating wireframes and prototypes.

Step 3

Development

Building the product.

Marker Colors

Use different colors to categorize events or show status:

Timeline with Colored Markers

Now

Primary Event

Default primary color marker.

1 day ago

Secondary Event

Secondary color marker.

2 days ago

Tertiary Event

Tertiary color marker.

3 days ago

Completed Task

Successfully completed milestone.

4 days ago

Error Occurred

An error was detected and resolved.

Icon Markers

Add icons to markers for better visual communication:

Timeline with Icon Markers

Completed

Task Finished

The task was completed successfully.

In Progress

New Feature

Working on the new feature implementation.

Verified

Quality Check

All tests passed verification.

Item States

Active/Current State

Highlight the current or active timeline item with a pulsing animation:

Timeline with Active State

Yesterday

Design Complete

All designs approved.

Today

Development in Progress

Currently implementing the features.

Tomorrow

Testing Phase

Scheduled to begin testing.

Pending State

Show future or pending items with reduced opacity:

Timeline with Pending State

Completed

Phase 1 Done

First phase successfully completed.

Upcoming

Phase 2 Pending

Waiting to start the next phase.

Size Variants

Small Timeline

Small Timeline

10:00 AM

Small Event

Compact timeline for tight spaces.

11:00 AM

Another Event

More concise display.

Large Timeline

Large Timeline

January 2025

Major Milestone

Larger timeline for prominent display with more visual impact and better readability.

February 2025

Next Milestone

Enhanced visibility for important events and detailed information.

Compact Timeline

Reduce spacing for more condensed display:

Compact Timeline

08:00

Morning Meeting

Team sync and planning.

10:00

Development

Coding session.

14:00

Code Review

PR review session.

Card Content

Display timeline content in card containers for better separation:

Timeline with Card Content

March 15, 2025

Product Launch

Successfully launched version 1.0 to production. All systems operational and receiving positive user feedback.

March 20, 2025

Feature Update

Added new analytics dashboard and improved performance by 40%.

March 25, 2025

Mobile App Release

iOS and Android apps now available on respective app stores.

Best Practices

Clear Chronological Order

Always display events in chronological order (newest first or oldest first, consistently):

Clear Chronological Order

March 1, 2025

Project Kickoff

March 15, 2025

Milestone 1

March 30, 2025

Current Sprint

Meaningful Time Labels

Use clear, contextual time labels:

Meaningful Time Labels

January 15, 2025 at 2:30 PM

Contract Signed

2 hours ago

Update Deployed

Use Colors Meaningfully

Apply colors to convey status or category:

Meaningful Color Usage

Deployment Successful

Build Failed

In Progress

Accessibility

Ensure timeline content is accessible:

Accessible Timeline

Project Started

Initial project setup and team onboarding completed.

Framework Examples

React

interface TimelineItemProps {
  time: string;
  title: string;
  description: string;
  markerColor?: 'primary' | 'secondary' | 'tertiary' | 'success' | 'error';
  state?: 'active' | 'pending';
  icon?: React.ReactNode;
}

interface TimelineProps {
  items: TimelineItemProps[];
  layout?: 'vertical' | 'horizontal' | 'alternate';
  size?: 'sm' | 'md' | 'lg';
  compact?: boolean;
}

export function Timeline({ items, layout = 'vertical', size, compact }: TimelineProps) {
  const baseClasses = ['timeline'];

  if (layout === 'horizontal') baseClasses.push('timeline-horizontal');
  if (layout === 'alternate') baseClasses.push('timeline-alternate');
  if (size === 'sm') baseClasses.push('timeline-sm');
  if (size === 'lg') baseClasses.push('timeline-lg');
  if (compact) baseClasses.push('timeline-compact');

  return (
    <div className={baseClasses.join(' ')}>
      {items.map((item, index) => (
        <TimelineItem key={index} {...item} />
      ))}
    </div>
  );
}

export function TimelineItem({
  time,
  title,
  description,
  markerColor,
  state,
  icon
}: TimelineItemProps) {
  const itemClasses = ['timeline-item'];
  const markerClasses = ['timeline-marker'];

  if (state === 'active') itemClasses.push('timeline-item-active');
  if (state === 'pending') itemClasses.push('timeline-item-pending');

  if (markerColor) markerClasses.push(`timeline-marker-${markerColor}`);
  if (icon) markerClasses.push('timeline-marker-icon');

  return (
    <div className={itemClasses.join(' ')}>
      <div className={markerClasses.join(' ')}>
        {icon}
      </div>
      <div className="timeline-content">
        <span className="timeline-time">{time}</span>
        <h3 className="timeline-title">{title}</h3>
        <p className="timeline-description">{description}</p>
      </div>
    </div>
  );
}

// Usage
<Timeline
  layout="vertical"
  items={[
    {
      time: '2 hours ago',
      title: 'Project Started',
      description: 'Initial setup complete',
      markerColor: 'success'
    },
    {
      time: '1 hour ago',
      title: 'Development',
      description: 'Working on features',
      state: 'active'
    }
  ]}
/>

Vue

<template>
  <div :class="timelineClasses">
    <div
      v-for="(item, index) in items"
      :key="index"
      :class="itemClasses(item)"
    >
      <div :class="markerClasses(item)">
        <slot :name="`icon-${index}`">{{ item.icon }}</slot>
      </div>
      <div class="timeline-content" :class="{ 'timeline-content-card': item.card }">
        <span class="timeline-time">{{ item.time }}</span>
        <h3 class="timeline-title">{{ item.title }}</h3>
        <p class="timeline-description">{{ item.description }}</p>
      </div>
    </div>
  </div>
</template>

<script setup>
import { computed } from 'vue'

const props = defineProps({
  items: {
    type: Array,
    required: true
  },
  layout: {
    type: String,
    default: 'vertical',
    validator: (value) => ['vertical', 'horizontal', 'alternate'].includes(value)
  },
  size: {
    type: String,
    validator: (value) => ['sm', 'md', 'lg'].includes(value)
  },
  compact: Boolean
})

const timelineClasses = computed(() => {
  const classes = ['timeline']
  if (props.layout === 'horizontal') classes.push('timeline-horizontal')
  if (props.layout === 'alternate') classes.push('timeline-alternate')
  if (props.size === 'sm') classes.push('timeline-sm')
  if (props.size === 'lg') classes.push('timeline-lg')
  if (props.compact) classes.push('timeline-compact')
  return classes
})

const itemClasses = (item) => {
  const classes = ['timeline-item']
  if (item.state === 'active') classes.push('timeline-item-active')
  if (item.state === 'pending') classes.push('timeline-item-pending')
  return classes
}

const markerClasses = (item) => {
  const classes = ['timeline-marker']
  if (item.markerColor) classes.push(`timeline-marker-${item.markerColor}`)
  if (item.icon) classes.push('timeline-marker-icon')
  return classes
}
</script>

<!-- Usage -->
<Timeline
  layout="vertical"
  :items="[
    {
      time: '2 hours ago',
      title: 'Project Started',
      description: 'Initial setup complete',
      markerColor: 'success'
    },
    {
      time: '1 hour ago',
      title: 'Development',
      description: 'Working on features',
      state: 'active'
    }
  ]"
/>

API Reference

Timeline Container Classes

ClassDescription
.timelineBase timeline container (required)
.timeline-horizontalHorizontal layout
.timeline-alternateAlternating zigzag layout
.timeline-smSmall size variant
.timeline-lgLarge size variant
.timeline-compactCompact spacing

Timeline Item Classes

ClassDescription
.timeline-itemIndividual timeline item (required)
.timeline-item-activeActive/current item with pulsing animation
.timeline-item-pendingPending/future item with reduced opacity

Marker Classes

ClassDescription
.timeline-markerTimeline marker dot (required)
.timeline-marker-secondarySecondary color marker
.timeline-marker-tertiaryTertiary color marker
.timeline-marker-successSuccess/green marker
.timeline-marker-errorError/red marker
.timeline-marker-iconMarker with icon content

Content Classes

ClassDescription
.timeline-contentContent container (required)
.timeline-content-cardCard-styled content with border and shadow
.timeline-timeTime/date label
.timeline-titleEvent title
.timeline-descriptionEvent description text

Combinations

Combined Timeline Features

...
Q1 2025

Major Release

Version 2.0 launched

Step 1

Initialize

  • Stepper - Step-by-step process indicator
  • Badge - Status indicators
  • Card - Content containers

See Also