@faixirk/timeline-gantt
v1.4.1
Published
A beautiful, modern, and high-performance React timeline/Gantt chart component with drag-and-drop functionality, advanced filtering, and virtualization support
Readme
@faixirk/timeline-gantt
A beautiful, modern, and high-performance React timeline/Gantt chart component with drag-and-drop functionality, advanced filtering, and virtualization support. Perfect for project management, scheduling, and timeline visualization.
✨ Features
- 🎨 Modern UI - Clean, professional interface built with shadcn/ui and Tailwind CSS
- 🖱️ Drag & Drop - Intuitive task repositioning with smooth animations and automatic date updates
- 🔍 Advanced Filtering - Filter by project, assignee, date range, and search by task name
- 📝 Task Management - Click tasks to edit name, dates, assignee, and color
- 📅 Multiple Zoom Levels - Switch between Day, Week, and Month views
- ⚡ High Performance - Built-in virtualization for handling 500+ tasks smoothly
- 🎯 Today Indicator - Visual marker highlighting the current date
- 🎨 Customizable Colors - Multiple color options for tasks and projects
- 📱 Responsive Design - Works seamlessly on all screen sizes
- 🔒 Type Safe - Full TypeScript support with comprehensive type definitions
- 🌙 Theme Support - Built-in dark mode support with next-themes
📦 Installation
npm install @faixirk/timeline-gantt date-fns react-virtuosoOr using yarn:
yarn add @faixirk/timeline-gantt date-fns react-virtuosoOr using pnpm:
pnpm add @faixirk/timeline-gantt date-fns react-virtuosoPeer Dependencies
This package requires the following peer dependencies:
react^18.0.0react-dom^18.0.0
Styling Requirements
This package provides two CSS options depending on your project setup:
Option 1: Standalone CSS (No Tailwind Required) ⭐ Recommended
If your project doesn't use Tailwind CSS or uses other styling libraries (MUI, Ant Design, etc.), use the standalone CSS file that includes all compiled styles:
import { Timeline } from "@faixirk/timeline-gantt";
import "@faixirk/timeline-gantt/dist/timeline-standalone.css";This file is self-contained and doesn't require Tailwind CSS in your project.
Option 2: With Tailwind CSS
If your project already uses Tailwind CSS, you can use the minimal CSS file and let Tailwind handle the utility classes:
- Install and configure Tailwind CSS:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p- Configure your
tailwind.config.js:
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
"./node_modules/@faixirk/timeline-gantt/**/*.{js,mjs,cjs}",
],
theme: {
extend: {},
},
plugins: [],
}- Import the minimal CSS:
import { Timeline } from "@faixirk/timeline-gantt";
import "@faixirk/timeline-gantt/styles.css";🚀 Quick Start
import { Timeline } from "@faixirk/timeline-gantt";
import "@faixirk/timeline-gantt/dist/timeline-standalone.css";
function App() {
const projects = [
{ id: "1", name: "Project Alpha", color: "blue" },
{ id: "2", name: "Project Beta", color: "green" },
];
const tasks = [
{
id: "t1",
name: "Design Phase",
projectId: "1",
startDate: "2025-01-10",
endDate: "2025-01-15",
color: "blue",
assignee: { name: "John Doe" },
},
{
id: "t2",
name: "Development",
projectId: "1",
startDate: "2025-01-16",
endDate: "2025-01-30",
color: "blue",
},
];
const handleTaskUpdate = (updatedTask) => {
console.log("Task updated:", updatedTask);
// Update your state/database here
};
const handleTaskDelete = (taskId) => {
console.log("Task deleted:", taskId);
// Remove task from your state/database here
};
return (
<div style={{ height: "100vh" }}>
<Timeline
projects={projects}
tasks={tasks}
onTaskUpdate={handleTaskUpdate}
onTaskDelete={handleTaskDelete}
/>
</div>
);
}📚 API Reference
Timeline Component Props
| Prop | Type | Default | Description |
| ---------------------- | ---------------------------- | ------------- | ------------------------------------------------------- |
| projects | Project[] | Required | Array of projects to display in the timeline |
| tasks | Task[] | Required | Array of tasks to display in the timeline |
| startDate | Date | 2 weeks ago | Timeline start date |
| endDate | Date | 6 weeks ahead | Timeline end date |
| initialZoom | 'day' \| 'week' \| 'month' | 'week' | Initial zoom level for the timeline |
| onTaskUpdate | (task: Task) => void | - | Callback fired when a task is updated (drag, edit) |
| onTaskDelete | (taskId: string) => void | - | Callback fired when a task is deleted |
| onTaskClick | (task: Task) => void | - | Callback fired when a task is clicked |
| enableVirtualization | boolean | true | Enable virtualization for large datasets (20+ projects) |
Type Definitions
type Project = {
id: string;
name: string;
color?: string; // Any valid CSS color or predefined color name
};
type Task = {
id: string;
name: string;
projectId: string;
startDate: string; // ISO date string (YYYY-MM-DD)
endDate: string; // ISO date string (YYYY-MM-DD)
color?: string; // Any valid CSS color
assignee?: {
name: string;
avatar?: string; // URL to avatar image
};
};
type ZoomLevel = "day" | "week" | "month";🎯 Features in Detail
Drag & Drop
Tasks can be dragged horizontally to different dates. The component automatically:
- Snaps to day boundaries for precise positioning
- Maintains the original task duration
- Triggers the
onTaskUpdatecallback with updated dates - Provides visual feedback during drag operations
- Prevents invalid date ranges
Advanced Filtering
Built-in filtering system with multiple options:
- Project Filter - Show tasks from specific projects only
- Assignee Filter - Filter tasks by assigned person
- Date Range Filter - Display tasks within a specific date range
- Search - Find tasks by name (case-insensitive)
- Clear All - Reset all filters with one click
Task Editing
Click any task to open a comprehensive edit dialog featuring:
- Task name input with validation (1-100 characters)
- Project selection dropdown
- Start and end date pickers with validation
- Assignee input field (optional)
- Color picker with predefined options
- Delete button with confirmation
- Form validation with error messages
Zoom Levels
Three zoom levels for different viewing needs:
- Day View - 48px per day - Detailed view for short-term planning
- Week View - 64px per day - Balanced view for medium-term planning
- Month View - 80px per day - Overview for long-term planning
Virtualization
For optimal performance with large datasets:
- Automatically enabled for timelines with 20+ projects
- Maintains smooth scrolling with 500+ tasks
- Reduces memory footprint significantly
- Can be disabled via
enableVirtualization={false}if needed
Today Indicator
A visual line marking the current date:
- Automatically scrolls into view on component mount
- Updates position in real-time
- Helps users stay oriented in the timeline
🎨 Customization
The component uses CSS variables for theming. You can customize colors by overriding these variables in your CSS:
:root {
/* Timeline colors */
--timeline-grid: hsl(214 32% 95%);
--timeline-header: hsl(0 0% 100%);
--timeline-today: hsl(217 91% 60%);
--timeline-weekend: hsl(214 32% 98%);
/* Task colors */
--task-blue: hsl(217 91% 60%);
--task-green: hsl(142 76% 36%);
--task-orange: hsl(25 95% 53%);
--task-purple: hsl(271 81% 56%);
--task-pink: hsl(330 81% 60%);
--task-teal: hsl(174 72% 36%);
}
/* Dark mode support */
.dark {
--timeline-grid: hsl(214 32% 15%);
--timeline-header: hsl(0 0% 10%);
/* ... other dark mode variables */
}🔧 Advanced Usage
With State Management
import { useState } from 'react';
import { Timeline, Task, Project } from '@faixirk/timeline-gantt';
function App() {
const [projects] = useState<Project[]>([...]);
const [tasks, setTasks] = useState<Task[]>([...]);
const handleTaskUpdate = (updatedTask: Task) => {
setTasks(prev =>
prev.map(task => task.id === updatedTask.id ? updatedTask : task)
);
};
const handleTaskDelete = (taskId: string) => {
setTasks(prev => prev.filter(task => task.id !== taskId));
};
return (
<Timeline
projects={projects}
tasks={tasks}
onTaskUpdate={handleTaskUpdate}
onTaskDelete={handleTaskDelete}
/>
);
}Custom Date Range
import { addMonths, subMonths } from "date-fns";
<Timeline
projects={projects}
tasks={tasks}
startDate={subMonths(new Date(), 3)}
endDate={addMonths(new Date(), 3)}
initialZoom="month"
/>;With API Integration
const handleTaskUpdate = async (updatedTask: Task) => {
try {
await fetch(`/api/tasks/${updatedTask.id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(updatedTask),
});
// Update local state
setTasks((prev) =>
prev.map((task) => (task.id === updatedTask.id ? updatedTask : task))
);
} catch (error) {
console.error("Failed to update task:", error);
}
};🏗️ Development
Prerequisites
- Node.js 18+
- npm, yarn, or pnpm
Setup
# Clone the repository
git clone https://github.com/faixirk/vista-timeline-kit.git
# Install dependencies
npm install
# Run development server
npm run dev
# Build for production
npm run build
# Build library
npm run build:lib🧪 Testing
# Run tests
npm test
# Run tests in watch mode
npm test:watch
# Run tests with coverage
npm test:coverage📝 License
ISC © Faisal
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
🐛 Issues
Found a bug or have a feature request? Please open an issue.
📧 Support
For questions and support, please open an issue on GitHub.
🙏 Acknowledgments
Built with:
- React - UI framework
- TypeScript - Type safety
- Vite - Build tool
- TailwindCSS - Styling
- shadcn/ui - UI components
- Radix UI - Accessible primitives
- date-fns - Date utilities
- react-virtuoso - Virtualization
- Lucide React - Icons
- @dnd-kit - Drag and drop
📊 Project Status
This project is actively maintained. Check the changelog for recent updates.
