gantt-lib 0.102.0 → 0.104.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.mjs CHANGED
@@ -577,13 +577,13 @@ function computeParentProgress(parentId, tasks) {
577
577
  if (children.length === 0) {
578
578
  return 0;
579
579
  }
580
- const DAY_MS4 = 24 * 60 * 60 * 1e3;
580
+ const DAY_MS5 = 24 * 60 * 60 * 1e3;
581
581
  let totalWeight = 0;
582
582
  let weightedSum = 0;
583
583
  for (const child of children) {
584
584
  const start = new Date(child.startDate).getTime();
585
585
  const end = new Date(child.endDate).getTime();
586
- const duration = (end - start + DAY_MS4) / DAY_MS4;
586
+ const duration = (end - start + DAY_MS5) / DAY_MS5;
587
587
  const progress = child.progress ?? 0;
588
588
  totalWeight += duration;
589
589
  weightedSum += duration * progress;
@@ -677,10 +677,10 @@ function buildTaskRangeFromStart(startDate, duration, businessDays = false, week
677
677
  end: parseDateOnly(addBusinessDays(normalizedStart, duration, weekendPredicate))
678
678
  };
679
679
  }
680
- const DAY_MS4 = 24 * 60 * 60 * 1e3;
680
+ const DAY_MS5 = 24 * 60 * 60 * 1e3;
681
681
  return {
682
682
  start: normalizedStart,
683
- end: new Date(normalizedStart.getTime() + (Math.max(1, duration) - 1) * DAY_MS4)
683
+ end: new Date(normalizedStart.getTime() + (Math.max(1, duration) - 1) * DAY_MS5)
684
684
  };
685
685
  }
686
686
  function buildTaskRangeFromEnd(endDate, duration, businessDays = false, weekendPredicate, snapDirection = -1) {
@@ -691,9 +691,9 @@ function buildTaskRangeFromEnd(endDate, duration, businessDays = false, weekendP
691
691
  end: normalizedEnd
692
692
  };
693
693
  }
694
- const DAY_MS4 = 24 * 60 * 60 * 1e3;
694
+ const DAY_MS5 = 24 * 60 * 60 * 1e3;
695
695
  return {
696
- start: new Date(normalizedEnd.getTime() - (Math.max(1, duration) - 1) * DAY_MS4),
696
+ start: new Date(normalizedEnd.getTime() - (Math.max(1, duration) - 1) * DAY_MS5),
697
697
  end: normalizedEnd
698
698
  };
699
699
  }
@@ -4741,6 +4741,30 @@ var TaskListRow = React9.memo(
4741
4741
  const editingName = editingColumnId === "name";
4742
4742
  const editingDuration = editingColumnId === "duration";
4743
4743
  const editingProgress = editingColumnId === "progress";
4744
+ const columnWidthStyleMap = useMemo7(() => {
4745
+ return new Map(
4746
+ (resolvedColumns ?? []).map((column) => {
4747
+ const width = column.width ?? 120;
4748
+ return [
4749
+ column.id,
4750
+ {
4751
+ width,
4752
+ minWidth: width,
4753
+ maxWidth: width,
4754
+ flex: `0 0 ${width}px`
4755
+ }
4756
+ ];
4757
+ })
4758
+ );
4759
+ }, [resolvedColumns]);
4760
+ const getColumnStyle = useCallback4((columnId, fallbackWidth) => {
4761
+ return columnWidthStyleMap.get(columnId) ?? {
4762
+ width: fallbackWidth,
4763
+ minWidth: fallbackWidth,
4764
+ maxWidth: fallbackWidth,
4765
+ flex: `0 0 ${fallbackWidth}px`
4766
+ };
4767
+ }, [columnWidthStyleMap]);
4744
4768
  const normalizedTask = useMemo7(() => normalizeTaskDatesForType(task), [task]);
4745
4769
  const isMilestone = useMemo7(() => isMilestoneTask(normalizedTask), [normalizedTask]);
4746
4770
  const [nameValue, setNameValue] = useState4("");
@@ -5538,6 +5562,7 @@ var TaskListRow = React9.memo(
5538
5562
  "div",
5539
5563
  {
5540
5564
  className: "gantt-tl-cell gantt-tl-cell-selection",
5565
+ style: getColumnStyle("selection", 36),
5541
5566
  onClick: (e) => e.stopPropagation(),
5542
5567
  children: /* @__PURE__ */ jsx12(
5543
5568
  "input",
@@ -5555,6 +5580,7 @@ var TaskListRow = React9.memo(
5555
5580
  "div",
5556
5581
  {
5557
5582
  className: "gantt-tl-cell gantt-tl-cell-number",
5583
+ style: getColumnStyle("number", 40),
5558
5584
  onClick: handleNumberClick,
5559
5585
  children: [
5560
5586
  onDragStart && /* @__PURE__ */ jsx12(
@@ -5577,7 +5603,7 @@ var TaskListRow = React9.memo(
5577
5603
  );
5578
5604
  const nameTriggerPaddingLeft = isParent ? `${nestingDepth * 20 + 28}px` : nestingDepth > 0 ? `${nestingDepth * 20 + 8}px` : void 0;
5579
5605
  const nameInputPaddingLeft = nestingDepth > 0 ? `${nestingDepth * 20 + 8}px` : void 0;
5580
- const nameCell = /* @__PURE__ */ jsxs9("div", { className: "gantt-tl-cell gantt-tl-cell-name", children: [
5606
+ const nameCell = /* @__PURE__ */ jsxs9("div", { className: "gantt-tl-cell gantt-tl-cell-name", style: getColumnStyle("name", 200), children: [
5581
5607
  isChild && !editingName && /* @__PURE__ */ jsxs9(Fragment2, { children: [
5582
5608
  !isFilterHideMode && /* @__PURE__ */ jsxs9(Fragment2, { children: [
5583
5609
  ancestorLineModes.map(
@@ -5939,6 +5965,7 @@ var TaskListRow = React9.memo(
5939
5965
  "div",
5940
5966
  {
5941
5967
  className: "gantt-tl-cell gantt-tl-cell-date",
5968
+ style: getColumnStyle("startDate", 90),
5942
5969
  onClick: (e) => e.stopPropagation(),
5943
5970
  children: /* @__PURE__ */ jsx12(
5944
5971
  DatePicker,
@@ -5959,6 +5986,7 @@ var TaskListRow = React9.memo(
5959
5986
  "div",
5960
5987
  {
5961
5988
  className: "gantt-tl-cell gantt-tl-cell-date",
5989
+ style: getColumnStyle("endDate", 90),
5962
5990
  onClick: (e) => e.stopPropagation(),
5963
5991
  children: /* @__PURE__ */ jsx12(
5964
5992
  DatePicker,
@@ -5979,6 +6007,7 @@ var TaskListRow = React9.memo(
5979
6007
  "div",
5980
6008
  {
5981
6009
  className: "gantt-tl-cell gantt-tl-cell-duration",
6010
+ style: getColumnStyle("duration", 60),
5982
6011
  onClick: handleDurationClick,
5983
6012
  children: [
5984
6013
  editingDuration && /* @__PURE__ */ jsxs9(
@@ -6070,6 +6099,7 @@ var TaskListRow = React9.memo(
6070
6099
  "div",
6071
6100
  {
6072
6101
  className: "gantt-tl-cell gantt-tl-cell-progress",
6102
+ style: getColumnStyle("progress", 50),
6073
6103
  onClick: handleProgressClick,
6074
6104
  children: [
6075
6105
  editingProgress && /* @__PURE__ */ jsxs9(
@@ -6167,6 +6197,7 @@ var TaskListRow = React9.memo(
6167
6197
  "div",
6168
6198
  {
6169
6199
  className: "gantt-tl-cell gantt-tl-cell-deps",
6200
+ style: getColumnStyle("dependencies", 128),
6170
6201
  onClick: isSourceRow ? handleSourceCellClick : isPicking ? handlePredecessorPick : void 0,
6171
6202
  children: isSourceRow ? /* @__PURE__ */ jsxs9(Fragment2, { children: [
6172
6203
  /* @__PURE__ */ jsx12(
@@ -6633,6 +6664,18 @@ function resolveTaskListColumns(builtIn, custom, hiddenColumnIds = []) {
6633
6664
  import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
6634
6665
  var LINK_TYPE_ORDER2 = ["FS", "SS", "FF", "SF"];
6635
6666
  var MIN_TASK_LIST_WIDTH = 530;
6667
+ var DEFAULT_COLUMN_MIN_WIDTH = 40;
6668
+ var BUILT_IN_COLUMN_MIN_WIDTHS = {
6669
+ selection: 36,
6670
+ number: 40,
6671
+ name: 160,
6672
+ startDate: 68,
6673
+ endDate: 68,
6674
+ duration: 60,
6675
+ progress: 50,
6676
+ dependencies: 128,
6677
+ actions: 56
6678
+ };
6636
6679
  var BUILT_IN_CSS_CLASSES = {
6637
6680
  selection: "gantt-tl-cell-selection",
6638
6681
  number: "gantt-tl-cell-number",
@@ -6710,6 +6753,24 @@ function getTaskNumber(tasks, taskIndex) {
6710
6753
  }
6711
6754
  return `${parentNumber}.${siblingIndex + 1}`;
6712
6755
  }
6756
+ function normalizeColumnWidthMap(widths) {
6757
+ if (!widths) {
6758
+ return {};
6759
+ }
6760
+ return Object.entries(widths).reduce((acc, [columnId, width]) => {
6761
+ if (typeof width !== "number" || !Number.isFinite(width) || width <= 0) {
6762
+ return acc;
6763
+ }
6764
+ acc[columnId] = Math.round(width);
6765
+ return acc;
6766
+ }, {});
6767
+ }
6768
+ function getColumnMinWidth(column) {
6769
+ return Math.max(
6770
+ typeof column.minWidth === "number" && Number.isFinite(column.minWidth) ? column.minWidth : 0,
6771
+ BUILT_IN_COLUMN_MIN_WIDTHS[column.id] ?? DEFAULT_COLUMN_MIN_WIDTH
6772
+ );
6773
+ }
6713
6774
  var SelectAllCheckbox = ({
6714
6775
  checked,
6715
6776
  indeterminate,
@@ -6773,6 +6834,8 @@ var TaskList = ({
6773
6834
  isFilterActive = false,
6774
6835
  additionalColumns,
6775
6836
  hiddenTaskListColumns,
6837
+ taskListColumnWidths,
6838
+ onTaskListColumnWidthsChange,
6776
6839
  taskListMenuCommands,
6777
6840
  hideTaskListRowActions = false,
6778
6841
  rowContentLines = 1,
@@ -6782,6 +6845,8 @@ var TaskList = ({
6782
6845
  }) => {
6783
6846
  const [internalSelectedTaskIds, setInternalSelectedTaskIds] = useState6(/* @__PURE__ */ new Set());
6784
6847
  const [activeCustomCell, setActiveCustomCell] = useState6(null);
6848
+ const [columnWidthOverrides, setColumnWidthOverrides] = useState6(() => normalizeColumnWidthMap(taskListColumnWidths));
6849
+ const resizeStateRef = useRef6(null);
6785
6850
  const effectiveSelectedTaskIds = selectedTaskIds ?? internalSelectedTaskIds;
6786
6851
  const emitSelectedTaskIdsChange = useCallback5((nextSelectedTaskIds) => {
6787
6852
  if (!selectedTaskIds) {
@@ -7354,13 +7419,24 @@ var TaskList = ({
7354
7419
  () => createBuiltInColumns({ businessDays, enableTaskMultiSelect }),
7355
7420
  [businessDays, enableTaskMultiSelect]
7356
7421
  );
7422
+ useEffect6(() => {
7423
+ setColumnWidthOverrides(normalizeColumnWidthMap(taskListColumnWidths));
7424
+ }, [taskListColumnWidths]);
7357
7425
  const resolvedColumns = useMemo8(
7358
7426
  () => resolveTaskListColumns(
7359
7427
  builtInColumns,
7360
7428
  additionalColumns ?? [],
7361
7429
  hiddenTaskListColumns
7362
- ),
7363
- [builtInColumns, additionalColumns, hiddenTaskListColumns]
7430
+ ).map((column) => {
7431
+ const configuredWidth = columnWidthOverrides[column.id];
7432
+ const baseWidth = configuredWidth ?? column.width ?? 120;
7433
+ const width = Math.max(getColumnMinWidth(column), baseWidth);
7434
+ return {
7435
+ ...column,
7436
+ width
7437
+ };
7438
+ }),
7439
+ [builtInColumns, additionalColumns, hiddenTaskListColumns, columnWidthOverrides]
7364
7440
  );
7365
7441
  const resolvedColumnWidthTotal = useMemo8(
7366
7442
  () => resolvedColumns.reduce((sum, col) => sum + (col.width ?? 120), 0),
@@ -7369,6 +7445,78 @@ var TaskList = ({
7369
7445
  const requestedTaskListWidth = taskListWidth ?? Math.min(MIN_TASK_LIST_WIDTH, resolvedColumnWidthTotal);
7370
7446
  const effectiveTaskListWidth = Math.max(requestedTaskListWidth, resolvedColumnWidthTotal);
7371
7447
  const tableHeaderHeight = headerHeight + 1;
7448
+ const updateColumnWidth = useCallback5((columnId, width) => {
7449
+ setColumnWidthOverrides((prev) => {
7450
+ if (prev[columnId] === width) {
7451
+ return prev;
7452
+ }
7453
+ const next = { ...prev, [columnId]: width };
7454
+ onTaskListColumnWidthsChange?.(next);
7455
+ return next;
7456
+ });
7457
+ }, [onTaskListColumnWidthsChange]);
7458
+ useEffect6(() => {
7459
+ const handleMouseMove = (event) => {
7460
+ const resizeState = resizeStateRef.current;
7461
+ if (!resizeState) {
7462
+ return;
7463
+ }
7464
+ const column = resolvedColumns.find((item) => item.id === resizeState.columnId);
7465
+ if (!column) {
7466
+ return;
7467
+ }
7468
+ const nextWidth = Math.max(
7469
+ getColumnMinWidth(column),
7470
+ Math.round(resizeState.startWidth + event.clientX - resizeState.startX)
7471
+ );
7472
+ updateColumnWidth(column.id, nextWidth);
7473
+ };
7474
+ const handleMouseUp = () => {
7475
+ if (!resizeStateRef.current) {
7476
+ return;
7477
+ }
7478
+ resizeStateRef.current = null;
7479
+ document.body.style.removeProperty("cursor");
7480
+ document.body.style.removeProperty("user-select");
7481
+ };
7482
+ window.addEventListener("mousemove", handleMouseMove);
7483
+ window.addEventListener("mouseup", handleMouseUp);
7484
+ return () => {
7485
+ window.removeEventListener("mousemove", handleMouseMove);
7486
+ window.removeEventListener("mouseup", handleMouseUp);
7487
+ document.body.style.removeProperty("cursor");
7488
+ document.body.style.removeProperty("user-select");
7489
+ };
7490
+ }, [resolvedColumns, updateColumnWidth]);
7491
+ const startColumnResize = useCallback5((columnId, event) => {
7492
+ const column = resolvedColumns.find((item) => item.id === columnId);
7493
+ if (!column) {
7494
+ return;
7495
+ }
7496
+ event.preventDefault();
7497
+ event.stopPropagation();
7498
+ resizeStateRef.current = {
7499
+ columnId,
7500
+ startX: event.clientX,
7501
+ startWidth: column.width ?? 120
7502
+ };
7503
+ document.body.style.cursor = "col-resize";
7504
+ document.body.style.userSelect = "none";
7505
+ }, [resolvedColumns]);
7506
+ const renderResizeHandle = useCallback5((columnId) => /* @__PURE__ */ jsx14(
7507
+ "button",
7508
+ {
7509
+ type: "button",
7510
+ className: "gantt-tl-column-resize-handle",
7511
+ "data-testid": `tasklist-resize-handle-${columnId}`,
7512
+ "aria-label": `Resize ${columnId} column`,
7513
+ onMouseDown: (event) => startColumnResize(columnId, event),
7514
+ onClick: (event) => {
7515
+ event.preventDefault();
7516
+ event.stopPropagation();
7517
+ }
7518
+ }
7519
+ ), [startColumnResize]);
7372
7520
  return /* @__PURE__ */ jsx14(
7373
7521
  "div",
7374
7522
  {
@@ -7381,19 +7529,23 @@ var TaskList = ({
7381
7529
  children: /* @__PURE__ */ jsxs11("div", { className: "gantt-tl-table", children: [
7382
7530
  /* @__PURE__ */ jsx14("div", { className: "gantt-tl-header", style: { height: `${tableHeaderHeight}px` }, children: resolvedColumns.map((col) => {
7383
7531
  if (col.id === "selection") {
7384
- return /* @__PURE__ */ jsx14(
7532
+ return /* @__PURE__ */ jsxs11(
7385
7533
  "div",
7386
7534
  {
7387
7535
  className: "gantt-tl-headerCell gantt-tl-cell-selection",
7388
7536
  "data-column-id": "selection",
7389
- children: /* @__PURE__ */ jsx14(
7390
- SelectAllCheckbox,
7391
- {
7392
- checked: areAllVisibleTasksSelected,
7393
- indeterminate: areSomeVisibleTasksSelected,
7394
- onChange: handleToggleAllVisibleTaskSelection
7395
- }
7396
- )
7537
+ style: { width: col.width, minWidth: col.width, maxWidth: col.width, flex: `0 0 ${col.width}px`, position: "relative" },
7538
+ children: [
7539
+ /* @__PURE__ */ jsx14(
7540
+ SelectAllCheckbox,
7541
+ {
7542
+ checked: areAllVisibleTasksSelected,
7543
+ indeterminate: areSomeVisibleTasksSelected,
7544
+ onChange: handleToggleAllVisibleTaskSelection
7545
+ }
7546
+ ),
7547
+ renderResizeHandle(col.id)
7548
+ ]
7397
7549
  },
7398
7550
  col.id
7399
7551
  );
@@ -7404,7 +7556,7 @@ var TaskList = ({
7404
7556
  {
7405
7557
  className: "gantt-tl-headerCell gantt-tl-cell-deps",
7406
7558
  "data-column-id": "dependencies",
7407
- style: { position: "relative" },
7559
+ style: { width: col.width, minWidth: col.width, maxWidth: col.width, flex: `0 0 ${col.width}px`, position: "relative" },
7408
7560
  children: [
7409
7561
  /* @__PURE__ */ jsxs11(Popover, { open: typeMenuOpen, onOpenChange: setTypeMenuOpen, children: [
7410
7562
  /* @__PURE__ */ jsx14(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs11(
@@ -7436,7 +7588,8 @@ var TaskList = ({
7436
7588
  lt
7437
7589
  )) }) })
7438
7590
  ] }),
7439
- dependencyError && /* @__PURE__ */ jsx14("div", { className: "gantt-tl-dep-error", children: dependencyError })
7591
+ dependencyError && /* @__PURE__ */ jsx14("div", { className: "gantt-tl-dep-error", children: dependencyError }),
7592
+ renderResizeHandle(col.id)
7440
7593
  ]
7441
7594
  },
7442
7595
  col.id
@@ -7444,24 +7597,31 @@ var TaskList = ({
7444
7597
  }
7445
7598
  const builtInClass = BUILT_IN_CSS_CLASSES[col.id];
7446
7599
  if (builtInClass !== void 0) {
7447
- return /* @__PURE__ */ jsx14(
7600
+ return /* @__PURE__ */ jsxs11(
7448
7601
  "div",
7449
7602
  {
7450
7603
  className: `gantt-tl-headerCell ${builtInClass}`,
7451
7604
  "data-column-id": col.id,
7452
- children: col.header
7605
+ style: { width: col.width, minWidth: col.width, maxWidth: col.width, flex: `0 0 ${col.width}px`, position: "relative" },
7606
+ children: [
7607
+ col.header,
7608
+ renderResizeHandle(col.id)
7609
+ ]
7453
7610
  },
7454
7611
  col.id
7455
7612
  );
7456
7613
  }
7457
- return /* @__PURE__ */ jsx14(
7614
+ return /* @__PURE__ */ jsxs11(
7458
7615
  "div",
7459
7616
  {
7460
7617
  className: `gantt-tl-headerCell gantt-tl-headerCell-custom gantt-tl-cell-align-${col.align ?? "left"}`,
7461
7618
  "data-column-id": `custom:${col.id}`,
7462
7619
  "data-custom-column-id": col.id,
7463
- style: { width: col.width, minWidth: col.width, flexShrink: 0 },
7464
- children: col.header
7620
+ style: { width: col.width, minWidth: col.width, maxWidth: col.width, flex: `0 0 ${col.width}px`, position: "relative" },
7621
+ children: [
7622
+ col.header,
7623
+ renderResizeHandle(col.id)
7624
+ ]
7465
7625
  },
7466
7626
  col.id
7467
7627
  );
@@ -9282,6 +9442,7 @@ import { useLayoutEffect, useMemo as useMemo10, useRef as useRef9, useState as u
9282
9442
  import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
9283
9443
  var AUTO_COLUMN_MIN_WIDTH = 72;
9284
9444
  var AUTO_COLUMN_MAX_WIDTH = 180;
9445
+ var DAY_MS4 = 24 * 60 * 60 * 1e3;
9285
9446
  function joinClasses(...values) {
9286
9447
  return values.filter(Boolean).join(" ");
9287
9448
  }
@@ -9294,6 +9455,40 @@ function getAutoMinWidth(column) {
9294
9455
  function getAutoMaxWidth(column) {
9295
9456
  return column.maxWidth ?? AUTO_COLUMN_MAX_WIDTH;
9296
9457
  }
9458
+ function parseDateOnlyMs(value) {
9459
+ if (value instanceof Date) {
9460
+ return Date.UTC(value.getFullYear(), value.getMonth(), value.getDate());
9461
+ }
9462
+ const [year, month, day] = value.split("T")[0].split("-").map(Number);
9463
+ if (!year || !month || !day) {
9464
+ return Number.NaN;
9465
+ }
9466
+ return Date.UTC(year, month - 1, day);
9467
+ }
9468
+ function getOverlayWidthPercent(column, overlayDateMs) {
9469
+ if (overlayDateMs === null || column.periodStartDate === void 0 || column.periodEndDate === void 0) {
9470
+ return 0;
9471
+ }
9472
+ const startMs = parseDateOnlyMs(column.periodStartDate);
9473
+ const endMs = parseDateOnlyMs(column.periodEndDate);
9474
+ if (!Number.isFinite(startMs) || !Number.isFinite(endMs) || endMs < startMs || overlayDateMs < startMs) {
9475
+ return 0;
9476
+ }
9477
+ if (overlayDateMs >= endMs) {
9478
+ return 100;
9479
+ }
9480
+ const totalDays = Math.max(1, Math.round((endMs - startMs) / DAY_MS4) + 1);
9481
+ const elapsedDays = Math.min(totalDays, Math.max(0, Math.round((overlayDateMs - startMs) / DAY_MS4) + 1));
9482
+ return elapsedDays / totalDays * 100;
9483
+ }
9484
+ function isOverlayDateInColumn(column, overlayDateMs) {
9485
+ if (overlayDateMs === null || column.periodStartDate === void 0 || column.periodEndDate === void 0) {
9486
+ return false;
9487
+ }
9488
+ const startMs = parseDateOnlyMs(column.periodStartDate);
9489
+ const endMs = parseDateOnlyMs(column.periodEndDate);
9490
+ return Number.isFinite(startMs) && Number.isFinite(endMs) && startMs <= overlayDateMs && overlayDateMs <= endMs;
9491
+ }
9297
9492
  function TableMatrix({
9298
9493
  tasks,
9299
9494
  allTasks = tasks,
@@ -9305,6 +9500,7 @@ function TableMatrix({
9305
9500
  selectedTaskId,
9306
9501
  onTaskSelect,
9307
9502
  onCellClick,
9503
+ dateOverlay,
9308
9504
  highlightedTaskIds,
9309
9505
  filterMode = "highlight"
9310
9506
  }) {
@@ -9358,6 +9554,10 @@ function TableMatrix({
9358
9554
  () => resolvedColumnWidths.reduce((sum, width) => sum + width, 0),
9359
9555
  [resolvedColumnWidths]
9360
9556
  );
9557
+ const overlayDateMs = useMemo10(
9558
+ () => dateOverlay ? parseDateOnlyMs(dateOverlay.date) : null,
9559
+ [dateOverlay]
9560
+ );
9361
9561
  const hasGroupHeader = useMemo10(
9362
9562
  () => columns.some((column) => !!column.groupId) || (columnGroups?.length ?? 0) > 0,
9363
9563
  [columnGroups, columns]
@@ -9368,7 +9568,7 @@ function TableMatrix({
9368
9568
  );
9369
9569
  const headerSpans = useMemo10(() => {
9370
9570
  if (!hasGroupHeader) return [];
9371
- if (!hasAutoWidthColumns && columnGroups?.some((group) => typeof group.width === "number")) {
9571
+ if (columnGroups?.some((group) => typeof group.width === "number")) {
9372
9572
  return columnGroups.map((group) => ({
9373
9573
  id: group.id,
9374
9574
  header: group.header,
@@ -9456,14 +9656,14 @@ function TableMatrix({
9456
9656
  {
9457
9657
  className: "gantt-mx-headerRow gantt-mx-headerGroupRow",
9458
9658
  style: {
9459
- gridTemplateColumns: hasAutoWidthColumns ? gridTemplateColumns : headerSpans.map((span) => `${span.width ?? 0}px`).join(" "),
9659
+ gridTemplateColumns: headerSpans.map((span) => `${span.width ?? 0}px`).join(" "),
9460
9660
  height: `${topRowHeight}px`
9461
9661
  },
9462
9662
  children: headerSpans.map((span) => /* @__PURE__ */ jsx16(
9463
9663
  "div",
9464
9664
  {
9465
9665
  className: joinClasses("gantt-mx-groupCell", span.className),
9466
- style: hasAutoWidthColumns ? { gridColumn: `span ${span.columnSpan ?? 1}` } : void 0,
9666
+ style: span.columnSpan !== void 0 ? { gridColumn: `span ${span.columnSpan}` } : void 0,
9467
9667
  children: span.header
9468
9668
  },
9469
9669
  span.id
@@ -9475,18 +9675,34 @@ function TableMatrix({
9475
9675
  {
9476
9676
  className: "gantt-mx-headerRow",
9477
9677
  style: { gridTemplateColumns, height: `${hasGroupHeader ? bottomRowHeight : topRowHeight}px` },
9478
- children: columns.map((column) => /* @__PURE__ */ jsx16(
9479
- "div",
9480
- {
9481
- className: joinClasses(
9482
- "gantt-mx-headerCell",
9483
- column.headerClassName
9484
- ),
9485
- style: column.minWidth !== void 0 ? { minWidth: `${column.minWidth}px` } : void 0,
9486
- children: column.header
9487
- },
9488
- column.id
9489
- ))
9678
+ children: columns.map((column) => {
9679
+ const overlayWidthPercent = getOverlayWidthPercent(column, overlayDateMs);
9680
+ const shouldRenderOverlayEdge = isOverlayDateInColumn(column, overlayDateMs);
9681
+ return /* @__PURE__ */ jsxs13(
9682
+ "div",
9683
+ {
9684
+ className: joinClasses(
9685
+ "gantt-mx-headerCell",
9686
+ column.headerClassName
9687
+ ),
9688
+ style: column.minWidth !== void 0 ? { minWidth: `${column.minWidth}px` } : void 0,
9689
+ children: [
9690
+ shouldRenderOverlayEdge && /* @__PURE__ */ jsx16(
9691
+ "span",
9692
+ {
9693
+ className: "gantt-mx-dateOverlayEdge",
9694
+ style: {
9695
+ left: `${overlayWidthPercent}%`,
9696
+ background: dateOverlay && dateOverlay.edgeColor ? dateOverlay.edgeColor : void 0
9697
+ }
9698
+ }
9699
+ ),
9700
+ /* @__PURE__ */ jsx16("span", { className: "gantt-mx-headerContent", children: column.header })
9701
+ ]
9702
+ },
9703
+ column.id
9704
+ );
9705
+ })
9490
9706
  }
9491
9707
  )
9492
9708
  ] }),
@@ -9526,7 +9742,10 @@ function TableMatrix({
9526
9742
  onClick: () => onTaskSelect?.(task.id),
9527
9743
  children: columns.map((column, columnIndex) => {
9528
9744
  const resolvedCellClassName = typeof column.cellClassName === "function" ? column.cellClassName(task) : column.cellClassName;
9529
- return /* @__PURE__ */ jsx16(
9745
+ const overlayWidthPercent = getOverlayWidthPercent(column, overlayDateMs);
9746
+ const shouldRenderOverlay = overlayWidthPercent > 0 && (!dateOverlay || !dateOverlay.shouldRender || dateOverlay.shouldRender({ task, column, rowIndex: index, columnIndex }));
9747
+ const shouldRenderOverlayEdge = isOverlayDateInColumn(column, overlayDateMs);
9748
+ return /* @__PURE__ */ jsxs13(
9530
9749
  "div",
9531
9750
  {
9532
9751
  className: joinClasses(
@@ -9540,7 +9759,29 @@ function TableMatrix({
9540
9759
  onClick: (event) => {
9541
9760
  onCellClick?.({ task, column, rowIndex: index, columnIndex, event });
9542
9761
  },
9543
- children: column.renderCell(task)
9762
+ children: [
9763
+ shouldRenderOverlay && /* @__PURE__ */ jsx16(
9764
+ "span",
9765
+ {
9766
+ className: joinClasses("gantt-mx-dateOverlay", dateOverlay && dateOverlay.className),
9767
+ style: {
9768
+ width: `${overlayWidthPercent}%`,
9769
+ background: dateOverlay && dateOverlay.color ? dateOverlay.color : void 0
9770
+ }
9771
+ }
9772
+ ),
9773
+ shouldRenderOverlayEdge && /* @__PURE__ */ jsx16(
9774
+ "span",
9775
+ {
9776
+ className: "gantt-mx-dateOverlayEdge",
9777
+ style: {
9778
+ left: `${overlayWidthPercent}%`,
9779
+ background: dateOverlay && dateOverlay.edgeColor ? dateOverlay.edgeColor : void 0
9780
+ }
9781
+ }
9782
+ ),
9783
+ /* @__PURE__ */ jsx16("div", { className: "gantt-mx-cellContent", children: column.renderCell(task) })
9784
+ ]
9544
9785
  },
9545
9786
  `${task.id}:${column.id}`
9546
9787
  );
@@ -9945,6 +10186,8 @@ function TaskGanttChartInner(props, ref) {
9945
10186
  showChart = true,
9946
10187
  additionalColumns,
9947
10188
  hiddenTaskListColumns,
10189
+ taskListColumnWidths,
10190
+ onTaskListColumnWidthsChange,
9948
10191
  taskListMenuCommands,
9949
10192
  hideTaskListRowActions = false,
9950
10193
  rowContentLines = 1,
@@ -9959,6 +10202,7 @@ function TaskGanttChartInner(props, ref) {
9959
10202
  const matrixColumns = isTableMatrixMode ? props.matrixColumns : [];
9960
10203
  const matrixColumnGroups = isTableMatrixMode ? props.matrixColumnGroups : void 0;
9961
10204
  const onMatrixCellClick = isTableMatrixMode ? props.onMatrixCellClick : void 0;
10205
+ const matrixDateOverlay = isTableMatrixMode ? props.matrixDateOverlay : void 0;
9962
10206
  const containerRef = useRef10(null);
9963
10207
  const scrollContainerRef = useRef10(null);
9964
10208
  const scrollContentRef = useRef10(null);
@@ -10610,6 +10854,8 @@ function TaskGanttChartInner(props, ref) {
10610
10854
  isFilterActive: !!taskFilter,
10611
10855
  additionalColumns,
10612
10856
  hiddenTaskListColumns,
10857
+ taskListColumnWidths,
10858
+ onTaskListColumnWidthsChange,
10613
10859
  taskListMenuCommands,
10614
10860
  hideTaskListRowActions,
10615
10861
  rowContentLines: resolvedRowContentLines,
@@ -10641,6 +10887,7 @@ function TaskGanttChartInner(props, ref) {
10641
10887
  selectedTaskId,
10642
10888
  onTaskSelect: handleTaskSelect,
10643
10889
  onCellClick: onMatrixCellClick,
10890
+ dateOverlay: matrixDateOverlay,
10644
10891
  highlightedTaskIds: taskListHighlightedTaskIds,
10645
10892
  filterMode
10646
10893
  }