@ganttloom/gantt-react 0.2.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -1
- package/dist/index.cjs +30 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +30 -9
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -8,6 +8,8 @@ wrapper: it owns no scheduling logic of its own, just React lifecycle,
|
|
|
8
8
|
props-as-events, and an imperative handle for the escape hatches (undo/redo,
|
|
9
9
|
zoom, export) that don't fit the declarative-props model.
|
|
10
10
|
|
|
11
|
+

|
|
12
|
+
|
|
11
13
|
## Install
|
|
12
14
|
|
|
13
15
|
```bash
|
|
@@ -107,7 +109,28 @@ shift-click selects a range. Then drive it from the handle:
|
|
|
107
109
|
```
|
|
108
110
|
|
|
109
111
|
Both off by default (same construction-time-only wiring caveat as
|
|
110
|
-
`onTaskCreate` — pass the prop from the first render).
|
|
112
|
+
`onTaskCreate` — pass the prop from the first render). Double-clicking a
|
|
113
|
+
task bar itself fires the separate `onTaskDblClick={(task) => ...}`, same
|
|
114
|
+
caveat.
|
|
115
|
+
|
|
116
|
+
## Filling the viewport at any zoom level
|
|
117
|
+
|
|
118
|
+
A short project at month/year zoom, or just a handful of tasks, naturally
|
|
119
|
+
renders narrow. `autoFitToViewport` stretches (never shrinks) the timeline
|
|
120
|
+
to fill the container instead of leaving empty space:
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
<GanttChart tasks={tasks} autoFitToViewport />
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Off by default — upgrading doesn't silently change an existing chart's
|
|
127
|
+
pixel layout for anyone who hasn't opted in.
|
|
128
|
+
|
|
129
|
+
Always on, separately: the visible range is padded to a minimum tick count
|
|
130
|
+
per zoom level, so a short project at year/quarter zoom never collapses
|
|
131
|
+
into one or two lonely columns, and the date header stays pinned to the
|
|
132
|
+
top while scrolling a tall task list vertically (still scrolling
|
|
133
|
+
horizontally in sync with the bars).
|
|
111
134
|
|
|
112
135
|
## Drag-to-create
|
|
113
136
|
|
|
@@ -140,6 +163,21 @@ See `@ganttloom/gantt-core`'s README for the full behavior of each — the
|
|
|
140
163
|
props here are 1:1 mirrors of its `GanttOptions` fields, and `filterTasks`
|
|
141
164
|
is a pure re-export.
|
|
142
165
|
|
|
166
|
+
## Column sorting
|
|
167
|
+
|
|
168
|
+
Mark a column `sortable`; clicking its header cycles asc → desc → none:
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
<GanttChart
|
|
172
|
+
tasks={tasks}
|
|
173
|
+
columns={[{ id: "name", title: "Task", sortable: true }]}
|
|
174
|
+
onSortChange={(sort) => console.log(sort)} // { columnId, direction } | null
|
|
175
|
+
/>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
`chartRef.current?.setSort(columnId, direction)` / `.getSort()` are also
|
|
179
|
+
available on the handle.
|
|
180
|
+
|
|
143
181
|
## Resource leveling and multi-page PNG export
|
|
144
182
|
|
|
145
183
|
```tsx
|
|
@@ -159,6 +197,21 @@ const svg = renderResourceHistogramSVG(buckets);
|
|
|
159
197
|
// e.g. <div dangerouslySetInnerHTML={{ __html: svg }} />
|
|
160
198
|
```
|
|
161
199
|
|
|
200
|
+
## Hover tooltips
|
|
201
|
+
|
|
202
|
+
On by default (name/dates/progress/assignees/notes), styled via plain CSS
|
|
203
|
+
(`.gantt-tooltip`, see `gantt-core`'s README) — not the browser's native
|
|
204
|
+
tooltip. `renderTooltip` fully replaces the content:
|
|
205
|
+
|
|
206
|
+
```tsx
|
|
207
|
+
<GanttChart
|
|
208
|
+
tasks={tasks}
|
|
209
|
+
renderTooltip={(task) => (task.isMilestone ? null : `${task.name} — ${task.progress ?? 0}%`)}
|
|
210
|
+
/>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Set `showTooltip={false}` to disable it entirely.
|
|
214
|
+
|
|
162
215
|
## `useGanttChart` (lower-level hook)
|
|
163
216
|
|
|
164
217
|
If you want to own the container element/DOM tree yourself instead of using
|
package/dist/index.cjs
CHANGED
|
@@ -134,7 +134,8 @@ var EMPTY_RENDER_MODEL = {
|
|
|
134
134
|
columns: [],
|
|
135
135
|
theme: {},
|
|
136
136
|
markers: [],
|
|
137
|
-
rangeStart: /* @__PURE__ */ new Date(0)
|
|
137
|
+
rangeStart: /* @__PURE__ */ new Date(0),
|
|
138
|
+
sort: null
|
|
138
139
|
};
|
|
139
140
|
function GanttChartInner(props, ref) {
|
|
140
141
|
const {
|
|
@@ -148,6 +149,7 @@ function GanttChartInner(props, ref) {
|
|
|
148
149
|
onDependencyRemove,
|
|
149
150
|
onDependencyDblClick,
|
|
150
151
|
onTaskClick,
|
|
152
|
+
onTaskDblClick,
|
|
151
153
|
onGroupToggle,
|
|
152
154
|
onContextMenu,
|
|
153
155
|
onTaskCreate,
|
|
@@ -155,6 +157,7 @@ function GanttChartInner(props, ref) {
|
|
|
155
157
|
onColumnReorder,
|
|
156
158
|
onTaskReorder,
|
|
157
159
|
onSelectionChange,
|
|
160
|
+
onSortChange,
|
|
158
161
|
...rest
|
|
159
162
|
} = props;
|
|
160
163
|
const containerRef = (0, import_react2.useRef)(null);
|
|
@@ -172,6 +175,8 @@ function GanttChartInner(props, ref) {
|
|
|
172
175
|
);
|
|
173
176
|
const enableDependencyDblClickWiring = (0, import_react2.useRef)((_dep) => {
|
|
174
177
|
});
|
|
178
|
+
const enableTaskDblClickWiring = (0, import_react2.useRef)((_task) => {
|
|
179
|
+
});
|
|
175
180
|
const options = (0, import_react2.useMemo)(
|
|
176
181
|
() => ({
|
|
177
182
|
...rest,
|
|
@@ -180,11 +185,11 @@ function GanttChartInner(props, ref) {
|
|
|
180
185
|
onColumnResize: onColumnResize ? enableColumnResizeWiring.current : void 0,
|
|
181
186
|
onColumnReorder: onColumnReorder ? enableColumnReorderWiring.current : void 0,
|
|
182
187
|
onTaskReorder: onTaskReorder ? enableTaskReorderWiring.current : void 0,
|
|
183
|
-
onDependencyDblClick: onDependencyDblClick ? enableDependencyDblClickWiring.current : void 0
|
|
184
|
-
|
|
185
|
-
//
|
|
186
|
-
//
|
|
187
|
-
//
|
|
188
|
+
onDependencyDblClick: onDependencyDblClick ? enableDependencyDblClickWiring.current : void 0,
|
|
189
|
+
onTaskDblClick: onTaskDblClick ? enableTaskDblClickWiring.current : void 0
|
|
190
|
+
// onSelectionChange/onSortChange are deliberately NOT set here: gantt-core invokes them
|
|
191
|
+
// directly from this.options AND emits a matching event at the same call sites, and the
|
|
192
|
+
// effect below already subscribes to those events — including them here would double-fire.
|
|
188
193
|
}),
|
|
189
194
|
[
|
|
190
195
|
rest.viewMode,
|
|
@@ -199,6 +204,9 @@ function GanttChartInner(props, ref) {
|
|
|
199
204
|
rest.showCriticalPath,
|
|
200
205
|
rest.showBaseline,
|
|
201
206
|
rest.showDeadlines,
|
|
207
|
+
rest.showTooltip,
|
|
208
|
+
rest.renderTooltip,
|
|
209
|
+
rest.autoFitToViewport,
|
|
202
210
|
rest.showAssigneeAvatars,
|
|
203
211
|
rest.enableHistory,
|
|
204
212
|
rest.keyboardAccessible,
|
|
@@ -214,7 +222,8 @@ function GanttChartInner(props, ref) {
|
|
|
214
222
|
Boolean(onColumnResize),
|
|
215
223
|
Boolean(onColumnReorder),
|
|
216
224
|
Boolean(onTaskReorder),
|
|
217
|
-
Boolean(onDependencyDblClick)
|
|
225
|
+
Boolean(onDependencyDblClick),
|
|
226
|
+
Boolean(onTaskDblClick)
|
|
218
227
|
]
|
|
219
228
|
);
|
|
220
229
|
const { chart } = useGanttChart(containerRef, tasks, dependencies, options);
|
|
@@ -225,13 +234,15 @@ function GanttChartInner(props, ref) {
|
|
|
225
234
|
onDependencyRemove,
|
|
226
235
|
onDependencyDblClick,
|
|
227
236
|
onTaskClick,
|
|
237
|
+
onTaskDblClick,
|
|
228
238
|
onGroupToggle,
|
|
229
239
|
onContextMenu,
|
|
230
240
|
onTaskCreate,
|
|
231
241
|
onColumnResize,
|
|
232
242
|
onColumnReorder,
|
|
233
243
|
onTaskReorder,
|
|
234
|
-
onSelectionChange
|
|
244
|
+
onSelectionChange,
|
|
245
|
+
onSortChange
|
|
235
246
|
});
|
|
236
247
|
callbacksRef.current = {
|
|
237
248
|
onDateChange,
|
|
@@ -240,13 +251,15 @@ function GanttChartInner(props, ref) {
|
|
|
240
251
|
onDependencyRemove,
|
|
241
252
|
onDependencyDblClick,
|
|
242
253
|
onTaskClick,
|
|
254
|
+
onTaskDblClick,
|
|
243
255
|
onGroupToggle,
|
|
244
256
|
onContextMenu,
|
|
245
257
|
onTaskCreate,
|
|
246
258
|
onColumnResize,
|
|
247
259
|
onColumnReorder,
|
|
248
260
|
onTaskReorder,
|
|
249
|
-
onSelectionChange
|
|
261
|
+
onSelectionChange,
|
|
262
|
+
onSortChange
|
|
250
263
|
};
|
|
251
264
|
(0, import_react2.useEffect)(() => {
|
|
252
265
|
if (!chart) return void 0;
|
|
@@ -255,6 +268,7 @@ function GanttChartInner(props, ref) {
|
|
|
255
268
|
const handleDependencyCreate = (dep) => callbacksRef.current.onDependencyCreate?.(dep);
|
|
256
269
|
const handleDependencyRemove = (dep) => callbacksRef.current.onDependencyRemove?.(dep);
|
|
257
270
|
const handleTaskClick = (p) => callbacksRef.current.onTaskClick?.(p.task);
|
|
271
|
+
const handleTaskDblClick = (p) => callbacksRef.current.onTaskDblClick?.(p.task);
|
|
258
272
|
const handleGroupToggle = (p) => callbacksRef.current.onGroupToggle?.(p.task, p.collapsed);
|
|
259
273
|
const handleContextMenu = (p) => callbacksRef.current.onContextMenu?.(p.task, p.evt);
|
|
260
274
|
const handleTaskCreate = (p) => callbacksRef.current.onTaskCreate?.(p.task);
|
|
@@ -263,12 +277,14 @@ function GanttChartInner(props, ref) {
|
|
|
263
277
|
const handleDependencyDblClick = (dep) => callbacksRef.current.onDependencyDblClick?.(dep);
|
|
264
278
|
const handleTaskReorder = (p) => callbacksRef.current.onTaskReorder?.(p.draggedTaskId, p.targetTaskId, p.position);
|
|
265
279
|
const handleSelectionChange = (p) => callbacksRef.current.onSelectionChange?.(p.taskIds);
|
|
280
|
+
const handleSortChange = (p) => callbacksRef.current.onSortChange?.(p.sort);
|
|
266
281
|
chart.on("date-change", handleDateChange);
|
|
267
282
|
chart.on("progress-change", handleProgressChange);
|
|
268
283
|
chart.on("dependency-create", handleDependencyCreate);
|
|
269
284
|
chart.on("dependency-remove", handleDependencyRemove);
|
|
270
285
|
chart.on("dependency-dblclick", handleDependencyDblClick);
|
|
271
286
|
chart.on("task-click", handleTaskClick);
|
|
287
|
+
chart.on("task-dblclick", handleTaskDblClick);
|
|
272
288
|
chart.on("group-toggle", handleGroupToggle);
|
|
273
289
|
chart.on("context-menu", handleContextMenu);
|
|
274
290
|
chart.on("task-create", handleTaskCreate);
|
|
@@ -276,6 +292,7 @@ function GanttChartInner(props, ref) {
|
|
|
276
292
|
chart.on("column-reorder", handleColumnReorder);
|
|
277
293
|
chart.on("task-reorder", handleTaskReorder);
|
|
278
294
|
chart.on("selection-change", handleSelectionChange);
|
|
295
|
+
chart.on("sort-change", handleSortChange);
|
|
279
296
|
return () => {
|
|
280
297
|
chart.off("date-change", handleDateChange);
|
|
281
298
|
chart.off("progress-change", handleProgressChange);
|
|
@@ -283,6 +300,7 @@ function GanttChartInner(props, ref) {
|
|
|
283
300
|
chart.off("dependency-remove", handleDependencyRemove);
|
|
284
301
|
chart.off("dependency-dblclick", handleDependencyDblClick);
|
|
285
302
|
chart.off("task-click", handleTaskClick);
|
|
303
|
+
chart.off("task-dblclick", handleTaskDblClick);
|
|
286
304
|
chart.off("group-toggle", handleGroupToggle);
|
|
287
305
|
chart.off("context-menu", handleContextMenu);
|
|
288
306
|
chart.off("task-create", handleTaskCreate);
|
|
@@ -290,6 +308,7 @@ function GanttChartInner(props, ref) {
|
|
|
290
308
|
chart.off("column-reorder", handleColumnReorder);
|
|
291
309
|
chart.off("task-reorder", handleTaskReorder);
|
|
292
310
|
chart.off("selection-change", handleSelectionChange);
|
|
311
|
+
chart.off("sort-change", handleSortChange);
|
|
293
312
|
};
|
|
294
313
|
}, [chart]);
|
|
295
314
|
(0, import_react2.useImperativeHandle)(
|
|
@@ -321,6 +340,8 @@ function GanttChartInner(props, ref) {
|
|
|
321
340
|
selectAllVisible: () => chart?.selectAllVisible(),
|
|
322
341
|
clearSelection: () => chart?.clearSelection(),
|
|
323
342
|
getSelectedTaskIds: () => chart?.getSelectedTaskIds() ?? [],
|
|
343
|
+
setSort: (columnId, direction) => chart?.setSort(columnId, direction),
|
|
344
|
+
getSort: () => chart?.getSort() ?? null,
|
|
324
345
|
bulkShiftDates: (deltaMs) => chart?.bulkShiftDates(deltaMs),
|
|
325
346
|
bulkDelete: () => chart?.bulkDelete(),
|
|
326
347
|
toSVGString: () => chart?.toSVGString() ?? "",
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/GanttChart.tsx","../src/useGanttChart.ts"],"sourcesContent":["export { GanttChart, default } from \"./GanttChart\";\nexport type { GanttChartProps, GanttChartHandle } from \"./GanttChart\";\n\nexport { useGanttChart } from \"./useGanttChart\";\nexport type { UseGanttChartResult } from \"./useGanttChart\";\n\n// Re-exported so consumers never need to add @ganttloom/gantt-core as a direct\n// dependency just to reference its types.\nexport type {\n ViewMode,\n DependencyType,\n GanttDependency,\n GanttAssignee,\n GanttTask,\n GanttColumn,\n GanttTheme,\n GanttRenderRow,\n GanttRenderBar,\n GanttRenderLink,\n GanttRenderTick,\n GanttRenderModel,\n GanttOptions,\n GanttEventMap,\n WorkingCalendar,\n ConstraintType,\n ResourceHistogramOptions,\n ResourceLoadBucket,\n GanttMarker,\n GanttRenderMarker,\n FilterTasksOptions,\n FilterTasksResult,\n Density,\n ResourceLevelingOptions,\n ResourceLevelingResult,\n} from \"@ganttloom/gantt-core\";\n\nexport {\n computeWBSCodes,\n applyConstraint,\n isWorkingDay,\n isHoliday,\n isWithinWorkingHours,\n isWorkingTime,\n nextWorkingDay,\n previousWorkingDay,\n shiftToWorkingDay,\n shiftToWorkingTime,\n computeResourceHistogram,\n renderResourceHistogramSVG,\n filterTasks,\n colorByField,\n applyColorByField,\n DEFAULT_PALETTE,\n DENSITY_PRESETS,\n levelResources,\n} from \"@ganttloom/gantt-core\";\n","// Pulls in the core's default styles so consumers get a working chart out of the box.\n// This resolves through gantt-core's package.json \"exports\" map (\"./styles.css\" -> \"./dist/styles.css\").\n// If your bundler can't resolve CSS imports from a dependency's export map, import it yourself instead:\n// import \"@ganttloom/gantt-core/styles.css\";\nimport \"@ganttloom/gantt-core/styles.css\";\n\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n type CSSProperties,\n type Ref,\n} from \"react\";\nimport type {\n GanttChart as GanttCore,\n GanttColumn,\n GanttDependency,\n GanttMarker,\n GanttOptions,\n GanttRenderModel,\n GanttTask,\n GanttTheme,\n ResourceHistogramOptions,\n ResourceLoadBucket,\n ResourceLevelingOptions,\n ResourceLevelingResult,\n ViewMode,\n WorkingCalendar,\n} from \"@ganttloom/gantt-core\";\nimport { useGanttChart } from \"./useGanttChart\";\n\nexport interface GanttChartProps {\n tasks: GanttTask[];\n dependencies?: GanttDependency[];\n\n // Mirrors of GanttOptions' non-callback fields.\n viewMode?: ViewMode;\n columns?: GanttColumn[];\n theme?: Partial<GanttTheme>;\n colorScheme?: \"light\" | \"dark\" | \"auto\";\n columnWidth?: number;\n readonly?: boolean;\n showProgress?: boolean;\n showDependencies?: boolean;\n gridPanelWidth?: number;\n showCriticalPath?: boolean;\n showBaseline?: boolean;\n showDeadlines?: boolean;\n showAssigneeAvatars?: boolean;\n enableHistory?: boolean;\n keyboardAccessible?: boolean;\n virtualScroll?: boolean;\n autoSchedule?: boolean;\n pagination?: { pageSize: number; page: number };\n snapToUnit?: \"hour\" | \"day\" | \"week\" | false;\n /** working-day/holiday definition used to shade non-working time and (with autoSchedule) skip it when cascading */\n calendar?: WorkingCalendar;\n /** arbitrary labeled vertical lines on the timeline, independent of any task */\n markers?: GanttMarker[];\n /** a group task with no explicit `progress` gets a duration-weighted average of its children's progress instead of 0 */\n autoRollupProgress?: boolean;\n /** enables click/ctrl-click/shift-click multi-selection of task bars, and the handle's bulkShiftDates()/bulkDelete() */\n selectable?: boolean;\n\n // Mirrors of GanttOptions' callback fields, as normal React event props.\n onDateChange?: (task: GanttTask, start: Date, end: Date) => void;\n onProgressChange?: (task: GanttTask, progress: number) => void;\n onDependencyCreate?: (dep: GanttDependency) => void;\n onDependencyRemove?: (dep: GanttDependency) => void;\n /** called on double-click of a dependency link, for building your own \"edit this link\" UI (see the handle's updateDependency) */\n onDependencyDblClick?: (dep: GanttDependency) => void;\n onTaskClick?: (task: GanttTask) => void;\n onGroupToggle?: (task: GanttTask, collapsed: boolean) => void;\n onContextMenu?: (task: GanttTask, evt: PointerEvent) => void;\n /** called when a task is created via drag-to-create on an empty timeline row */\n onTaskCreate?: (task: GanttTask) => void;\n /** called when a grid column is resized by dragging its header's edge */\n onColumnResize?: (columnId: string, width: number) => void;\n /** called when grid columns are reordered by dragging a header; `order` is the new full list of column ids */\n onColumnReorder?: (order: string[]) => void;\n /** called when a grid row is dragged onto another; \"inside\" reparents the dragged task under the target */\n onTaskReorder?: (draggedTaskId: string, targetTaskId: string, position: \"before\" | \"after\" | \"inside\") => void;\n onSelectionChange?: (taskIds: string[]) => void;\n\n /** Applied to the wrapping container div. */\n className?: string;\n style?: CSSProperties;\n}\n\n/** Imperative escape hatches that don't need to be reactive props. */\nexport interface GanttChartHandle {\n undo(): void;\n redo(): void;\n canUndo(): boolean;\n canRedo(): boolean;\n expandAll(): void;\n collapseAll(): void;\n toggleGroup(taskId: string): void;\n removeDependency(fromId: string, toId: string): void;\n updateDependency(fromId: string, toId: string, partial: Partial<GanttDependency>): void;\n updateTask(id: string, partial: Partial<GanttTask>): void;\n setViewMode(mode: ViewMode): void;\n fitToViewport(containerWidthPx: number): void;\n scrollToToday(): void;\n scrollToRangeStart(): void;\n scrollToRangeEnd(): void;\n getPageCount(): number;\n setPage(page: number): void;\n zoomIn(factor?: number): void;\n zoomOut(factor?: number): void;\n getZoomLevel(): number;\n getResourceHistogram(options?: ResourceHistogramOptions): ResourceLoadBucket[];\n getLeveledTasks(options?: ResourceLevelingOptions): ResourceLevelingResult;\n selectTask(id: string, options?: { additive?: boolean }): void;\n selectAllVisible(): void;\n clearSelection(): void;\n getSelectedTaskIds(): string[];\n bulkShiftDates(deltaMs: number): void;\n bulkDelete(): void;\n toSVGString(): string;\n toPNGDataURL(): Promise<string>;\n toPNGDataURLs(options?: { pageWidthPx?: number; pageHeightPx?: number }): Promise<string[]>;\n getRenderModel(): GanttRenderModel | null;\n /** Direct access to the underlying framework-agnostic core instance (null before mount). */\n getInstance(): GanttCore | null;\n}\n\nconst EMPTY_DEPENDENCIES: GanttDependency[] = [];\n\nconst EMPTY_RENDER_MODEL: GanttRenderModel = {\n width: 0,\n height: 0,\n rowHeight: 0,\n headerHeight: 0,\n rows: [],\n bars: [],\n links: [],\n ticks: [],\n columns: [],\n theme: {} as GanttTheme,\n markers: [],\n rangeStart: new Date(0),\n};\n\nfunction GanttChartInner(props: GanttChartProps, ref: Ref<GanttChartHandle>) {\n const {\n tasks,\n dependencies = EMPTY_DEPENDENCIES,\n className,\n style,\n onDateChange,\n onProgressChange,\n onDependencyCreate,\n onDependencyRemove,\n onDependencyDblClick,\n onTaskClick,\n onGroupToggle,\n onContextMenu,\n onTaskCreate,\n onColumnResize,\n onColumnReorder,\n onTaskReorder,\n onSelectionChange,\n ...rest\n } = props;\n\n const containerRef = useRef<HTMLDivElement | null>(null);\n\n // The core only wires up its internal contextmenu DOM listener (and therefore only\n // ever emits the \"context-menu\" event) when options.onContextMenu is truthy AT\n // CONSTRUCTION TIME (see GanttChart#setupDom in gantt-core). We pass a stable no-op\n // here purely to force that wiring on regardless of whether the consumer supplied\n // onContextMenu, and dispatch the actual prop via the \"context-menu\" event\n // subscription below (so it stays reactive to prop changes and is never double-fired).\n const enableContextMenuWiring = useRef(() => {});\n\n // Same construction-time-only caveat as onContextMenu above: drag-to-create is only\n // wired into the core's InteractionController when options.onTaskCreate is truthy at\n // construction. A stable no-op forces it on whenever this component was given an\n // onTaskCreate prop at all; the real dispatch goes through the \"task-create\" event.\n const enableCreateWiring = useRef(() => {});\n\n // Same construction-time-only caveat: column resize/reorder DOM listeners are only\n // built into the grid header when these options are truthy at construction.\n const enableColumnResizeWiring = useRef((_columnId: string, _width: number) => {});\n const enableColumnReorderWiring = useRef((_order: string[]) => {});\n const enableTaskReorderWiring = useRef(\n (_draggedTaskId: string, _targetTaskId: string, _position: \"before\" | \"after\" | \"inside\") => {}\n );\n const enableDependencyDblClickWiring = useRef((_dep: GanttDependency) => {});\n\n // Deliberately depend on Boolean(handler) rather than the handler itself below: the\n // ref-backed enableXWiring callbacks already pick up the latest handler without\n // needing the memo to re-run, so depending on the raw (often inline) callback would\n // just re-create `options` — and remount the chart — every render.\n /* eslint-disable react-hooks/exhaustive-deps */\n const options = useMemo<GanttOptions>(\n () => ({\n ...rest,\n onContextMenu: enableContextMenuWiring.current,\n onTaskCreate: onTaskCreate ? enableCreateWiring.current : undefined,\n onColumnResize: onColumnResize ? enableColumnResizeWiring.current : undefined,\n onColumnReorder: onColumnReorder ? enableColumnReorderWiring.current : undefined,\n onTaskReorder: onTaskReorder ? enableTaskReorderWiring.current : undefined,\n onDependencyDblClick: onDependencyDblClick ? enableDependencyDblClickWiring.current : undefined,\n // onSelectionChange is deliberately NOT set here: gantt-core invokes it directly from\n // this.options AND emits a \"selection-change\" event at the same call sites, and the\n // effect below already subscribes to that event — including it here would double-fire\n // every selection change.\n }),\n [\n rest.viewMode,\n rest.columns,\n rest.theme,\n rest.colorScheme,\n rest.columnWidth,\n rest.readonly,\n rest.showProgress,\n rest.showDependencies,\n rest.gridPanelWidth,\n rest.showCriticalPath,\n rest.showBaseline,\n rest.showDeadlines,\n rest.showAssigneeAvatars,\n rest.enableHistory,\n rest.keyboardAccessible,\n rest.virtualScroll,\n rest.autoSchedule,\n rest.pagination,\n rest.snapToUnit,\n rest.calendar,\n rest.markers,\n rest.autoRollupProgress,\n rest.selectable,\n Boolean(onTaskCreate),\n Boolean(onColumnResize),\n Boolean(onColumnReorder),\n Boolean(onTaskReorder),\n Boolean(onDependencyDblClick),\n ]\n );\n /* eslint-enable react-hooks/exhaustive-deps */\n\n const { chart } = useGanttChart(containerRef, tasks, dependencies, options);\n\n // Keep the latest callback props in a ref so the event-subscription effect below\n // doesn't need to re-subscribe (tearing down/rebuilding listeners) on every render.\n const callbacksRef = useRef({\n onDateChange,\n onProgressChange,\n onDependencyCreate,\n onDependencyRemove,\n onDependencyDblClick,\n onTaskClick,\n onGroupToggle,\n onContextMenu,\n onTaskCreate,\n onColumnResize,\n onColumnReorder,\n onTaskReorder,\n onSelectionChange,\n });\n callbacksRef.current = {\n onDateChange,\n onProgressChange,\n onDependencyCreate,\n onDependencyRemove,\n onDependencyDblClick,\n onTaskClick,\n onGroupToggle,\n onContextMenu,\n onTaskCreate,\n onColumnResize,\n onColumnReorder,\n onTaskReorder,\n onSelectionChange,\n };\n\n useEffect(() => {\n if (!chart) return undefined;\n\n const handleDateChange = (p: { task: GanttTask; start: Date; end: Date }) =>\n callbacksRef.current.onDateChange?.(p.task, p.start, p.end);\n const handleProgressChange = (p: { task: GanttTask; progress: number }) =>\n callbacksRef.current.onProgressChange?.(p.task, p.progress);\n const handleDependencyCreate = (dep: GanttDependency) =>\n callbacksRef.current.onDependencyCreate?.(dep);\n const handleDependencyRemove = (dep: GanttDependency) =>\n callbacksRef.current.onDependencyRemove?.(dep);\n const handleTaskClick = (p: { task: GanttTask }) =>\n callbacksRef.current.onTaskClick?.(p.task);\n const handleGroupToggle = (p: { task: GanttTask; collapsed: boolean }) =>\n callbacksRef.current.onGroupToggle?.(p.task, p.collapsed);\n const handleContextMenu = (p: { task: GanttTask; evt: PointerEvent }) =>\n callbacksRef.current.onContextMenu?.(p.task, p.evt);\n const handleTaskCreate = (p: { task: GanttTask }) => callbacksRef.current.onTaskCreate?.(p.task);\n const handleColumnResize = (p: { columnId: string; width: number }) =>\n callbacksRef.current.onColumnResize?.(p.columnId, p.width);\n const handleColumnReorder = (p: { order: string[] }) =>\n callbacksRef.current.onColumnReorder?.(p.order);\n const handleDependencyDblClick = (dep: GanttDependency) =>\n callbacksRef.current.onDependencyDblClick?.(dep);\n const handleTaskReorder = (p: {\n draggedTaskId: string;\n targetTaskId: string;\n position: \"before\" | \"after\" | \"inside\";\n }) => callbacksRef.current.onTaskReorder?.(p.draggedTaskId, p.targetTaskId, p.position);\n const handleSelectionChange = (p: { taskIds: string[] }) =>\n callbacksRef.current.onSelectionChange?.(p.taskIds);\n\n chart.on(\"date-change\", handleDateChange);\n chart.on(\"progress-change\", handleProgressChange);\n chart.on(\"dependency-create\", handleDependencyCreate);\n chart.on(\"dependency-remove\", handleDependencyRemove);\n chart.on(\"dependency-dblclick\", handleDependencyDblClick);\n chart.on(\"task-click\", handleTaskClick);\n chart.on(\"group-toggle\", handleGroupToggle);\n chart.on(\"context-menu\", handleContextMenu);\n chart.on(\"task-create\", handleTaskCreate);\n chart.on(\"column-resize\", handleColumnResize);\n chart.on(\"column-reorder\", handleColumnReorder);\n chart.on(\"task-reorder\", handleTaskReorder);\n chart.on(\"selection-change\", handleSelectionChange);\n\n return () => {\n chart.off(\"date-change\", handleDateChange);\n chart.off(\"progress-change\", handleProgressChange);\n chart.off(\"dependency-create\", handleDependencyCreate);\n chart.off(\"dependency-remove\", handleDependencyRemove);\n chart.off(\"dependency-dblclick\", handleDependencyDblClick);\n chart.off(\"task-click\", handleTaskClick);\n chart.off(\"group-toggle\", handleGroupToggle);\n chart.off(\"context-menu\", handleContextMenu);\n chart.off(\"task-create\", handleTaskCreate);\n chart.off(\"column-resize\", handleColumnResize);\n chart.off(\"column-reorder\", handleColumnReorder);\n chart.off(\"task-reorder\", handleTaskReorder);\n chart.off(\"selection-change\", handleSelectionChange);\n };\n }, [chart]);\n\n useImperativeHandle(\n ref,\n (): GanttChartHandle => ({\n undo: () => chart?.undo(),\n redo: () => chart?.redo(),\n canUndo: () => chart?.canUndo ?? false,\n canRedo: () => chart?.canRedo ?? false,\n expandAll: () => chart?.expandAll(),\n collapseAll: () => chart?.collapseAll(),\n toggleGroup: (taskId: string) => chart?.toggleGroup(taskId),\n removeDependency: (fromId: string, toId: string) => chart?.removeDependency(fromId, toId),\n updateDependency: (fromId: string, toId: string, partial: Partial<GanttDependency>) =>\n chart?.updateDependency(fromId, toId, partial),\n updateTask: (id: string, partial: Partial<GanttTask>) => chart?.updateTask(id, partial),\n setViewMode: (mode: ViewMode) => chart?.setViewMode(mode),\n fitToViewport: (containerWidthPx: number) => chart?.fitToViewport(containerWidthPx),\n scrollToToday: () => chart?.scrollToToday(),\n scrollToRangeStart: () => chart?.scrollToRangeStart(),\n scrollToRangeEnd: () => chart?.scrollToRangeEnd(),\n getPageCount: () => chart?.getPageCount() ?? 1,\n setPage: (page: number) => chart?.setPage(page),\n zoomIn: (factor?: number) => chart?.zoomIn(factor),\n zoomOut: (factor?: number) => chart?.zoomOut(factor),\n getZoomLevel: () => chart?.getZoomLevel() ?? 0,\n getResourceHistogram: (options?: ResourceHistogramOptions) =>\n chart?.getResourceHistogram(options) ?? [],\n getLeveledTasks: (options?: ResourceLevelingOptions) =>\n chart?.getLeveledTasks(options) ?? { tasks: [], shifted: [] },\n selectTask: (id: string, options?: { additive?: boolean }) => chart?.selectTask(id, options),\n selectAllVisible: () => chart?.selectAllVisible(),\n clearSelection: () => chart?.clearSelection(),\n getSelectedTaskIds: () => chart?.getSelectedTaskIds() ?? [],\n bulkShiftDates: (deltaMs: number) => chart?.bulkShiftDates(deltaMs),\n bulkDelete: () => chart?.bulkDelete(),\n toSVGString: () => chart?.toSVGString() ?? \"\",\n toPNGDataURL: () => chart?.toPNGDataURL() ?? Promise.resolve(\"\"),\n toPNGDataURLs: (options?: { pageWidthPx?: number; pageHeightPx?: number }) =>\n chart?.toPNGDataURLs(options) ?? Promise.resolve([]),\n getRenderModel: () => chart?.getRenderModel() ?? EMPTY_RENDER_MODEL,\n getInstance: () => chart,\n }),\n [chart]\n );\n\n return <div ref={containerRef} className={className} style={style} />;\n}\n\nexport const GanttChart = forwardRef(GanttChartInner);\nGanttChart.displayName = \"GanttChart\";\n\nexport default GanttChart;\n","import { useEffect, useRef, useState, type RefObject } from \"react\";\nimport { GanttChart as GanttCore } from \"@ganttloom/gantt-core\";\nimport type { GanttDependency, GanttOptions, GanttTask } from \"@ganttloom/gantt-core\";\n\nexport interface UseGanttChartResult {\n /** The underlying framework-agnostic GanttChart instance, or null before the DOM mount effect runs (or on the server). */\n chart: GanttCore | null;\n /** Reactive, subscribed to the core's \"history-change\" event. Only meaningful when `enableHistory` is set in options. */\n canUndo: boolean;\n /** Reactive, subscribed to the core's \"history-change\" event. Only meaningful when `enableHistory` is set in options. */\n canRedo: boolean;\n}\n\nconst EMPTY_DEPENDENCIES: GanttDependency[] = [];\nconst EMPTY_OPTIONS: GanttOptions = {};\n\n/**\n * Lower-level escape hatch for consumers who want to own their own container element\n * and DOM tree instead of using the <GanttChart /> component. Constructs a\n * @ganttloom/gantt-core GanttChart instance against `containerRef.current` on mount,\n * keeps it in sync with `tasks` / `dependencies` / `options` via setTasks / setDependencies /\n * setOptions (reference-equality checks only — pass new arrays/objects to trigger a sync),\n * and destroys it on unmount.\n */\nexport function useGanttChart(\n containerRef: RefObject<HTMLElement | null>,\n tasks: GanttTask[],\n dependencies: GanttDependency[] = EMPTY_DEPENDENCIES,\n options: GanttOptions = EMPTY_OPTIONS\n): UseGanttChartResult {\n const [chart, setChart] = useState<GanttCore | null>(null);\n const [canUndo, setCanUndo] = useState(false);\n const [canRedo, setCanRedo] = useState(false);\n\n const chartRef = useRef<GanttCore | null>(null);\n\n // Latest props, read from the mount effect so it doesn't need to depend on them\n // (which would otherwise tear down and recreate the whole chart on every change).\n const initialTasksRef = useRef(tasks);\n initialTasksRef.current = tasks;\n const initialDepsRef = useRef(dependencies);\n initialDepsRef.current = dependencies;\n const initialOptionsRef = useRef(options);\n initialOptionsRef.current = options;\n\n useEffect(() => {\n if (typeof window === \"undefined\") return undefined;\n const container = containerRef.current;\n if (!container) return undefined;\n\n const instance = new GanttCore(\n container,\n initialTasksRef.current,\n initialDepsRef.current,\n initialOptionsRef.current\n );\n chartRef.current = instance;\n setChart(instance);\n setCanUndo(instance.canUndo);\n setCanRedo(instance.canRedo);\n\n const onHistoryChange = (state: { canUndo: boolean; canRedo: boolean }) => {\n setCanUndo(state.canUndo);\n setCanRedo(state.canRedo);\n };\n instance.on(\"history-change\", onHistoryChange);\n\n return () => {\n instance.off(\"history-change\", onHistoryChange);\n instance.destroy();\n chartRef.current = null;\n setChart(null);\n setCanUndo(false);\n setCanRedo(false);\n };\n // Intentionally mount/unmount only — the container element identity is what matters.\n }, [containerRef]);\n\n const isFirstTasksSync = useRef(true);\n useEffect(() => {\n if (isFirstTasksSync.current) {\n isFirstTasksSync.current = false;\n return;\n }\n chartRef.current?.setTasks(tasks);\n }, [tasks]);\n\n const isFirstDepsSync = useRef(true);\n useEffect(() => {\n if (isFirstDepsSync.current) {\n isFirstDepsSync.current = false;\n return;\n }\n chartRef.current?.setDependencies(dependencies);\n }, [dependencies]);\n\n const isFirstOptionsSync = useRef(true);\n useEffect(() => {\n if (isFirstOptionsSync.current) {\n isFirstOptionsSync.current = false;\n return;\n }\n chartRef.current?.setOptions(options);\n }, [options]);\n\n return { chart, canUndo, canRedo };\n}\n"],"mappings":"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","names":["import_react","GanttCore","EMPTY_DEPENDENCIES","options","import_gantt_core"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/GanttChart.tsx","../src/useGanttChart.ts"],"sourcesContent":["export { GanttChart, default } from \"./GanttChart\";\nexport type { GanttChartProps, GanttChartHandle } from \"./GanttChart\";\n\nexport { useGanttChart } from \"./useGanttChart\";\nexport type { UseGanttChartResult } from \"./useGanttChart\";\n\n// Re-exported so consumers never need to add @ganttloom/gantt-core as a direct\n// dependency just to reference its types.\nexport type {\n ViewMode,\n DependencyType,\n GanttDependency,\n GanttAssignee,\n GanttTask,\n GanttColumn,\n GanttTheme,\n GanttRenderRow,\n GanttRenderBar,\n GanttRenderLink,\n GanttRenderTick,\n GanttRenderModel,\n GanttOptions,\n GanttEventMap,\n WorkingCalendar,\n ConstraintType,\n ResourceHistogramOptions,\n ResourceLoadBucket,\n GanttMarker,\n GanttRenderMarker,\n FilterTasksOptions,\n FilterTasksResult,\n Density,\n ResourceLevelingOptions,\n ResourceLevelingResult,\n} from \"@ganttloom/gantt-core\";\n\nexport {\n computeWBSCodes,\n applyConstraint,\n isWorkingDay,\n isHoliday,\n isWithinWorkingHours,\n isWorkingTime,\n nextWorkingDay,\n previousWorkingDay,\n shiftToWorkingDay,\n shiftToWorkingTime,\n computeResourceHistogram,\n renderResourceHistogramSVG,\n filterTasks,\n colorByField,\n applyColorByField,\n DEFAULT_PALETTE,\n DENSITY_PRESETS,\n levelResources,\n} from \"@ganttloom/gantt-core\";\n","// Pulls in the core's default styles so consumers get a working chart out of the box.\n// This resolves through gantt-core's package.json \"exports\" map (\"./styles.css\" -> \"./dist/styles.css\").\n// If your bundler can't resolve CSS imports from a dependency's export map, import it yourself instead:\n// import \"@ganttloom/gantt-core/styles.css\";\nimport \"@ganttloom/gantt-core/styles.css\";\n\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n type CSSProperties,\n type Ref,\n} from \"react\";\nimport type {\n GanttChart as GanttCore,\n GanttColumn,\n GanttDependency,\n GanttMarker,\n GanttOptions,\n GanttRenderModel,\n GanttTask,\n GanttTheme,\n ResourceHistogramOptions,\n ResourceLoadBucket,\n ResourceLevelingOptions,\n ResourceLevelingResult,\n ViewMode,\n WorkingCalendar,\n} from \"@ganttloom/gantt-core\";\nimport { useGanttChart } from \"./useGanttChart\";\n\nexport interface GanttChartProps {\n tasks: GanttTask[];\n dependencies?: GanttDependency[];\n\n // Mirrors of GanttOptions' non-callback fields.\n viewMode?: ViewMode;\n columns?: GanttColumn[];\n theme?: Partial<GanttTheme>;\n colorScheme?: \"light\" | \"dark\" | \"auto\";\n columnWidth?: number;\n readonly?: boolean;\n showProgress?: boolean;\n showDependencies?: boolean;\n gridPanelWidth?: number;\n showCriticalPath?: boolean;\n showBaseline?: boolean;\n showDeadlines?: boolean;\n /** hover tooltip on task bars, defaults to true. A floating, CSS-customizable element (`.gantt-tooltip`) - not the browser's native title tooltip. */\n showTooltip?: boolean;\n /** fully control tooltip content/markup; return null/undefined to suppress it for a specific task. Defaults to name/dates/progress/assignees/notes. */\n renderTooltip?: (task: GanttTask) => HTMLElement | string | null | undefined;\n showAssigneeAvatars?: boolean;\n enableHistory?: boolean;\n keyboardAccessible?: boolean;\n virtualScroll?: boolean;\n autoSchedule?: boolean;\n pagination?: { pageSize: number; page: number };\n snapToUnit?: \"hour\" | \"day\" | \"week\" | false;\n /** working-day/holiday definition used to shade non-working time and (with autoSchedule) skip it when cascading */\n calendar?: WorkingCalendar;\n /** arbitrary labeled vertical lines on the timeline, independent of any task */\n markers?: GanttMarker[];\n /** a group task with no explicit `progress` gets a duration-weighted average of its children's progress instead of 0 */\n autoRollupProgress?: boolean;\n /** enables click/ctrl-click/shift-click multi-selection of task bars, and the handle's bulkShiftDates()/bulkDelete() */\n selectable?: boolean;\n /**\n * Stretch (never shrink) the timeline to fill the container's width instead of leaving empty\n * space - the common \"short project at month/year zoom\" or \"just a few tasks\" case. Off by\n * default (a new chart's pixel layout shouldn't change for existing consumers who don't opt in).\n */\n autoFitToViewport?: boolean;\n\n // Mirrors of GanttOptions' callback fields, as normal React event props.\n onDateChange?: (task: GanttTask, start: Date, end: Date) => void;\n onProgressChange?: (task: GanttTask, progress: number) => void;\n onDependencyCreate?: (dep: GanttDependency) => void;\n onDependencyRemove?: (dep: GanttDependency) => void;\n /** called on double-click of a dependency link, for building your own \"edit this link\" UI (see the handle's updateDependency) */\n onDependencyDblClick?: (dep: GanttDependency) => void;\n onTaskClick?: (task: GanttTask) => void;\n /** called on double-click of a task bar (distinct from onDependencyDblClick, which is for links) */\n onTaskDblClick?: (task: GanttTask) => void;\n onGroupToggle?: (task: GanttTask, collapsed: boolean) => void;\n onContextMenu?: (task: GanttTask, evt: PointerEvent) => void;\n /** called when a task is created via drag-to-create on an empty timeline row */\n onTaskCreate?: (task: GanttTask) => void;\n /** called when a grid column is resized by dragging its header's edge */\n onColumnResize?: (columnId: string, width: number) => void;\n /** called when grid columns are reordered by dragging a header; `order` is the new full list of column ids */\n onColumnReorder?: (order: string[]) => void;\n /** called when a grid row is dragged onto another; \"inside\" reparents the dragged task under the target */\n onTaskReorder?: (draggedTaskId: string, targetTaskId: string, position: \"before\" | \"after\" | \"inside\") => void;\n onSelectionChange?: (taskIds: string[]) => void;\n /** fired whenever the sort state changes, via a sortable column header click or the handle's setSort() */\n onSortChange?: (sort: { columnId: string; direction: \"asc\" | \"desc\" } | null) => void;\n\n /** Applied to the wrapping container div. */\n className?: string;\n style?: CSSProperties;\n}\n\n/** Imperative escape hatches that don't need to be reactive props. */\nexport interface GanttChartHandle {\n undo(): void;\n redo(): void;\n canUndo(): boolean;\n canRedo(): boolean;\n expandAll(): void;\n collapseAll(): void;\n toggleGroup(taskId: string): void;\n removeDependency(fromId: string, toId: string): void;\n updateDependency(fromId: string, toId: string, partial: Partial<GanttDependency>): void;\n updateTask(id: string, partial: Partial<GanttTask>): void;\n setViewMode(mode: ViewMode): void;\n fitToViewport(containerWidthPx: number): void;\n scrollToToday(): void;\n scrollToRangeStart(): void;\n scrollToRangeEnd(): void;\n getPageCount(): number;\n setPage(page: number): void;\n zoomIn(factor?: number): void;\n zoomOut(factor?: number): void;\n getZoomLevel(): number;\n getResourceHistogram(options?: ResourceHistogramOptions): ResourceLoadBucket[];\n getLeveledTasks(options?: ResourceLevelingOptions): ResourceLevelingResult;\n selectTask(id: string, options?: { additive?: boolean }): void;\n selectAllVisible(): void;\n clearSelection(): void;\n getSelectedTaskIds(): string[];\n setSort(columnId: string | null, direction?: \"asc\" | \"desc\" | null): void;\n getSort(): { columnId: string; direction: \"asc\" | \"desc\" } | null;\n bulkShiftDates(deltaMs: number): void;\n bulkDelete(): void;\n toSVGString(): string;\n toPNGDataURL(): Promise<string>;\n toPNGDataURLs(options?: { pageWidthPx?: number; pageHeightPx?: number }): Promise<string[]>;\n getRenderModel(): GanttRenderModel | null;\n /** Direct access to the underlying framework-agnostic core instance (null before mount). */\n getInstance(): GanttCore | null;\n}\n\nconst EMPTY_DEPENDENCIES: GanttDependency[] = [];\n\nconst EMPTY_RENDER_MODEL: GanttRenderModel = {\n width: 0,\n height: 0,\n rowHeight: 0,\n headerHeight: 0,\n rows: [],\n bars: [],\n links: [],\n ticks: [],\n columns: [],\n theme: {} as GanttTheme,\n markers: [],\n rangeStart: new Date(0),\n sort: null,\n};\n\nfunction GanttChartInner(props: GanttChartProps, ref: Ref<GanttChartHandle>) {\n const {\n tasks,\n dependencies = EMPTY_DEPENDENCIES,\n className,\n style,\n onDateChange,\n onProgressChange,\n onDependencyCreate,\n onDependencyRemove,\n onDependencyDblClick,\n onTaskClick,\n onTaskDblClick,\n onGroupToggle,\n onContextMenu,\n onTaskCreate,\n onColumnResize,\n onColumnReorder,\n onTaskReorder,\n onSelectionChange,\n onSortChange,\n ...rest\n } = props;\n\n const containerRef = useRef<HTMLDivElement | null>(null);\n\n // The core only wires up its internal contextmenu DOM listener (and therefore only\n // ever emits the \"context-menu\" event) when options.onContextMenu is truthy AT\n // CONSTRUCTION TIME (see GanttChart#setupDom in gantt-core). We pass a stable no-op\n // here purely to force that wiring on regardless of whether the consumer supplied\n // onContextMenu, and dispatch the actual prop via the \"context-menu\" event\n // subscription below (so it stays reactive to prop changes and is never double-fired).\n const enableContextMenuWiring = useRef(() => {});\n\n // Same construction-time-only caveat as onContextMenu above: drag-to-create is only\n // wired into the core's InteractionController when options.onTaskCreate is truthy at\n // construction. A stable no-op forces it on whenever this component was given an\n // onTaskCreate prop at all; the real dispatch goes through the \"task-create\" event.\n const enableCreateWiring = useRef(() => {});\n\n // Same construction-time-only caveat: column resize/reorder DOM listeners are only\n // built into the grid header when these options are truthy at construction.\n const enableColumnResizeWiring = useRef((_columnId: string, _width: number) => {});\n const enableColumnReorderWiring = useRef((_order: string[]) => {});\n const enableTaskReorderWiring = useRef(\n (_draggedTaskId: string, _targetTaskId: string, _position: \"before\" | \"after\" | \"inside\") => {}\n );\n const enableDependencyDblClickWiring = useRef((_dep: GanttDependency) => {});\n const enableTaskDblClickWiring = useRef((_task: GanttTask) => {});\n\n // Deliberately depend on Boolean(handler) rather than the handler itself below: the\n // ref-backed enableXWiring callbacks already pick up the latest handler without\n // needing the memo to re-run, so depending on the raw (often inline) callback would\n // just re-create `options` — and remount the chart — every render.\n /* eslint-disable react-hooks/exhaustive-deps */\n const options = useMemo<GanttOptions>(\n () => ({\n ...rest,\n onContextMenu: enableContextMenuWiring.current,\n onTaskCreate: onTaskCreate ? enableCreateWiring.current : undefined,\n onColumnResize: onColumnResize ? enableColumnResizeWiring.current : undefined,\n onColumnReorder: onColumnReorder ? enableColumnReorderWiring.current : undefined,\n onTaskReorder: onTaskReorder ? enableTaskReorderWiring.current : undefined,\n onDependencyDblClick: onDependencyDblClick ? enableDependencyDblClickWiring.current : undefined,\n onTaskDblClick: onTaskDblClick ? enableTaskDblClickWiring.current : undefined,\n // onSelectionChange/onSortChange are deliberately NOT set here: gantt-core invokes them\n // directly from this.options AND emits a matching event at the same call sites, and the\n // effect below already subscribes to those events — including them here would double-fire.\n }),\n [\n rest.viewMode,\n rest.columns,\n rest.theme,\n rest.colorScheme,\n rest.columnWidth,\n rest.readonly,\n rest.showProgress,\n rest.showDependencies,\n rest.gridPanelWidth,\n rest.showCriticalPath,\n rest.showBaseline,\n rest.showDeadlines,\n rest.showTooltip,\n rest.renderTooltip,\n rest.autoFitToViewport,\n rest.showAssigneeAvatars,\n rest.enableHistory,\n rest.keyboardAccessible,\n rest.virtualScroll,\n rest.autoSchedule,\n rest.pagination,\n rest.snapToUnit,\n rest.calendar,\n rest.markers,\n rest.autoRollupProgress,\n rest.selectable,\n Boolean(onTaskCreate),\n Boolean(onColumnResize),\n Boolean(onColumnReorder),\n Boolean(onTaskReorder),\n Boolean(onDependencyDblClick),\n Boolean(onTaskDblClick),\n ]\n );\n /* eslint-enable react-hooks/exhaustive-deps */\n\n const { chart } = useGanttChart(containerRef, tasks, dependencies, options);\n\n // Keep the latest callback props in a ref so the event-subscription effect below\n // doesn't need to re-subscribe (tearing down/rebuilding listeners) on every render.\n const callbacksRef = useRef({\n onDateChange,\n onProgressChange,\n onDependencyCreate,\n onDependencyRemove,\n onDependencyDblClick,\n onTaskClick,\n onTaskDblClick,\n onGroupToggle,\n onContextMenu,\n onTaskCreate,\n onColumnResize,\n onColumnReorder,\n onTaskReorder,\n onSelectionChange,\n onSortChange,\n });\n callbacksRef.current = {\n onDateChange,\n onProgressChange,\n onDependencyCreate,\n onDependencyRemove,\n onDependencyDblClick,\n onTaskClick,\n onTaskDblClick,\n onGroupToggle,\n onContextMenu,\n onTaskCreate,\n onColumnResize,\n onColumnReorder,\n onTaskReorder,\n onSelectionChange,\n onSortChange,\n };\n\n useEffect(() => {\n if (!chart) return undefined;\n\n const handleDateChange = (p: { task: GanttTask; start: Date; end: Date }) =>\n callbacksRef.current.onDateChange?.(p.task, p.start, p.end);\n const handleProgressChange = (p: { task: GanttTask; progress: number }) =>\n callbacksRef.current.onProgressChange?.(p.task, p.progress);\n const handleDependencyCreate = (dep: GanttDependency) =>\n callbacksRef.current.onDependencyCreate?.(dep);\n const handleDependencyRemove = (dep: GanttDependency) =>\n callbacksRef.current.onDependencyRemove?.(dep);\n const handleTaskClick = (p: { task: GanttTask }) =>\n callbacksRef.current.onTaskClick?.(p.task);\n const handleTaskDblClick = (p: { task: GanttTask }) =>\n callbacksRef.current.onTaskDblClick?.(p.task);\n const handleGroupToggle = (p: { task: GanttTask; collapsed: boolean }) =>\n callbacksRef.current.onGroupToggle?.(p.task, p.collapsed);\n const handleContextMenu = (p: { task: GanttTask; evt: PointerEvent }) =>\n callbacksRef.current.onContextMenu?.(p.task, p.evt);\n const handleTaskCreate = (p: { task: GanttTask }) => callbacksRef.current.onTaskCreate?.(p.task);\n const handleColumnResize = (p: { columnId: string; width: number }) =>\n callbacksRef.current.onColumnResize?.(p.columnId, p.width);\n const handleColumnReorder = (p: { order: string[] }) =>\n callbacksRef.current.onColumnReorder?.(p.order);\n const handleDependencyDblClick = (dep: GanttDependency) =>\n callbacksRef.current.onDependencyDblClick?.(dep);\n const handleTaskReorder = (p: {\n draggedTaskId: string;\n targetTaskId: string;\n position: \"before\" | \"after\" | \"inside\";\n }) => callbacksRef.current.onTaskReorder?.(p.draggedTaskId, p.targetTaskId, p.position);\n const handleSelectionChange = (p: { taskIds: string[] }) =>\n callbacksRef.current.onSelectionChange?.(p.taskIds);\n const handleSortChange = (p: { sort: { columnId: string; direction: \"asc\" | \"desc\" } | null }) =>\n callbacksRef.current.onSortChange?.(p.sort);\n\n chart.on(\"date-change\", handleDateChange);\n chart.on(\"progress-change\", handleProgressChange);\n chart.on(\"dependency-create\", handleDependencyCreate);\n chart.on(\"dependency-remove\", handleDependencyRemove);\n chart.on(\"dependency-dblclick\", handleDependencyDblClick);\n chart.on(\"task-click\", handleTaskClick);\n chart.on(\"task-dblclick\", handleTaskDblClick);\n chart.on(\"group-toggle\", handleGroupToggle);\n chart.on(\"context-menu\", handleContextMenu);\n chart.on(\"task-create\", handleTaskCreate);\n chart.on(\"column-resize\", handleColumnResize);\n chart.on(\"column-reorder\", handleColumnReorder);\n chart.on(\"task-reorder\", handleTaskReorder);\n chart.on(\"selection-change\", handleSelectionChange);\n chart.on(\"sort-change\", handleSortChange);\n\n return () => {\n chart.off(\"date-change\", handleDateChange);\n chart.off(\"progress-change\", handleProgressChange);\n chart.off(\"dependency-create\", handleDependencyCreate);\n chart.off(\"dependency-remove\", handleDependencyRemove);\n chart.off(\"dependency-dblclick\", handleDependencyDblClick);\n chart.off(\"task-click\", handleTaskClick);\n chart.off(\"task-dblclick\", handleTaskDblClick);\n chart.off(\"group-toggle\", handleGroupToggle);\n chart.off(\"context-menu\", handleContextMenu);\n chart.off(\"task-create\", handleTaskCreate);\n chart.off(\"column-resize\", handleColumnResize);\n chart.off(\"column-reorder\", handleColumnReorder);\n chart.off(\"task-reorder\", handleTaskReorder);\n chart.off(\"selection-change\", handleSelectionChange);\n chart.off(\"sort-change\", handleSortChange);\n };\n }, [chart]);\n\n useImperativeHandle(\n ref,\n (): GanttChartHandle => ({\n undo: () => chart?.undo(),\n redo: () => chart?.redo(),\n canUndo: () => chart?.canUndo ?? false,\n canRedo: () => chart?.canRedo ?? false,\n expandAll: () => chart?.expandAll(),\n collapseAll: () => chart?.collapseAll(),\n toggleGroup: (taskId: string) => chart?.toggleGroup(taskId),\n removeDependency: (fromId: string, toId: string) => chart?.removeDependency(fromId, toId),\n updateDependency: (fromId: string, toId: string, partial: Partial<GanttDependency>) =>\n chart?.updateDependency(fromId, toId, partial),\n updateTask: (id: string, partial: Partial<GanttTask>) => chart?.updateTask(id, partial),\n setViewMode: (mode: ViewMode) => chart?.setViewMode(mode),\n fitToViewport: (containerWidthPx: number) => chart?.fitToViewport(containerWidthPx),\n scrollToToday: () => chart?.scrollToToday(),\n scrollToRangeStart: () => chart?.scrollToRangeStart(),\n scrollToRangeEnd: () => chart?.scrollToRangeEnd(),\n getPageCount: () => chart?.getPageCount() ?? 1,\n setPage: (page: number) => chart?.setPage(page),\n zoomIn: (factor?: number) => chart?.zoomIn(factor),\n zoomOut: (factor?: number) => chart?.zoomOut(factor),\n getZoomLevel: () => chart?.getZoomLevel() ?? 0,\n getResourceHistogram: (options?: ResourceHistogramOptions) =>\n chart?.getResourceHistogram(options) ?? [],\n getLeveledTasks: (options?: ResourceLevelingOptions) =>\n chart?.getLeveledTasks(options) ?? { tasks: [], shifted: [] },\n selectTask: (id: string, options?: { additive?: boolean }) => chart?.selectTask(id, options),\n selectAllVisible: () => chart?.selectAllVisible(),\n clearSelection: () => chart?.clearSelection(),\n getSelectedTaskIds: () => chart?.getSelectedTaskIds() ?? [],\n setSort: (columnId: string | null, direction?: \"asc\" | \"desc\" | null) => chart?.setSort(columnId, direction),\n getSort: () => chart?.getSort() ?? null,\n bulkShiftDates: (deltaMs: number) => chart?.bulkShiftDates(deltaMs),\n bulkDelete: () => chart?.bulkDelete(),\n toSVGString: () => chart?.toSVGString() ?? \"\",\n toPNGDataURL: () => chart?.toPNGDataURL() ?? Promise.resolve(\"\"),\n toPNGDataURLs: (options?: { pageWidthPx?: number; pageHeightPx?: number }) =>\n chart?.toPNGDataURLs(options) ?? Promise.resolve([]),\n getRenderModel: () => chart?.getRenderModel() ?? EMPTY_RENDER_MODEL,\n getInstance: () => chart,\n }),\n [chart]\n );\n\n return <div ref={containerRef} className={className} style={style} />;\n}\n\nexport const GanttChart = forwardRef(GanttChartInner);\nGanttChart.displayName = \"GanttChart\";\n\nexport default GanttChart;\n","import { useEffect, useRef, useState, type RefObject } from \"react\";\nimport { GanttChart as GanttCore } from \"@ganttloom/gantt-core\";\nimport type { GanttDependency, GanttOptions, GanttTask } from \"@ganttloom/gantt-core\";\n\nexport interface UseGanttChartResult {\n /** The underlying framework-agnostic GanttChart instance, or null before the DOM mount effect runs (or on the server). */\n chart: GanttCore | null;\n /** Reactive, subscribed to the core's \"history-change\" event. Only meaningful when `enableHistory` is set in options. */\n canUndo: boolean;\n /** Reactive, subscribed to the core's \"history-change\" event. Only meaningful when `enableHistory` is set in options. */\n canRedo: boolean;\n}\n\nconst EMPTY_DEPENDENCIES: GanttDependency[] = [];\nconst EMPTY_OPTIONS: GanttOptions = {};\n\n/**\n * Lower-level escape hatch for consumers who want to own their own container element\n * and DOM tree instead of using the <GanttChart /> component. Constructs a\n * @ganttloom/gantt-core GanttChart instance against `containerRef.current` on mount,\n * keeps it in sync with `tasks` / `dependencies` / `options` via setTasks / setDependencies /\n * setOptions (reference-equality checks only — pass new arrays/objects to trigger a sync),\n * and destroys it on unmount.\n */\nexport function useGanttChart(\n containerRef: RefObject<HTMLElement | null>,\n tasks: GanttTask[],\n dependencies: GanttDependency[] = EMPTY_DEPENDENCIES,\n options: GanttOptions = EMPTY_OPTIONS\n): UseGanttChartResult {\n const [chart, setChart] = useState<GanttCore | null>(null);\n const [canUndo, setCanUndo] = useState(false);\n const [canRedo, setCanRedo] = useState(false);\n\n const chartRef = useRef<GanttCore | null>(null);\n\n // Latest props, read from the mount effect so it doesn't need to depend on them\n // (which would otherwise tear down and recreate the whole chart on every change).\n const initialTasksRef = useRef(tasks);\n initialTasksRef.current = tasks;\n const initialDepsRef = useRef(dependencies);\n initialDepsRef.current = dependencies;\n const initialOptionsRef = useRef(options);\n initialOptionsRef.current = options;\n\n useEffect(() => {\n if (typeof window === \"undefined\") return undefined;\n const container = containerRef.current;\n if (!container) return undefined;\n\n const instance = new GanttCore(\n container,\n initialTasksRef.current,\n initialDepsRef.current,\n initialOptionsRef.current\n );\n chartRef.current = instance;\n setChart(instance);\n setCanUndo(instance.canUndo);\n setCanRedo(instance.canRedo);\n\n const onHistoryChange = (state: { canUndo: boolean; canRedo: boolean }) => {\n setCanUndo(state.canUndo);\n setCanRedo(state.canRedo);\n };\n instance.on(\"history-change\", onHistoryChange);\n\n return () => {\n instance.off(\"history-change\", onHistoryChange);\n instance.destroy();\n chartRef.current = null;\n setChart(null);\n setCanUndo(false);\n setCanRedo(false);\n };\n // Intentionally mount/unmount only — the container element identity is what matters.\n }, [containerRef]);\n\n const isFirstTasksSync = useRef(true);\n useEffect(() => {\n if (isFirstTasksSync.current) {\n isFirstTasksSync.current = false;\n return;\n }\n chartRef.current?.setTasks(tasks);\n }, [tasks]);\n\n const isFirstDepsSync = useRef(true);\n useEffect(() => {\n if (isFirstDepsSync.current) {\n isFirstDepsSync.current = false;\n return;\n }\n chartRef.current?.setDependencies(dependencies);\n }, [dependencies]);\n\n const isFirstOptionsSync = useRef(true);\n useEffect(() => {\n if (isFirstOptionsSync.current) {\n isFirstOptionsSync.current = false;\n return;\n }\n chartRef.current?.setOptions(options);\n }, [options]);\n\n return { chart, canUndo, canRedo };\n}\n"],"mappings":"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","names":["import_react","GanttCore","EMPTY_DEPENDENCIES","options","import_gantt_core"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -18,6 +18,10 @@ interface GanttChartProps {
|
|
|
18
18
|
showCriticalPath?: boolean;
|
|
19
19
|
showBaseline?: boolean;
|
|
20
20
|
showDeadlines?: boolean;
|
|
21
|
+
/** hover tooltip on task bars, defaults to true. A floating, CSS-customizable element (`.gantt-tooltip`) - not the browser's native title tooltip. */
|
|
22
|
+
showTooltip?: boolean;
|
|
23
|
+
/** fully control tooltip content/markup; return null/undefined to suppress it for a specific task. Defaults to name/dates/progress/assignees/notes. */
|
|
24
|
+
renderTooltip?: (task: GanttTask) => HTMLElement | string | null | undefined;
|
|
21
25
|
showAssigneeAvatars?: boolean;
|
|
22
26
|
enableHistory?: boolean;
|
|
23
27
|
keyboardAccessible?: boolean;
|
|
@@ -36,6 +40,12 @@ interface GanttChartProps {
|
|
|
36
40
|
autoRollupProgress?: boolean;
|
|
37
41
|
/** enables click/ctrl-click/shift-click multi-selection of task bars, and the handle's bulkShiftDates()/bulkDelete() */
|
|
38
42
|
selectable?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Stretch (never shrink) the timeline to fill the container's width instead of leaving empty
|
|
45
|
+
* space - the common "short project at month/year zoom" or "just a few tasks" case. Off by
|
|
46
|
+
* default (a new chart's pixel layout shouldn't change for existing consumers who don't opt in).
|
|
47
|
+
*/
|
|
48
|
+
autoFitToViewport?: boolean;
|
|
39
49
|
onDateChange?: (task: GanttTask, start: Date, end: Date) => void;
|
|
40
50
|
onProgressChange?: (task: GanttTask, progress: number) => void;
|
|
41
51
|
onDependencyCreate?: (dep: GanttDependency) => void;
|
|
@@ -43,6 +53,8 @@ interface GanttChartProps {
|
|
|
43
53
|
/** called on double-click of a dependency link, for building your own "edit this link" UI (see the handle's updateDependency) */
|
|
44
54
|
onDependencyDblClick?: (dep: GanttDependency) => void;
|
|
45
55
|
onTaskClick?: (task: GanttTask) => void;
|
|
56
|
+
/** called on double-click of a task bar (distinct from onDependencyDblClick, which is for links) */
|
|
57
|
+
onTaskDblClick?: (task: GanttTask) => void;
|
|
46
58
|
onGroupToggle?: (task: GanttTask, collapsed: boolean) => void;
|
|
47
59
|
onContextMenu?: (task: GanttTask, evt: PointerEvent) => void;
|
|
48
60
|
/** called when a task is created via drag-to-create on an empty timeline row */
|
|
@@ -54,6 +66,11 @@ interface GanttChartProps {
|
|
|
54
66
|
/** called when a grid row is dragged onto another; "inside" reparents the dragged task under the target */
|
|
55
67
|
onTaskReorder?: (draggedTaskId: string, targetTaskId: string, position: "before" | "after" | "inside") => void;
|
|
56
68
|
onSelectionChange?: (taskIds: string[]) => void;
|
|
69
|
+
/** fired whenever the sort state changes, via a sortable column header click or the handle's setSort() */
|
|
70
|
+
onSortChange?: (sort: {
|
|
71
|
+
columnId: string;
|
|
72
|
+
direction: "asc" | "desc";
|
|
73
|
+
} | null) => void;
|
|
57
74
|
/** Applied to the wrapping container div. */
|
|
58
75
|
className?: string;
|
|
59
76
|
style?: CSSProperties;
|
|
@@ -88,6 +105,11 @@ interface GanttChartHandle {
|
|
|
88
105
|
selectAllVisible(): void;
|
|
89
106
|
clearSelection(): void;
|
|
90
107
|
getSelectedTaskIds(): string[];
|
|
108
|
+
setSort(columnId: string | null, direction?: "asc" | "desc" | null): void;
|
|
109
|
+
getSort(): {
|
|
110
|
+
columnId: string;
|
|
111
|
+
direction: "asc" | "desc";
|
|
112
|
+
} | null;
|
|
91
113
|
bulkShiftDates(deltaMs: number): void;
|
|
92
114
|
bulkDelete(): void;
|
|
93
115
|
toSVGString(): string;
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,10 @@ interface GanttChartProps {
|
|
|
18
18
|
showCriticalPath?: boolean;
|
|
19
19
|
showBaseline?: boolean;
|
|
20
20
|
showDeadlines?: boolean;
|
|
21
|
+
/** hover tooltip on task bars, defaults to true. A floating, CSS-customizable element (`.gantt-tooltip`) - not the browser's native title tooltip. */
|
|
22
|
+
showTooltip?: boolean;
|
|
23
|
+
/** fully control tooltip content/markup; return null/undefined to suppress it for a specific task. Defaults to name/dates/progress/assignees/notes. */
|
|
24
|
+
renderTooltip?: (task: GanttTask) => HTMLElement | string | null | undefined;
|
|
21
25
|
showAssigneeAvatars?: boolean;
|
|
22
26
|
enableHistory?: boolean;
|
|
23
27
|
keyboardAccessible?: boolean;
|
|
@@ -36,6 +40,12 @@ interface GanttChartProps {
|
|
|
36
40
|
autoRollupProgress?: boolean;
|
|
37
41
|
/** enables click/ctrl-click/shift-click multi-selection of task bars, and the handle's bulkShiftDates()/bulkDelete() */
|
|
38
42
|
selectable?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Stretch (never shrink) the timeline to fill the container's width instead of leaving empty
|
|
45
|
+
* space - the common "short project at month/year zoom" or "just a few tasks" case. Off by
|
|
46
|
+
* default (a new chart's pixel layout shouldn't change for existing consumers who don't opt in).
|
|
47
|
+
*/
|
|
48
|
+
autoFitToViewport?: boolean;
|
|
39
49
|
onDateChange?: (task: GanttTask, start: Date, end: Date) => void;
|
|
40
50
|
onProgressChange?: (task: GanttTask, progress: number) => void;
|
|
41
51
|
onDependencyCreate?: (dep: GanttDependency) => void;
|
|
@@ -43,6 +53,8 @@ interface GanttChartProps {
|
|
|
43
53
|
/** called on double-click of a dependency link, for building your own "edit this link" UI (see the handle's updateDependency) */
|
|
44
54
|
onDependencyDblClick?: (dep: GanttDependency) => void;
|
|
45
55
|
onTaskClick?: (task: GanttTask) => void;
|
|
56
|
+
/** called on double-click of a task bar (distinct from onDependencyDblClick, which is for links) */
|
|
57
|
+
onTaskDblClick?: (task: GanttTask) => void;
|
|
46
58
|
onGroupToggle?: (task: GanttTask, collapsed: boolean) => void;
|
|
47
59
|
onContextMenu?: (task: GanttTask, evt: PointerEvent) => void;
|
|
48
60
|
/** called when a task is created via drag-to-create on an empty timeline row */
|
|
@@ -54,6 +66,11 @@ interface GanttChartProps {
|
|
|
54
66
|
/** called when a grid row is dragged onto another; "inside" reparents the dragged task under the target */
|
|
55
67
|
onTaskReorder?: (draggedTaskId: string, targetTaskId: string, position: "before" | "after" | "inside") => void;
|
|
56
68
|
onSelectionChange?: (taskIds: string[]) => void;
|
|
69
|
+
/** fired whenever the sort state changes, via a sortable column header click or the handle's setSort() */
|
|
70
|
+
onSortChange?: (sort: {
|
|
71
|
+
columnId: string;
|
|
72
|
+
direction: "asc" | "desc";
|
|
73
|
+
} | null) => void;
|
|
57
74
|
/** Applied to the wrapping container div. */
|
|
58
75
|
className?: string;
|
|
59
76
|
style?: CSSProperties;
|
|
@@ -88,6 +105,11 @@ interface GanttChartHandle {
|
|
|
88
105
|
selectAllVisible(): void;
|
|
89
106
|
clearSelection(): void;
|
|
90
107
|
getSelectedTaskIds(): string[];
|
|
108
|
+
setSort(columnId: string | null, direction?: "asc" | "desc" | null): void;
|
|
109
|
+
getSort(): {
|
|
110
|
+
columnId: string;
|
|
111
|
+
direction: "asc" | "desc";
|
|
112
|
+
} | null;
|
|
91
113
|
bulkShiftDates(deltaMs: number): void;
|
|
92
114
|
bulkDelete(): void;
|
|
93
115
|
toSVGString(): string;
|
package/dist/index.js
CHANGED
|
@@ -94,7 +94,8 @@ var EMPTY_RENDER_MODEL = {
|
|
|
94
94
|
columns: [],
|
|
95
95
|
theme: {},
|
|
96
96
|
markers: [],
|
|
97
|
-
rangeStart: /* @__PURE__ */ new Date(0)
|
|
97
|
+
rangeStart: /* @__PURE__ */ new Date(0),
|
|
98
|
+
sort: null
|
|
98
99
|
};
|
|
99
100
|
function GanttChartInner(props, ref) {
|
|
100
101
|
const {
|
|
@@ -108,6 +109,7 @@ function GanttChartInner(props, ref) {
|
|
|
108
109
|
onDependencyRemove,
|
|
109
110
|
onDependencyDblClick,
|
|
110
111
|
onTaskClick,
|
|
112
|
+
onTaskDblClick,
|
|
111
113
|
onGroupToggle,
|
|
112
114
|
onContextMenu,
|
|
113
115
|
onTaskCreate,
|
|
@@ -115,6 +117,7 @@ function GanttChartInner(props, ref) {
|
|
|
115
117
|
onColumnReorder,
|
|
116
118
|
onTaskReorder,
|
|
117
119
|
onSelectionChange,
|
|
120
|
+
onSortChange,
|
|
118
121
|
...rest
|
|
119
122
|
} = props;
|
|
120
123
|
const containerRef = useRef2(null);
|
|
@@ -132,6 +135,8 @@ function GanttChartInner(props, ref) {
|
|
|
132
135
|
);
|
|
133
136
|
const enableDependencyDblClickWiring = useRef2((_dep) => {
|
|
134
137
|
});
|
|
138
|
+
const enableTaskDblClickWiring = useRef2((_task) => {
|
|
139
|
+
});
|
|
135
140
|
const options = useMemo(
|
|
136
141
|
() => ({
|
|
137
142
|
...rest,
|
|
@@ -140,11 +145,11 @@ function GanttChartInner(props, ref) {
|
|
|
140
145
|
onColumnResize: onColumnResize ? enableColumnResizeWiring.current : void 0,
|
|
141
146
|
onColumnReorder: onColumnReorder ? enableColumnReorderWiring.current : void 0,
|
|
142
147
|
onTaskReorder: onTaskReorder ? enableTaskReorderWiring.current : void 0,
|
|
143
|
-
onDependencyDblClick: onDependencyDblClick ? enableDependencyDblClickWiring.current : void 0
|
|
144
|
-
|
|
145
|
-
//
|
|
146
|
-
//
|
|
147
|
-
//
|
|
148
|
+
onDependencyDblClick: onDependencyDblClick ? enableDependencyDblClickWiring.current : void 0,
|
|
149
|
+
onTaskDblClick: onTaskDblClick ? enableTaskDblClickWiring.current : void 0
|
|
150
|
+
// onSelectionChange/onSortChange are deliberately NOT set here: gantt-core invokes them
|
|
151
|
+
// directly from this.options AND emits a matching event at the same call sites, and the
|
|
152
|
+
// effect below already subscribes to those events — including them here would double-fire.
|
|
148
153
|
}),
|
|
149
154
|
[
|
|
150
155
|
rest.viewMode,
|
|
@@ -159,6 +164,9 @@ function GanttChartInner(props, ref) {
|
|
|
159
164
|
rest.showCriticalPath,
|
|
160
165
|
rest.showBaseline,
|
|
161
166
|
rest.showDeadlines,
|
|
167
|
+
rest.showTooltip,
|
|
168
|
+
rest.renderTooltip,
|
|
169
|
+
rest.autoFitToViewport,
|
|
162
170
|
rest.showAssigneeAvatars,
|
|
163
171
|
rest.enableHistory,
|
|
164
172
|
rest.keyboardAccessible,
|
|
@@ -174,7 +182,8 @@ function GanttChartInner(props, ref) {
|
|
|
174
182
|
Boolean(onColumnResize),
|
|
175
183
|
Boolean(onColumnReorder),
|
|
176
184
|
Boolean(onTaskReorder),
|
|
177
|
-
Boolean(onDependencyDblClick)
|
|
185
|
+
Boolean(onDependencyDblClick),
|
|
186
|
+
Boolean(onTaskDblClick)
|
|
178
187
|
]
|
|
179
188
|
);
|
|
180
189
|
const { chart } = useGanttChart(containerRef, tasks, dependencies, options);
|
|
@@ -185,13 +194,15 @@ function GanttChartInner(props, ref) {
|
|
|
185
194
|
onDependencyRemove,
|
|
186
195
|
onDependencyDblClick,
|
|
187
196
|
onTaskClick,
|
|
197
|
+
onTaskDblClick,
|
|
188
198
|
onGroupToggle,
|
|
189
199
|
onContextMenu,
|
|
190
200
|
onTaskCreate,
|
|
191
201
|
onColumnResize,
|
|
192
202
|
onColumnReorder,
|
|
193
203
|
onTaskReorder,
|
|
194
|
-
onSelectionChange
|
|
204
|
+
onSelectionChange,
|
|
205
|
+
onSortChange
|
|
195
206
|
});
|
|
196
207
|
callbacksRef.current = {
|
|
197
208
|
onDateChange,
|
|
@@ -200,13 +211,15 @@ function GanttChartInner(props, ref) {
|
|
|
200
211
|
onDependencyRemove,
|
|
201
212
|
onDependencyDblClick,
|
|
202
213
|
onTaskClick,
|
|
214
|
+
onTaskDblClick,
|
|
203
215
|
onGroupToggle,
|
|
204
216
|
onContextMenu,
|
|
205
217
|
onTaskCreate,
|
|
206
218
|
onColumnResize,
|
|
207
219
|
onColumnReorder,
|
|
208
220
|
onTaskReorder,
|
|
209
|
-
onSelectionChange
|
|
221
|
+
onSelectionChange,
|
|
222
|
+
onSortChange
|
|
210
223
|
};
|
|
211
224
|
useEffect2(() => {
|
|
212
225
|
if (!chart) return void 0;
|
|
@@ -215,6 +228,7 @@ function GanttChartInner(props, ref) {
|
|
|
215
228
|
const handleDependencyCreate = (dep) => callbacksRef.current.onDependencyCreate?.(dep);
|
|
216
229
|
const handleDependencyRemove = (dep) => callbacksRef.current.onDependencyRemove?.(dep);
|
|
217
230
|
const handleTaskClick = (p) => callbacksRef.current.onTaskClick?.(p.task);
|
|
231
|
+
const handleTaskDblClick = (p) => callbacksRef.current.onTaskDblClick?.(p.task);
|
|
218
232
|
const handleGroupToggle = (p) => callbacksRef.current.onGroupToggle?.(p.task, p.collapsed);
|
|
219
233
|
const handleContextMenu = (p) => callbacksRef.current.onContextMenu?.(p.task, p.evt);
|
|
220
234
|
const handleTaskCreate = (p) => callbacksRef.current.onTaskCreate?.(p.task);
|
|
@@ -223,12 +237,14 @@ function GanttChartInner(props, ref) {
|
|
|
223
237
|
const handleDependencyDblClick = (dep) => callbacksRef.current.onDependencyDblClick?.(dep);
|
|
224
238
|
const handleTaskReorder = (p) => callbacksRef.current.onTaskReorder?.(p.draggedTaskId, p.targetTaskId, p.position);
|
|
225
239
|
const handleSelectionChange = (p) => callbacksRef.current.onSelectionChange?.(p.taskIds);
|
|
240
|
+
const handleSortChange = (p) => callbacksRef.current.onSortChange?.(p.sort);
|
|
226
241
|
chart.on("date-change", handleDateChange);
|
|
227
242
|
chart.on("progress-change", handleProgressChange);
|
|
228
243
|
chart.on("dependency-create", handleDependencyCreate);
|
|
229
244
|
chart.on("dependency-remove", handleDependencyRemove);
|
|
230
245
|
chart.on("dependency-dblclick", handleDependencyDblClick);
|
|
231
246
|
chart.on("task-click", handleTaskClick);
|
|
247
|
+
chart.on("task-dblclick", handleTaskDblClick);
|
|
232
248
|
chart.on("group-toggle", handleGroupToggle);
|
|
233
249
|
chart.on("context-menu", handleContextMenu);
|
|
234
250
|
chart.on("task-create", handleTaskCreate);
|
|
@@ -236,6 +252,7 @@ function GanttChartInner(props, ref) {
|
|
|
236
252
|
chart.on("column-reorder", handleColumnReorder);
|
|
237
253
|
chart.on("task-reorder", handleTaskReorder);
|
|
238
254
|
chart.on("selection-change", handleSelectionChange);
|
|
255
|
+
chart.on("sort-change", handleSortChange);
|
|
239
256
|
return () => {
|
|
240
257
|
chart.off("date-change", handleDateChange);
|
|
241
258
|
chart.off("progress-change", handleProgressChange);
|
|
@@ -243,6 +260,7 @@ function GanttChartInner(props, ref) {
|
|
|
243
260
|
chart.off("dependency-remove", handleDependencyRemove);
|
|
244
261
|
chart.off("dependency-dblclick", handleDependencyDblClick);
|
|
245
262
|
chart.off("task-click", handleTaskClick);
|
|
263
|
+
chart.off("task-dblclick", handleTaskDblClick);
|
|
246
264
|
chart.off("group-toggle", handleGroupToggle);
|
|
247
265
|
chart.off("context-menu", handleContextMenu);
|
|
248
266
|
chart.off("task-create", handleTaskCreate);
|
|
@@ -250,6 +268,7 @@ function GanttChartInner(props, ref) {
|
|
|
250
268
|
chart.off("column-reorder", handleColumnReorder);
|
|
251
269
|
chart.off("task-reorder", handleTaskReorder);
|
|
252
270
|
chart.off("selection-change", handleSelectionChange);
|
|
271
|
+
chart.off("sort-change", handleSortChange);
|
|
253
272
|
};
|
|
254
273
|
}, [chart]);
|
|
255
274
|
useImperativeHandle(
|
|
@@ -281,6 +300,8 @@ function GanttChartInner(props, ref) {
|
|
|
281
300
|
selectAllVisible: () => chart?.selectAllVisible(),
|
|
282
301
|
clearSelection: () => chart?.clearSelection(),
|
|
283
302
|
getSelectedTaskIds: () => chart?.getSelectedTaskIds() ?? [],
|
|
303
|
+
setSort: (columnId, direction) => chart?.setSort(columnId, direction),
|
|
304
|
+
getSort: () => chart?.getSort() ?? null,
|
|
284
305
|
bulkShiftDates: (deltaMs) => chart?.bulkShiftDates(deltaMs),
|
|
285
306
|
bulkDelete: () => chart?.bulkDelete(),
|
|
286
307
|
toSVGString: () => chart?.toSVGString() ?? "",
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/GanttChart.tsx","../src/useGanttChart.ts","../src/index.ts"],"sourcesContent":["// Pulls in the core's default styles so consumers get a working chart out of the box.\n// This resolves through gantt-core's package.json \"exports\" map (\"./styles.css\" -> \"./dist/styles.css\").\n// If your bundler can't resolve CSS imports from a dependency's export map, import it yourself instead:\n// import \"@ganttloom/gantt-core/styles.css\";\nimport \"@ganttloom/gantt-core/styles.css\";\n\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n type CSSProperties,\n type Ref,\n} from \"react\";\nimport type {\n GanttChart as GanttCore,\n GanttColumn,\n GanttDependency,\n GanttMarker,\n GanttOptions,\n GanttRenderModel,\n GanttTask,\n GanttTheme,\n ResourceHistogramOptions,\n ResourceLoadBucket,\n ResourceLevelingOptions,\n ResourceLevelingResult,\n ViewMode,\n WorkingCalendar,\n} from \"@ganttloom/gantt-core\";\nimport { useGanttChart } from \"./useGanttChart\";\n\nexport interface GanttChartProps {\n tasks: GanttTask[];\n dependencies?: GanttDependency[];\n\n // Mirrors of GanttOptions' non-callback fields.\n viewMode?: ViewMode;\n columns?: GanttColumn[];\n theme?: Partial<GanttTheme>;\n colorScheme?: \"light\" | \"dark\" | \"auto\";\n columnWidth?: number;\n readonly?: boolean;\n showProgress?: boolean;\n showDependencies?: boolean;\n gridPanelWidth?: number;\n showCriticalPath?: boolean;\n showBaseline?: boolean;\n showDeadlines?: boolean;\n showAssigneeAvatars?: boolean;\n enableHistory?: boolean;\n keyboardAccessible?: boolean;\n virtualScroll?: boolean;\n autoSchedule?: boolean;\n pagination?: { pageSize: number; page: number };\n snapToUnit?: \"hour\" | \"day\" | \"week\" | false;\n /** working-day/holiday definition used to shade non-working time and (with autoSchedule) skip it when cascading */\n calendar?: WorkingCalendar;\n /** arbitrary labeled vertical lines on the timeline, independent of any task */\n markers?: GanttMarker[];\n /** a group task with no explicit `progress` gets a duration-weighted average of its children's progress instead of 0 */\n autoRollupProgress?: boolean;\n /** enables click/ctrl-click/shift-click multi-selection of task bars, and the handle's bulkShiftDates()/bulkDelete() */\n selectable?: boolean;\n\n // Mirrors of GanttOptions' callback fields, as normal React event props.\n onDateChange?: (task: GanttTask, start: Date, end: Date) => void;\n onProgressChange?: (task: GanttTask, progress: number) => void;\n onDependencyCreate?: (dep: GanttDependency) => void;\n onDependencyRemove?: (dep: GanttDependency) => void;\n /** called on double-click of a dependency link, for building your own \"edit this link\" UI (see the handle's updateDependency) */\n onDependencyDblClick?: (dep: GanttDependency) => void;\n onTaskClick?: (task: GanttTask) => void;\n onGroupToggle?: (task: GanttTask, collapsed: boolean) => void;\n onContextMenu?: (task: GanttTask, evt: PointerEvent) => void;\n /** called when a task is created via drag-to-create on an empty timeline row */\n onTaskCreate?: (task: GanttTask) => void;\n /** called when a grid column is resized by dragging its header's edge */\n onColumnResize?: (columnId: string, width: number) => void;\n /** called when grid columns are reordered by dragging a header; `order` is the new full list of column ids */\n onColumnReorder?: (order: string[]) => void;\n /** called when a grid row is dragged onto another; \"inside\" reparents the dragged task under the target */\n onTaskReorder?: (draggedTaskId: string, targetTaskId: string, position: \"before\" | \"after\" | \"inside\") => void;\n onSelectionChange?: (taskIds: string[]) => void;\n\n /** Applied to the wrapping container div. */\n className?: string;\n style?: CSSProperties;\n}\n\n/** Imperative escape hatches that don't need to be reactive props. */\nexport interface GanttChartHandle {\n undo(): void;\n redo(): void;\n canUndo(): boolean;\n canRedo(): boolean;\n expandAll(): void;\n collapseAll(): void;\n toggleGroup(taskId: string): void;\n removeDependency(fromId: string, toId: string): void;\n updateDependency(fromId: string, toId: string, partial: Partial<GanttDependency>): void;\n updateTask(id: string, partial: Partial<GanttTask>): void;\n setViewMode(mode: ViewMode): void;\n fitToViewport(containerWidthPx: number): void;\n scrollToToday(): void;\n scrollToRangeStart(): void;\n scrollToRangeEnd(): void;\n getPageCount(): number;\n setPage(page: number): void;\n zoomIn(factor?: number): void;\n zoomOut(factor?: number): void;\n getZoomLevel(): number;\n getResourceHistogram(options?: ResourceHistogramOptions): ResourceLoadBucket[];\n getLeveledTasks(options?: ResourceLevelingOptions): ResourceLevelingResult;\n selectTask(id: string, options?: { additive?: boolean }): void;\n selectAllVisible(): void;\n clearSelection(): void;\n getSelectedTaskIds(): string[];\n bulkShiftDates(deltaMs: number): void;\n bulkDelete(): void;\n toSVGString(): string;\n toPNGDataURL(): Promise<string>;\n toPNGDataURLs(options?: { pageWidthPx?: number; pageHeightPx?: number }): Promise<string[]>;\n getRenderModel(): GanttRenderModel | null;\n /** Direct access to the underlying framework-agnostic core instance (null before mount). */\n getInstance(): GanttCore | null;\n}\n\nconst EMPTY_DEPENDENCIES: GanttDependency[] = [];\n\nconst EMPTY_RENDER_MODEL: GanttRenderModel = {\n width: 0,\n height: 0,\n rowHeight: 0,\n headerHeight: 0,\n rows: [],\n bars: [],\n links: [],\n ticks: [],\n columns: [],\n theme: {} as GanttTheme,\n markers: [],\n rangeStart: new Date(0),\n};\n\nfunction GanttChartInner(props: GanttChartProps, ref: Ref<GanttChartHandle>) {\n const {\n tasks,\n dependencies = EMPTY_DEPENDENCIES,\n className,\n style,\n onDateChange,\n onProgressChange,\n onDependencyCreate,\n onDependencyRemove,\n onDependencyDblClick,\n onTaskClick,\n onGroupToggle,\n onContextMenu,\n onTaskCreate,\n onColumnResize,\n onColumnReorder,\n onTaskReorder,\n onSelectionChange,\n ...rest\n } = props;\n\n const containerRef = useRef<HTMLDivElement | null>(null);\n\n // The core only wires up its internal contextmenu DOM listener (and therefore only\n // ever emits the \"context-menu\" event) when options.onContextMenu is truthy AT\n // CONSTRUCTION TIME (see GanttChart#setupDom in gantt-core). We pass a stable no-op\n // here purely to force that wiring on regardless of whether the consumer supplied\n // onContextMenu, and dispatch the actual prop via the \"context-menu\" event\n // subscription below (so it stays reactive to prop changes and is never double-fired).\n const enableContextMenuWiring = useRef(() => {});\n\n // Same construction-time-only caveat as onContextMenu above: drag-to-create is only\n // wired into the core's InteractionController when options.onTaskCreate is truthy at\n // construction. A stable no-op forces it on whenever this component was given an\n // onTaskCreate prop at all; the real dispatch goes through the \"task-create\" event.\n const enableCreateWiring = useRef(() => {});\n\n // Same construction-time-only caveat: column resize/reorder DOM listeners are only\n // built into the grid header when these options are truthy at construction.\n const enableColumnResizeWiring = useRef((_columnId: string, _width: number) => {});\n const enableColumnReorderWiring = useRef((_order: string[]) => {});\n const enableTaskReorderWiring = useRef(\n (_draggedTaskId: string, _targetTaskId: string, _position: \"before\" | \"after\" | \"inside\") => {}\n );\n const enableDependencyDblClickWiring = useRef((_dep: GanttDependency) => {});\n\n // Deliberately depend on Boolean(handler) rather than the handler itself below: the\n // ref-backed enableXWiring callbacks already pick up the latest handler without\n // needing the memo to re-run, so depending on the raw (often inline) callback would\n // just re-create `options` — and remount the chart — every render.\n /* eslint-disable react-hooks/exhaustive-deps */\n const options = useMemo<GanttOptions>(\n () => ({\n ...rest,\n onContextMenu: enableContextMenuWiring.current,\n onTaskCreate: onTaskCreate ? enableCreateWiring.current : undefined,\n onColumnResize: onColumnResize ? enableColumnResizeWiring.current : undefined,\n onColumnReorder: onColumnReorder ? enableColumnReorderWiring.current : undefined,\n onTaskReorder: onTaskReorder ? enableTaskReorderWiring.current : undefined,\n onDependencyDblClick: onDependencyDblClick ? enableDependencyDblClickWiring.current : undefined,\n // onSelectionChange is deliberately NOT set here: gantt-core invokes it directly from\n // this.options AND emits a \"selection-change\" event at the same call sites, and the\n // effect below already subscribes to that event — including it here would double-fire\n // every selection change.\n }),\n [\n rest.viewMode,\n rest.columns,\n rest.theme,\n rest.colorScheme,\n rest.columnWidth,\n rest.readonly,\n rest.showProgress,\n rest.showDependencies,\n rest.gridPanelWidth,\n rest.showCriticalPath,\n rest.showBaseline,\n rest.showDeadlines,\n rest.showAssigneeAvatars,\n rest.enableHistory,\n rest.keyboardAccessible,\n rest.virtualScroll,\n rest.autoSchedule,\n rest.pagination,\n rest.snapToUnit,\n rest.calendar,\n rest.markers,\n rest.autoRollupProgress,\n rest.selectable,\n Boolean(onTaskCreate),\n Boolean(onColumnResize),\n Boolean(onColumnReorder),\n Boolean(onTaskReorder),\n Boolean(onDependencyDblClick),\n ]\n );\n /* eslint-enable react-hooks/exhaustive-deps */\n\n const { chart } = useGanttChart(containerRef, tasks, dependencies, options);\n\n // Keep the latest callback props in a ref so the event-subscription effect below\n // doesn't need to re-subscribe (tearing down/rebuilding listeners) on every render.\n const callbacksRef = useRef({\n onDateChange,\n onProgressChange,\n onDependencyCreate,\n onDependencyRemove,\n onDependencyDblClick,\n onTaskClick,\n onGroupToggle,\n onContextMenu,\n onTaskCreate,\n onColumnResize,\n onColumnReorder,\n onTaskReorder,\n onSelectionChange,\n });\n callbacksRef.current = {\n onDateChange,\n onProgressChange,\n onDependencyCreate,\n onDependencyRemove,\n onDependencyDblClick,\n onTaskClick,\n onGroupToggle,\n onContextMenu,\n onTaskCreate,\n onColumnResize,\n onColumnReorder,\n onTaskReorder,\n onSelectionChange,\n };\n\n useEffect(() => {\n if (!chart) return undefined;\n\n const handleDateChange = (p: { task: GanttTask; start: Date; end: Date }) =>\n callbacksRef.current.onDateChange?.(p.task, p.start, p.end);\n const handleProgressChange = (p: { task: GanttTask; progress: number }) =>\n callbacksRef.current.onProgressChange?.(p.task, p.progress);\n const handleDependencyCreate = (dep: GanttDependency) =>\n callbacksRef.current.onDependencyCreate?.(dep);\n const handleDependencyRemove = (dep: GanttDependency) =>\n callbacksRef.current.onDependencyRemove?.(dep);\n const handleTaskClick = (p: { task: GanttTask }) =>\n callbacksRef.current.onTaskClick?.(p.task);\n const handleGroupToggle = (p: { task: GanttTask; collapsed: boolean }) =>\n callbacksRef.current.onGroupToggle?.(p.task, p.collapsed);\n const handleContextMenu = (p: { task: GanttTask; evt: PointerEvent }) =>\n callbacksRef.current.onContextMenu?.(p.task, p.evt);\n const handleTaskCreate = (p: { task: GanttTask }) => callbacksRef.current.onTaskCreate?.(p.task);\n const handleColumnResize = (p: { columnId: string; width: number }) =>\n callbacksRef.current.onColumnResize?.(p.columnId, p.width);\n const handleColumnReorder = (p: { order: string[] }) =>\n callbacksRef.current.onColumnReorder?.(p.order);\n const handleDependencyDblClick = (dep: GanttDependency) =>\n callbacksRef.current.onDependencyDblClick?.(dep);\n const handleTaskReorder = (p: {\n draggedTaskId: string;\n targetTaskId: string;\n position: \"before\" | \"after\" | \"inside\";\n }) => callbacksRef.current.onTaskReorder?.(p.draggedTaskId, p.targetTaskId, p.position);\n const handleSelectionChange = (p: { taskIds: string[] }) =>\n callbacksRef.current.onSelectionChange?.(p.taskIds);\n\n chart.on(\"date-change\", handleDateChange);\n chart.on(\"progress-change\", handleProgressChange);\n chart.on(\"dependency-create\", handleDependencyCreate);\n chart.on(\"dependency-remove\", handleDependencyRemove);\n chart.on(\"dependency-dblclick\", handleDependencyDblClick);\n chart.on(\"task-click\", handleTaskClick);\n chart.on(\"group-toggle\", handleGroupToggle);\n chart.on(\"context-menu\", handleContextMenu);\n chart.on(\"task-create\", handleTaskCreate);\n chart.on(\"column-resize\", handleColumnResize);\n chart.on(\"column-reorder\", handleColumnReorder);\n chart.on(\"task-reorder\", handleTaskReorder);\n chart.on(\"selection-change\", handleSelectionChange);\n\n return () => {\n chart.off(\"date-change\", handleDateChange);\n chart.off(\"progress-change\", handleProgressChange);\n chart.off(\"dependency-create\", handleDependencyCreate);\n chart.off(\"dependency-remove\", handleDependencyRemove);\n chart.off(\"dependency-dblclick\", handleDependencyDblClick);\n chart.off(\"task-click\", handleTaskClick);\n chart.off(\"group-toggle\", handleGroupToggle);\n chart.off(\"context-menu\", handleContextMenu);\n chart.off(\"task-create\", handleTaskCreate);\n chart.off(\"column-resize\", handleColumnResize);\n chart.off(\"column-reorder\", handleColumnReorder);\n chart.off(\"task-reorder\", handleTaskReorder);\n chart.off(\"selection-change\", handleSelectionChange);\n };\n }, [chart]);\n\n useImperativeHandle(\n ref,\n (): GanttChartHandle => ({\n undo: () => chart?.undo(),\n redo: () => chart?.redo(),\n canUndo: () => chart?.canUndo ?? false,\n canRedo: () => chart?.canRedo ?? false,\n expandAll: () => chart?.expandAll(),\n collapseAll: () => chart?.collapseAll(),\n toggleGroup: (taskId: string) => chart?.toggleGroup(taskId),\n removeDependency: (fromId: string, toId: string) => chart?.removeDependency(fromId, toId),\n updateDependency: (fromId: string, toId: string, partial: Partial<GanttDependency>) =>\n chart?.updateDependency(fromId, toId, partial),\n updateTask: (id: string, partial: Partial<GanttTask>) => chart?.updateTask(id, partial),\n setViewMode: (mode: ViewMode) => chart?.setViewMode(mode),\n fitToViewport: (containerWidthPx: number) => chart?.fitToViewport(containerWidthPx),\n scrollToToday: () => chart?.scrollToToday(),\n scrollToRangeStart: () => chart?.scrollToRangeStart(),\n scrollToRangeEnd: () => chart?.scrollToRangeEnd(),\n getPageCount: () => chart?.getPageCount() ?? 1,\n setPage: (page: number) => chart?.setPage(page),\n zoomIn: (factor?: number) => chart?.zoomIn(factor),\n zoomOut: (factor?: number) => chart?.zoomOut(factor),\n getZoomLevel: () => chart?.getZoomLevel() ?? 0,\n getResourceHistogram: (options?: ResourceHistogramOptions) =>\n chart?.getResourceHistogram(options) ?? [],\n getLeveledTasks: (options?: ResourceLevelingOptions) =>\n chart?.getLeveledTasks(options) ?? { tasks: [], shifted: [] },\n selectTask: (id: string, options?: { additive?: boolean }) => chart?.selectTask(id, options),\n selectAllVisible: () => chart?.selectAllVisible(),\n clearSelection: () => chart?.clearSelection(),\n getSelectedTaskIds: () => chart?.getSelectedTaskIds() ?? [],\n bulkShiftDates: (deltaMs: number) => chart?.bulkShiftDates(deltaMs),\n bulkDelete: () => chart?.bulkDelete(),\n toSVGString: () => chart?.toSVGString() ?? \"\",\n toPNGDataURL: () => chart?.toPNGDataURL() ?? Promise.resolve(\"\"),\n toPNGDataURLs: (options?: { pageWidthPx?: number; pageHeightPx?: number }) =>\n chart?.toPNGDataURLs(options) ?? Promise.resolve([]),\n getRenderModel: () => chart?.getRenderModel() ?? EMPTY_RENDER_MODEL,\n getInstance: () => chart,\n }),\n [chart]\n );\n\n return <div ref={containerRef} className={className} style={style} />;\n}\n\nexport const GanttChart = forwardRef(GanttChartInner);\nGanttChart.displayName = \"GanttChart\";\n\nexport default GanttChart;\n","import { useEffect, useRef, useState, type RefObject } from \"react\";\nimport { GanttChart as GanttCore } from \"@ganttloom/gantt-core\";\nimport type { GanttDependency, GanttOptions, GanttTask } from \"@ganttloom/gantt-core\";\n\nexport interface UseGanttChartResult {\n /** The underlying framework-agnostic GanttChart instance, or null before the DOM mount effect runs (or on the server). */\n chart: GanttCore | null;\n /** Reactive, subscribed to the core's \"history-change\" event. Only meaningful when `enableHistory` is set in options. */\n canUndo: boolean;\n /** Reactive, subscribed to the core's \"history-change\" event. Only meaningful when `enableHistory` is set in options. */\n canRedo: boolean;\n}\n\nconst EMPTY_DEPENDENCIES: GanttDependency[] = [];\nconst EMPTY_OPTIONS: GanttOptions = {};\n\n/**\n * Lower-level escape hatch for consumers who want to own their own container element\n * and DOM tree instead of using the <GanttChart /> component. Constructs a\n * @ganttloom/gantt-core GanttChart instance against `containerRef.current` on mount,\n * keeps it in sync with `tasks` / `dependencies` / `options` via setTasks / setDependencies /\n * setOptions (reference-equality checks only — pass new arrays/objects to trigger a sync),\n * and destroys it on unmount.\n */\nexport function useGanttChart(\n containerRef: RefObject<HTMLElement | null>,\n tasks: GanttTask[],\n dependencies: GanttDependency[] = EMPTY_DEPENDENCIES,\n options: GanttOptions = EMPTY_OPTIONS\n): UseGanttChartResult {\n const [chart, setChart] = useState<GanttCore | null>(null);\n const [canUndo, setCanUndo] = useState(false);\n const [canRedo, setCanRedo] = useState(false);\n\n const chartRef = useRef<GanttCore | null>(null);\n\n // Latest props, read from the mount effect so it doesn't need to depend on them\n // (which would otherwise tear down and recreate the whole chart on every change).\n const initialTasksRef = useRef(tasks);\n initialTasksRef.current = tasks;\n const initialDepsRef = useRef(dependencies);\n initialDepsRef.current = dependencies;\n const initialOptionsRef = useRef(options);\n initialOptionsRef.current = options;\n\n useEffect(() => {\n if (typeof window === \"undefined\") return undefined;\n const container = containerRef.current;\n if (!container) return undefined;\n\n const instance = new GanttCore(\n container,\n initialTasksRef.current,\n initialDepsRef.current,\n initialOptionsRef.current\n );\n chartRef.current = instance;\n setChart(instance);\n setCanUndo(instance.canUndo);\n setCanRedo(instance.canRedo);\n\n const onHistoryChange = (state: { canUndo: boolean; canRedo: boolean }) => {\n setCanUndo(state.canUndo);\n setCanRedo(state.canRedo);\n };\n instance.on(\"history-change\", onHistoryChange);\n\n return () => {\n instance.off(\"history-change\", onHistoryChange);\n instance.destroy();\n chartRef.current = null;\n setChart(null);\n setCanUndo(false);\n setCanRedo(false);\n };\n // Intentionally mount/unmount only — the container element identity is what matters.\n }, [containerRef]);\n\n const isFirstTasksSync = useRef(true);\n useEffect(() => {\n if (isFirstTasksSync.current) {\n isFirstTasksSync.current = false;\n return;\n }\n chartRef.current?.setTasks(tasks);\n }, [tasks]);\n\n const isFirstDepsSync = useRef(true);\n useEffect(() => {\n if (isFirstDepsSync.current) {\n isFirstDepsSync.current = false;\n return;\n }\n chartRef.current?.setDependencies(dependencies);\n }, [dependencies]);\n\n const isFirstOptionsSync = useRef(true);\n useEffect(() => {\n if (isFirstOptionsSync.current) {\n isFirstOptionsSync.current = false;\n return;\n }\n chartRef.current?.setOptions(options);\n }, [options]);\n\n return { chart, canUndo, canRedo };\n}\n","export { GanttChart, default } from \"./GanttChart\";\nexport type { GanttChartProps, GanttChartHandle } from \"./GanttChart\";\n\nexport { useGanttChart } from \"./useGanttChart\";\nexport type { UseGanttChartResult } from \"./useGanttChart\";\n\n// Re-exported so consumers never need to add @ganttloom/gantt-core as a direct\n// dependency just to reference its types.\nexport type {\n ViewMode,\n DependencyType,\n GanttDependency,\n GanttAssignee,\n GanttTask,\n GanttColumn,\n GanttTheme,\n GanttRenderRow,\n GanttRenderBar,\n GanttRenderLink,\n GanttRenderTick,\n GanttRenderModel,\n GanttOptions,\n GanttEventMap,\n WorkingCalendar,\n ConstraintType,\n ResourceHistogramOptions,\n ResourceLoadBucket,\n GanttMarker,\n GanttRenderMarker,\n FilterTasksOptions,\n FilterTasksResult,\n Density,\n ResourceLevelingOptions,\n ResourceLevelingResult,\n} from \"@ganttloom/gantt-core\";\n\nexport {\n computeWBSCodes,\n applyConstraint,\n isWorkingDay,\n isHoliday,\n isWithinWorkingHours,\n isWorkingTime,\n nextWorkingDay,\n previousWorkingDay,\n shiftToWorkingDay,\n shiftToWorkingTime,\n computeResourceHistogram,\n renderResourceHistogramSVG,\n filterTasks,\n colorByField,\n applyColorByField,\n DEFAULT_PALETTE,\n DENSITY_PRESETS,\n levelResources,\n} from \"@ganttloom/gantt-core\";\n"],"mappings":"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","names":["useEffect","useRef","EMPTY_DEPENDENCIES","useRef","useEffect","options"]}
|
|
1
|
+
{"version":3,"sources":["../src/GanttChart.tsx","../src/useGanttChart.ts","../src/index.ts"],"sourcesContent":["// Pulls in the core's default styles so consumers get a working chart out of the box.\n// This resolves through gantt-core's package.json \"exports\" map (\"./styles.css\" -> \"./dist/styles.css\").\n// If your bundler can't resolve CSS imports from a dependency's export map, import it yourself instead:\n// import \"@ganttloom/gantt-core/styles.css\";\nimport \"@ganttloom/gantt-core/styles.css\";\n\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n type CSSProperties,\n type Ref,\n} from \"react\";\nimport type {\n GanttChart as GanttCore,\n GanttColumn,\n GanttDependency,\n GanttMarker,\n GanttOptions,\n GanttRenderModel,\n GanttTask,\n GanttTheme,\n ResourceHistogramOptions,\n ResourceLoadBucket,\n ResourceLevelingOptions,\n ResourceLevelingResult,\n ViewMode,\n WorkingCalendar,\n} from \"@ganttloom/gantt-core\";\nimport { useGanttChart } from \"./useGanttChart\";\n\nexport interface GanttChartProps {\n tasks: GanttTask[];\n dependencies?: GanttDependency[];\n\n // Mirrors of GanttOptions' non-callback fields.\n viewMode?: ViewMode;\n columns?: GanttColumn[];\n theme?: Partial<GanttTheme>;\n colorScheme?: \"light\" | \"dark\" | \"auto\";\n columnWidth?: number;\n readonly?: boolean;\n showProgress?: boolean;\n showDependencies?: boolean;\n gridPanelWidth?: number;\n showCriticalPath?: boolean;\n showBaseline?: boolean;\n showDeadlines?: boolean;\n /** hover tooltip on task bars, defaults to true. A floating, CSS-customizable element (`.gantt-tooltip`) - not the browser's native title tooltip. */\n showTooltip?: boolean;\n /** fully control tooltip content/markup; return null/undefined to suppress it for a specific task. Defaults to name/dates/progress/assignees/notes. */\n renderTooltip?: (task: GanttTask) => HTMLElement | string | null | undefined;\n showAssigneeAvatars?: boolean;\n enableHistory?: boolean;\n keyboardAccessible?: boolean;\n virtualScroll?: boolean;\n autoSchedule?: boolean;\n pagination?: { pageSize: number; page: number };\n snapToUnit?: \"hour\" | \"day\" | \"week\" | false;\n /** working-day/holiday definition used to shade non-working time and (with autoSchedule) skip it when cascading */\n calendar?: WorkingCalendar;\n /** arbitrary labeled vertical lines on the timeline, independent of any task */\n markers?: GanttMarker[];\n /** a group task with no explicit `progress` gets a duration-weighted average of its children's progress instead of 0 */\n autoRollupProgress?: boolean;\n /** enables click/ctrl-click/shift-click multi-selection of task bars, and the handle's bulkShiftDates()/bulkDelete() */\n selectable?: boolean;\n /**\n * Stretch (never shrink) the timeline to fill the container's width instead of leaving empty\n * space - the common \"short project at month/year zoom\" or \"just a few tasks\" case. Off by\n * default (a new chart's pixel layout shouldn't change for existing consumers who don't opt in).\n */\n autoFitToViewport?: boolean;\n\n // Mirrors of GanttOptions' callback fields, as normal React event props.\n onDateChange?: (task: GanttTask, start: Date, end: Date) => void;\n onProgressChange?: (task: GanttTask, progress: number) => void;\n onDependencyCreate?: (dep: GanttDependency) => void;\n onDependencyRemove?: (dep: GanttDependency) => void;\n /** called on double-click of a dependency link, for building your own \"edit this link\" UI (see the handle's updateDependency) */\n onDependencyDblClick?: (dep: GanttDependency) => void;\n onTaskClick?: (task: GanttTask) => void;\n /** called on double-click of a task bar (distinct from onDependencyDblClick, which is for links) */\n onTaskDblClick?: (task: GanttTask) => void;\n onGroupToggle?: (task: GanttTask, collapsed: boolean) => void;\n onContextMenu?: (task: GanttTask, evt: PointerEvent) => void;\n /** called when a task is created via drag-to-create on an empty timeline row */\n onTaskCreate?: (task: GanttTask) => void;\n /** called when a grid column is resized by dragging its header's edge */\n onColumnResize?: (columnId: string, width: number) => void;\n /** called when grid columns are reordered by dragging a header; `order` is the new full list of column ids */\n onColumnReorder?: (order: string[]) => void;\n /** called when a grid row is dragged onto another; \"inside\" reparents the dragged task under the target */\n onTaskReorder?: (draggedTaskId: string, targetTaskId: string, position: \"before\" | \"after\" | \"inside\") => void;\n onSelectionChange?: (taskIds: string[]) => void;\n /** fired whenever the sort state changes, via a sortable column header click or the handle's setSort() */\n onSortChange?: (sort: { columnId: string; direction: \"asc\" | \"desc\" } | null) => void;\n\n /** Applied to the wrapping container div. */\n className?: string;\n style?: CSSProperties;\n}\n\n/** Imperative escape hatches that don't need to be reactive props. */\nexport interface GanttChartHandle {\n undo(): void;\n redo(): void;\n canUndo(): boolean;\n canRedo(): boolean;\n expandAll(): void;\n collapseAll(): void;\n toggleGroup(taskId: string): void;\n removeDependency(fromId: string, toId: string): void;\n updateDependency(fromId: string, toId: string, partial: Partial<GanttDependency>): void;\n updateTask(id: string, partial: Partial<GanttTask>): void;\n setViewMode(mode: ViewMode): void;\n fitToViewport(containerWidthPx: number): void;\n scrollToToday(): void;\n scrollToRangeStart(): void;\n scrollToRangeEnd(): void;\n getPageCount(): number;\n setPage(page: number): void;\n zoomIn(factor?: number): void;\n zoomOut(factor?: number): void;\n getZoomLevel(): number;\n getResourceHistogram(options?: ResourceHistogramOptions): ResourceLoadBucket[];\n getLeveledTasks(options?: ResourceLevelingOptions): ResourceLevelingResult;\n selectTask(id: string, options?: { additive?: boolean }): void;\n selectAllVisible(): void;\n clearSelection(): void;\n getSelectedTaskIds(): string[];\n setSort(columnId: string | null, direction?: \"asc\" | \"desc\" | null): void;\n getSort(): { columnId: string; direction: \"asc\" | \"desc\" } | null;\n bulkShiftDates(deltaMs: number): void;\n bulkDelete(): void;\n toSVGString(): string;\n toPNGDataURL(): Promise<string>;\n toPNGDataURLs(options?: { pageWidthPx?: number; pageHeightPx?: number }): Promise<string[]>;\n getRenderModel(): GanttRenderModel | null;\n /** Direct access to the underlying framework-agnostic core instance (null before mount). */\n getInstance(): GanttCore | null;\n}\n\nconst EMPTY_DEPENDENCIES: GanttDependency[] = [];\n\nconst EMPTY_RENDER_MODEL: GanttRenderModel = {\n width: 0,\n height: 0,\n rowHeight: 0,\n headerHeight: 0,\n rows: [],\n bars: [],\n links: [],\n ticks: [],\n columns: [],\n theme: {} as GanttTheme,\n markers: [],\n rangeStart: new Date(0),\n sort: null,\n};\n\nfunction GanttChartInner(props: GanttChartProps, ref: Ref<GanttChartHandle>) {\n const {\n tasks,\n dependencies = EMPTY_DEPENDENCIES,\n className,\n style,\n onDateChange,\n onProgressChange,\n onDependencyCreate,\n onDependencyRemove,\n onDependencyDblClick,\n onTaskClick,\n onTaskDblClick,\n onGroupToggle,\n onContextMenu,\n onTaskCreate,\n onColumnResize,\n onColumnReorder,\n onTaskReorder,\n onSelectionChange,\n onSortChange,\n ...rest\n } = props;\n\n const containerRef = useRef<HTMLDivElement | null>(null);\n\n // The core only wires up its internal contextmenu DOM listener (and therefore only\n // ever emits the \"context-menu\" event) when options.onContextMenu is truthy AT\n // CONSTRUCTION TIME (see GanttChart#setupDom in gantt-core). We pass a stable no-op\n // here purely to force that wiring on regardless of whether the consumer supplied\n // onContextMenu, and dispatch the actual prop via the \"context-menu\" event\n // subscription below (so it stays reactive to prop changes and is never double-fired).\n const enableContextMenuWiring = useRef(() => {});\n\n // Same construction-time-only caveat as onContextMenu above: drag-to-create is only\n // wired into the core's InteractionController when options.onTaskCreate is truthy at\n // construction. A stable no-op forces it on whenever this component was given an\n // onTaskCreate prop at all; the real dispatch goes through the \"task-create\" event.\n const enableCreateWiring = useRef(() => {});\n\n // Same construction-time-only caveat: column resize/reorder DOM listeners are only\n // built into the grid header when these options are truthy at construction.\n const enableColumnResizeWiring = useRef((_columnId: string, _width: number) => {});\n const enableColumnReorderWiring = useRef((_order: string[]) => {});\n const enableTaskReorderWiring = useRef(\n (_draggedTaskId: string, _targetTaskId: string, _position: \"before\" | \"after\" | \"inside\") => {}\n );\n const enableDependencyDblClickWiring = useRef((_dep: GanttDependency) => {});\n const enableTaskDblClickWiring = useRef((_task: GanttTask) => {});\n\n // Deliberately depend on Boolean(handler) rather than the handler itself below: the\n // ref-backed enableXWiring callbacks already pick up the latest handler without\n // needing the memo to re-run, so depending on the raw (often inline) callback would\n // just re-create `options` — and remount the chart — every render.\n /* eslint-disable react-hooks/exhaustive-deps */\n const options = useMemo<GanttOptions>(\n () => ({\n ...rest,\n onContextMenu: enableContextMenuWiring.current,\n onTaskCreate: onTaskCreate ? enableCreateWiring.current : undefined,\n onColumnResize: onColumnResize ? enableColumnResizeWiring.current : undefined,\n onColumnReorder: onColumnReorder ? enableColumnReorderWiring.current : undefined,\n onTaskReorder: onTaskReorder ? enableTaskReorderWiring.current : undefined,\n onDependencyDblClick: onDependencyDblClick ? enableDependencyDblClickWiring.current : undefined,\n onTaskDblClick: onTaskDblClick ? enableTaskDblClickWiring.current : undefined,\n // onSelectionChange/onSortChange are deliberately NOT set here: gantt-core invokes them\n // directly from this.options AND emits a matching event at the same call sites, and the\n // effect below already subscribes to those events — including them here would double-fire.\n }),\n [\n rest.viewMode,\n rest.columns,\n rest.theme,\n rest.colorScheme,\n rest.columnWidth,\n rest.readonly,\n rest.showProgress,\n rest.showDependencies,\n rest.gridPanelWidth,\n rest.showCriticalPath,\n rest.showBaseline,\n rest.showDeadlines,\n rest.showTooltip,\n rest.renderTooltip,\n rest.autoFitToViewport,\n rest.showAssigneeAvatars,\n rest.enableHistory,\n rest.keyboardAccessible,\n rest.virtualScroll,\n rest.autoSchedule,\n rest.pagination,\n rest.snapToUnit,\n rest.calendar,\n rest.markers,\n rest.autoRollupProgress,\n rest.selectable,\n Boolean(onTaskCreate),\n Boolean(onColumnResize),\n Boolean(onColumnReorder),\n Boolean(onTaskReorder),\n Boolean(onDependencyDblClick),\n Boolean(onTaskDblClick),\n ]\n );\n /* eslint-enable react-hooks/exhaustive-deps */\n\n const { chart } = useGanttChart(containerRef, tasks, dependencies, options);\n\n // Keep the latest callback props in a ref so the event-subscription effect below\n // doesn't need to re-subscribe (tearing down/rebuilding listeners) on every render.\n const callbacksRef = useRef({\n onDateChange,\n onProgressChange,\n onDependencyCreate,\n onDependencyRemove,\n onDependencyDblClick,\n onTaskClick,\n onTaskDblClick,\n onGroupToggle,\n onContextMenu,\n onTaskCreate,\n onColumnResize,\n onColumnReorder,\n onTaskReorder,\n onSelectionChange,\n onSortChange,\n });\n callbacksRef.current = {\n onDateChange,\n onProgressChange,\n onDependencyCreate,\n onDependencyRemove,\n onDependencyDblClick,\n onTaskClick,\n onTaskDblClick,\n onGroupToggle,\n onContextMenu,\n onTaskCreate,\n onColumnResize,\n onColumnReorder,\n onTaskReorder,\n onSelectionChange,\n onSortChange,\n };\n\n useEffect(() => {\n if (!chart) return undefined;\n\n const handleDateChange = (p: { task: GanttTask; start: Date; end: Date }) =>\n callbacksRef.current.onDateChange?.(p.task, p.start, p.end);\n const handleProgressChange = (p: { task: GanttTask; progress: number }) =>\n callbacksRef.current.onProgressChange?.(p.task, p.progress);\n const handleDependencyCreate = (dep: GanttDependency) =>\n callbacksRef.current.onDependencyCreate?.(dep);\n const handleDependencyRemove = (dep: GanttDependency) =>\n callbacksRef.current.onDependencyRemove?.(dep);\n const handleTaskClick = (p: { task: GanttTask }) =>\n callbacksRef.current.onTaskClick?.(p.task);\n const handleTaskDblClick = (p: { task: GanttTask }) =>\n callbacksRef.current.onTaskDblClick?.(p.task);\n const handleGroupToggle = (p: { task: GanttTask; collapsed: boolean }) =>\n callbacksRef.current.onGroupToggle?.(p.task, p.collapsed);\n const handleContextMenu = (p: { task: GanttTask; evt: PointerEvent }) =>\n callbacksRef.current.onContextMenu?.(p.task, p.evt);\n const handleTaskCreate = (p: { task: GanttTask }) => callbacksRef.current.onTaskCreate?.(p.task);\n const handleColumnResize = (p: { columnId: string; width: number }) =>\n callbacksRef.current.onColumnResize?.(p.columnId, p.width);\n const handleColumnReorder = (p: { order: string[] }) =>\n callbacksRef.current.onColumnReorder?.(p.order);\n const handleDependencyDblClick = (dep: GanttDependency) =>\n callbacksRef.current.onDependencyDblClick?.(dep);\n const handleTaskReorder = (p: {\n draggedTaskId: string;\n targetTaskId: string;\n position: \"before\" | \"after\" | \"inside\";\n }) => callbacksRef.current.onTaskReorder?.(p.draggedTaskId, p.targetTaskId, p.position);\n const handleSelectionChange = (p: { taskIds: string[] }) =>\n callbacksRef.current.onSelectionChange?.(p.taskIds);\n const handleSortChange = (p: { sort: { columnId: string; direction: \"asc\" | \"desc\" } | null }) =>\n callbacksRef.current.onSortChange?.(p.sort);\n\n chart.on(\"date-change\", handleDateChange);\n chart.on(\"progress-change\", handleProgressChange);\n chart.on(\"dependency-create\", handleDependencyCreate);\n chart.on(\"dependency-remove\", handleDependencyRemove);\n chart.on(\"dependency-dblclick\", handleDependencyDblClick);\n chart.on(\"task-click\", handleTaskClick);\n chart.on(\"task-dblclick\", handleTaskDblClick);\n chart.on(\"group-toggle\", handleGroupToggle);\n chart.on(\"context-menu\", handleContextMenu);\n chart.on(\"task-create\", handleTaskCreate);\n chart.on(\"column-resize\", handleColumnResize);\n chart.on(\"column-reorder\", handleColumnReorder);\n chart.on(\"task-reorder\", handleTaskReorder);\n chart.on(\"selection-change\", handleSelectionChange);\n chart.on(\"sort-change\", handleSortChange);\n\n return () => {\n chart.off(\"date-change\", handleDateChange);\n chart.off(\"progress-change\", handleProgressChange);\n chart.off(\"dependency-create\", handleDependencyCreate);\n chart.off(\"dependency-remove\", handleDependencyRemove);\n chart.off(\"dependency-dblclick\", handleDependencyDblClick);\n chart.off(\"task-click\", handleTaskClick);\n chart.off(\"task-dblclick\", handleTaskDblClick);\n chart.off(\"group-toggle\", handleGroupToggle);\n chart.off(\"context-menu\", handleContextMenu);\n chart.off(\"task-create\", handleTaskCreate);\n chart.off(\"column-resize\", handleColumnResize);\n chart.off(\"column-reorder\", handleColumnReorder);\n chart.off(\"task-reorder\", handleTaskReorder);\n chart.off(\"selection-change\", handleSelectionChange);\n chart.off(\"sort-change\", handleSortChange);\n };\n }, [chart]);\n\n useImperativeHandle(\n ref,\n (): GanttChartHandle => ({\n undo: () => chart?.undo(),\n redo: () => chart?.redo(),\n canUndo: () => chart?.canUndo ?? false,\n canRedo: () => chart?.canRedo ?? false,\n expandAll: () => chart?.expandAll(),\n collapseAll: () => chart?.collapseAll(),\n toggleGroup: (taskId: string) => chart?.toggleGroup(taskId),\n removeDependency: (fromId: string, toId: string) => chart?.removeDependency(fromId, toId),\n updateDependency: (fromId: string, toId: string, partial: Partial<GanttDependency>) =>\n chart?.updateDependency(fromId, toId, partial),\n updateTask: (id: string, partial: Partial<GanttTask>) => chart?.updateTask(id, partial),\n setViewMode: (mode: ViewMode) => chart?.setViewMode(mode),\n fitToViewport: (containerWidthPx: number) => chart?.fitToViewport(containerWidthPx),\n scrollToToday: () => chart?.scrollToToday(),\n scrollToRangeStart: () => chart?.scrollToRangeStart(),\n scrollToRangeEnd: () => chart?.scrollToRangeEnd(),\n getPageCount: () => chart?.getPageCount() ?? 1,\n setPage: (page: number) => chart?.setPage(page),\n zoomIn: (factor?: number) => chart?.zoomIn(factor),\n zoomOut: (factor?: number) => chart?.zoomOut(factor),\n getZoomLevel: () => chart?.getZoomLevel() ?? 0,\n getResourceHistogram: (options?: ResourceHistogramOptions) =>\n chart?.getResourceHistogram(options) ?? [],\n getLeveledTasks: (options?: ResourceLevelingOptions) =>\n chart?.getLeveledTasks(options) ?? { tasks: [], shifted: [] },\n selectTask: (id: string, options?: { additive?: boolean }) => chart?.selectTask(id, options),\n selectAllVisible: () => chart?.selectAllVisible(),\n clearSelection: () => chart?.clearSelection(),\n getSelectedTaskIds: () => chart?.getSelectedTaskIds() ?? [],\n setSort: (columnId: string | null, direction?: \"asc\" | \"desc\" | null) => chart?.setSort(columnId, direction),\n getSort: () => chart?.getSort() ?? null,\n bulkShiftDates: (deltaMs: number) => chart?.bulkShiftDates(deltaMs),\n bulkDelete: () => chart?.bulkDelete(),\n toSVGString: () => chart?.toSVGString() ?? \"\",\n toPNGDataURL: () => chart?.toPNGDataURL() ?? Promise.resolve(\"\"),\n toPNGDataURLs: (options?: { pageWidthPx?: number; pageHeightPx?: number }) =>\n chart?.toPNGDataURLs(options) ?? Promise.resolve([]),\n getRenderModel: () => chart?.getRenderModel() ?? EMPTY_RENDER_MODEL,\n getInstance: () => chart,\n }),\n [chart]\n );\n\n return <div ref={containerRef} className={className} style={style} />;\n}\n\nexport const GanttChart = forwardRef(GanttChartInner);\nGanttChart.displayName = \"GanttChart\";\n\nexport default GanttChart;\n","import { useEffect, useRef, useState, type RefObject } from \"react\";\nimport { GanttChart as GanttCore } from \"@ganttloom/gantt-core\";\nimport type { GanttDependency, GanttOptions, GanttTask } from \"@ganttloom/gantt-core\";\n\nexport interface UseGanttChartResult {\n /** The underlying framework-agnostic GanttChart instance, or null before the DOM mount effect runs (or on the server). */\n chart: GanttCore | null;\n /** Reactive, subscribed to the core's \"history-change\" event. Only meaningful when `enableHistory` is set in options. */\n canUndo: boolean;\n /** Reactive, subscribed to the core's \"history-change\" event. Only meaningful when `enableHistory` is set in options. */\n canRedo: boolean;\n}\n\nconst EMPTY_DEPENDENCIES: GanttDependency[] = [];\nconst EMPTY_OPTIONS: GanttOptions = {};\n\n/**\n * Lower-level escape hatch for consumers who want to own their own container element\n * and DOM tree instead of using the <GanttChart /> component. Constructs a\n * @ganttloom/gantt-core GanttChart instance against `containerRef.current` on mount,\n * keeps it in sync with `tasks` / `dependencies` / `options` via setTasks / setDependencies /\n * setOptions (reference-equality checks only — pass new arrays/objects to trigger a sync),\n * and destroys it on unmount.\n */\nexport function useGanttChart(\n containerRef: RefObject<HTMLElement | null>,\n tasks: GanttTask[],\n dependencies: GanttDependency[] = EMPTY_DEPENDENCIES,\n options: GanttOptions = EMPTY_OPTIONS\n): UseGanttChartResult {\n const [chart, setChart] = useState<GanttCore | null>(null);\n const [canUndo, setCanUndo] = useState(false);\n const [canRedo, setCanRedo] = useState(false);\n\n const chartRef = useRef<GanttCore | null>(null);\n\n // Latest props, read from the mount effect so it doesn't need to depend on them\n // (which would otherwise tear down and recreate the whole chart on every change).\n const initialTasksRef = useRef(tasks);\n initialTasksRef.current = tasks;\n const initialDepsRef = useRef(dependencies);\n initialDepsRef.current = dependencies;\n const initialOptionsRef = useRef(options);\n initialOptionsRef.current = options;\n\n useEffect(() => {\n if (typeof window === \"undefined\") return undefined;\n const container = containerRef.current;\n if (!container) return undefined;\n\n const instance = new GanttCore(\n container,\n initialTasksRef.current,\n initialDepsRef.current,\n initialOptionsRef.current\n );\n chartRef.current = instance;\n setChart(instance);\n setCanUndo(instance.canUndo);\n setCanRedo(instance.canRedo);\n\n const onHistoryChange = (state: { canUndo: boolean; canRedo: boolean }) => {\n setCanUndo(state.canUndo);\n setCanRedo(state.canRedo);\n };\n instance.on(\"history-change\", onHistoryChange);\n\n return () => {\n instance.off(\"history-change\", onHistoryChange);\n instance.destroy();\n chartRef.current = null;\n setChart(null);\n setCanUndo(false);\n setCanRedo(false);\n };\n // Intentionally mount/unmount only — the container element identity is what matters.\n }, [containerRef]);\n\n const isFirstTasksSync = useRef(true);\n useEffect(() => {\n if (isFirstTasksSync.current) {\n isFirstTasksSync.current = false;\n return;\n }\n chartRef.current?.setTasks(tasks);\n }, [tasks]);\n\n const isFirstDepsSync = useRef(true);\n useEffect(() => {\n if (isFirstDepsSync.current) {\n isFirstDepsSync.current = false;\n return;\n }\n chartRef.current?.setDependencies(dependencies);\n }, [dependencies]);\n\n const isFirstOptionsSync = useRef(true);\n useEffect(() => {\n if (isFirstOptionsSync.current) {\n isFirstOptionsSync.current = false;\n return;\n }\n chartRef.current?.setOptions(options);\n }, [options]);\n\n return { chart, canUndo, canRedo };\n}\n","export { GanttChart, default } from \"./GanttChart\";\nexport type { GanttChartProps, GanttChartHandle } from \"./GanttChart\";\n\nexport { useGanttChart } from \"./useGanttChart\";\nexport type { UseGanttChartResult } from \"./useGanttChart\";\n\n// Re-exported so consumers never need to add @ganttloom/gantt-core as a direct\n// dependency just to reference its types.\nexport type {\n ViewMode,\n DependencyType,\n GanttDependency,\n GanttAssignee,\n GanttTask,\n GanttColumn,\n GanttTheme,\n GanttRenderRow,\n GanttRenderBar,\n GanttRenderLink,\n GanttRenderTick,\n GanttRenderModel,\n GanttOptions,\n GanttEventMap,\n WorkingCalendar,\n ConstraintType,\n ResourceHistogramOptions,\n ResourceLoadBucket,\n GanttMarker,\n GanttRenderMarker,\n FilterTasksOptions,\n FilterTasksResult,\n Density,\n ResourceLevelingOptions,\n ResourceLevelingResult,\n} from \"@ganttloom/gantt-core\";\n\nexport {\n computeWBSCodes,\n applyConstraint,\n isWorkingDay,\n isHoliday,\n isWithinWorkingHours,\n isWorkingTime,\n nextWorkingDay,\n previousWorkingDay,\n shiftToWorkingDay,\n shiftToWorkingTime,\n computeResourceHistogram,\n renderResourceHistogramSVG,\n filterTasks,\n colorByField,\n applyColorByField,\n DEFAULT_PALETTE,\n DENSITY_PRESETS,\n levelResources,\n} from \"@ganttloom/gantt-core\";\n"],"mappings":"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","names":["useEffect","useRef","EMPTY_DEPENDENCIES","useRef","useEffect","options"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ganttloom/gantt-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "React wrapper for @ganttloom/gantt-core — fully customizable Gantt chart component.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"react-dom": ">=18"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@ganttloom/gantt-core": "0.
|
|
43
|
+
"@ganttloom/gantt-core": "0.4.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"react": "^18.3.1",
|