gantt-lib 0.91.0 → 0.101.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.js CHANGED
@@ -45,6 +45,7 @@ __export(index_exports, {
45
45
  PopoverContent: () => PopoverContent,
46
46
  PopoverTrigger: () => PopoverTrigger,
47
47
  ResourceTimelineChart: () => ResourceTimelineChart,
48
+ TableMatrix: () => TableMatrix,
48
49
  TaskList: () => TaskList,
49
50
  TaskRow: () => TaskRow_default,
50
51
  TimeScaleHeader: () => TimeScaleHeader_default,
@@ -142,7 +143,7 @@ __export(index_exports, {
142
143
  module.exports = __toCommonJS(index_exports);
143
144
 
144
145
  // src/components/GanttChart/GanttChart.tsx
145
- var import_react15 = require("react");
146
+ var import_react16 = require("react");
146
147
 
147
148
  // src/core/scheduling/dateMath.ts
148
149
  var DAY_MS = 24 * 60 * 60 * 1e3;
@@ -4844,11 +4845,15 @@ var TaskListRow = import_react10.default.memo(
4844
4845
  resolvedColumns,
4845
4846
  isTaskSelected = false,
4846
4847
  onTaskSelectionChange,
4848
+ activeCustomCell,
4849
+ onActiveCustomCellChange,
4847
4850
  taskListMenuCommands = [],
4851
+ hideTaskListRowActions = false,
4848
4852
  taskDateChangeMode = "preserve-duration",
4849
4853
  onTaskDateChangeModeChange
4850
4854
  }) => {
4851
4855
  const [editingColumnId, setEditingColumnId] = (0, import_react10.useState)(null);
4856
+ const [editingColumnStartValue, setEditingColumnStartValue] = (0, import_react10.useState)(void 0);
4852
4857
  const editingName = editingColumnId === "name";
4853
4858
  const editingDuration = editingColumnId === "duration";
4854
4859
  const editingProgress = editingColumnId === "progress";
@@ -4874,12 +4879,15 @@ var TaskListRow = import_react10.default.memo(
4874
4879
  const editTriggerRef = (0, import_react10.useRef)(
4875
4880
  "doubleclick"
4876
4881
  );
4882
+ const rowRef = (0, import_react10.useRef)(null);
4877
4883
  const isSelected = selectedTaskId === task.id;
4878
4884
  const isParent = (0, import_react10.useMemo)(
4879
4885
  () => isTaskParent(task.id, allTasks),
4880
4886
  [task.id, allTasks]
4881
4887
  );
4882
4888
  const isChild = task.parentId !== void 0;
4889
+ const rowFillLevel = Math.min(nestingDepth, 2);
4890
+ const isTotalRow = Boolean(task.isTotal);
4883
4891
  const isMilestoneRow = normalizedTask.type === "milestone";
4884
4892
  const weekendPredicate = (0, import_react10.useMemo)(
4885
4893
  () => createCustomDayPredicate({ customDays, isWeekend: isWeekend3 }),
@@ -5426,7 +5434,7 @@ var TaskListRow = import_react10.default.memo(
5426
5434
  ),
5427
5435
  [taskListMenuCommands, task, isParent, isMilestoneRow]
5428
5436
  );
5429
- const hasContextMenu = visibleCustomMenuCommands.length > 0 || !!onDuplicateTask || !!onDelete || !!onTasksChange || isParent && !!onUngroupTask;
5437
+ const hasContextMenu = !hideTaskListRowActions && (visibleCustomMenuCommands.length > 0 || !!onDuplicateTask || !!onDelete || !!onTasksChange || isParent && !!onUngroupTask);
5430
5438
  const handleCustomMenuCommandClick = (0, import_react10.useCallback)(
5431
5439
  (command) => (e) => {
5432
5440
  e.stopPropagation();
@@ -5665,14 +5673,14 @@ var TaskListRow = import_react10.default.memo(
5665
5673
  className: "gantt-tl-cell gantt-tl-cell-number",
5666
5674
  onClick: handleNumberClick,
5667
5675
  children: [
5668
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5676
+ onDragStart && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5669
5677
  "span",
5670
5678
  {
5671
5679
  className: "gantt-tl-drag-handle",
5672
5680
  draggable: true,
5673
5681
  onDragStart: (e) => {
5674
5682
  e.stopPropagation();
5675
- onDragStart?.(rowIndex, e);
5683
+ onDragStart(rowIndex, e);
5676
5684
  },
5677
5685
  onDragEnd: (e) => onDragEnd?.(e),
5678
5686
  onClick: (e) => e.stopPropagation(),
@@ -5868,7 +5876,7 @@ var TaskListRow = import_react10.default.memo(
5868
5876
  "aria-hidden": "true"
5869
5877
  }
5870
5878
  ),
5871
- !editingName && (onInsertAfter || onDelete || onPromoteTask || onDemoteTask || onUngroupTask || onDuplicateTask || onTasksChange || hasContextMenu) && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `gantt-tl-name-actions${contextMenuOpen ? " gantt-tl-name-actions-open" : ""}`, children: [
5879
+ !editingName && !hideTaskListRowActions && (onInsertAfter || onDelete || onPromoteTask || onDemoteTask || onUngroupTask || onDuplicateTask || onTasksChange || hasContextMenu) && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `gantt-tl-name-actions${contextMenuOpen ? " gantt-tl-name-actions-open" : ""}`, children: [
5872
5880
  onInsertAfter && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5873
5881
  "button",
5874
5882
  {
@@ -6387,9 +6395,52 @@ var TaskListRow = import_react10.default.memo(
6387
6395
  progress: progressCell,
6388
6396
  dependencies: dependenciesCell
6389
6397
  };
6398
+ const focusCustomCell = (0, import_react10.useCallback)((taskId, columnId) => {
6399
+ const overlay = rowRef.current?.closest(".gantt-tl-overlay");
6400
+ if (!overlay) {
6401
+ return;
6402
+ }
6403
+ const selector = `[data-gantt-task-row-id="${taskId}"] [data-custom-column-id="${columnId}"]`;
6404
+ const nextCell = overlay.querySelector(selector);
6405
+ nextCell?.focus();
6406
+ }, []);
6407
+ const moveActiveCustomCell = (0, import_react10.useCallback)((columnId, direction) => {
6408
+ const overlay = rowRef.current?.closest(".gantt-tl-overlay");
6409
+ if (!overlay || !resolvedColumns) {
6410
+ return;
6411
+ }
6412
+ const customColumnIds = resolvedColumns.filter((column) => !["selection", "number", "name", "startDate", "endDate", "duration", "progress", "dependencies"].includes(column.id)).map((column) => column.id);
6413
+ const columnIndex = customColumnIds.indexOf(columnId);
6414
+ if (columnIndex === -1) {
6415
+ return;
6416
+ }
6417
+ const rowElements = Array.from(
6418
+ overlay.querySelectorAll(".gantt-tl-row[data-gantt-task-row-id]")
6419
+ );
6420
+ const rowIds = rowElements.map((element) => element.dataset.ganttTaskRowId).filter((value) => Boolean(value));
6421
+ const rowIndex2 = rowIds.indexOf(task.id);
6422
+ if (rowIndex2 === -1) {
6423
+ return;
6424
+ }
6425
+ let nextRowIndex = rowIndex2;
6426
+ let nextColumnIndex = columnIndex;
6427
+ if (direction === "left") nextColumnIndex -= 1;
6428
+ if (direction === "right") nextColumnIndex += 1;
6429
+ if (direction === "up") nextRowIndex -= 1;
6430
+ if (direction === "down") nextRowIndex += 1;
6431
+ if (nextRowIndex < 0 || nextRowIndex >= rowIds.length || nextColumnIndex < 0 || nextColumnIndex >= customColumnIds.length) {
6432
+ return;
6433
+ }
6434
+ const nextCell = { taskId: rowIds[nextRowIndex], columnId: customColumnIds[nextColumnIndex] };
6435
+ onActiveCustomCellChange?.(nextCell);
6436
+ window.requestAnimationFrame(() => {
6437
+ focusCustomCell(nextCell.taskId, nextCell.columnId);
6438
+ });
6439
+ }, [focusCustomCell, onActiveCustomCellChange, resolvedColumns, task.id]);
6390
6440
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
6391
6441
  "div",
6392
6442
  {
6443
+ ref: rowRef,
6393
6444
  "data-filter-match": isFilterMatch ? "true" : "false",
6394
6445
  className: [
6395
6446
  "gantt-tl-row",
@@ -6402,9 +6453,11 @@ var TaskListRow = import_react10.default.memo(
6402
6453
  isDragging ? "gantt-tl-row-dragging" : "",
6403
6454
  isDragOver ? "gantt-tl-row-drag-over" : "",
6404
6455
  isChild ? "gantt-tl-row-child" : "",
6405
- isParent ? "gantt-tl-row-parent" : ""
6456
+ isParent ? "gantt-tl-row-parent" : "",
6457
+ `gantt-tl-row-level-${rowFillLevel}`,
6458
+ isTotalRow ? "gantt-tl-row-total" : ""
6406
6459
  ].filter(Boolean).join(" "),
6407
- style: { minHeight: `${rowHeight}px`, position: "relative" },
6460
+ style: { height: `${rowHeight}px`, position: "relative" },
6408
6461
  "data-gantt-task-row-id": task.id,
6409
6462
  onClick: handleRowClickInternal,
6410
6463
  onKeyDown: handleRowKeyDown,
@@ -6416,43 +6469,120 @@ var TaskListRow = import_react10.default.memo(
6416
6469
  if (builtIn) return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react10.default.Fragment, { children: builtIn }, col.id);
6417
6470
  const isEditing = editingColumnId === col.id;
6418
6471
  const editorFn = col.renderEditor;
6472
+ const isActiveCustomCell = activeCustomCell?.taskId === task.id && activeCustomCell?.columnId === col.id;
6473
+ const startEditingCustomCell = (startValue) => {
6474
+ if (!editorFn) return;
6475
+ onActiveCustomCellChange?.({ taskId: task.id, columnId: col.id });
6476
+ setEditingColumnStartValue(startValue);
6477
+ setEditingColumnId(col.id);
6478
+ };
6419
6479
  const columnContext = {
6420
6480
  task,
6421
6481
  rowIndex,
6422
6482
  isEditing,
6483
+ editStartValue: isEditing ? editingColumnStartValue : void 0,
6423
6484
  openEditor: () => {
6424
- if (editorFn) setEditingColumnId(col.id);
6485
+ startEditingCustomCell();
6425
6486
  },
6426
6487
  closeEditor: () => {
6427
- if (editingColumnId === col.id) setEditingColumnId(null);
6488
+ if (editingColumnId === col.id) {
6489
+ setEditingColumnId(null);
6490
+ setEditingColumnStartValue(void 0);
6491
+ onActiveCustomCellChange?.({ taskId: task.id, columnId: col.id });
6492
+ window.requestAnimationFrame(() => {
6493
+ focusCustomCell(task.id, col.id);
6494
+ });
6495
+ }
6428
6496
  },
6429
6497
  updateTask: (patch) => {
6430
6498
  onTasksChange?.([{ ...task, ...patch }]);
6499
+ onActiveCustomCellChange?.({ taskId: task.id, columnId: col.id });
6500
+ setEditingColumnStartValue(void 0);
6431
6501
  setEditingColumnId(null);
6502
+ window.requestAnimationFrame(() => {
6503
+ focusCustomCell(task.id, col.id);
6504
+ });
6432
6505
  }
6433
6506
  };
6434
6507
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
6435
6508
  "div",
6436
6509
  {
6437
- className: "gantt-tl-cell gantt-tl-cell-custom",
6510
+ className: `gantt-tl-cell gantt-tl-cell-custom gantt-tl-cell-align-${col.align ?? "left"}`,
6438
6511
  "data-column-id": `custom:${col.id}`,
6439
6512
  "data-custom-column-id": col.id,
6513
+ "data-custom-column-active": isActiveCustomCell ? "true" : "false",
6440
6514
  "data-custom-column-editing": isEditing ? "true" : "false",
6441
6515
  "data-testid": `custom-cell-${col.id}`,
6442
- onClick: editorFn && !isEditing ? (e) => {
6516
+ tabIndex: editorFn ? 0 : -1,
6517
+ onFocus: editorFn ? () => {
6518
+ onActiveCustomCellChange?.({ taskId: task.id, columnId: col.id });
6519
+ } : void 0,
6520
+ onClick: editorFn ? (e) => {
6521
+ e.stopPropagation();
6522
+ onActiveCustomCellChange?.({ taskId: task.id, columnId: col.id });
6523
+ if (isEditing) {
6524
+ return;
6525
+ }
6526
+ e.currentTarget.focus();
6527
+ } : void 0,
6528
+ onDoubleClick: editorFn && !isEditing ? (e) => {
6443
6529
  e.stopPropagation();
6444
- setEditingColumnId(col.id);
6530
+ startEditingCustomCell();
6531
+ } : void 0,
6532
+ onKeyDown: editorFn && !isEditing ? (e) => {
6533
+ if (e.key === "ArrowLeft") {
6534
+ e.preventDefault();
6535
+ e.stopPropagation();
6536
+ moveActiveCustomCell(col.id, "left");
6537
+ return;
6538
+ }
6539
+ if (e.key === "ArrowRight") {
6540
+ e.preventDefault();
6541
+ e.stopPropagation();
6542
+ moveActiveCustomCell(col.id, "right");
6543
+ return;
6544
+ }
6545
+ if (e.key === "ArrowUp") {
6546
+ e.preventDefault();
6547
+ e.stopPropagation();
6548
+ moveActiveCustomCell(col.id, "up");
6549
+ return;
6550
+ }
6551
+ if (e.key === "ArrowDown") {
6552
+ e.preventDefault();
6553
+ e.stopPropagation();
6554
+ moveActiveCustomCell(col.id, "down");
6555
+ return;
6556
+ }
6557
+ if (e.key === "Enter" || e.key === "F2") {
6558
+ e.preventDefault();
6559
+ e.stopPropagation();
6560
+ startEditingCustomCell();
6561
+ return;
6562
+ }
6563
+ if (e.key === "Backspace" || e.key === "Delete") {
6564
+ e.preventDefault();
6565
+ e.stopPropagation();
6566
+ startEditingCustomCell("");
6567
+ return;
6568
+ }
6569
+ if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {
6570
+ e.preventDefault();
6571
+ e.stopPropagation();
6572
+ startEditingCustomCell(e.key);
6573
+ }
6445
6574
  } : void 0,
6446
6575
  style: { width: col.width ?? 120, minWidth: col.width ?? 120, flexShrink: 0 },
6447
6576
  children: isEditing && editorFn ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
6448
6577
  "div",
6449
6578
  {
6579
+ className: "gantt-tl-cell-custom-editor",
6450
6580
  "data-custom-column-editor": col.id,
6451
6581
  onMouseDown: (e) => e.stopPropagation(),
6452
6582
  onClick: (e) => e.stopPropagation(),
6453
6583
  children: editorFn(columnContext)
6454
6584
  }
6455
- ) : col.renderCell(columnContext)
6585
+ ) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "gantt-tl-cell-custom-content", children: col.renderCell(columnContext) })
6456
6586
  },
6457
6587
  col.id
6458
6588
  );
@@ -6504,7 +6634,7 @@ var NewTaskRow = ({
6504
6634
  onCancel();
6505
6635
  }
6506
6636
  };
6507
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "gantt-tl-row gantt-tl-row-new", style: { minHeight: `${rowHeight}px` }, children: [
6637
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "gantt-tl-row gantt-tl-row-new", style: { height: `${rowHeight}px` }, children: [
6508
6638
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "gantt-tl-cell gantt-tl-cell-number" }),
6509
6639
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "gantt-tl-cell gantt-tl-cell-name gantt-tl-cell-new-name", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
6510
6640
  Input,
@@ -6738,6 +6868,7 @@ var TaskList = ({
6738
6868
  onDelete,
6739
6869
  onInsertAfter,
6740
6870
  onReorder,
6871
+ disableTaskDrag = false,
6741
6872
  editingTaskId: propEditingTaskId,
6742
6873
  enableAddTask = true,
6743
6874
  defaultTaskDurationDays = DEFAULT_TASK_DURATION_DAYS,
@@ -6759,10 +6890,14 @@ var TaskList = ({
6759
6890
  additionalColumns,
6760
6891
  hiddenTaskListColumns,
6761
6892
  taskListMenuCommands,
6893
+ hideTaskListRowActions = false,
6894
+ rowContentLines = 1,
6895
+ bodyMinHeight,
6762
6896
  taskDateChangeMode = "preserve-duration",
6763
6897
  onTaskDateChangeModeChange
6764
6898
  }) => {
6765
6899
  const [internalSelectedTaskIds, setInternalSelectedTaskIds] = (0, import_react12.useState)(/* @__PURE__ */ new Set());
6900
+ const [activeCustomCell, setActiveCustomCell] = (0, import_react12.useState)(null);
6766
6901
  const effectiveSelectedTaskIds = selectedTaskIds ?? internalSelectedTaskIds;
6767
6902
  const emitSelectedTaskIdsChange = (0, import_react12.useCallback)((nextSelectedTaskIds) => {
6768
6903
  if (!selectedTaskIds) {
@@ -6934,21 +7069,28 @@ var TaskList = ({
6934
7069
  onSelectedChipChange?.(chip);
6935
7070
  }, [onSelectedChipChange]);
6936
7071
  (0, import_react12.useEffect)(() => {
6937
- if (!selectingPredecessorFor && !selectedChip && !selectedTaskId) return;
7072
+ if (!selectingPredecessorFor && !selectedChip && !selectedTaskId && !activeCustomCell) return;
6938
7073
  const handleKeyDown = (e) => {
6939
7074
  if (e.key === "Escape") {
6940
7075
  setSelectingPredecessorFor(null);
6941
7076
  setSelectedChip(null);
7077
+ setActiveCustomCell(null);
6942
7078
  onSelectedChipChange?.(null);
6943
7079
  onTaskSelect?.(null);
6944
7080
  }
6945
7081
  };
6946
7082
  const handleMouseDown = (e) => {
6947
7083
  const target = e.target;
6948
- if (overlayRef.current?.contains(target)) return;
7084
+ if (overlayRef.current?.contains(target)) {
7085
+ if (activeCustomCell && !target.closest?.("[data-custom-column-id]")) {
7086
+ setActiveCustomCell(null);
7087
+ }
7088
+ return;
7089
+ }
6949
7090
  if (target.closest?.(".gantt-popover")) return;
6950
7091
  setSelectingPredecessorFor(null);
6951
7092
  setSelectedChip(null);
7093
+ setActiveCustomCell(null);
6952
7094
  onSelectedChipChange?.(null);
6953
7095
  onTaskSelect?.(null);
6954
7096
  };
@@ -6958,7 +7100,7 @@ var TaskList = ({
6958
7100
  document.removeEventListener("keydown", handleKeyDown);
6959
7101
  document.removeEventListener("mousedown", handleMouseDown, true);
6960
7102
  };
6961
- }, [selectingPredecessorFor, selectedChip, selectedTaskId, onTaskSelect, onSelectedChipChange]);
7103
+ }, [selectingPredecessorFor, selectedChip, selectedTaskId, activeCustomCell, onTaskSelect, onSelectedChipChange]);
6962
7104
  const handleAddDependency = (0, import_react12.useCallback)((successorTaskId, predecessorTaskId, linkType) => {
6963
7105
  if (successorTaskId === predecessorTaskId) return;
6964
7106
  if (areTasksHierarchicallyRelated(successorTaskId, predecessorTaskId, tasks)) {
@@ -7348,7 +7490,10 @@ var TaskList = ({
7348
7490
  {
7349
7491
  ref: overlayRef,
7350
7492
  className: `gantt-tl-overlay${show ? "" : " gantt-tl-hidden"}${hasRightShadow ? " gantt-tl-overlay-shadowed" : ""}`,
7351
- style: { "--tasklist-width": `${effectiveTaskListWidth}px` },
7493
+ style: {
7494
+ "--tasklist-width": `${effectiveTaskListWidth}px`,
7495
+ "--gantt-row-content-lines": String(Math.max(2, Math.floor(rowContentLines)))
7496
+ },
7352
7497
  children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "gantt-tl-table", children: [
7353
7498
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "gantt-tl-header", style: { height: `${tableHeaderHeight}px` }, children: resolvedColumns.map((col) => {
7354
7499
  if (col.id === "selection") {
@@ -7428,7 +7573,7 @@ var TaskList = ({
7428
7573
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7429
7574
  "div",
7430
7575
  {
7431
- className: "gantt-tl-headerCell gantt-tl-headerCell-custom",
7576
+ className: `gantt-tl-headerCell gantt-tl-headerCell-custom gantt-tl-cell-align-${col.align ?? "left"}`,
7432
7577
  "data-column-id": `custom:${col.id}`,
7433
7578
  "data-custom-column-id": col.id,
7434
7579
  style: { width: col.width, minWidth: col.width, flexShrink: 0 },
@@ -7437,81 +7582,94 @@ var TaskList = ({
7437
7582
  col.id
7438
7583
  );
7439
7584
  }) }),
7440
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "gantt-tl-body", style: { height: `${totalHeight}px` }, children: visibleTasks.map((task, index) => {
7441
- const previousVisibleTask = index > 0 ? visibleTasks[index - 1] : void 0;
7442
- const canDemoteTask = index === 0 || !task.parentId || previousVisibleTask?.id !== task.parentId;
7443
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react12.default.Fragment, { children: [
7444
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7445
- TaskListRow,
7446
- {
7447
- task,
7448
- rowIndex: index,
7449
- taskNumber: originalTaskNumberMap[task.id] || "",
7450
- taskNumberMap: originalTaskNumberMap,
7451
- rowHeight,
7452
- onTasksChange,
7453
- selectedTaskId,
7454
- onRowClick: handleRowClick,
7455
- disableTaskNameEditing,
7456
- disableDependencyEditing,
7457
- allTasks: tasks,
7458
- activeLinkType,
7459
- onSetActiveLinkType: setActiveLinkType,
7460
- selectingPredecessorFor,
7461
- dependencyPickMode,
7462
- onSetDependencyPickMode: setDependencyPickMode,
7463
- onSetSelectingPredecessorFor: setSelectingPredecessorFor,
7464
- onAddDependency: handleAddDependency,
7465
- onRemoveDependency: handleRemoveDependency,
7466
- selectedChip,
7467
- onChipSelect: handleChipSelect,
7468
- onScrollToTask,
7469
- onDelete,
7470
- onAdd,
7471
- onInsertAfter: handleStartInsertAfter,
7472
- editingTaskId: propEditingTaskId,
7473
- isDragging: draggingIndex === index,
7474
- isDragOver: dragOverIndex === index,
7475
- onDragStart: handleDragStart,
7476
- onDragOver: handleDragOver,
7477
- onDrop: handleDrop,
7478
- onDragEnd: handleDragEnd,
7479
- collapsedParentIds,
7480
- onToggleCollapse: handleToggleCollapse,
7481
- onPromoteTask,
7482
- onDemoteTask: onDemoteTask ? handleDemoteWrapper : void 0,
7483
- onUngroupTask,
7484
- onDuplicateTask: onReorder ? handleDuplicateTask : void 0,
7485
- canDemoteTask,
7486
- isLastChild: lastChildIds.has(task.id),
7487
- nestingDepth: nestingDepthMap.get(task.id) ?? 0,
7488
- hasVisibleChildren: visibleParentIds.has(task.id),
7489
- ancestorLineModes: ancestorLineModesMap.get(task.id) ?? [],
7490
- customDays,
7491
- isWeekend: isWeekend3,
7492
- businessDays,
7493
- defaultTaskDurationDays,
7494
- isFilterMatch: filterMode === "highlight" ? highlightedTaskIds.has(task.id) : false,
7495
- isFilterHideMode: filterMode === "hide" && isFilterActive,
7496
- resolvedColumns,
7497
- isTaskSelected: effectiveSelectedTaskIds.has(task.id),
7498
- onTaskSelectionChange: handleToggleTaskSelection,
7499
- taskListMenuCommands,
7500
- taskDateChangeMode,
7501
- onTaskDateChangeModeChange
7502
- }
7503
- ),
7504
- pendingInsertDisplayTaskId === task.id && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7505
- NewTaskRow,
7506
- {
7507
- rowHeight,
7508
- onConfirm: handleConfirmInsertedTask,
7509
- onCancel: handleCancelInsertedTask,
7510
- nestingDepth: pendingInsert?.nestingDepth ?? 0
7511
- }
7512
- )
7513
- ] }, task.id);
7514
- }) }),
7585
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7586
+ "div",
7587
+ {
7588
+ className: "gantt-tl-body",
7589
+ style: {
7590
+ height: `${totalHeight}px`,
7591
+ minHeight: bodyMinHeight
7592
+ },
7593
+ children: visibleTasks.map((task, index) => {
7594
+ const previousVisibleTask = index > 0 ? visibleTasks[index - 1] : void 0;
7595
+ const canDemoteTask = index === 0 || !task.parentId || previousVisibleTask?.id !== task.parentId;
7596
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react12.default.Fragment, { children: [
7597
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7598
+ TaskListRow,
7599
+ {
7600
+ task,
7601
+ rowIndex: index,
7602
+ taskNumber: originalTaskNumberMap[task.id] || "",
7603
+ taskNumberMap: originalTaskNumberMap,
7604
+ rowHeight,
7605
+ onTasksChange,
7606
+ selectedTaskId,
7607
+ onRowClick: handleRowClick,
7608
+ disableTaskNameEditing,
7609
+ disableDependencyEditing,
7610
+ allTasks: tasks,
7611
+ activeLinkType,
7612
+ onSetActiveLinkType: setActiveLinkType,
7613
+ selectingPredecessorFor,
7614
+ dependencyPickMode,
7615
+ onSetDependencyPickMode: setDependencyPickMode,
7616
+ onSetSelectingPredecessorFor: setSelectingPredecessorFor,
7617
+ onAddDependency: handleAddDependency,
7618
+ onRemoveDependency: handleRemoveDependency,
7619
+ selectedChip,
7620
+ onChipSelect: handleChipSelect,
7621
+ onScrollToTask,
7622
+ onDelete,
7623
+ onAdd,
7624
+ onInsertAfter: handleStartInsertAfter,
7625
+ editingTaskId: propEditingTaskId,
7626
+ isDragging: !disableTaskDrag && draggingIndex === index,
7627
+ isDragOver: !disableTaskDrag && dragOverIndex === index,
7628
+ onDragStart: disableTaskDrag ? void 0 : handleDragStart,
7629
+ onDragOver: disableTaskDrag ? void 0 : handleDragOver,
7630
+ onDrop: disableTaskDrag ? void 0 : handleDrop,
7631
+ onDragEnd: disableTaskDrag ? void 0 : handleDragEnd,
7632
+ collapsedParentIds,
7633
+ onToggleCollapse: handleToggleCollapse,
7634
+ onPromoteTask,
7635
+ onDemoteTask: onDemoteTask ? handleDemoteWrapper : void 0,
7636
+ onUngroupTask,
7637
+ onDuplicateTask: onReorder ? handleDuplicateTask : void 0,
7638
+ canDemoteTask,
7639
+ isLastChild: lastChildIds.has(task.id),
7640
+ nestingDepth: nestingDepthMap.get(task.id) ?? 0,
7641
+ hasVisibleChildren: visibleParentIds.has(task.id),
7642
+ ancestorLineModes: ancestorLineModesMap.get(task.id) ?? [],
7643
+ customDays,
7644
+ isWeekend: isWeekend3,
7645
+ businessDays,
7646
+ defaultTaskDurationDays,
7647
+ isFilterMatch: filterMode === "highlight" ? highlightedTaskIds.has(task.id) : false,
7648
+ isFilterHideMode: filterMode === "hide" && isFilterActive,
7649
+ resolvedColumns,
7650
+ isTaskSelected: effectiveSelectedTaskIds.has(task.id),
7651
+ onTaskSelectionChange: handleToggleTaskSelection,
7652
+ activeCustomCell,
7653
+ onActiveCustomCellChange: setActiveCustomCell,
7654
+ taskListMenuCommands,
7655
+ hideTaskListRowActions,
7656
+ taskDateChangeMode,
7657
+ onTaskDateChangeModeChange
7658
+ }
7659
+ ),
7660
+ pendingInsertDisplayTaskId === task.id && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7661
+ NewTaskRow,
7662
+ {
7663
+ rowHeight,
7664
+ onConfirm: handleConfirmInsertedTask,
7665
+ onCancel: handleCancelInsertedTask,
7666
+ nestingDepth: pendingInsert?.nestingDepth ?? 0
7667
+ }
7668
+ )
7669
+ ] }, task.id);
7670
+ })
7671
+ }
7672
+ ),
7515
7673
  isCreating && !pendingInsert && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7516
7674
  NewTaskRow,
7517
7675
  {
@@ -7524,25 +7682,25 @@ var TaskList = ({
7524
7682
  enableAddTask && onAdd && !isCreating && !pendingInsert && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7525
7683
  "button",
7526
7684
  {
7527
- className: `gantt-tl-add-btn${dragOverIndex === visibleTasks.length ? " gantt-tl-add-btn-drag-over" : ""}`,
7685
+ className: `gantt-tl-add-btn${!disableTaskDrag && dragOverIndex === visibleTasks.length ? " gantt-tl-add-btn-drag-over" : ""}`,
7528
7686
  onClick: () => {
7529
7687
  setPendingInsert(null);
7530
7688
  setIsCreating(true);
7531
7689
  },
7532
- onDragEnter: (e) => {
7690
+ onDragEnter: disableTaskDrag ? void 0 : (e) => {
7533
7691
  e.preventDefault();
7534
7692
  setDragOverIndex(visibleTasks.length);
7535
7693
  },
7536
- onDragOver: (e) => {
7694
+ onDragOver: disableTaskDrag ? void 0 : (e) => {
7537
7695
  e.preventDefault();
7538
7696
  e.dataTransfer.dropEffect = "move";
7539
7697
  setDragOverIndex(visibleTasks.length);
7540
7698
  },
7541
- onDragLeave: (e) => {
7699
+ onDragLeave: disableTaskDrag ? void 0 : (e) => {
7542
7700
  e.preventDefault();
7543
7701
  setDragOverIndex(null);
7544
7702
  },
7545
- onDrop: (e) => {
7703
+ onDrop: disableTaskDrag ? void 0 : (e) => {
7546
7704
  e.preventDefault();
7547
7705
  handleDrop(visibleTasks.length, e);
7548
7706
  },
@@ -9235,6 +9393,194 @@ function ResourceTimelineChart({
9235
9393
  ) });
9236
9394
  }
9237
9395
 
9396
+ // src/components/TableMatrix/TableMatrix.tsx
9397
+ var import_react15 = require("react");
9398
+ var import_jsx_runtime16 = require("react/jsx-runtime");
9399
+ function joinClasses(...values) {
9400
+ return values.filter(Boolean).join(" ");
9401
+ }
9402
+ function TableMatrix({
9403
+ tasks,
9404
+ allTasks = tasks,
9405
+ columns,
9406
+ columnGroups,
9407
+ rowHeight,
9408
+ headerHeight,
9409
+ bodyMinHeight,
9410
+ selectedTaskId,
9411
+ onTaskSelect,
9412
+ onCellClick,
9413
+ highlightedTaskIds,
9414
+ filterMode = "highlight"
9415
+ }) {
9416
+ const gridTemplateColumns = (0, import_react15.useMemo)(
9417
+ () => columns.map((column) => `${column.width}px`).join(" "),
9418
+ [columns]
9419
+ );
9420
+ const totalWidth = (0, import_react15.useMemo)(
9421
+ () => columns.reduce((sum, column) => sum + column.width, 0),
9422
+ [columns]
9423
+ );
9424
+ const hasGroupHeader = (0, import_react15.useMemo)(
9425
+ () => columns.some((column) => !!column.groupId) || (columnGroups?.length ?? 0) > 0,
9426
+ [columnGroups, columns]
9427
+ );
9428
+ const groupMap = (0, import_react15.useMemo)(
9429
+ () => new Map((columnGroups ?? []).map((group) => [group.id, group])),
9430
+ [columnGroups]
9431
+ );
9432
+ const headerSpans = (0, import_react15.useMemo)(() => {
9433
+ if (!hasGroupHeader) return [];
9434
+ if (columnGroups?.some((group) => typeof group.width === "number")) {
9435
+ return columnGroups.map((group) => ({
9436
+ id: group.id,
9437
+ header: group.header,
9438
+ width: group.width ?? 0,
9439
+ className: group.className
9440
+ }));
9441
+ }
9442
+ const spans = [];
9443
+ for (const column of columns) {
9444
+ const groupId = column.groupId ?? column.id;
9445
+ const lastSpan = spans[spans.length - 1];
9446
+ if (lastSpan?.id === groupId) {
9447
+ lastSpan.width += column.width;
9448
+ continue;
9449
+ }
9450
+ const group = groupMap.get(groupId);
9451
+ spans.push({
9452
+ id: groupId,
9453
+ header: group?.header ?? column.header,
9454
+ width: column.width,
9455
+ className: group?.className
9456
+ });
9457
+ }
9458
+ return spans;
9459
+ }, [columns, groupMap, hasGroupHeader]);
9460
+ const headerContentHeight = Math.max(0, headerHeight - 1);
9461
+ const topRowHeight = hasGroupHeader ? Math.ceil(headerContentHeight / 2) : headerContentHeight;
9462
+ const bottomRowHeight = hasGroupHeader ? Math.floor(headerContentHeight / 2) : 0;
9463
+ const parentTaskIds = (0, import_react15.useMemo)(() => {
9464
+ const ids = /* @__PURE__ */ new Set();
9465
+ for (const task of allTasks) {
9466
+ if (task.parentId) {
9467
+ ids.add(task.parentId);
9468
+ }
9469
+ }
9470
+ return ids;
9471
+ }, [allTasks]);
9472
+ const nestingDepthMap = (0, import_react15.useMemo)(() => {
9473
+ const depthMap = /* @__PURE__ */ new Map();
9474
+ const taskById = new Map(allTasks.map((task) => [task.id, task]));
9475
+ const getDepth = (taskId, seen = /* @__PURE__ */ new Set()) => {
9476
+ if (depthMap.has(taskId)) return depthMap.get(taskId);
9477
+ if (seen.has(taskId)) return 0;
9478
+ const task = taskById.get(taskId);
9479
+ if (!task?.parentId || !taskById.has(task.parentId)) {
9480
+ depthMap.set(taskId, 0);
9481
+ return 0;
9482
+ }
9483
+ seen.add(taskId);
9484
+ const depth = getDepth(task.parentId, seen) + 1;
9485
+ depthMap.set(taskId, depth);
9486
+ return depth;
9487
+ };
9488
+ for (const task of allTasks) {
9489
+ getDepth(task.id);
9490
+ }
9491
+ return depthMap;
9492
+ }, [allTasks]);
9493
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "gantt-mx-root", style: { width: `${totalWidth}px` }, children: [
9494
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "gantt-mx-header", style: { height: `${headerHeight}px` }, children: [
9495
+ hasGroupHeader && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
9496
+ "div",
9497
+ {
9498
+ className: "gantt-mx-headerRow gantt-mx-headerGroupRow",
9499
+ style: { gridTemplateColumns: headerSpans.map((span) => `${span.width}px`).join(" "), height: `${topRowHeight}px` },
9500
+ children: headerSpans.map((span) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: joinClasses("gantt-mx-groupCell", span.className), children: span.header }, span.id))
9501
+ }
9502
+ ),
9503
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
9504
+ "div",
9505
+ {
9506
+ className: "gantt-mx-headerRow",
9507
+ style: { gridTemplateColumns, height: `${hasGroupHeader ? bottomRowHeight : topRowHeight}px` },
9508
+ children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
9509
+ "div",
9510
+ {
9511
+ className: joinClasses(
9512
+ "gantt-mx-headerCell",
9513
+ column.headerClassName
9514
+ ),
9515
+ children: column.header
9516
+ },
9517
+ column.id
9518
+ ))
9519
+ }
9520
+ )
9521
+ ] }),
9522
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
9523
+ "div",
9524
+ {
9525
+ className: "gantt-mx-body",
9526
+ style: {
9527
+ height: `${tasks.length * rowHeight}px`,
9528
+ minHeight: bodyMinHeight
9529
+ },
9530
+ children: tasks.map((task, index) => {
9531
+ const isHighlighted = filterMode === "highlight" && !!highlightedTaskIds?.has(task.id);
9532
+ const isParent = parentTaskIds.has(task.id);
9533
+ const nestingDepth = nestingDepthMap.get(task.id) ?? 0;
9534
+ const rowFillLevel = Math.min(nestingDepth, 2);
9535
+ const isTotal = Boolean(task.isTotal);
9536
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
9537
+ "div",
9538
+ {
9539
+ "data-gantt-task-row-id": task.id,
9540
+ className: joinClasses(
9541
+ "gantt-mx-row",
9542
+ task.parentId && "gantt-mx-row-child",
9543
+ isParent && "gantt-mx-row-parent",
9544
+ `gantt-mx-row-level-${rowFillLevel}`,
9545
+ isTotal && "gantt-mx-row-total",
9546
+ selectedTaskId === task.id && "gantt-mx-row-selected",
9547
+ isHighlighted && "gantt-mx-row-highlighted"
9548
+ ),
9549
+ style: {
9550
+ gridTemplateColumns,
9551
+ top: `${index * rowHeight}px`,
9552
+ height: `${rowHeight}px`
9553
+ },
9554
+ onClick: () => onTaskSelect?.(task.id),
9555
+ children: columns.map((column, columnIndex) => {
9556
+ const resolvedCellClassName = typeof column.cellClassName === "function" ? column.cellClassName(task) : column.cellClassName;
9557
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
9558
+ "div",
9559
+ {
9560
+ className: joinClasses(
9561
+ "gantt-mx-cell",
9562
+ onCellClick && "gantt-mx-cell-clickable",
9563
+ `gantt-mx-cellAlign-${column.align ?? "right"}`,
9564
+ column.className,
9565
+ resolvedCellClassName
9566
+ ),
9567
+ onClick: (event) => {
9568
+ onCellClick?.({ task, column, rowIndex: index, columnIndex, event });
9569
+ },
9570
+ children: column.renderCell(task)
9571
+ },
9572
+ `${task.id}:${column.id}`
9573
+ );
9574
+ })
9575
+ },
9576
+ task.id
9577
+ );
9578
+ })
9579
+ }
9580
+ )
9581
+ ] });
9582
+ }
9583
+
9238
9584
  // src/components/GanttChart/print.ts
9239
9585
  function getPrintDocumentTitle({
9240
9586
  header,
@@ -9573,13 +9919,13 @@ async function printGanttChart({
9573
9919
  }
9574
9920
 
9575
9921
  // src/components/GanttChart/GanttChart.tsx
9576
- var import_jsx_runtime16 = require("react/jsx-runtime");
9922
+ var import_jsx_runtime17 = require("react/jsx-runtime");
9577
9923
  var SCROLL_TO_ROW_CONTEXT_ROWS = 2;
9578
9924
  function GanttChartInner(props, ref) {
9579
9925
  if (props.mode === "resource-planner") {
9580
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ResourceTimelineChart, { ...props });
9926
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ResourceTimelineChart, { ...props });
9581
9927
  }
9582
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
9928
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
9583
9929
  TaskGanttChart,
9584
9930
  {
9585
9931
  ...props,
@@ -9588,9 +9934,9 @@ function GanttChartInner(props, ref) {
9588
9934
  );
9589
9935
  }
9590
9936
  function TaskGanttChartInner(props, ref) {
9937
+ const isTableMatrixMode = props.mode === "table-matrix";
9591
9938
  const {
9592
9939
  tasks,
9593
- dayWidth = 40,
9594
9940
  rowHeight = 40,
9595
9941
  headerHeight = 40,
9596
9942
  containerHeight,
@@ -9614,10 +9960,6 @@ function TaskGanttChartInner(props, ref) {
9614
9960
  onUngroupTask,
9615
9961
  enableAddTask = true,
9616
9962
  defaultTaskDurationDays,
9617
- viewMode = "day",
9618
- customDays,
9619
- isWeekend: isWeekend3,
9620
- businessDays = true,
9621
9963
  taskFilter,
9622
9964
  filterMode = "highlight",
9623
9965
  collapsedParentIds: externalCollapsedParentIds,
@@ -9631,28 +9973,43 @@ function TaskGanttChartInner(props, ref) {
9631
9973
  additionalColumns,
9632
9974
  hiddenTaskListColumns,
9633
9975
  taskListMenuCommands,
9976
+ hideTaskListRowActions = false,
9977
+ rowContentLines = 1,
9634
9978
  taskDateChangeMode: externalTaskDateChangeMode,
9635
9979
  onTaskDateChangeModeChange: externalOnTaskDateChangeModeChange
9636
9980
  } = props;
9637
- const containerRef = (0, import_react15.useRef)(null);
9638
- const scrollContainerRef = (0, import_react15.useRef)(null);
9639
- const scrollContentRef = (0, import_react15.useRef)(null);
9640
- const clearSelectedTaskTimeoutRef = (0, import_react15.useRef)(null);
9641
- const [selectedTaskId, setSelectedTaskId] = (0, import_react15.useState)(null);
9642
- const [taskListHasRightShadow, setTaskListHasRightShadow] = (0, import_react15.useState)(false);
9643
- const [internalTaskDateChangeMode, setInternalTaskDateChangeMode] = (0, import_react15.useState)("preserve-duration");
9644
- const [selectedChip, setSelectedChip] = (0, import_react15.useState)(null);
9645
- const [internalCollapsedParentIds, setInternalCollapsedParentIds] = (0, import_react15.useState)(/* @__PURE__ */ new Set());
9981
+ const dayWidth = !isTableMatrixMode ? props.dayWidth ?? 40 : 40;
9982
+ const viewMode = !isTableMatrixMode ? props.viewMode ?? "day" : "day";
9983
+ const customDays = !isTableMatrixMode ? props.customDays : void 0;
9984
+ const isWeekend3 = !isTableMatrixMode ? props.isWeekend : void 0;
9985
+ const businessDays = !isTableMatrixMode ? props.businessDays ?? true : true;
9986
+ const matrixColumns = isTableMatrixMode ? props.matrixColumns : [];
9987
+ const matrixColumnGroups = isTableMatrixMode ? props.matrixColumnGroups : void 0;
9988
+ const onMatrixCellClick = isTableMatrixMode ? props.onMatrixCellClick : void 0;
9989
+ const containerRef = (0, import_react16.useRef)(null);
9990
+ const scrollContainerRef = (0, import_react16.useRef)(null);
9991
+ const scrollContentRef = (0, import_react16.useRef)(null);
9992
+ const clearSelectedTaskTimeoutRef = (0, import_react16.useRef)(null);
9993
+ const [selectedTaskId, setSelectedTaskId] = (0, import_react16.useState)(null);
9994
+ const [taskListHasRightShadow, setTaskListHasRightShadow] = (0, import_react16.useState)(false);
9995
+ const [internalTaskDateChangeMode, setInternalTaskDateChangeMode] = (0, import_react16.useState)("preserve-duration");
9996
+ const [selectedChip, setSelectedChip] = (0, import_react16.useState)(null);
9997
+ const [internalCollapsedParentIds, setInternalCollapsedParentIds] = (0, import_react16.useState)(/* @__PURE__ */ new Set());
9646
9998
  const collapsedParentIds = externalCollapsedParentIds ?? internalCollapsedParentIds;
9647
- const [editingTaskId, setEditingTaskId] = (0, import_react15.useState)(null);
9999
+ const [editingTaskId, setEditingTaskId] = (0, import_react16.useState)(null);
9648
10000
  const taskDateChangeMode = externalTaskDateChangeMode ?? internalTaskDateChangeMode;
9649
10001
  const handleTaskDateChangeMode = externalOnTaskDateChangeModeChange ?? setInternalTaskDateChangeMode;
9650
- const normalizedTasks = (0, import_react15.useMemo)(() => normalizeHierarchyTasks(tasks), [tasks]);
9651
- const isCustomWeekend = (0, import_react15.useMemo)(
10002
+ const resolvedRowContentLines = Math.max(1, Math.floor(rowContentLines));
10003
+ const effectiveRowHeight = (0, import_react16.useMemo)(
10004
+ () => Math.max(rowHeight, 10 + resolvedRowContentLines * 18),
10005
+ [resolvedRowContentLines, rowHeight]
10006
+ );
10007
+ const normalizedTasks = (0, import_react16.useMemo)(() => normalizeHierarchyTasks(tasks), [tasks]);
10008
+ const isCustomWeekend = (0, import_react16.useMemo)(
9652
10009
  () => createCustomDayPredicate({ customDays, isWeekend: isWeekend3 }),
9653
10010
  [customDays, isWeekend3]
9654
10011
  );
9655
- const dateRangeTasks = (0, import_react15.useMemo)(() => {
10012
+ const dateRangeTasks = (0, import_react16.useMemo)(() => {
9656
10013
  if (!showBaseline) {
9657
10014
  return normalizedTasks;
9658
10015
  }
@@ -9662,14 +10019,18 @@ function TaskGanttChartInner(props, ref) {
9662
10019
  endDate: task.baselineEndDate && parseUTCDate(task.baselineEndDate).getTime() > parseUTCDate(task.endDate).getTime() ? task.baselineEndDate : task.endDate
9663
10020
  }));
9664
10021
  }, [normalizedTasks, showBaseline]);
9665
- const dateRange = (0, import_react15.useMemo)(() => getMultiMonthDays(dateRangeTasks), [dateRangeTasks]);
9666
- const [validationResult, setValidationResult] = (0, import_react15.useState)(null);
9667
- const [cascadeOverrides, setCascadeOverrides] = (0, import_react15.useState)(/* @__PURE__ */ new Map());
9668
- const gridWidth = (0, import_react15.useMemo)(
10022
+ const dateRange = (0, import_react16.useMemo)(() => getMultiMonthDays(dateRangeTasks), [dateRangeTasks]);
10023
+ const [validationResult, setValidationResult] = (0, import_react16.useState)(null);
10024
+ const [cascadeOverrides, setCascadeOverrides] = (0, import_react16.useState)(/* @__PURE__ */ new Map());
10025
+ const gridWidth = (0, import_react16.useMemo)(
9669
10026
  () => Math.round(dateRange.length * dayWidth),
9670
10027
  [dateRange.length, dayWidth]
9671
10028
  );
9672
- const visibleTasks = (0, import_react15.useMemo)(() => {
10029
+ const matrixWidth = (0, import_react16.useMemo)(
10030
+ () => matrixColumns.reduce((sum, column) => sum + column.width, 0),
10031
+ [matrixColumns]
10032
+ );
10033
+ const visibleTasks = (0, import_react16.useMemo)(() => {
9673
10034
  const parentMap = new Map(normalizedTasks.map((t) => [t.id, t.parentId]));
9674
10035
  function isAnyAncestorCollapsed(parentId) {
9675
10036
  let current = parentId;
@@ -9685,11 +10046,11 @@ function TaskGanttChartInner(props, ref) {
9685
10046
  }
9686
10047
  return tasks2;
9687
10048
  }, [normalizedTasks, collapsedParentIds, filterMode, taskFilter]);
9688
- const matchedTaskIds = (0, import_react15.useMemo)(() => {
10049
+ const matchedTaskIds = (0, import_react16.useMemo)(() => {
9689
10050
  if (!taskFilter) return /* @__PURE__ */ new Set();
9690
10051
  return new Set(visibleTasks.filter(taskFilter).map((task) => task.id));
9691
10052
  }, [visibleTasks, taskFilter]);
9692
- const taskListHighlightedTaskIds = (0, import_react15.useMemo)(() => {
10053
+ const taskListHighlightedTaskIds = (0, import_react16.useMemo)(() => {
9693
10054
  if (filterMode === "hide") {
9694
10055
  return /* @__PURE__ */ new Set();
9695
10056
  }
@@ -9700,24 +10061,34 @@ function TaskGanttChartInner(props, ref) {
9700
10061
  matchedTaskIds.forEach((taskId) => mergedHighlightedTaskIds.add(taskId));
9701
10062
  return mergedHighlightedTaskIds;
9702
10063
  }, [filterMode, highlightedTaskIds, matchedTaskIds]);
9703
- const totalGridHeight = (0, import_react15.useMemo)(
9704
- () => visibleTasks.length * rowHeight,
9705
- [visibleTasks.length, rowHeight]
10064
+ const totalGridHeight = (0, import_react16.useMemo)(
10065
+ () => visibleTasks.length * effectiveRowHeight,
10066
+ [effectiveRowHeight, visibleTasks.length]
9706
10067
  );
9707
10068
  const timelineHeaderHeight = headerHeight + 1;
9708
- const monthStart = (0, import_react15.useMemo)(() => {
10069
+ const tableBodyMinHeight = (0, import_react16.useMemo)(() => {
10070
+ if (!isTableMatrixMode || containerHeight === void 0) {
10071
+ return void 0;
10072
+ }
10073
+ if (typeof containerHeight === "number") {
10074
+ return Math.max(0, containerHeight - timelineHeaderHeight);
10075
+ }
10076
+ return `calc(${containerHeight} - ${timelineHeaderHeight}px)`;
10077
+ }, [containerHeight, isTableMatrixMode, timelineHeaderHeight]);
10078
+ const monthStart = (0, import_react16.useMemo)(() => {
9709
10079
  if (dateRange.length === 0) {
9710
10080
  return new Date(Date.UTC((/* @__PURE__ */ new Date()).getUTCFullYear(), (/* @__PURE__ */ new Date()).getUTCMonth(), 1));
9711
10081
  }
9712
10082
  const firstDay = dateRange[0];
9713
10083
  return new Date(Date.UTC(firstDay.getUTCFullYear(), firstDay.getUTCMonth(), 1));
9714
10084
  }, [dateRange]);
9715
- const todayInRange = (0, import_react15.useMemo)(() => {
10085
+ const todayInRange = (0, import_react16.useMemo)(() => {
9716
10086
  const now = /* @__PURE__ */ new Date();
9717
10087
  const today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
9718
10088
  return dateRange.some((day) => day.getTime() === today.getTime());
9719
10089
  }, [dateRange]);
9720
- (0, import_react15.useEffect)(() => {
10090
+ (0, import_react16.useEffect)(() => {
10091
+ if (isTableMatrixMode) return;
9721
10092
  const container = scrollContainerRef.current;
9722
10093
  if (!container || dateRange.length === 0) return;
9723
10094
  const now = /* @__PURE__ */ new Date();
@@ -9728,8 +10099,8 @@ function TaskGanttChartInner(props, ref) {
9728
10099
  const containerWidth = container.clientWidth;
9729
10100
  const scrollLeft = Math.round(todayOffset + dayWidth / 2 - containerWidth * 0.3);
9730
10101
  container.scrollLeft = Math.max(0, scrollLeft);
9731
- }, []);
9732
- (0, import_react15.useEffect)(() => {
10102
+ }, [dateRange, dayWidth, isTableMatrixMode]);
10103
+ (0, import_react16.useEffect)(() => {
9733
10104
  const container = scrollContainerRef.current;
9734
10105
  if (!container) return;
9735
10106
  const updateShadow = () => {
@@ -9741,7 +10112,8 @@ function TaskGanttChartInner(props, ref) {
9741
10112
  container.removeEventListener("scroll", updateShadow);
9742
10113
  };
9743
10114
  }, []);
9744
- const scrollToToday = (0, import_react15.useCallback)(() => {
10115
+ const scrollToToday = (0, import_react16.useCallback)(() => {
10116
+ if (isTableMatrixMode) return;
9745
10117
  const container = scrollContainerRef.current;
9746
10118
  if (!container || dateRange.length === 0) return;
9747
10119
  const now = /* @__PURE__ */ new Date();
@@ -9752,8 +10124,18 @@ function TaskGanttChartInner(props, ref) {
9752
10124
  const containerWidth = container.clientWidth;
9753
10125
  const scrollLeft = Math.round(todayOffset + dayWidth / 2 - containerWidth * 0.3);
9754
10126
  container.scrollTo({ left: Math.max(0, scrollLeft), behavior: "smooth" });
9755
- }, [dateRange, dayWidth]);
9756
- const scrollToTask = (0, import_react15.useCallback)((taskId) => {
10127
+ }, [dateRange, dayWidth, isTableMatrixMode]);
10128
+ const scrollToTask = (0, import_react16.useCallback)((taskId) => {
10129
+ if (isTableMatrixMode) {
10130
+ const container2 = scrollContainerRef.current;
10131
+ if (!container2) return;
10132
+ const rowIndex = visibleTasks.findIndex((visibleTask) => visibleTask.id === taskId);
10133
+ if (rowIndex === -1) return;
10134
+ const paddedRowIndex = Math.max(0, rowIndex - SCROLL_TO_ROW_CONTEXT_ROWS);
10135
+ container2.scrollTo({ top: Math.max(0, effectiveRowHeight * paddedRowIndex), behavior: "smooth" });
10136
+ setSelectedTaskId(taskId);
10137
+ return;
10138
+ }
9757
10139
  const container = scrollContainerRef.current;
9758
10140
  if (!container || dateRange.length === 0) return;
9759
10141
  const task = tasks.find((t) => t.id === taskId);
@@ -9769,8 +10151,8 @@ function TaskGanttChartInner(props, ref) {
9769
10151
  const taskOffset = taskIndex * dayWidth;
9770
10152
  const scrollLeft = Math.round(taskOffset - dayWidth * 2);
9771
10153
  container.scrollTo({ left: Math.max(0, scrollLeft), behavior: "smooth" });
9772
- }, [tasks, dateRange, dayWidth]);
9773
- const scrollToRow = (0, import_react15.useCallback)((taskId, options = {}) => {
10154
+ }, [dateRange, dayWidth, effectiveRowHeight, isTableMatrixMode, tasks, visibleTasks]);
10155
+ const scrollToRow = (0, import_react16.useCallback)((taskId, options = {}) => {
9774
10156
  const container = scrollContainerRef.current;
9775
10157
  if (!container) return;
9776
10158
  const task = tasks.find((t) => t.id === taskId);
@@ -9778,7 +10160,7 @@ function TaskGanttChartInner(props, ref) {
9778
10160
  const rowIndex = visibleTasks.findIndex((visibleTask) => visibleTask.id === task.id);
9779
10161
  if (rowIndex === -1) return;
9780
10162
  const paddedRowIndex = Math.max(0, rowIndex - SCROLL_TO_ROW_CONTEXT_ROWS);
9781
- const scrollTop = Math.max(0, rowHeight * paddedRowIndex);
10163
+ const scrollTop = Math.max(0, effectiveRowHeight * paddedRowIndex);
9782
10164
  const {
9783
10165
  select = true,
9784
10166
  behavior = "smooth",
@@ -9798,21 +10180,21 @@ function TaskGanttChartInner(props, ref) {
9798
10180
  }
9799
10181
  }
9800
10182
  container.scrollTo({ top: scrollTop, behavior });
9801
- }, [tasks, visibleTasks, rowHeight]);
9802
- const [dragGuideLines, setDragGuideLines] = (0, import_react15.useState)(null);
9803
- const [draggedTaskOverride, setDraggedTaskOverride] = (0, import_react15.useState)(null);
9804
- const [previewTasksById, setPreviewTasksById] = (0, import_react15.useState)(/* @__PURE__ */ new Map());
9805
- (0, import_react15.useEffect)(() => {
10183
+ }, [effectiveRowHeight, tasks, visibleTasks]);
10184
+ const [dragGuideLines, setDragGuideLines] = (0, import_react16.useState)(null);
10185
+ const [draggedTaskOverride, setDraggedTaskOverride] = (0, import_react16.useState)(null);
10186
+ const [previewTasksById, setPreviewTasksById] = (0, import_react16.useState)(/* @__PURE__ */ new Map());
10187
+ (0, import_react16.useEffect)(() => {
9806
10188
  const result = validateDependencies(tasks);
9807
10189
  setValidationResult(result);
9808
10190
  onValidateDependencies?.(result);
9809
10191
  }, [tasks, onValidateDependencies]);
9810
- (0, import_react15.useEffect)(() => () => {
10192
+ (0, import_react16.useEffect)(() => () => {
9811
10193
  if (clearSelectedTaskTimeoutRef.current !== null) {
9812
10194
  window.clearTimeout(clearSelectedTaskTimeoutRef.current);
9813
10195
  }
9814
10196
  }, []);
9815
- const handleTaskChange = (0, import_react15.useCallback)((updatedTasks) => {
10197
+ const handleTaskChange = (0, import_react16.useCallback)((updatedTasks) => {
9816
10198
  const updatedTask = updatedTasks[0];
9817
10199
  if (!updatedTask) return;
9818
10200
  const originalTask = tasks.find((t) => t.id === updatedTask.id);
@@ -9858,7 +10240,7 @@ function TaskGanttChartInner(props, ref) {
9858
10240
  const cascadedTasks = disableConstraints ? [updatedTask] : universalCascade(updatedTask, newStart, newEnd, sourceTasks, businessDays, isCustomWeekend);
9859
10241
  onTasksChange?.(cascadedTasks);
9860
10242
  }, [tasks, onTasksChange, disableConstraints, editingTaskId, businessDays, isCustomWeekend]);
9861
- const handleDelete = (0, import_react15.useCallback)((taskId) => {
10243
+ const handleDelete = (0, import_react16.useCallback)((taskId) => {
9862
10244
  const toDelete = /* @__PURE__ */ new Set([taskId]);
9863
10245
  function collectDescendants(parentId) {
9864
10246
  const children = getChildren(parentId, tasks);
@@ -9883,10 +10265,10 @@ function TaskGanttChartInner(props, ref) {
9883
10265
  }
9884
10266
  toDelete.forEach((id) => onDelete?.(id));
9885
10267
  }, [tasks, onTasksChange, onDelete]);
9886
- const handleInsertAfter = (0, import_react15.useCallback)((taskId, newTask) => {
10268
+ const handleInsertAfter = (0, import_react16.useCallback)((taskId, newTask) => {
9887
10269
  onInsertAfter?.(taskId, newTask);
9888
10270
  }, [onInsertAfter]);
9889
- const handleReorder = (0, import_react15.useCallback)((reorderedTasks, movedTaskId, inferredParentId) => {
10271
+ const handleReorder = (0, import_react16.useCallback)((reorderedTasks, movedTaskId, inferredParentId) => {
9890
10272
  let updated = reorderedTasks;
9891
10273
  if (movedTaskId) {
9892
10274
  updated = updated.map((t) => {
@@ -9903,7 +10285,7 @@ function TaskGanttChartInner(props, ref) {
9903
10285
  }
9904
10286
  onTasksChange?.(normalized);
9905
10287
  }, [onTasksChange, onReorder]);
9906
- const dependencyOverrides = (0, import_react15.useMemo)(() => {
10288
+ const dependencyOverrides = (0, import_react16.useMemo)(() => {
9907
10289
  const map = new Map(cascadeOverrides);
9908
10290
  if (draggedTaskOverride) {
9909
10291
  map.set(draggedTaskOverride.taskId, {
@@ -9913,32 +10295,32 @@ function TaskGanttChartInner(props, ref) {
9913
10295
  }
9914
10296
  return map;
9915
10297
  }, [cascadeOverrides, draggedTaskOverride]);
9916
- const handleCascadeProgress = (0, import_react15.useCallback)((overrides, previewTasks = []) => {
10298
+ const handleCascadeProgress = (0, import_react16.useCallback)((overrides, previewTasks = []) => {
9917
10299
  setCascadeOverrides(new Map(overrides));
9918
10300
  setPreviewTasksById(new Map(previewTasks.map((task) => [task.id, task])));
9919
10301
  }, []);
9920
- const previewNormalizedTasks = (0, import_react15.useMemo)(() => {
10302
+ const previewNormalizedTasks = (0, import_react16.useMemo)(() => {
9921
10303
  if (previewTasksById.size === 0) return normalizedTasks;
9922
10304
  return normalizedTasks.map((task) => previewTasksById.get(task.id) ?? task);
9923
10305
  }, [normalizedTasks, previewTasksById]);
9924
- const previewVisibleTasks = (0, import_react15.useMemo)(() => {
10306
+ const previewVisibleTasks = (0, import_react16.useMemo)(() => {
9925
10307
  if (previewTasksById.size === 0) return visibleTasks;
9926
10308
  return visibleTasks.map((task) => previewTasksById.get(task.id) ?? task);
9927
10309
  }, [visibleTasks, previewTasksById]);
9928
- const handleCascade = (0, import_react15.useCallback)((cascadedTasks) => {
10310
+ const handleCascade = (0, import_react16.useCallback)((cascadedTasks) => {
9929
10311
  onTasksChange?.(cascadedTasks);
9930
10312
  }, [tasks, onTasksChange]);
9931
- const handleTaskSelect = (0, import_react15.useCallback)((taskId) => {
10313
+ const handleTaskSelect = (0, import_react16.useCallback)((taskId) => {
9932
10314
  setSelectedTaskId(taskId);
9933
10315
  }, []);
9934
- const hoveredRowElementsRef = (0, import_react15.useRef)([]);
9935
- const clearHoveredRows = (0, import_react15.useCallback)(() => {
10316
+ const hoveredRowElementsRef = (0, import_react16.useRef)([]);
10317
+ const clearHoveredRows = (0, import_react16.useCallback)(() => {
9936
10318
  for (const element of hoveredRowElementsRef.current) {
9937
- element.classList.remove("gantt-tl-row-hovered", "gantt-tr-row-hovered");
10319
+ element.classList.remove("gantt-tl-row-hovered", "gantt-tr-row-hovered", "gantt-mx-row-hovered");
9938
10320
  }
9939
10321
  hoveredRowElementsRef.current = [];
9940
10322
  }, []);
9941
- const applyHoveredRows = (0, import_react15.useCallback)((taskId) => {
10323
+ const applyHoveredRows = (0, import_react16.useCallback)((taskId) => {
9942
10324
  const root = scrollContentRef.current;
9943
10325
  if (!root) return;
9944
10326
  clearHoveredRows();
@@ -9952,10 +10334,13 @@ function TaskGanttChartInner(props, ref) {
9952
10334
  if (element.classList.contains("gantt-tr-row")) {
9953
10335
  element.classList.add("gantt-tr-row-hovered");
9954
10336
  }
10337
+ if (element.classList.contains("gantt-mx-row")) {
10338
+ element.classList.add("gantt-mx-row-hovered");
10339
+ }
9955
10340
  }
9956
10341
  hoveredRowElementsRef.current = nextHoveredRows;
9957
10342
  }, [clearHoveredRows]);
9958
- const handleSharedRowHover = (0, import_react15.useCallback)((event) => {
10343
+ const handleSharedRowHover = (0, import_react16.useCallback)((event) => {
9959
10344
  const target = event.target;
9960
10345
  const row = target.closest("[data-gantt-task-row-id]");
9961
10346
  const taskId = row?.dataset.ganttTaskRowId;
@@ -9965,7 +10350,7 @@ function TaskGanttChartInner(props, ref) {
9965
10350
  }
9966
10351
  applyHoveredRows(taskId);
9967
10352
  }, [applyHoveredRows]);
9968
- const handleToggleCollapse = externalOnToggleCollapse ?? (0, import_react15.useCallback)((parentId) => {
10353
+ const handleToggleCollapse = externalOnToggleCollapse ?? (0, import_react16.useCallback)((parentId) => {
9969
10354
  setInternalCollapsedParentIds((prev) => {
9970
10355
  const next = new Set(prev);
9971
10356
  if (next.has(parentId)) {
@@ -9976,20 +10361,20 @@ function TaskGanttChartInner(props, ref) {
9976
10361
  return next;
9977
10362
  });
9978
10363
  }, []);
9979
- const allParentIds = (0, import_react15.useMemo)(() => {
10364
+ const allParentIds = (0, import_react16.useMemo)(() => {
9980
10365
  return new Set(
9981
10366
  normalizedTasks.filter((t) => isTaskParent(t.id, normalizedTasks)).map((t) => t.id)
9982
10367
  );
9983
10368
  }, [normalizedTasks]);
9984
- const handleCollapseAll = (0, import_react15.useCallback)(() => {
10369
+ const handleCollapseAll = (0, import_react16.useCallback)(() => {
9985
10370
  if (externalCollapsedParentIds) return;
9986
10371
  setInternalCollapsedParentIds(allParentIds);
9987
10372
  }, [allParentIds, externalCollapsedParentIds]);
9988
- const handleExpandAll = (0, import_react15.useCallback)(() => {
10373
+ const handleExpandAll = (0, import_react16.useCallback)(() => {
9989
10374
  if (externalCollapsedParentIds) return;
9990
10375
  setInternalCollapsedParentIds(/* @__PURE__ */ new Set());
9991
10376
  }, [externalCollapsedParentIds]);
9992
- const exportToPdf = (0, import_react15.useCallback)(async (options) => {
10377
+ const exportToPdf = (0, import_react16.useCallback)(async (options) => {
9993
10378
  const sourceContainer = containerRef.current;
9994
10379
  const sourceContent = scrollContentRef.current;
9995
10380
  if (!sourceContainer || !sourceContent || typeof window === "undefined" || typeof document === "undefined") {
@@ -10025,7 +10410,7 @@ function TaskGanttChartInner(props, ref) {
10025
10410
  orientation: options?.orientation
10026
10411
  });
10027
10412
  }, [showTaskList, showChart]);
10028
- (0, import_react15.useImperativeHandle)(
10413
+ (0, import_react16.useImperativeHandle)(
10029
10414
  ref,
10030
10415
  () => ({
10031
10416
  scrollToToday,
@@ -10048,7 +10433,7 @@ function TaskGanttChartInner(props, ref) {
10048
10433
  }
10049
10434
  return depth;
10050
10435
  }
10051
- const handlePromoteTask = (0, import_react15.useCallback)((taskId) => {
10436
+ const handlePromoteTask = (0, import_react16.useCallback)((taskId) => {
10052
10437
  if (onPromoteTask) {
10053
10438
  onPromoteTask(taskId);
10054
10439
  return;
@@ -10078,7 +10463,7 @@ function TaskGanttChartInner(props, ref) {
10078
10463
  ]);
10079
10464
  onTasksChange?.(reorderedTasks);
10080
10465
  }, [tasks, onTasksChange, onPromoteTask]);
10081
- const handleDemoteTask = (0, import_react15.useCallback)((taskId, newParentId) => {
10466
+ const handleDemoteTask = (0, import_react16.useCallback)((taskId, newParentId) => {
10082
10467
  if (onDemoteTask) {
10083
10468
  onDemoteTask(taskId, newParentId);
10084
10469
  return;
@@ -10119,7 +10504,7 @@ function TaskGanttChartInner(props, ref) {
10119
10504
  };
10120
10505
  onTasksChange?.([updatedDemotedTask]);
10121
10506
  }, [tasks, onTasksChange, onDemoteTask]);
10122
- const handleUngroupTask = (0, import_react15.useCallback)((taskId) => {
10507
+ const handleUngroupTask = (0, import_react16.useCallback)((taskId) => {
10123
10508
  if (onUngroupTask) {
10124
10509
  onUngroupTask(taskId);
10125
10510
  return;
@@ -10144,8 +10529,8 @@ function TaskGanttChartInner(props, ref) {
10144
10529
  onTasksChange?.(changedTasks);
10145
10530
  }
10146
10531
  }, [tasks, onTasksChange, onUngroupTask]);
10147
- const panStateRef = (0, import_react15.useRef)(null);
10148
- const handlePanStart = (0, import_react15.useCallback)((e) => {
10532
+ const panStateRef = (0, import_react16.useRef)(null);
10533
+ const handlePanStart = (0, import_react16.useCallback)((e) => {
10149
10534
  if (e.button !== 0) return;
10150
10535
  const target = e.target;
10151
10536
  if (target.closest("[data-taskbar]")) return;
@@ -10166,7 +10551,7 @@ function TaskGanttChartInner(props, ref) {
10166
10551
  container.style.cursor = "grabbing";
10167
10552
  e.preventDefault();
10168
10553
  }, []);
10169
- (0, import_react15.useEffect)(() => {
10554
+ (0, import_react16.useEffect)(() => {
10170
10555
  const handlePanMove = (e) => {
10171
10556
  const pan = panStateRef.current;
10172
10557
  if (!pan?.active) return;
@@ -10188,190 +10573,221 @@ function TaskGanttChartInner(props, ref) {
10188
10573
  window.removeEventListener("mouseup", handlePanEnd);
10189
10574
  };
10190
10575
  }, []);
10191
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: containerRef, className: "gantt-container", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
10576
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10192
10577
  "div",
10193
10578
  {
10194
- ref: scrollContainerRef,
10195
- className: "gantt-scrollContainer",
10196
- style: { height: containerHeight ?? "auto", cursor: "grab" },
10197
- onMouseDown: handlePanStart,
10198
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
10579
+ ref: containerRef,
10580
+ className: isTableMatrixMode ? "gantt-container gantt-container-tableMatrix" : "gantt-container",
10581
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10199
10582
  "div",
10200
10583
  {
10201
- ref: scrollContentRef,
10202
- className: "gantt-scrollContent",
10203
- onMouseOver: handleSharedRowHover,
10204
- onMouseLeave: clearHoveredRows,
10205
- children: [
10206
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
10207
- TaskList,
10208
- {
10209
- tasks: normalizedTasks,
10210
- rowHeight,
10211
- headerHeight,
10212
- taskListWidth,
10213
- onTasksChange: handleTaskChange,
10214
- selectedTaskId: selectedTaskId ?? void 0,
10215
- onTaskSelect: handleTaskSelect,
10216
- show: showTaskList,
10217
- hasRightShadow: taskListHasRightShadow,
10218
- disableTaskNameEditing,
10219
- disableDependencyEditing,
10220
- onScrollToTask: scrollToTask,
10221
- onSelectedChipChange: setSelectedChip,
10222
- onAdd,
10223
- onDelete: handleDelete,
10224
- onInsertAfter: handleInsertAfter,
10225
- onReorder: handleReorder,
10226
- editingTaskId,
10227
- enableAddTask,
10228
- defaultTaskDurationDays,
10229
- collapsedParentIds,
10230
- onToggleCollapse: handleToggleCollapse,
10231
- onPromoteTask: onPromoteTask ?? handlePromoteTask,
10232
- onDemoteTask: onDemoteTask ?? handleDemoteTask,
10233
- onUngroupTask: onUngroupTask ?? handleUngroupTask,
10234
- highlightedTaskIds: taskListHighlightedTaskIds,
10235
- enableTaskMultiSelect,
10236
- selectedTaskIds,
10237
- onSelectedTaskIdsChange,
10238
- customDays,
10239
- isWeekend: isWeekend3,
10240
- businessDays,
10241
- filterMode,
10242
- filteredTaskIds: matchedTaskIds,
10243
- isFilterActive: !!taskFilter,
10244
- additionalColumns,
10245
- hiddenTaskListColumns,
10246
- taskListMenuCommands,
10247
- taskDateChangeMode,
10248
- onTaskDateChangeModeChange: handleTaskDateChangeMode
10249
- }
10250
- ),
10251
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
10252
- "div",
10253
- {
10254
- className: showChart ? "gantt-chartSurface" : "gantt-chartSurface gantt-chart-hidden",
10255
- style: { minWidth: `${gridWidth}px`, flex: 1, display: showChart ? void 0 : "none" },
10256
- children: [
10257
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
10258
- "div",
10259
- {
10260
- className: "gantt-stickyHeader",
10261
- style: { width: `${gridWidth}px`, height: `${timelineHeaderHeight}px` },
10262
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
10263
- TimeScaleHeader_default,
10584
+ ref: scrollContainerRef,
10585
+ className: "gantt-scrollContainer",
10586
+ style: { height: containerHeight ?? "auto", cursor: "grab" },
10587
+ onMouseDown: handlePanStart,
10588
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
10589
+ "div",
10590
+ {
10591
+ ref: scrollContentRef,
10592
+ className: "gantt-scrollContent",
10593
+ onMouseOver: handleSharedRowHover,
10594
+ onMouseLeave: clearHoveredRows,
10595
+ children: [
10596
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10597
+ TaskList,
10598
+ {
10599
+ tasks: normalizedTasks,
10600
+ rowHeight: effectiveRowHeight,
10601
+ headerHeight,
10602
+ taskListWidth,
10603
+ onTasksChange: handleTaskChange,
10604
+ selectedTaskId: selectedTaskId ?? void 0,
10605
+ onTaskSelect: handleTaskSelect,
10606
+ show: showTaskList,
10607
+ hasRightShadow: taskListHasRightShadow,
10608
+ disableTaskNameEditing,
10609
+ disableDependencyEditing,
10610
+ onScrollToTask: scrollToTask,
10611
+ onSelectedChipChange: setSelectedChip,
10612
+ onAdd,
10613
+ onDelete: handleDelete,
10614
+ onInsertAfter: handleInsertAfter,
10615
+ onReorder: handleReorder,
10616
+ disableTaskDrag,
10617
+ editingTaskId,
10618
+ enableAddTask,
10619
+ defaultTaskDurationDays,
10620
+ collapsedParentIds,
10621
+ onToggleCollapse: handleToggleCollapse,
10622
+ onPromoteTask: onPromoteTask ?? handlePromoteTask,
10623
+ onDemoteTask: onDemoteTask ?? handleDemoteTask,
10624
+ onUngroupTask: onUngroupTask ?? handleUngroupTask,
10625
+ highlightedTaskIds: taskListHighlightedTaskIds,
10626
+ enableTaskMultiSelect,
10627
+ selectedTaskIds,
10628
+ onSelectedTaskIdsChange,
10629
+ customDays,
10630
+ isWeekend: isWeekend3,
10631
+ businessDays,
10632
+ filterMode,
10633
+ filteredTaskIds: matchedTaskIds,
10634
+ isFilterActive: !!taskFilter,
10635
+ additionalColumns,
10636
+ hiddenTaskListColumns,
10637
+ taskListMenuCommands,
10638
+ hideTaskListRowActions,
10639
+ rowContentLines: resolvedRowContentLines,
10640
+ bodyMinHeight: tableBodyMinHeight,
10641
+ taskDateChangeMode,
10642
+ onTaskDateChangeModeChange: handleTaskDateChangeMode
10643
+ }
10644
+ ),
10645
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10646
+ "div",
10647
+ {
10648
+ className: isTableMatrixMode || showChart ? "gantt-chartSurface" : "gantt-chartSurface gantt-chart-hidden",
10649
+ style: {
10650
+ minWidth: `${isTableMatrixMode ? matrixWidth : gridWidth}px`,
10651
+ flex: 1,
10652
+ display: isTableMatrixMode || showChart ? void 0 : "none"
10653
+ },
10654
+ children: isTableMatrixMode ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10655
+ TableMatrix,
10656
+ {
10657
+ tasks: visibleTasks,
10658
+ allTasks: normalizedTasks,
10659
+ columns: matrixColumns,
10660
+ columnGroups: matrixColumnGroups,
10661
+ rowHeight: effectiveRowHeight,
10662
+ headerHeight: timelineHeaderHeight,
10663
+ bodyMinHeight: tableBodyMinHeight,
10664
+ selectedTaskId,
10665
+ onTaskSelect: handleTaskSelect,
10666
+ onCellClick: onMatrixCellClick,
10667
+ highlightedTaskIds: taskListHighlightedTaskIds,
10668
+ filterMode
10669
+ }
10670
+ ) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
10671
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10672
+ "div",
10264
10673
  {
10265
- days: dateRange,
10266
- dayWidth,
10267
- headerHeight,
10268
- viewMode,
10269
- isCustomWeekend
10674
+ className: "gantt-stickyHeader",
10675
+ style: { width: `${gridWidth}px`, height: `${timelineHeaderHeight}px` },
10676
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10677
+ TimeScaleHeader_default,
10678
+ {
10679
+ days: dateRange,
10680
+ dayWidth,
10681
+ headerHeight,
10682
+ viewMode,
10683
+ isCustomWeekend
10684
+ }
10685
+ )
10270
10686
  }
10271
- )
10272
- }
10273
- ),
10274
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
10275
- "div",
10276
- {
10277
- className: "gantt-taskArea",
10278
- style: {
10279
- position: "relative",
10280
- width: `${gridWidth}px`
10281
- },
10282
- children: [
10283
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
10284
- GridBackground_default,
10285
- {
10286
- dateRange,
10287
- dayWidth,
10288
- totalHeight: totalGridHeight,
10289
- viewMode,
10290
- isCustomWeekend
10291
- }
10292
- ),
10293
- todayInRange && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TodayIndicator_default, { monthStart, dayWidth }),
10294
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
10295
- DependencyLines_default,
10296
- {
10297
- tasks: previewVisibleTasks,
10298
- allTasks: previewNormalizedTasks,
10299
- collapsedParentIds,
10300
- monthStart,
10301
- dayWidth,
10302
- rowHeight,
10303
- gridWidth,
10304
- dragOverrides: dependencyOverrides,
10305
- selectedDep: selectedChip,
10306
- businessDays,
10307
- weekendPredicate: isCustomWeekend
10308
- }
10309
- ),
10310
- dragGuideLines && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
10311
- DragGuideLines_default,
10312
- {
10313
- isDragging: dragGuideLines.isDragging,
10314
- dragMode: dragGuideLines.dragMode,
10315
- left: dragGuideLines.left,
10316
- width: dragGuideLines.width,
10317
- totalHeight: totalGridHeight
10318
- }
10319
- ),
10320
- visibleTasks.map((task, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
10321
- TaskRow_default,
10322
- {
10323
- task,
10324
- monthStart,
10325
- dayWidth,
10326
- rowHeight,
10327
- onTasksChange: handleTaskChange,
10328
- onDragStateChange: (state) => {
10329
- if (state.isDragging) {
10330
- setDragGuideLines(state);
10331
- setDraggedTaskOverride({ taskId: task.id, left: state.left, width: state.width });
10332
- } else {
10333
- setDragGuideLines(null);
10334
- setDraggedTaskOverride(null);
10335
- }
10336
- },
10337
- rowIndex: index,
10338
- allTasks: normalizedTasks,
10339
- enableAutoSchedule: enableAutoSchedule ?? false,
10340
- disableConstraints: disableConstraints ?? false,
10341
- overridePosition: cascadeOverrides.get(task.id),
10342
- onCascadeProgress: handleCascadeProgress,
10343
- onCascade: handleCascade,
10344
- highlightExpiredTasks,
10345
- showBaseline,
10346
- isFilterMatch: filterMode === "highlight" ? matchedTaskIds.has(task.id) : false,
10347
- businessDays,
10348
- customDays,
10349
- isWeekend: isWeekend3,
10350
- disableTaskDrag,
10351
- viewMode
10687
+ ),
10688
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
10689
+ "div",
10690
+ {
10691
+ className: "gantt-taskArea",
10692
+ style: {
10693
+ position: "relative",
10694
+ width: `${gridWidth}px`
10352
10695
  },
10353
- task.id
10354
- ))
10355
- ]
10356
- }
10357
- )
10358
- ]
10359
- }
10360
- )
10361
- ]
10696
+ children: [
10697
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10698
+ GridBackground_default,
10699
+ {
10700
+ dateRange,
10701
+ dayWidth,
10702
+ totalHeight: totalGridHeight,
10703
+ viewMode,
10704
+ isCustomWeekend
10705
+ }
10706
+ ),
10707
+ todayInRange && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TodayIndicator_default, { monthStart, dayWidth }),
10708
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10709
+ DependencyLines_default,
10710
+ {
10711
+ tasks: previewVisibleTasks,
10712
+ allTasks: previewNormalizedTasks,
10713
+ collapsedParentIds,
10714
+ monthStart,
10715
+ dayWidth,
10716
+ rowHeight: effectiveRowHeight,
10717
+ gridWidth,
10718
+ dragOverrides: dependencyOverrides,
10719
+ selectedDep: selectedChip,
10720
+ businessDays,
10721
+ weekendPredicate: isCustomWeekend
10722
+ }
10723
+ ),
10724
+ dragGuideLines && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10725
+ DragGuideLines_default,
10726
+ {
10727
+ isDragging: dragGuideLines.isDragging,
10728
+ dragMode: dragGuideLines.dragMode,
10729
+ left: dragGuideLines.left,
10730
+ width: dragGuideLines.width,
10731
+ totalHeight: totalGridHeight
10732
+ }
10733
+ ),
10734
+ visibleTasks.map((task, index) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10735
+ TaskRow_default,
10736
+ {
10737
+ task,
10738
+ monthStart,
10739
+ dayWidth,
10740
+ rowHeight: effectiveRowHeight,
10741
+ onTasksChange: handleTaskChange,
10742
+ onDragStateChange: (state) => {
10743
+ if (state.isDragging) {
10744
+ setDragGuideLines(state);
10745
+ setDraggedTaskOverride({ taskId: task.id, left: state.left, width: state.width });
10746
+ } else {
10747
+ setDragGuideLines(null);
10748
+ setDraggedTaskOverride(null);
10749
+ }
10750
+ },
10751
+ rowIndex: index,
10752
+ allTasks: normalizedTasks,
10753
+ enableAutoSchedule: enableAutoSchedule ?? false,
10754
+ disableConstraints: disableConstraints ?? false,
10755
+ overridePosition: cascadeOverrides.get(task.id),
10756
+ onCascadeProgress: handleCascadeProgress,
10757
+ onCascade: handleCascade,
10758
+ highlightExpiredTasks,
10759
+ showBaseline,
10760
+ isFilterMatch: filterMode === "highlight" ? matchedTaskIds.has(task.id) : false,
10761
+ businessDays,
10762
+ customDays,
10763
+ isWeekend: isWeekend3,
10764
+ disableTaskDrag,
10765
+ viewMode
10766
+ },
10767
+ task.id
10768
+ ))
10769
+ ]
10770
+ }
10771
+ )
10772
+ ] })
10773
+ }
10774
+ )
10775
+ ]
10776
+ }
10777
+ )
10362
10778
  }
10363
10779
  )
10364
10780
  }
10365
- ) });
10781
+ );
10366
10782
  }
10367
- var TaskGanttChart = (0, import_react15.forwardRef)(TaskGanttChartInner);
10368
- var GanttChart = (0, import_react15.forwardRef)(GanttChartInner);
10783
+ var TaskGanttChart = (0, import_react16.forwardRef)(TaskGanttChartInner);
10784
+ var GanttChart = (0, import_react16.forwardRef)(GanttChartInner);
10369
10785
  GanttChart.displayName = "GanttChart";
10370
10786
 
10371
10787
  // src/components/ui/Button.tsx
10372
- var import_react16 = __toESM(require("react"));
10373
- var import_jsx_runtime17 = require("react/jsx-runtime");
10374
- var Button = import_react16.default.forwardRef(
10788
+ var import_react17 = __toESM(require("react"));
10789
+ var import_jsx_runtime18 = require("react/jsx-runtime");
10790
+ var Button = import_react17.default.forwardRef(
10375
10791
  ({ className, variant = "default", size = "default", children, ...props }, ref) => {
10376
10792
  const classes = [
10377
10793
  "gantt-btn",
@@ -10379,7 +10795,7 @@ var Button = import_react16.default.forwardRef(
10379
10795
  size !== "default" ? `gantt-btn-${size}` : "",
10380
10796
  className || ""
10381
10797
  ].filter(Boolean).join(" ");
10382
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { ref, className: classes, ...props, children });
10798
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { ref, className: classes, ...props, children });
10383
10799
  }
10384
10800
  );
10385
10801
  Button.displayName = "Button";
@@ -10431,6 +10847,7 @@ var nameContains = (substring, caseSensitive = false) => (task) => {
10431
10847
  PopoverContent,
10432
10848
  PopoverTrigger,
10433
10849
  ResourceTimelineChart,
10850
+ TableMatrix,
10434
10851
  TaskList,
10435
10852
  TaskRow,
10436
10853
  TimeScaleHeader,