Gantt
proGantt plots tasks, milestones, and dependencies across a timeline, with drag-to-reschedule, resize-to-adjust-duration, and drag-to-set-progress built in.
Installation
Add this component with the NateUI CLI.
Examples
Every example below shares the same chart interactions: hold Space and drag to pan, hover a row to highlight it in both the table and the chart, and scrollbars stay hidden until the pointer is over the chart.
View Modes
Off Days
Grouped Tasks
Add & Edit Tasks
Resizable Bars
Resizable Task List
Custom Columns
Custom Bar Content
Bar Context Menu
Fixed Height
API
Gantt
| Prop | Description | Type | Default |
|---|---|---|---|
tasks | Rows to render: tasks, milestones, and project groups. Required. | Task<T>[] | — |
columns | Task-list columns shown on the left. An empty array renders the default Name column; null hides the task list and shows the timeline only. | Columns<T>[] | null | [] |
customBarContent | Renders custom content inside each task bar's inset label area. Called for task-type rows only. Not the route for a menu — use renderBarMenu. | CustomBarContent<T> | — |
renderBarMenu | Menu content for a bar's right-click menu. Return Dropdown.Item children. Applies to tasks, milestones, and project rows. | (task: Task<T>) => ReactNode | — |
viewMode | Time scale of the timeline. | ViewMode | 'Day' |
viewDate | Scrolls the timeline so this date is in view. | Date | — |
scrollToTodayOnLoad | Scrolls to today on first render when today falls inside the data range. Ignored when viewDate is set. | boolean | true |
ref | Imperative handle for scrolling the timeline. See GanttRef. | Ref<GanttRef> | — |
preStepsCount | Empty time columns kept before the first task. | number | 1 |
locale | Locale used for the header's day and month labels. | string | 'en-GB' |
rtl | Lays the chart out right-to-left. | boolean | false |
className | Extra classes on the Gantt wrapper element. | string | — |
rowHeight | Height of each row, in px. | number | 50 |
gridColumnsWidth | Width of each time column, in px. | number | 100 |
headerHeight | Height of the date header, in px. | number | 70 |
ganttHeight | Fixed chart height in px; rows scroll vertically inside it. 0 grows to fit every row. | number | 0 |
resizableTaskList | Lets the user drag the divider between the task list and the timeline. | boolean | true |
defaultTaskListWidth | Initial task-list width in px. Omit to size to the columns' content. | number | — |
taskListMinWidth | Lower clamp when dragging the task list, in px. | number | 160 |
taskListMaxWidth | Upper clamp when dragging the task list, in px. | number | 720 |
resizableColumns | Lets the user drag the boundary between task-list columns. | boolean | true |
barFill | Percentage of the row height a bar occupies. | number | 60 |
barCornerRadius | Corner radius of bars, in px. | number | 4 |
handleWidth | Width of the move/resize handles, in px. | number | 8 |
barProgressClass | SVG fill-* class for a task bar's progress fill. | string | 'fill-primary' |
barWrapperClass | SVG fill-* class for a task bar's track. | string | 'fill-[#b8c2cc]' |
projectProgressClass | Progress fill for project rows. | string | 'fill-primary' |
projectWrapperClass | Track fill for project rows. | string | 'fill-[#b8c2cc]' |
milestoneClass | Fill for milestone diamonds. | string | 'fill-primary' |
todayColor | Fill color of the current-day column. | string | 'var(--nui-muted)' |
offDays | Weekday indices shaded as non-working, 0 = Sunday. Only applies to Day and finer view modes. [] disables. | number[] | [0, 6] |
offDayClass | SVG fill-* class for non-working columns. Non-working columns show a diagonal hatch by default; passing this replaces the hatch with a flat wash. | string | '' |
rollUpParents | Draws project rows spanning their children instead of their own dates. Dates only — a project's own progress stays as authored. Computed for display; never written to your data. | boolean | false |
arrowClass | Extra class on dependency arrows, which otherwise inherit border. | string | '' |
arrowIndent | Horizontal indent of dependency arrows, in px. | number | 20 |
timeStep | Snap interval for drag and resize, in ms. | number | 300000 |
TooltipContent | Component rendered in the hover/drag tooltip. | FC<{ task: Task<T> }> | StandardTooltipContent |
pushDependents | Moves a dragged task's dependents with it — live during the drag, committed on drop. Only pushes later, never pulls earlier. | boolean | false |
onDateChange | Fires after a bar is moved or resized. Return false to reject the change — with pushDependents on, this reverts every task that moved, not just the dragged one. Providing this also enables the move and resize handles. The second argument is the task's direct successors when pushDependents is off (informational only); every task that actually moved when it's on. | (task: Task<T>, children: Task<T>[]) => void | boolean | Promise<void | boolean> | — |
onProgressChange | Fires after the progress handle is dragged. Return false to reject. Providing this also enables the progress handle. | (task: Task<T>, children: Task<T>[]) => void | boolean | Promise<void | boolean> | — |
onExpanderClick | Fires when a project's expander is toggled. Providing this also hides the children of collapsed projects. | (task: Task<T>) => void | — |
onClick | Fires when a bar is clicked. | (task: Task<T>) => void | — |
onDoubleClick | Fires when a bar is double-clicked. | (task: Task<T>) => void | — |
onSelect | Fires when a bar gains or loses selection (focus). | (task: Task<T>, isSelected: boolean) => void | — |
onDelete | Fires when Delete is pressed on a focused bar. Return truthy to remove it. | (task: Task<T>) => void | boolean | Promise<void | boolean> | — |
onCellClick | Fires when an empty timeline cell is clicked. Receives the row's task and the clicked column's start date. Providing this also enables the cell hover highlight and pointer cursor. | (task: Task<T>, date: Date, event: MouseEvent) => void | — |
onBarContextMenu | Fires on right-click of a bar, before the menu opens. | (task: Task<T>, event: MouseEvent) => void | — |
The move and resize handles only appear when onDateChange is set, and the progress handle only appears when onProgressChange is set. The chart keeps its own internal copy of the rows, so a bar stays where it is dragged even before the callback updates your data; return false from the callback to snap it back. With custom columns, the built-in expander button is not rendered — wire the cell's expander node to your own handler when you need clickable groups.