@ganttloom/gantt-core 0.2.0 → 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/dist/index.d.cts CHANGED
@@ -123,7 +123,7 @@ interface GanttTask {
123
123
  /** the date the constraint is relative to (ignored for "asap"/"alap") */
124
124
  constraintDate?: Date;
125
125
  assignees?: GanttAssignee[];
126
- /** shown as a native hover tooltip on the bar (an SVG <title>, so it works with zero extra markup/JS) */
126
+ /** shown as an extra line in the default hover tooltip (see GanttOptions.showTooltip/renderTooltip) */
127
127
  notes?: string;
128
128
  /** additional named baseline snapshots beyond baselineStart/baselineEnd (e.g. "as of last Friday") - rendered as extra faint bars, oldest furthest back */
129
129
  baselines?: {
@@ -152,6 +152,14 @@ interface GanttColumn {
152
152
  /** anchor target, defaults to "_blank" */
153
153
  linkTarget?: string;
154
154
  align?: "left" | "center" | "right";
155
+ /**
156
+ * Lets clicking this column's header cycle sort asc -> desc -> none. Sorting reorders
157
+ * siblings at every tree level by this column's value (via `accessor`, or `task.name` for
158
+ * the conventional unaccessored "name" column) - the group/parent hierarchy itself is
159
+ * never reshuffled, only the order within it. A column with neither `accessor` nor the id
160
+ * "name" has nothing sortable to read and is a no-op if marked sortable.
161
+ */
162
+ sortable?: boolean;
155
163
  }
156
164
  interface GanttTheme {
157
165
  rowHeight: number;
@@ -265,6 +273,10 @@ interface GanttRenderModel {
265
273
  markers: GanttRenderMarker[];
266
274
  /** start of the timeline's date range, in real time - lets callers convert chart-space x back to a Date */
267
275
  rangeStart: Date;
276
+ sort: {
277
+ columnId: string;
278
+ direction: "asc" | "desc";
279
+ } | null;
268
280
  }
269
281
  interface GanttOptions {
270
282
  viewMode?: ViewMode;
@@ -281,6 +293,24 @@ interface GanttOptions {
281
293
  showCriticalPath?: boolean;
282
294
  showBaseline?: boolean;
283
295
  showDeadlines?: boolean;
296
+ /**
297
+ * Stretch (never shrink) the timeline so it fills the container's width instead of leaving
298
+ * empty space to the right - the common "short project at month/year zoom" or "just a
299
+ * handful of tasks" case, where the natural columnWidth would otherwise render a narrow
300
+ * chart floating in a mostly-empty viewport. Re-evaluated on viewMode/task changes and on
301
+ * container resize (via ResizeObserver). Never applied if the content is already wider than
302
+ * the container (that's what normal horizontal scrolling is for). Default false.
303
+ */
304
+ autoFitToViewport?: boolean;
305
+ /** hover tooltip on task bars, defaults to true. A floating, CSS-customizable element (see `.gantt-tooltip` in styles.css) - not the browser's native title tooltip. */
306
+ showTooltip?: boolean;
307
+ /**
308
+ * Fully control tooltip content/markup. Return an HTMLElement to mount directly, or a plain
309
+ * string rendered as text (never parsed as HTML, same XSS-safe contract as GanttColumn.render);
310
+ * return null/undefined to suppress the tooltip for that specific task. Defaults to task name,
311
+ * dates, progress, assignees, and notes.
312
+ */
313
+ renderTooltip?: (task: GanttTask) => HTMLElement | string | null | undefined;
284
314
  showAssigneeAvatars?: boolean;
285
315
  /** working-day/holiday definition used to shade non-working time and (with autoSchedule) skip it when cascading */
286
316
  calendar?: WorkingCalendar;
@@ -291,6 +321,11 @@ interface GanttOptions {
291
321
  /** enables click/ctrl-click/shift-click multi-selection of task bars, and chart.bulkShiftDates()/bulkDelete() */
292
322
  selectable?: boolean;
293
323
  onSelectionChange?: (taskIds: string[]) => void;
324
+ /** fired whenever the sort state changes, via a sortable column header click or chart.setSort() */
325
+ onSortChange?: (sort: {
326
+ columnId: string;
327
+ direction: "asc" | "desc";
328
+ } | null) => void;
294
329
  /** enable Ctrl+Z / Ctrl+Y undo-redo history for move/resize/link actions */
295
330
  enableHistory?: boolean;
296
331
  /** enable arrow-key task movement + ARIA labels on bars/rows */
@@ -314,6 +349,8 @@ interface GanttOptions {
314
349
  /** called on double-click of a dependency link, for building your own "edit this link" UI (see chart.updateDependency) */
315
350
  onDependencyDblClick?: (dep: GanttDependency) => void;
316
351
  onTaskClick?: (task: GanttTask) => void;
352
+ /** called on double-click of a task bar (distinct from onDependencyDblClick, which is for links) */
353
+ onTaskDblClick?: (task: GanttTask) => void;
317
354
  onGroupToggle?: (task: GanttTask, collapsed: boolean) => void;
318
355
  /** called when a task is created via drag-to-create on an empty timeline row */
319
356
  onTaskCreate?: (task: GanttTask) => void;
@@ -369,6 +406,9 @@ type GanttEventMap = {
369
406
  order: string[];
370
407
  };
371
408
  "dependency-dblclick": GanttDependency;
409
+ "task-dblclick": {
410
+ task: GanttTask;
411
+ };
372
412
  "task-reorder": {
373
413
  draggedTaskId: string;
374
414
  targetTaskId: string;
@@ -377,6 +417,12 @@ type GanttEventMap = {
377
417
  "selection-change": {
378
418
  taskIds: string[];
379
419
  };
420
+ "sort-change": {
421
+ sort: {
422
+ columnId: string;
423
+ direction: "asc" | "desc";
424
+ } | null;
425
+ };
380
426
  };
381
427
 
382
428
  interface ResourceLevelingOptions {
@@ -479,6 +525,11 @@ interface LayoutInput {
479
525
  pageSize: number;
480
526
  page: number;
481
527
  };
528
+ /** sort siblings at every tree level by a column's value, preserving the group/parent hierarchy */
529
+ sort?: {
530
+ columnId: string;
531
+ direction: "asc" | "desc";
532
+ } | null;
482
533
  }
483
534
  declare function computeLayout(input: LayoutInput): GanttRenderModel;
484
535
 
@@ -657,6 +708,9 @@ declare class GanttChart {
657
708
  private history;
658
709
  private renderer;
659
710
  private interactions;
711
+ private tooltip;
712
+ private resizeObserver;
713
+ private sort;
660
714
  private renderModel;
661
715
  private rafHandle;
662
716
  private currentPage;
@@ -690,6 +744,14 @@ declare class GanttChart {
690
744
  private runCommand;
691
745
  private handleColumnResize;
692
746
  private handleColumnReorder;
747
+ /** Cycles a sortable column's header through asc -> desc -> none; clicking a different column starts it fresh at asc. */
748
+ private handleSortClick;
749
+ /** Sorts siblings at every tree level by a column's value (see GanttColumn.sortable); `direction: null`/omitted `columnId` clears it. */
750
+ setSort(columnId: string | null, direction?: "asc" | "desc" | null): void;
751
+ getSort(): {
752
+ columnId: string;
753
+ direction: "asc" | "desc";
754
+ } | null;
693
755
  private handleRowReorder;
694
756
  toggleGroup(taskId: string): void;
695
757
  expandAll(): void;
@@ -727,6 +789,12 @@ declare class GanttChart {
727
789
  private computeModel;
728
790
  private scheduleRender;
729
791
  private doRender;
792
+ /**
793
+ * Stretch-only fit: bump columnWidth up so the timeline fills the container's available
794
+ * width, but never shrink it below what the current zoom level already implies - a project
795
+ * wider than the container should still scroll normally, not get crammed to fit.
796
+ */
797
+ private applyAutoFit;
730
798
  undo(): void;
731
799
  redo(): void;
732
800
  get canUndo(): boolean;
package/dist/index.d.ts CHANGED
@@ -123,7 +123,7 @@ interface GanttTask {
123
123
  /** the date the constraint is relative to (ignored for "asap"/"alap") */
124
124
  constraintDate?: Date;
125
125
  assignees?: GanttAssignee[];
126
- /** shown as a native hover tooltip on the bar (an SVG <title>, so it works with zero extra markup/JS) */
126
+ /** shown as an extra line in the default hover tooltip (see GanttOptions.showTooltip/renderTooltip) */
127
127
  notes?: string;
128
128
  /** additional named baseline snapshots beyond baselineStart/baselineEnd (e.g. "as of last Friday") - rendered as extra faint bars, oldest furthest back */
129
129
  baselines?: {
@@ -152,6 +152,14 @@ interface GanttColumn {
152
152
  /** anchor target, defaults to "_blank" */
153
153
  linkTarget?: string;
154
154
  align?: "left" | "center" | "right";
155
+ /**
156
+ * Lets clicking this column's header cycle sort asc -> desc -> none. Sorting reorders
157
+ * siblings at every tree level by this column's value (via `accessor`, or `task.name` for
158
+ * the conventional unaccessored "name" column) - the group/parent hierarchy itself is
159
+ * never reshuffled, only the order within it. A column with neither `accessor` nor the id
160
+ * "name" has nothing sortable to read and is a no-op if marked sortable.
161
+ */
162
+ sortable?: boolean;
155
163
  }
156
164
  interface GanttTheme {
157
165
  rowHeight: number;
@@ -265,6 +273,10 @@ interface GanttRenderModel {
265
273
  markers: GanttRenderMarker[];
266
274
  /** start of the timeline's date range, in real time - lets callers convert chart-space x back to a Date */
267
275
  rangeStart: Date;
276
+ sort: {
277
+ columnId: string;
278
+ direction: "asc" | "desc";
279
+ } | null;
268
280
  }
269
281
  interface GanttOptions {
270
282
  viewMode?: ViewMode;
@@ -281,6 +293,24 @@ interface GanttOptions {
281
293
  showCriticalPath?: boolean;
282
294
  showBaseline?: boolean;
283
295
  showDeadlines?: boolean;
296
+ /**
297
+ * Stretch (never shrink) the timeline so it fills the container's width instead of leaving
298
+ * empty space to the right - the common "short project at month/year zoom" or "just a
299
+ * handful of tasks" case, where the natural columnWidth would otherwise render a narrow
300
+ * chart floating in a mostly-empty viewport. Re-evaluated on viewMode/task changes and on
301
+ * container resize (via ResizeObserver). Never applied if the content is already wider than
302
+ * the container (that's what normal horizontal scrolling is for). Default false.
303
+ */
304
+ autoFitToViewport?: boolean;
305
+ /** hover tooltip on task bars, defaults to true. A floating, CSS-customizable element (see `.gantt-tooltip` in styles.css) - not the browser's native title tooltip. */
306
+ showTooltip?: boolean;
307
+ /**
308
+ * Fully control tooltip content/markup. Return an HTMLElement to mount directly, or a plain
309
+ * string rendered as text (never parsed as HTML, same XSS-safe contract as GanttColumn.render);
310
+ * return null/undefined to suppress the tooltip for that specific task. Defaults to task name,
311
+ * dates, progress, assignees, and notes.
312
+ */
313
+ renderTooltip?: (task: GanttTask) => HTMLElement | string | null | undefined;
284
314
  showAssigneeAvatars?: boolean;
285
315
  /** working-day/holiday definition used to shade non-working time and (with autoSchedule) skip it when cascading */
286
316
  calendar?: WorkingCalendar;
@@ -291,6 +321,11 @@ interface GanttOptions {
291
321
  /** enables click/ctrl-click/shift-click multi-selection of task bars, and chart.bulkShiftDates()/bulkDelete() */
292
322
  selectable?: boolean;
293
323
  onSelectionChange?: (taskIds: string[]) => void;
324
+ /** fired whenever the sort state changes, via a sortable column header click or chart.setSort() */
325
+ onSortChange?: (sort: {
326
+ columnId: string;
327
+ direction: "asc" | "desc";
328
+ } | null) => void;
294
329
  /** enable Ctrl+Z / Ctrl+Y undo-redo history for move/resize/link actions */
295
330
  enableHistory?: boolean;
296
331
  /** enable arrow-key task movement + ARIA labels on bars/rows */
@@ -314,6 +349,8 @@ interface GanttOptions {
314
349
  /** called on double-click of a dependency link, for building your own "edit this link" UI (see chart.updateDependency) */
315
350
  onDependencyDblClick?: (dep: GanttDependency) => void;
316
351
  onTaskClick?: (task: GanttTask) => void;
352
+ /** called on double-click of a task bar (distinct from onDependencyDblClick, which is for links) */
353
+ onTaskDblClick?: (task: GanttTask) => void;
317
354
  onGroupToggle?: (task: GanttTask, collapsed: boolean) => void;
318
355
  /** called when a task is created via drag-to-create on an empty timeline row */
319
356
  onTaskCreate?: (task: GanttTask) => void;
@@ -369,6 +406,9 @@ type GanttEventMap = {
369
406
  order: string[];
370
407
  };
371
408
  "dependency-dblclick": GanttDependency;
409
+ "task-dblclick": {
410
+ task: GanttTask;
411
+ };
372
412
  "task-reorder": {
373
413
  draggedTaskId: string;
374
414
  targetTaskId: string;
@@ -377,6 +417,12 @@ type GanttEventMap = {
377
417
  "selection-change": {
378
418
  taskIds: string[];
379
419
  };
420
+ "sort-change": {
421
+ sort: {
422
+ columnId: string;
423
+ direction: "asc" | "desc";
424
+ } | null;
425
+ };
380
426
  };
381
427
 
382
428
  interface ResourceLevelingOptions {
@@ -479,6 +525,11 @@ interface LayoutInput {
479
525
  pageSize: number;
480
526
  page: number;
481
527
  };
528
+ /** sort siblings at every tree level by a column's value, preserving the group/parent hierarchy */
529
+ sort?: {
530
+ columnId: string;
531
+ direction: "asc" | "desc";
532
+ } | null;
482
533
  }
483
534
  declare function computeLayout(input: LayoutInput): GanttRenderModel;
484
535
 
@@ -657,6 +708,9 @@ declare class GanttChart {
657
708
  private history;
658
709
  private renderer;
659
710
  private interactions;
711
+ private tooltip;
712
+ private resizeObserver;
713
+ private sort;
660
714
  private renderModel;
661
715
  private rafHandle;
662
716
  private currentPage;
@@ -690,6 +744,14 @@ declare class GanttChart {
690
744
  private runCommand;
691
745
  private handleColumnResize;
692
746
  private handleColumnReorder;
747
+ /** Cycles a sortable column's header through asc -> desc -> none; clicking a different column starts it fresh at asc. */
748
+ private handleSortClick;
749
+ /** Sorts siblings at every tree level by a column's value (see GanttColumn.sortable); `direction: null`/omitted `columnId` clears it. */
750
+ setSort(columnId: string | null, direction?: "asc" | "desc" | null): void;
751
+ getSort(): {
752
+ columnId: string;
753
+ direction: "asc" | "desc";
754
+ } | null;
693
755
  private handleRowReorder;
694
756
  toggleGroup(taskId: string): void;
695
757
  expandAll(): void;
@@ -727,6 +789,12 @@ declare class GanttChart {
727
789
  private computeModel;
728
790
  private scheduleRender;
729
791
  private doRender;
792
+ /**
793
+ * Stretch-only fit: bump columnWidth up so the timeline fills the container's available
794
+ * width, but never shrink it below what the current zoom level already implies - a project
795
+ * wider than the container should still scroll normally, not get crammed to fit.
796
+ */
797
+ private applyAutoFit;
730
798
  undo(): void;
731
799
  redo(): void;
732
800
  get canUndo(): boolean;