@sokkay/react-gantt
v0.6.0
Published
Controlled React Gantt chart component with timeline editing primitives.
Readme
@sokkay/react-gantt
Controlled React Gantt chart for React 18+, TypeScript-first, with importable CSS.
Install
pnpm add @sokkay/react-ganttimport { GanttChart } from "@sokkay/react-gantt";
import "@sokkay/react-gantt/styles.css";Peer dependencies: react and react-dom >=18 <20.
Quick start
import { useState } from "react";
import {
GanttChart,
type GanttProject,
type GanttViewMode,
} from "@sokkay/react-gantt";
import "@sokkay/react-gantt/styles.css";
const initialProjects: GanttProject[] = [
{
id: "platform",
name: "Platform",
tasks: [
{
id: "api",
projectId: "platform",
name: "Public API",
start: "2026-07-01",
end: "2026-07-12",
progress: 45,
},
],
},
];
export function Example() {
const [projects, setProjects] = useState(initialProjects);
const [viewMode, setViewMode] = useState<GanttViewMode>("day");
const [selectedTaskId, setSelectedTaskId] = useState<string | null>(null);
return (
<>
<select
value={viewMode}
onChange={(event) => setViewMode(event.target.value as GanttViewMode)}
>
<option value="day">Day</option>
<option value="week">Week</option>
<option value="month">Month</option>
</select>
<GanttChart
projects={projects}
viewMode={viewMode}
selectedTaskId={selectedTaskId}
onTaskSelect={(task) => setSelectedTaskId(task?.id ?? null)}
onTaskMove={({ taskId, start, end }) => {
setProjects((current) =>
current.map((project) => ({
...project,
tasks: project.tasks.map((task) =>
task.id === taskId ? { ...task, start, end } : task
),
}))
);
}}
/>
</>
);
}Sidebar columns
Pass an ordered columns array. Use kind: "tree" for the project/task chrome
(grip, collapse, name) and kind: "data" for extra values. Omit columns to
get a single tree column from labels.projectHeader.
<GanttChart
projects={projects}
viewMode="month"
layoutMode="tree"
sidebarWidth={520}
columns={[
{ id: "project", kind: "tree", header: "Project" },
{
id: "start",
kind: "data",
header: "Start",
width: 100,
resizable: true,
renderTask: (task) => task.start.toLocaleDateString(),
},
]}
onSidebarColumnWidthChange={({ columnId, width }) => {
/* update controlled widths in host state */
}}
/>Sorting: put a button in column.header and reorder projects in your
state. The library does not sort rows internally.
Project collapse toggle
The expand/collapse control is shown by default for projects that have tasks. Hide it globally or decide per project:
<GanttChart projects={projects} viewMode="month" showProjectToggle={false} />
<GanttChart
projects={projects}
viewMode="month"
showProjectToggle={(project) => project.tasks.length > 1}
/>Projects with no tasks never show the toggle. Collapse state
(collapsedProjectIds / imperative methods) still works when the control is
hidden.
Row drag
Sidebar project and task rows can be dragged by default. Disable the grip and those drag interactions globally:
<GanttChart projects={projects} viewMode="month" enableRowDrag={false} />Horizontal task bar move and resize stay available.
Timeline zoom / column width
customCellWidths sets the pixel width of each timeline column (the bars
grid) per view mode. Scale DEFAULT_CELL_WIDTHS to zoom without changing
viewMode. Values are clamped between 24 and 480.
import { DEFAULT_CELL_WIDTHS, GanttChart } from "@sokkay/react-gantt";
const zoom = 1.5;
<GanttChart
projects={projects}
viewMode="day"
customCellWidths={{
day: DEFAULT_CELL_WIDTHS.day * zoom,
week: DEFAULT_CELL_WIDTHS.week * zoom,
month: DEFAULT_CELL_WIDTHS.month * zoom,
quarter: DEFAULT_CELL_WIDTHS.quarter * zoom,
year: DEFAULT_CELL_WIDTHS.year * zoom,
}}
/>;Documentation for agents / IDEs
When this package is installed from npm, prefer:
llms.txt— compact API map and invariantsdist/index.d.ts— full typed public surface with JSDocCHANGELOG.md— breaking changes and migrations
Features
- View modes:
day,week,month,quarter,year - Controlled selection, collapse, move, resize, reorder, transfer
- Optional
showProjectToggleto hide the expand/collapse control - Optional
enableRowDrag={false}to hide the row grip and disable row drag - Optional task
segmentsand segment connectors - Unified sidebar
columns(tree|data) with resize - Timeline zoom via
customCellWidths/DEFAULT_CELL_WIDTHS - Render slots for bars, tooltips, context menu, toolbar, timeline cells
- Theme / className overrides and
labels/locale - Imperative handle via
useGanttChart - Row virtualization
Development (monorepo)
pnpm install
pnpm dev
pnpm --filter @sokkay/react-gantt test
pnpm --filter @sokkay/react-gantt buildRelease
Publishing is manual. From a clean main:
pnpm release patch # or minor | major | x.y.z
pnpm --filter @sokkay/react-gantt build
pnpm --filter @sokkay/react-gantt publish --access public
git push
git push origin vX.Y.ZLicense
MIT
