gantt-renderer 0.9.0 → 0.10.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.
Files changed (142) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/index.d.mts +12 -2
  3. package/dist/index.mjs +111 -5
  4. package/dist/index.mjs.map +1 -1
  5. package/dist/{locale-BQKHOEOx.d.mts → locale-B81kcgPd.d.mts} +2 -2
  6. package/dist/locales/all.d.mts +1 -1
  7. package/dist/locales/ar.d.mts +1 -1
  8. package/dist/locales/ar.mjs +2 -0
  9. package/dist/locales/ar.mjs.map +1 -1
  10. package/dist/locales/be.d.mts +1 -1
  11. package/dist/locales/be.mjs +2 -0
  12. package/dist/locales/be.mjs.map +1 -1
  13. package/dist/locales/bg.d.mts +1 -1
  14. package/dist/locales/bg.mjs +2 -0
  15. package/dist/locales/bg.mjs.map +1 -1
  16. package/dist/locales/ca.d.mts +1 -1
  17. package/dist/locales/ca.mjs +2 -0
  18. package/dist/locales/ca.mjs.map +1 -1
  19. package/dist/locales/cs.d.mts +1 -1
  20. package/dist/locales/cs.mjs +2 -0
  21. package/dist/locales/cs.mjs.map +1 -1
  22. package/dist/locales/cy.d.mts +1 -1
  23. package/dist/locales/cy.mjs +2 -0
  24. package/dist/locales/cy.mjs.map +1 -1
  25. package/dist/locales/da.d.mts +1 -1
  26. package/dist/locales/da.mjs +2 -0
  27. package/dist/locales/da.mjs.map +1 -1
  28. package/dist/locales/de.d.mts +1 -1
  29. package/dist/locales/de.mjs +2 -0
  30. package/dist/locales/de.mjs.map +1 -1
  31. package/dist/locales/el.d.mts +1 -1
  32. package/dist/locales/el.mjs +2 -0
  33. package/dist/locales/el.mjs.map +1 -1
  34. package/dist/locales/en.d.mts +1 -1
  35. package/dist/locales/en.mjs +2 -0
  36. package/dist/locales/en.mjs.map +1 -1
  37. package/dist/locales/es.d.mts +1 -1
  38. package/dist/locales/es.mjs +2 -0
  39. package/dist/locales/es.mjs.map +1 -1
  40. package/dist/locales/et.d.mts +1 -1
  41. package/dist/locales/et.mjs +2 -0
  42. package/dist/locales/et.mjs.map +1 -1
  43. package/dist/locales/eu.d.mts +1 -1
  44. package/dist/locales/eu.mjs +2 -0
  45. package/dist/locales/eu.mjs.map +1 -1
  46. package/dist/locales/fi.d.mts +1 -1
  47. package/dist/locales/fi.mjs +2 -0
  48. package/dist/locales/fi.mjs.map +1 -1
  49. package/dist/locales/fr.d.mts +1 -1
  50. package/dist/locales/fr.mjs +2 -0
  51. package/dist/locales/fr.mjs.map +1 -1
  52. package/dist/locales/ga.d.mts +1 -1
  53. package/dist/locales/ga.mjs +2 -0
  54. package/dist/locales/ga.mjs.map +1 -1
  55. package/dist/locales/hi.d.mts +1 -1
  56. package/dist/locales/hi.mjs +2 -0
  57. package/dist/locales/hi.mjs.map +1 -1
  58. package/dist/locales/hr.d.mts +1 -1
  59. package/dist/locales/hr.mjs +2 -0
  60. package/dist/locales/hr.mjs.map +1 -1
  61. package/dist/locales/hu.d.mts +1 -1
  62. package/dist/locales/hu.mjs +2 -0
  63. package/dist/locales/hu.mjs.map +1 -1
  64. package/dist/locales/id.d.mts +1 -1
  65. package/dist/locales/id.mjs +2 -0
  66. package/dist/locales/id.mjs.map +1 -1
  67. package/dist/locales/it.d.mts +1 -1
  68. package/dist/locales/it.mjs +2 -0
  69. package/dist/locales/it.mjs.map +1 -1
  70. package/dist/locales/ja.d.mts +1 -1
  71. package/dist/locales/ja.mjs +2 -0
  72. package/dist/locales/ja.mjs.map +1 -1
  73. package/dist/locales/ko.d.mts +1 -1
  74. package/dist/locales/ko.mjs +2 -0
  75. package/dist/locales/ko.mjs.map +1 -1
  76. package/dist/locales/load.d.mts +1 -1
  77. package/dist/locales/lt.d.mts +1 -1
  78. package/dist/locales/lt.mjs +2 -0
  79. package/dist/locales/lt.mjs.map +1 -1
  80. package/dist/locales/lv.d.mts +1 -1
  81. package/dist/locales/lv.mjs +2 -0
  82. package/dist/locales/lv.mjs.map +1 -1
  83. package/dist/locales/mk.d.mts +1 -1
  84. package/dist/locales/mk.mjs +2 -0
  85. package/dist/locales/mk.mjs.map +1 -1
  86. package/dist/locales/mt.d.mts +1 -1
  87. package/dist/locales/mt.mjs +2 -0
  88. package/dist/locales/mt.mjs.map +1 -1
  89. package/dist/locales/nb.d.mts +1 -1
  90. package/dist/locales/nb.mjs +2 -0
  91. package/dist/locales/nb.mjs.map +1 -1
  92. package/dist/locales/nl.d.mts +1 -1
  93. package/dist/locales/nl.mjs +2 -0
  94. package/dist/locales/nl.mjs.map +1 -1
  95. package/dist/locales/pl.d.mts +1 -1
  96. package/dist/locales/pl.mjs +2 -0
  97. package/dist/locales/pl.mjs.map +1 -1
  98. package/dist/locales/pt-BR.d.mts +1 -1
  99. package/dist/locales/pt-BR.mjs +2 -0
  100. package/dist/locales/pt-BR.mjs.map +1 -1
  101. package/dist/locales/pt-PT.d.mts +1 -1
  102. package/dist/locales/pt-PT.mjs +2 -0
  103. package/dist/locales/pt-PT.mjs.map +1 -1
  104. package/dist/locales/registry.d.mts +1 -1
  105. package/dist/locales/ro.d.mts +1 -1
  106. package/dist/locales/ro.mjs +2 -0
  107. package/dist/locales/ro.mjs.map +1 -1
  108. package/dist/locales/ru.d.mts +1 -1
  109. package/dist/locales/ru.mjs +2 -0
  110. package/dist/locales/ru.mjs.map +1 -1
  111. package/dist/locales/sk.d.mts +1 -1
  112. package/dist/locales/sk.mjs +2 -0
  113. package/dist/locales/sk.mjs.map +1 -1
  114. package/dist/locales/sl.d.mts +1 -1
  115. package/dist/locales/sl.mjs +2 -0
  116. package/dist/locales/sl.mjs.map +1 -1
  117. package/dist/locales/sq.d.mts +1 -1
  118. package/dist/locales/sq.mjs +2 -0
  119. package/dist/locales/sq.mjs.map +1 -1
  120. package/dist/locales/sr.d.mts +1 -1
  121. package/dist/locales/sr.mjs +2 -0
  122. package/dist/locales/sr.mjs.map +1 -1
  123. package/dist/locales/sv.d.mts +1 -1
  124. package/dist/locales/sv.mjs +2 -0
  125. package/dist/locales/sv.mjs.map +1 -1
  126. package/dist/locales/th.d.mts +1 -1
  127. package/dist/locales/th.mjs +2 -0
  128. package/dist/locales/th.mjs.map +1 -1
  129. package/dist/locales/tr.d.mts +1 -1
  130. package/dist/locales/tr.mjs +2 -0
  131. package/dist/locales/tr.mjs.map +1 -1
  132. package/dist/locales/uk.d.mts +1 -1
  133. package/dist/locales/uk.mjs +2 -0
  134. package/dist/locales/uk.mjs.map +1 -1
  135. package/dist/locales/zh-Hans.d.mts +1 -1
  136. package/dist/locales/zh-Hans.mjs +2 -0
  137. package/dist/locales/zh-Hans.mjs.map +1 -1
  138. package/dist/locales/zh-Hant.d.mts +1 -1
  139. package/dist/locales/zh-Hant.mjs +2 -0
  140. package/dist/locales/zh-Hant.mjs.map +1 -1
  141. package/dist/styles/gantt.css +23 -0
  142. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [0.10.0](https://github.com/doberkofler/gantt-renderer/compare/v0.9.0...v0.10.0) (2026-05-13)
2
+
3
+
4
+ ### Features
5
+
6
+ * **gantt:** add onExpandCollapse/onExpandCollapseAll callbacks and header +/− controls ([652d626](https://github.com/doberkofler/gantt-renderer/commit/652d6261b7d6cdfd74c07acebb54b84708a155b1))
7
+
1
8
  # [0.9.0](https://github.com/doberkofler/gantt-renderer/compare/v0.8.0...v0.9.0) (2026-05-13)
2
9
 
3
10
 
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as deriveWeekStartsOn, c as formatWeekNumber, i as deriveWeekNumbering, l as resolveChartLocale, n as EN_US_LABELS, o as deriveWeekendDays, r as LocaleLabelKey, s as formatLabel, t as ChartLocale } from "./locale-BQKHOEOx.mjs";
1
+ import { a as deriveWeekStartsOn, c as formatWeekNumber, i as deriveWeekNumbering, l as resolveChartLocale, n as EN_US_LABELS, o as deriveWeekendDays, r as LocaleLabelKey, s as formatLabel, t as ChartLocale } from "./locale-B81kcgPd.mjs";
2
2
  import { z } from "zod";
3
3
 
4
4
  //#region src/lib/validation/schemas.d.ts
@@ -489,6 +489,14 @@ type OnProgressChange<TTaskData = never, TLinkData = never> = (payload: {
489
489
  newPercentComplete: number;
490
490
  instance: GanttInstance<TTaskData, TLinkData>;
491
491
  }) => boolean | Promise<boolean>;
492
+ type OnExpandCollapse<TTaskData = never, TLinkData = never> = (payload: {
493
+ task: Task<TTaskData>;
494
+ instance: GanttInstance<TTaskData, TLinkData>;
495
+ }) => void | Promise<void>;
496
+ type OnExpandCollapseAll<TTaskData = never, TLinkData = never> = (payload: {
497
+ tasks: Task<TTaskData>[];
498
+ instance: GanttInstance<TTaskData, TLinkData>;
499
+ }) => void | Promise<void>;
492
500
  type OnTooltipText<TTaskData = never, TLinkData = never> = (payload: {
493
501
  task: Task<TTaskData>;
494
502
  instance: GanttInstance<TTaskData, TLinkData>;
@@ -503,6 +511,8 @@ type GanttCallbacks<TTaskData = never, TLinkData = never> = {
503
511
  onLinkClick?: OnLinkClick<TTaskData, TLinkData>;
504
512
  onLinkDblClick?: OnLinkDblClick<TTaskData, TLinkData>;
505
513
  onProgressChange?: OnProgressChange<TTaskData, TLinkData>;
514
+ onExpandCollapse?: OnExpandCollapse<TTaskData, TLinkData>;
515
+ onExpandCollapseAll?: OnExpandCollapseAll<TTaskData, TLinkData>;
506
516
  onTooltipText?: OnTooltipText<TTaskData, TLinkData>;
507
517
  onLeftPaneWidthChange?: (payload: {
508
518
  width: number;
@@ -639,5 +649,5 @@ declare class GanttError extends Error {
639
649
  constructor(code: GanttErrorCode, message: string);
640
650
  }
641
651
  //#endregion
642
- export { BAR_HEIGHT, BAR_Y_OFFSET, type BarLayout, type ChartLocale, DEFAULT_GRID_COLUMNS, DENSITY, EN_US_LABELS, GRID_COLUMN_FR_MIN_WIDTH, type GanttCallbacks, GanttChart, GanttError, type GanttErrorCode, type GanttInput, type GanttInputRaw, type GanttInstance, type GanttOptions, type GridColumn, type Link, type LinkType, type LocaleLabelKey, MILESTONE_HALF, MILESTONE_SIZE, type OnLinkClick, type OnLinkCreate, type OnLinkDblClick, type OnProgressChange, type OnTaskAdd, type OnTaskClick, type OnTaskDoubleClick, type OnTaskMove, type OnTaskResize, type OnTooltipText, type PixelMapper, type Point, ROW_HEIGHT, type RoutedLink, SCALE_CONFIGS, type ScaleConfig, type SpecialDay, type SpecialDayKind, type Task, type TaskDataField, type TaskKind, type TaskNode, type ThemeMode, type TimeScale, addDays, addHours, buildTaskTree, computeLayout, createPixelMapper, deriveViewport, deriveWeekNumbering, deriveWeekStartsOn, deriveWeekendDays, detectCycles, diffDays, diffHours, flattenTree, formatLabel, formatWeekNumber, gridColumnDefaults, gridNaturalWidth, gridTemplateColumns, isParent, parseDate, resolveChartLocale, routeLinks, validateLinkRefs, visibleColumns };
652
+ export { BAR_HEIGHT, BAR_Y_OFFSET, type BarLayout, type ChartLocale, DEFAULT_GRID_COLUMNS, DENSITY, EN_US_LABELS, GRID_COLUMN_FR_MIN_WIDTH, type GanttCallbacks, GanttChart, GanttError, type GanttErrorCode, type GanttInput, type GanttInputRaw, type GanttInstance, type GanttOptions, type GridColumn, type Link, type LinkType, type LocaleLabelKey, MILESTONE_HALF, MILESTONE_SIZE, type OnExpandCollapse, type OnExpandCollapseAll, type OnLinkClick, type OnLinkCreate, type OnLinkDblClick, type OnProgressChange, type OnTaskAdd, type OnTaskClick, type OnTaskDoubleClick, type OnTaskMove, type OnTaskResize, type OnTooltipText, type PixelMapper, type Point, ROW_HEIGHT, type RoutedLink, SCALE_CONFIGS, type ScaleConfig, type SpecialDay, type SpecialDayKind, type Task, type TaskDataField, type TaskKind, type TaskNode, type ThemeMode, type TimeScale, addDays, addHours, buildTaskTree, computeLayout, createPixelMapper, deriveViewport, deriveWeekNumbering, deriveWeekStartsOn, deriveWeekendDays, detectCycles, diffDays, diffHours, flattenTree, formatLabel, formatWeekNumber, gridColumnDefaults, gridNaturalWidth, gridTemplateColumns, isParent, parseDate, resolveChartLocale, routeLinks, validateLinkRefs, visibleColumns };
643
653
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -303,6 +303,8 @@ const EN_US_LABELS = {
303
303
  ariaTask: "Task {0}",
304
304
  ariaMilestone: "Milestone {0}",
305
305
  addSubtaskTitle: "Add subtask",
306
+ expandAllTitle: "Expand all",
307
+ collapseAllTitle: "Collapse all",
306
308
  columnTaskName: "Task name",
307
309
  columnStartDate: "Start",
308
310
  columnEndDate: "End",
@@ -1784,9 +1786,10 @@ function renderLeftPane(container, state, cbs, columns, showAddTaskButton = true
1784
1786
  * Builds the header row for the left pane.
1785
1787
  *
1786
1788
  * @param columns - The grid column schema.
1789
+ * @param locale - The current chart locale.
1787
1790
  * @returns The header DOM element.
1788
1791
  */
1789
- function buildLeftPaneHeader(columns) {
1792
+ function buildLeftPaneHeader(columns, locale) {
1790
1793
  const header = el("div");
1791
1794
  css(header, {
1792
1795
  display: "grid",
@@ -1809,6 +1812,60 @@ function buildLeftPaneHeader(columns) {
1809
1812
  display: "flex",
1810
1813
  alignItems: "flex-end"
1811
1814
  });
1815
+ if (i === 0 && visible[0]?.id === "name") {
1816
+ const btnContainer = el("div");
1817
+ btnContainer.className = "gantt-header-tree-controls";
1818
+ css(btnContainer, {
1819
+ display: "flex",
1820
+ gap: "4px",
1821
+ marginRight: "6px",
1822
+ paddingBottom: "1px"
1823
+ });
1824
+ const expandBtn = el("button");
1825
+ expandBtn.className = "gantt-header-expand-btn";
1826
+ expandBtn.textContent = "+";
1827
+ expandBtn.title = locale.labels?.expandAllTitle ?? EN_US_LABELS.expandAllTitle;
1828
+ expandBtn.setAttribute("aria-label", expandBtn.title);
1829
+ css(expandBtn, {
1830
+ width: "18px",
1831
+ height: "18px",
1832
+ display: "flex",
1833
+ alignItems: "center",
1834
+ justifyContent: "center",
1835
+ background: "var(--gantt-header-bg)",
1836
+ border: "1px solid var(--gantt-border)",
1837
+ borderRadius: "3px",
1838
+ cursor: "pointer",
1839
+ color: "var(--gantt-text-secondary)",
1840
+ fontSize: "14px",
1841
+ fontWeight: "var(--gantt-font-weight-bold)",
1842
+ lineHeight: "1",
1843
+ padding: "0"
1844
+ });
1845
+ const collapseBtn = el("button");
1846
+ collapseBtn.className = "gantt-header-collapse-btn";
1847
+ collapseBtn.textContent = "−";
1848
+ collapseBtn.title = locale.labels?.collapseAllTitle ?? EN_US_LABELS.collapseAllTitle;
1849
+ collapseBtn.setAttribute("aria-label", collapseBtn.title);
1850
+ css(collapseBtn, {
1851
+ width: "18px",
1852
+ height: "18px",
1853
+ display: "flex",
1854
+ alignItems: "center",
1855
+ justifyContent: "center",
1856
+ background: "var(--gantt-header-bg)",
1857
+ border: "1px solid var(--gantt-border)",
1858
+ borderRadius: "3px",
1859
+ cursor: "pointer",
1860
+ color: "var(--gantt-text-secondary)",
1861
+ fontSize: "14px",
1862
+ fontWeight: "var(--gantt-font-weight-bold)",
1863
+ lineHeight: "1",
1864
+ padding: "0"
1865
+ });
1866
+ btnContainer.append(expandBtn, collapseBtn);
1867
+ wrapper.append(btnContainer);
1868
+ }
1812
1869
  const cell = el("span");
1813
1870
  css(cell, {
1814
1871
  fontSize: "var(--gantt-font-size-xs)",
@@ -3287,6 +3344,7 @@ var GanttChart = class {
3287
3344
  */
3288
3345
  collapseAll() {
3289
3346
  this.#assertAlive();
3347
+ const changed = this.#buildExpandCollapseAllPayload(false);
3290
3348
  this.#expandedIds.clear();
3291
3349
  if (this.#rafPending && this.#rafId !== null) {
3292
3350
  cancelAnimationFrame(this.#rafId);
@@ -3294,6 +3352,10 @@ var GanttChart = class {
3294
3352
  this.#rafPending = false;
3295
3353
  }
3296
3354
  this.#render();
3355
+ if (changed.length > 0) this.#callbacks.onExpandCollapseAll?.({
3356
+ tasks: changed,
3357
+ instance: this
3358
+ });
3297
3359
  }
3298
3360
  /**
3299
3361
  * Expands all expandable groups in the task tree.
@@ -3302,6 +3364,7 @@ var GanttChart = class {
3302
3364
  */
3303
3365
  expandAll() {
3304
3366
  this.#assertAlive();
3367
+ const changed = this.#buildExpandCollapseAllPayload(true);
3305
3368
  this.#expandedIds.clear();
3306
3369
  if (this.#input !== null) for (const id of getExpandableTaskIds(this.#input.tasks)) this.#expandedIds.add(id);
3307
3370
  if (this.#rafPending && this.#rafId !== null) {
@@ -3310,6 +3373,23 @@ var GanttChart = class {
3310
3373
  this.#rafPending = false;
3311
3374
  }
3312
3375
  this.#render();
3376
+ if (changed.length > 0) this.#callbacks.onExpandCollapseAll?.({
3377
+ tasks: changed,
3378
+ instance: this
3379
+ });
3380
+ }
3381
+ #buildExpandCollapseAllPayload(open) {
3382
+ if (this.#input === null) return [];
3383
+ const expandableIds = getExpandableTaskIds(this.#input.tasks);
3384
+ const changed = [];
3385
+ for (const id of expandableIds) if (this.#expandedIds.has(id) !== open) {
3386
+ const task = this.#findTask(id);
3387
+ if (task !== void 0) changed.push(task.kind === "project" ? {
3388
+ ...task,
3389
+ open
3390
+ } : { ...task });
3391
+ }
3392
+ return changed;
3313
3393
  }
3314
3394
  /**
3315
3395
  * Removes the chart DOM and internal listeners, rendering the instance
@@ -3446,8 +3526,20 @@ var GanttChart = class {
3446
3526
  #renderGridInternal(state) {
3447
3527
  renderLeftPane(this.#leftBody, state, {
3448
3528
  onToggle: (id) => {
3449
- if (this.#expandedIds.has(id)) this.#expandedIds.delete(id);
3450
- else this.#expandedIds.add(id);
3529
+ const expanded = !this.#expandedIds.has(id);
3530
+ if (expanded) this.#expandedIds.add(id);
3531
+ else this.#expandedIds.delete(id);
3532
+ const task = this.#findTask(id);
3533
+ if (task !== void 0) {
3534
+ const payload = task.kind === "project" ? {
3535
+ ...task,
3536
+ open: expanded
3537
+ } : { ...task };
3538
+ this.#callbacks.onExpandCollapse?.({
3539
+ task: payload,
3540
+ instance: this
3541
+ });
3542
+ }
3451
3543
  this.#scheduleRender();
3452
3544
  },
3453
3545
  onTaskClick: (id) => this.#cbs.onTaskClick?.(id),
@@ -3469,12 +3561,25 @@ var GanttChart = class {
3469
3561
  #rebuildLeftPaneHeader() {
3470
3562
  this.#columnResizeCleanup();
3471
3563
  clearChildren(this.#leftHeader);
3472
- const headerEl = buildLeftPaneHeader(this.#columns);
3564
+ const headerEl = buildLeftPaneHeader(this.#columns, this.#locale);
3565
+ this.#wireHeaderTreeControls(headerEl);
3473
3566
  this.#leftHeader.append(headerEl);
3474
3567
  this.#columnResizeCleanup = setupColumnResize(headerEl, this.#leftBody, this.#columns, (updated) => {
3475
3568
  this.#cbs.onGridColumnsChange?.(updated);
3476
3569
  });
3477
3570
  }
3571
+ #wireHeaderTreeControls(headerEl) {
3572
+ const expandBtn = headerEl.querySelector(".gantt-header-expand-btn");
3573
+ const collapseBtn = headerEl.querySelector(".gantt-header-collapse-btn");
3574
+ if (expandBtn !== null) expandBtn.addEventListener("click", (e) => {
3575
+ e.stopPropagation();
3576
+ this.expandAll();
3577
+ });
3578
+ if (collapseBtn !== null) collapseBtn.addEventListener("click", (e) => {
3579
+ e.stopPropagation();
3580
+ this.collapseAll();
3581
+ });
3582
+ }
3478
3583
  #scheduleRender() {
3479
3584
  if (this.#rafPending || this.#destroyed) return;
3480
3585
  this.#rafPending = true;
@@ -3527,7 +3632,8 @@ var GanttChart = class {
3527
3632
  zIndex: "11",
3528
3633
  background: "var(--gantt-header-bg)"
3529
3634
  });
3530
- const headerEl = buildLeftPaneHeader(this.#columns);
3635
+ const headerEl = buildLeftPaneHeader(this.#columns, this.#locale);
3636
+ this.#wireHeaderTreeControls(headerEl);
3531
3637
  leftHeader.append(headerEl);
3532
3638
  leftPane.append(leftHeader);
3533
3639
  this.#leftHeader = leftHeader;