react-modern-gantt
Version:
A modern, customizable Gantt chart component for React applications
469 lines (373 loc) • 13.2 kB
Markdown
# React Modern Gantt
A flexible, customizable Gantt chart component for React applications with drag-and-drop task scheduling, dark mode support, progress tracking, and multiple view modes.
[](https://www.npmjs.com/package/react-modern-gantt)
[](https://github.com/MikaStiebitz/React-Modern-Gantt/blob/main/LICENSE)
[](https://bundlephobia.com/result?p=react-modern-gantt)
<p align="center">
<img src="https://github.com/user-attachments/assets/bc5ab980-6a28-4010-83bc-a88ae81bb6fa" alt="React Modern Gantt in Dark Mode" width="800" />
</p>
<p align="center">
<a href="https://react-gantt-demo.vercel.app/" target="_blank" rel="noopener noreferrer">
<img src="https://img.shields.io/badge/View-LIVE_DEMO-blue?style=for-the-badge" alt="Live Demo" />
</a>
</p>
---
## 📋 Table of Contents
- [Features](#-features)
- [Installation](#-installation)
- [Quick Start](#-quick-start)
- [Components](#-components)
- [Task & TaskGroup Data Structure](#-task--taskgroup-data-structure)
- [View Modes](#-view-modes)
- [Customization](#-customization)
- [Event Handling](#-event-handling)
- [Dark Mode](#-dark-mode)
- [Advanced Examples](#-advanced-examples)
- [Browser Support](#-browser-support)
- [FAQ](#-faq)
- [Contributing](#-contributing)
- [License](#-license)
## ✨ Features
- 📊 **Interactive timeline** with drag-and-drop task scheduling
- 🎨 **Fully customizable** with CSS variables and custom classes
- 🕒 **Multiple view modes** (Day, Week, Month, Quarter, Year)
- 🌙 **Dark mode support** built-in
- 📱 **Responsive design** that works across devices
- 📈 **Progress tracking** with visual indicators and interactive updates
- 🔄 **Task dependencies** and relationship management
- 🎯 **Event handling** for clicks, updates, selections
- 🧩 **Composable API** with extensive custom render props for advanced customization
- 🌊 **Smooth animations** with configurable speeds and thresholds
- 🔄 **Auto-scrolling** during drag operations
## 📦 Installation
### NPM
```bash
npm install react-modern-gantt
```
### Yarn
```bash
yarn add react-modern-gantt
```
## 🚀 Quick Start
```jsx
import React, { useState } from "react";
import GanttChart from "react-modern-gantt";
// ⚠️ IMPORTANT: Don't forget to import the styles!
import "react-modern-gantt/dist/index.css";
function App() {
const [tasks, setTasks] = useState([
{
id: "team-1",
name: "Engineering",
description: "Development Team",
tasks: [
{
id: "task-1",
name: "Website Redesign",
startDate: new Date(2023, 0, 1),
endDate: new Date(2023, 2, 15),
color: "#3b82f6",
percent: 75,
},
// More tasks...
],
},
// More groups...
]);
const handleTaskUpdate = (groupId, updatedTask) => {
setTasks(prevTasks =>
prevTasks.map(group =>
group.id === groupId
? {
...group,
tasks: group.tasks.map(task => (task.id === updatedTask.id ? updatedTask : task)),
}
: group
)
);
};
return <GanttChart tasks={tasks} onTaskUpdate={handleTaskUpdate} darkMode={false} showProgress={true} />;
}
```
> 📌 **Note:** Make sure to import the CSS file to apply all necessary styles:
> `import "react-modern-gantt/dist/index.css";`
> Without this import, the component will not be styled correctly.
### Using CSS styles
The Gantt chart requires CSS styles that are shipped separately from the component code. You have two options:
#### Option 1: Import CSS file (Recommended)
```js
// In your application entry point (e.g., App.js or index.js)
import "react-modern-gantt/dist/index.css";
```
#### Option 2: Reference CSS in HTML
```html
<!-- In your HTML file -->
<link rel="stylesheet" href="https://unpkg.com/react-modern-gantt@0.5.0/dist/index.css" />
```
## 🧩 Components
### Main Components
- **`GanttChart`**: The main component for rendering a Gantt chart
- **`TaskItem`**: Individual task bars
- **`TaskList`**: The left sidebar with task groups
- **`Timeline`**: The header timeline display
- **`ViewModeSelector`**: Controls for switching between timeline views
### Utility Components
- **`Tooltip`**: Information tooltip for tasks
- **`TodayMarker`**: Vertical line indicating the current date
## 📊 Task & TaskGroup Data Structure
```typescript
interface Task {
id: string; // Unique identifier
name: string; // Task name
startDate: Date; // Start date
endDate: Date; // End date
color?: string; // Task color (CSS color value or hex code)
percent?: number; // Completion percentage (0-100)
dependencies?: string[]; // IDs of dependent tasks
[key: string]: any; // Additional custom properties
}
interface TaskGroup {
id: string; // Unique identifier
name: string; // Group name
description?: string; // Group description
icon?: string; // Optional icon (HTML string)
tasks: Task[]; // Array of tasks in this group
[key: string]: any; // Additional custom properties
}
```
## 🕒 View Modes
The component supports five different view modes to adapt to different timeline needs:
| View Mode | Description | Best Used For |
| --------- | -------------- | -------------------------------------------- |
| `DAY` | Shows days | Detailed short-term planning (days/weeks) |
| `WEEK` | Shows weeks | Short to medium-term planning (weeks/months) |
| `MONTH` | Shows months | Medium-term planning (months/quarters) |
| `QUARTER` | Shows quarters | Medium to long-term planning (quarters/year) |
| `YEAR` | Shows years | Long-term planning (years) |
```jsx
import { GanttChart, ViewMode } from "react-modern-gantt";
// Using string literals
<GanttChart tasks={tasks} viewMode="day" />
// Using the ViewMode enum
<GanttChart tasks={tasks} viewMode={ViewMode.DAY} />
```
## 🎨 Customization
### CSS Variables
The easiest way to customize the appearance is by overriding CSS variables:
```css
:root {
/* Primary colors */
--rmg-bg-color: #f8f9fb;
--rmg-text-color: #1a202c;
--rmg-border-color: #e2e8f0;
--rmg-task-color: #3182ce;
--rmg-task-text-color: white;
--rmg-marker-color: #e53e3e;
/* Size variables */
--rmg-row-height: 50px;
--rmg-task-height: 36px;
--rmg-border-radius: 6px;
/* Animation speed */
--rmg-animation-speed: 0.25;
}
```
### Custom Styles
```jsx
<GanttChart
tasks={tasks}
styles={{
container: "my-gantt-container",
title: "my-gantt-title",
taskList: "my-task-list",
timeline: "my-timeline",
todayMarker: "my-today-marker",
taskRow: "my-task-row",
tooltip: "my-tooltip",
}}
onTaskUpdate={handleTaskUpdate}
/>
```
### Custom Rendering
```jsx
<GanttChart
tasks={tasks}
renderTask={({ task, leftPx, widthPx, topPx, isHovered, isDragging, showProgress }) => (
<div
className="my-custom-task"
style={{
position: "absolute",
left: `${leftPx}px`,
width: `${widthPx}px`,
top: `${topPx}px`,
backgroundColor: task.color || "#3182ce",
}}>
<div className="my-task-label">{task.name}</div>
{showProgress && (
<div className="my-progress-bar">
<div className="my-progress-fill" style={{ width: `${task.percent || 0}%` }} />
</div>
)}
</div>
)}
/>
```
## 🎯 Event Handling
Handle various interactions with the Gantt chart:
```jsx
<GanttChart
tasks={tasks}
onTaskUpdate={(groupId, updatedTask) => {
console.log(`Task ${updatedTask.id} updated in group ${groupId}`);
// Update your state here
updateTasks(groupId, updatedTask);
}}
onTaskClick={(task, group) => {
console.log(`Task ${task.id} clicked in group ${group.id}`);
// Do something when a task is clicked
selectTask(task.id);
}}
onTaskSelect={(task, isSelected) => {
console.log(`Task ${task.id} selection state: ${isSelected}`);
// Handle selection state changes
}}
onGroupClick={group => {
console.log(`Group ${group.id} clicked`);
// Do something when a group is clicked
}}
onViewModeChange={viewMode => {
console.log(`View mode changed to: ${viewMode}`);
// Handle view mode changes
}}
/>
```
## 🌙 Dark Mode
Dark mode is built-in and easy to enable:
```jsx
<GanttChart tasks={tasks} darkMode={true} onTaskUpdate={handleTaskUpdate} />
```
## 🔄 Advanced Examples
### Custom Task Rendering by Status
```jsx
<GanttChart
tasks={tasks}
getTaskColor={({ task }) => {
// Task is complete
if (task.percent === 100) {
return {
backgroundColor: "#22c55e", // Green
borderColor: "#166534",
textColor: "#ffffff",
};
}
// Task has dependencies
if (task.dependencies?.length > 0) {
return {
backgroundColor: "#f59e0b", // Orange
textColor: "#ffffff",
};
}
// High priority task
if (task.priority === "high") {
return {
backgroundColor: "#ef4444", // Red
textColor: "#ffffff",
};
}
// Default color
return {
backgroundColor: "#3b82f6", // Blue
textColor: "#ffffff",
};
}}
/>
```
### Custom Tooltip for Detailed Information
```jsx
<GanttChart
tasks={tasks}
renderTooltip={({ task, position, dragType, startDate, endDate }) => (
<div className="custom-tooltip">
<h3>{task.name}</h3>
{dragType && (
<div className="drag-indicator">{dragType === "move" ? "Moving task..." : "Resizing task..."}</div>
)}
<div className="date-range">
{format(startDate, "MMM d, yyyy")} - {format(endDate, "MMM d, yyyy")}
</div>
<div className="progress-section">
<div className="progress-label">Progress: {task.percent || 0}%</div>
<div className="progress-bar">
<div className="progress-fill" style={{ width: `${task.percent || 0}%` }} />
</div>
</div>
{task.assignee && <div className="assignee">Assigned to: {task.assignee}</div>}
</div>
)}
/>
```
## 🌐 Browser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
## ❓ FAQ
### Can I change the date format in the timeline?
Yes, you can use the `locale` prop to change the date formatting:
```jsx
<GanttChart
tasks={tasks}
locale="de-DE" // For German formatting
/>
```
### How do I handle updates to tasks?
The Gantt chart is a controlled component, so updates are handled through the `onTaskUpdate` callback:
```jsx
const handleTaskUpdate = (groupId, updatedTask) => {
setTasks(prevTasks =>
prevTasks.map(group =>
group.id === groupId
? {
...group,
tasks: group.tasks.map(task => (task.id === updatedTask.id ? updatedTask : task)),
}
: group
)
);
};
```
### Can I make the Gantt chart read-only?
Yes, set the `editMode` prop to `false`:
```jsx
<GanttChart tasks={tasks} editMode={false} />
```
### How do I disable progress indicators?
Set the `showProgress` prop to `false`:
```jsx
<GanttChart tasks={tasks} showProgress={false} />
```
### Can I customize the visual appearance of specific tasks?
Yes, use the `getTaskColor` function:
```jsx
<GanttChart
tasks={tasks}
getTaskColor={({ task }) => ({
backgroundColor: task.isUrgent ? "#ef4444" : "#3b82f6",
textColor: "white",
})}
/>
```
### Why are my styles not loading?
If your Gantt chart appears without styling, make sure you've imported the CSS file:
```js
import "react-modern-gantt/dist/index.css";
```
This import should be included in your application's entry point or in the component where you use the Gantt chart.
## 🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## 📄 License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.