Component reference
Gantt
A project roadmap across a time axis.
Preview
Live previewOptional six-digit hex. Clear to restore the preset. Check contrast with your brand color.
Changes apply to this preview only.
Core flows
Oct 6, 2026 – Oct 16, 2026
Dependencies: audit
Timeline controls
Scale, zoom and navigation are controlled by the page.
Width adapts to the available space
"use client";
import { useState } from "react";
import {
type PimoluGanttScale,
type PimoluGanttTask,
Gantt,
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
Badge
} from "@pimolu/react";
const roadmap: PimoluGanttTask[] = [
{
id: "interviews",
name: "Customer interviews",
start: new Date(2026, 8, 28),
end: new Date(2026, 9, 2),
progress: 100,
group: "Discovery",
color: "#0ea5e9",
},
{
id: "audit",
name: "Interface audit",
start: new Date(2026, 9, 1),
end: new Date(2026, 9, 7),
progress: 100,
dependencies: ["interviews"],
group: "Discovery",
color: "#0ea5e9",
},
{
id: "flows",
name: "Core flows",
start: new Date(2026, 9, 6),
end: new Date(2026, 9, 16),
progress: 72,
dependencies: ["audit"],
group: "Design",
color: "#7c3aed",
},
{
id: "tokens",
name: "Token refresh",
start: new Date(2026, 9, 12),
end: new Date(2026, 9, 23),
progress: 48,
dependencies: ["audit"],
group: "Design",
color: "#7c3aed",
},
{
id: "scheduler",
name: "Scheduler + Gantt",
start: new Date(2026, 9, 19),
end: new Date(2026, 10, 1),
progress: 24,
dependencies: ["flows"],
group: "Build",
color: "#16a34a",
},
{
id: "file-manager",
name: "File manager",
start: new Date(2026, 9, 22),
end: new Date(2026, 10, 4),
progress: 10,
dependencies: ["tokens"],
group: "Build",
color: "#16a34a",
},
{
id: "docs",
name: "Docs and examples",
start: new Date(2026, 9, 26),
end: new Date(2026, 10, 8),
progress: 0,
dependencies: ["scheduler", "file-manager"],
group: "Launch",
color: "#d97706",
},
{
id: "release",
name: "Public release",
start: new Date(2026, 10, 9),
end: new Date(2026, 10, 13),
progress: 0,
dependencies: ["docs"],
group: "Launch",
color: "#dc2626",
},
];
const dateFormat = new Intl.DateTimeFormat("en-US", {
month: "short",
day: "numeric",
year: "numeric",
});
function RoadmapExample() {
const [start, setStart] = useState(new Date(2026, 8, 28));
const [scale, setScale] = useState<PimoluGanttScale>("day");
const [zoom, setZoom] = useState(1);
const [selected, setSelected] = useState<PimoluGanttTask | null>(roadmap[2]);
return (
<div className="grid gap-5 min-w-0">
<Gantt
aria-label="Design system roadmap"
tasks={roadmap}
start={start}
onStartChange={setStart}
scale={scale}
onScaleChange={setScale}
zoom={zoom}
onZoomChange={setZoom}
onTaskClick={setSelected}
maxHeight={420}
/>
<div
className="grid grid-cols-[repeat(auto-fit,minmax(min(100%,280px),1fr))] gap-6 min-w-0"
>
<Card>
<CardHeader>
<CardTitle>
{selected?.name ?? "Select a task"}
</CardTitle>
<CardDescription>
{
selected
? `${dateFormat.format(selected.start)} – ${dateFormat.format(selected.end)}`
: "Click a bar or a task name to inspect it."
}
</CardDescription>
</CardHeader>
<CardContent className="grid gap-5 min-w-0">
{
selected
? (<>
<div className="flex flex-wrap items-center gap-3 min-w-0">
<Badge variant="primary">
{selected.group ?? "Ungrouped"}
</Badge>
<Badge variant="neutral">
{selected.progress ?? 0}% complete
</Badge>
</div>
<p className="text-sm text-muted">
Dependencies:{" "}
{
selected.dependencies?.length
? selected.dependencies.join(", ")
: "none"
}
</p>
</>)
: (<p className="text-sm text-muted">No task selected yet.</p>)
}
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Timeline controls</CardTitle>
<CardDescription>
Scale, zoom and navigation are controlled by the page.
</CardDescription>
</CardHeader>
<CardContent className="grid gap-5 min-w-0">
<div className="flex flex-wrap items-center gap-3 min-w-0 justify-between">
<span className="text-sm text-muted">Scale</span>
<Badge variant="neutral">
{scale}
</Badge>
</div>
<div className="flex flex-wrap items-center gap-3 min-w-0 justify-between">
<span className="text-sm text-muted">Zoom</span>
<Badge variant="neutral">
{Math.round(zoom * 100)}%
</Badge>
</div>
<div className="flex flex-wrap items-center gap-3 min-w-0 justify-between">
<span className="text-sm text-muted">Visible start</span>
<span>{dateFormat.format(start)}</span>
</div>
</CardContent>
</Card>
</div>
</div>
);
}
export function DemoExample() {
return (<RoadmapExample />);
}More examples
Different configurations and compositions using the real Pimolu API. Each preview runs independently and follows the site appearance.
Weekly planning
Navigate the timeline and zoom; task details remain available as text.
Task inspection
Navigate the timeline and zoom; task details remain available as text.
Executive overview
A month-scale variant with an explicit range and dependency links turned off.
Usage
Treat dates, dependency validation and progress updates as application data.
API reference
Generated from the public TypeScript declarations. Native HTML attributes are inherited where the component extends them; this reference includes Pimolu props and selected common native attributes.
PimoluGanttTask
Type source| Name | Type | Default | Description |
|---|---|---|---|
idRequired | string | — | Stable identifier, also used to resolve dependencies. |
nameRequired | string | — | Visible task name. |
startRequired | Date | — | First day of the task. The time part is ignored. |
endRequired | Date | — | Last day of the task, inclusive. The time part is ignored. |
progress | number | undefined | 0 | Completion percentage, clamped to 0–100. Defaults to 0. |
dependencies | readonly string[] | undefined | — | IDs of tasks that must finish before this one starts. |
color | string | undefined | — | Optional bar accent colour. |
group | string | undefined | — | Optional group heading. Tasks sharing a group are rendered together. |
idRequiredstringNo default extracted.
Stable identifier, also used to resolve dependencies.
nameRequiredstringNo default extracted.
Visible task name.
startRequiredDateNo default extracted.
First day of the task. The time part is ignored.
endRequiredDateNo default extracted.
Last day of the task, inclusive. The time part is ignored.
progressnumber | undefinedDefault: 0
Completion percentage, clamped to 0–100. Defaults to 0.
dependenciesreadonly string[] | undefinedNo default extracted.
IDs of tasks that must finish before this one starts.
colorstring | undefinedNo default extracted.
Optional bar accent colour.
groupstring | undefinedNo default extracted.
Optional group heading. Tasks sharing a group are rendered together.
PimoluGanttProps
Type source| Name | Type | Default | Description |
|---|---|---|---|
tasksRequired | readonly PimoluGanttTask[] | — | Tasks to display. |
start | Date | undefined | — | Controlled first day of the visible range. When omitted, the range is derived from the tasks, unless a navigation or Today action moved it. |
defaultStart | Date | undefined | the task range | Initial visible start when uncontrolled. Defaults to the task range. |
end | Date | undefined | the task range | Last day of the visible range, inclusive. Defaults to the task range. |
onStartChange | ((start: Date) => void) | undefined | — | Called with the next visible start after navigation or Today. |
scale | PimoluGanttScale | undefined | — | Controlled timeline scale. |
defaultScale | PimoluGanttScale | undefined | "day" | Initial scale when uncontrolled. Defaults to "day". |
onScaleChange | ((scale: PimoluGanttScale) => void) | undefined | — | Called when the Day/Week/Month control changes. |
zoom | number | undefined | 1 | Controlled zoom multiplier between 0.5 and 2. Defaults to 1. |
defaultZoom | number | undefined | 1 | Initial zoom when uncontrolled. Defaults to 1. |
onZoomChange | ((zoom: number) => void) | undefined | — | Called when the zoom controls change the multiplier. |
showDependencies | boolean | undefined | true | Draw SVG dependency links between tasks. Defaults to true. |
showToday | boolean | undefined | true | Draw a vertical marker for today when it is inside the range. Defaults to true. |
locale | string | undefined | "en-US" | BCP 47 locale used for date labels. Defaults to "en-US". |
onTaskClick | ((task: PimoluGanttTask) => void) | undefined | — | Called when a task bar or task name is activated. |
maxHeight | string | number | undefined | — | Maximum height of the scrollable chart. |
className | string | undefined | — | Class applied to the outer Gantt. |
aria-label | string | undefined | "Project timeline" | Accessible name of the timeline table. Defaults to "Project timeline". |
tasksRequiredreadonly PimoluGanttTask[]No default extracted.
Tasks to display.
startDate | undefinedNo default extracted.
Controlled first day of the visible range. When omitted, the range is derived from the tasks, unless a navigation or Today action moved it.
defaultStartDate | undefinedDefault: the task range
Initial visible start when uncontrolled. Defaults to the task range.
endDate | undefinedDefault: the task range
Last day of the visible range, inclusive. Defaults to the task range.
onStartChange((start: Date) => void) | undefinedNo default extracted.
Called with the next visible start after navigation or Today.
scalePimoluGanttScale | undefinedNo default extracted.
Controlled timeline scale.
defaultScalePimoluGanttScale | undefinedDefault: "day"
Initial scale when uncontrolled. Defaults to "day".
onScaleChange((scale: PimoluGanttScale) => void) | undefinedNo default extracted.
Called when the Day/Week/Month control changes.
zoomnumber | undefinedDefault: 1
Controlled zoom multiplier between 0.5 and 2. Defaults to 1.
defaultZoomnumber | undefinedDefault: 1
Initial zoom when uncontrolled. Defaults to 1.
onZoomChange((zoom: number) => void) | undefinedNo default extracted.
Called when the zoom controls change the multiplier.
showDependenciesboolean | undefinedDefault: true
Draw SVG dependency links between tasks. Defaults to true.
showTodayboolean | undefinedDefault: true
Draw a vertical marker for today when it is inside the range. Defaults to true.
localestring | undefinedDefault: "en-US"
BCP 47 locale used for date labels. Defaults to "en-US".
onTaskClick((task: PimoluGanttTask) => void) | undefinedNo default extracted.
Called when a task bar or task name is activated.
maxHeightstring | number | undefinedNo default extracted.
Maximum height of the scrollable chart.
classNamestring | undefinedNo default extracted.
Class applied to the outer Gantt.
aria-labelstring | undefinedDefault: "Project timeline"
Accessible name of the timeline table. Defaults to "Project timeline".
Accessibility
- Keep task names and dates available in text and provide keyboard access to selectable tasks.