React Timeline
2.1KB gzipped
The Timeline component is a lightweight React component for creating dynamic timelines in web applications. It supports event logs, roadmaps, and chronological displays with customizable styling. Includes automatic monthly grouping, sorting options, and positioning controls. Ships with @calendarjs/react alongside Calendar and Schedule.
- Event logs and roadmaps
- Monthly view with navigation
- Ascending/descending sorting
- Customizable positioning (left, right, top, bottom)
- Border styles and colors
- Responsive design
- TypeScript support
CalendarJS Product Suite
Section titled “CalendarJS Product Suite”CalendarJS is a complete calendar and scheduling solution that includes:
- Calendar - Date picker with range selection (3.18KB)
- Schedule - Event scheduler with drag & drop (4.2KB)
- Timeline - Chronological event display (this page)
Related Components
Section titled “Related Components”Schedule - Event Scheduling
Section titled “Schedule - Event Scheduling”For interactive event scheduling with drag-and-drop instead of a chronological list, use the Schedule component:
- Day, week, and weekdays views
- Drag & drop event management
- Resource scheduling
- Time slot configuration
- Undo/redo support
Perfect for: Appointment calendars, team schedules, booking systems, resource planning
Calendar - Date Selection
Section titled “Calendar - Date Selection”For date picking and selection before displaying timeline events, use the Calendar component:
- Single and range date selection
- Date validation
- International formats
- Keyboard navigation
Perfect for: Date range filters, report selectors, booking date pickers
LemonadeJS Timeline - Reactive Framework
Section titled “LemonadeJS Timeline - Reactive Framework”For reactive applications with data binding, LemonadeJS Timeline provides:
- Reactive data binding
- Vue, React, Angular integration
- Built on CalendarJS Timeline (this component)
- Framework-agnostic reactive wrapper
Documentation
Section titled “Documentation”Installation
Section titled “Installation”npm install @calendarjs/react react
Settings
Section titled “Settings”| Property | Description |
|---|---|
data?: ItemInput[] | Array of timeline items to display. Loose input shape — only date is required (see below). |
type?: 'default' | 'monthly' | Display mode. Monthly groups items by month with navigation. Default: 'default'. |
align?: 'left' | 'right' | 'top' | 'bottom' | Bullet point alignment. Default: 'left'. |
message?: string | Message shown when no data is available. |
order?: 'asc' | 'desc' | Sort order by date. Default: 'asc'. |
width?: number | Width of the timeline container in pixels. |
height?: number | Height of the timeline container in pixels. |
value?: string | object | Initial value form type='monthly'. |
Item types — input vs resolved
Section titled “Item types — input vs resolved”The package distinguishes the input shape (what you pass into data) from the resolved shape (what callbacks like onUpdate hand back, with defaults filled in). See the TypeScript guide for full details.
ItemInput — loose input shape
Section titled “ItemInput — loose input shape”Only date is required; everything else is optional. An index signature lets you attach app-specific metadata (id, foreign keys, status, ...) without casts.
| Property | Description |
|---|---|
date: string | Date | Required. Date associated with the item. |
title?: string | Title for the item. |
subtitle?: string | Subtitle or secondary text. |
description?: string | Item description or content. |
borderColor?: string | Border color (hex or CSS color). |
borderStyle?: string | Border style: 'solid', 'dashed', or 'dotted'. |
editable?: boolean | Show an edit icon on the item. |
tags?: Tag[] | Tags to display on this item (Tags →). |
[key: string]: any | App-specific metadata (no cast required). |
Item — resolved runtime shape
Section titled “Item — resolved runtime shape”Returned by result and passed to onUpdate. Extends ItemInput with title always present.
interface Item extends ItemInput {
title: string;
}
Events
Section titled “Events”| Event | Description |
|---|---|
onUpdate | Fired after result is recomputed (initial render + every change).onUpdate?: (result: Item[]) => void |
onEdition | Fired when the edit icon is clicked on an editable item.onEdition?: (entry: Item) => void |
The instance is available via the forwarded ref — your handler receives just the event data.
Methods
Section titled “Methods”| Method | Description |
|---|---|
next(): void | Go to the next month (in monthly type) |
prev(): void | Go to the previous month (in monthly type) |
Examples
Section titled “Examples”Basic Timeline
Section titled “Basic Timeline”import { Timeline } from '@calendarjs/react';
export default function App() {
const data = [
{ title: 'Planning Phase', date: '2025-01-15', borderColor: '#3498db' },
{ title: 'Development', date: '2025-02-01', borderColor: '#e74c3c' },
{ title: 'Testing', date: '2025-02-15', borderColor: '#2ecc71' },
{ title: 'Deployment', date: '2025-03-01', borderColor: '#9b59b6' }
];
return <Timeline data={data} align="left" />;
}
Monthly View
Section titled “Monthly View”import { Timeline } from '@calendarjs/react';
export default function App() {
const data = [
{ title: 'Sprint Planning', subtitle: 'Team A', date: '2025-01-05' },
{ title: 'Code Review', subtitle: 'Team B', date: '2025-01-12' },
{ title: 'Release v1.0', subtitle: 'Production', date: '2025-02-01' },
{ title: 'Sprint Retrospective', subtitle: 'Team A', date: '2025-02-15' }
];
return <Timeline type="monthly" value="2025-01-05" data={data} style={{ width: 500, height: 400 }} />;
}
Controlled with React state
Section titled “Controlled with React state”Replace the array reference (don't mutate in place) and the timeline re-renders:
import { useCallback, useState } from 'react';
import { Timeline } from '@calendarjs/react';
export default function App() {
const [data, setData] = useState([
{ date: '2025-01-01', title: 'Project Started', borderColor: '#3498db' },
]);
const addEntry = useCallback(() => {
setData((prev) => [
...prev,
{ date: new Date().toISOString().split('T')[0], title: 'New Entry' },
]);
}, []);
return (
<>
<button onClick={addEntry}>Add entry</button>
<Timeline data={data} align="left" />
</>
);
}
Imperative with useTimeline
Section titled “Imperative with useTimeline”The hook gives you a callback ref plus a reactive instance — null before mount, the live instance after. Useful for monthly-view navigation buttons:
import { useState } from 'react';
import { Timeline, useTimeline } from '@calendarjs/react';
export default function App() {
const { ref, instance } = useTimeline();
const [data] = useState([
{ date: '2025-01-15', title: 'Sprint Planning' },
{ date: '2025-02-15', title: 'Sprint Retrospective' },
]);
return (
<>
<button disabled={!instance} onClick={() => instance.prev()}>Previous month</button>
<button disabled={!instance} onClick={() => instance.next()}>Next month</button>
<Timeline ref={ref} type="monthly" value="2025-01-15" data={data} />
</>
);
}
App metadata on items (TypeScript)
Section titled “App metadata on items (TypeScript)”The ItemInput index signature accepts arbitrary keys — no as any:
import { Timeline } from '@calendarjs/react';
import type { Timeline as TimelineNS } from '@calendarjs/react';
const items: TimelineNS.ItemInput[] = [
{ id: 1, title: 'A', date: '2026-01-01', status: 'done' },
{ id: 2, title: 'B', date: '2026-01-02', status: 'in-progress' },
];
<Timeline data={items} order="asc" />
See TypeScript for the full input-vs-resolved type guide.
Related
Section titled “Related”- Timeline Events - Event callbacks
- Timeline Controls - Navigation and controls
- Hooks —
useTimelineand friends - TypeScript — input vs resolved types, app metadata