gantt-lib 0.90.0 → 0.100.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
@@ -3,7 +3,7 @@
3
3
  "use client";
4
4
 
5
5
  // src/components/GanttChart/GanttChart.tsx
6
- import { useMemo as useMemo10, useCallback as useCallback8, useRef as useRef9, useState as useState9, useEffect as useEffect9, useImperativeHandle, forwardRef } from "react";
6
+ import { useMemo as useMemo11, useCallback as useCallback8, useRef as useRef9, useState as useState9, useEffect as useEffect9, useImperativeHandle, forwardRef } from "react";
7
7
 
8
8
  // src/core/scheduling/dateMath.ts
9
9
  var DAY_MS = 24 * 60 * 60 * 1e3;
@@ -3807,7 +3807,8 @@ var DatePicker = ({
3807
3807
  className,
3808
3808
  disabled = false,
3809
3809
  isWeekend: isWeekend3,
3810
- businessDays = true
3810
+ businessDays = true,
3811
+ footer
3811
3812
  }) => {
3812
3813
  const [open, setOpen] = useState3(false);
3813
3814
  const [inputValue, setInputValue] = useState3("");
@@ -4085,7 +4086,8 @@ var DatePicker = ({
4085
4086
  initialDate: activeDate,
4086
4087
  isWeekend: isWeekend3
4087
4088
  }
4088
- )
4089
+ ),
4090
+ footer ? /* @__PURE__ */ jsx10("div", { className: "gantt-datepicker-footer", children: footer }) : null
4089
4091
  ]
4090
4092
  }
4091
4093
  )
@@ -4727,9 +4729,15 @@ var TaskListRow = React9.memo(
4727
4729
  resolvedColumns,
4728
4730
  isTaskSelected = false,
4729
4731
  onTaskSelectionChange,
4730
- taskListMenuCommands = []
4732
+ activeCustomCell,
4733
+ onActiveCustomCellChange,
4734
+ taskListMenuCommands = [],
4735
+ hideTaskListRowActions = false,
4736
+ taskDateChangeMode = "preserve-duration",
4737
+ onTaskDateChangeModeChange
4731
4738
  }) => {
4732
4739
  const [editingColumnId, setEditingColumnId] = useState4(null);
4740
+ const [editingColumnStartValue, setEditingColumnStartValue] = useState4(void 0);
4733
4741
  const editingName = editingColumnId === "name";
4734
4742
  const editingDuration = editingColumnId === "duration";
4735
4743
  const editingProgress = editingColumnId === "progress";
@@ -4755,12 +4763,15 @@ var TaskListRow = React9.memo(
4755
4763
  const editTriggerRef = useRef4(
4756
4764
  "doubleclick"
4757
4765
  );
4766
+ const rowRef = useRef4(null);
4758
4767
  const isSelected = selectedTaskId === task.id;
4759
4768
  const isParent = useMemo7(
4760
4769
  () => isTaskParent(task.id, allTasks),
4761
4770
  [task.id, allTasks]
4762
4771
  );
4763
4772
  const isChild = task.parentId !== void 0;
4773
+ const rowFillLevel = Math.min(nestingDepth, 2);
4774
+ const isTotalRow = Boolean(task.isTotal);
4764
4775
  const isMilestoneRow = normalizedTask.type === "milestone";
4765
4776
  const weekendPredicate = useMemo7(
4766
4777
  () => createCustomDayPredicate({ customDays, isWeekend: isWeekend3 }),
@@ -5130,24 +5141,22 @@ var TaskListRow = React9.memo(
5130
5141
  emitMilestoneDateChange(newDateISO);
5131
5142
  return;
5132
5143
  }
5133
- let nextEndISO;
5134
5144
  const normalizedInputStart = businessDays ? alignToWorkingDay(/* @__PURE__ */ new Date(`${newDateISO}T00:00:00.000Z`), 1, weekendPredicate) : /* @__PURE__ */ new Date(`${newDateISO}T00:00:00.000Z`);
5135
- if (businessDays) {
5136
- const duration = getDuration(task.startDate, task.endDate);
5137
- nextEndISO = buildTaskRangeFromStart(
5145
+ const { startDate: normalizedStart, endDate: normalizedEnd } = taskDateChangeMode === "free" ? normalizeTaskDates(
5146
+ normalizedInputStart,
5147
+ normalizedInputStart.getTime() > parseUTCDate(task.endDate).getTime() ? normalizedInputStart : parseUTCDate(task.endDate)
5148
+ ) : normalizeTaskDates(
5149
+ normalizedInputStart,
5150
+ businessDays ? buildTaskRangeFromStart(
5138
5151
  normalizedInputStart,
5139
- duration,
5152
+ getDuration(task.startDate, task.endDate),
5140
5153
  true,
5141
5154
  weekendPredicate,
5142
5155
  1
5143
- ).end.toISOString().split("T")[0];
5144
- } else {
5145
- const origStart = parseUTCDate(task.startDate);
5146
- const origEnd = parseUTCDate(task.endDate);
5147
- const durationMs = origEnd.getTime() - origStart.getTime();
5148
- nextEndISO = new Date(normalizedInputStart.getTime() + durationMs).toISOString().split("T")[0];
5149
- }
5150
- const { startDate: normalizedStart, endDate: normalizedEnd } = normalizeTaskDates(normalizedInputStart, nextEndISO);
5156
+ ).end.toISOString().split("T")[0] : new Date(
5157
+ normalizedInputStart.getTime() + (parseUTCDate(task.endDate).getTime() - parseUTCDate(task.startDate).getTime())
5158
+ ).toISOString().split("T")[0]
5159
+ );
5151
5160
  const clampedRange = clampTaskRangeForIncomingFS(
5152
5161
  task,
5153
5162
  /* @__PURE__ */ new Date(`${normalizedStart}T00:00:00.000Z`),
@@ -5176,7 +5185,7 @@ var TaskListRow = React9.memo(
5176
5185
  }
5177
5186
  ]);
5178
5187
  },
5179
- [task, onTasksChange, businessDays, getDuration, getEndDate, allTasks, weekendPredicate, isMilestone, emitMilestoneDateChange]
5188
+ [task, onTasksChange, businessDays, getDuration, allTasks, weekendPredicate, isMilestone, emitMilestoneDateChange, taskDateChangeMode]
5180
5189
  );
5181
5190
  const handleEndDateChange = useCallback4(
5182
5191
  (newDateISO) => {
@@ -5185,24 +5194,22 @@ var TaskListRow = React9.memo(
5185
5194
  emitMilestoneDateChange(newDateISO);
5186
5195
  return;
5187
5196
  }
5188
- let nextStartISO;
5189
5197
  const normalizedInputEnd = businessDays ? alignToWorkingDay(/* @__PURE__ */ new Date(`${newDateISO}T00:00:00.000Z`), -1, weekendPredicate) : /* @__PURE__ */ new Date(`${newDateISO}T00:00:00.000Z`);
5190
- if (businessDays) {
5191
- const duration = getDuration(task.startDate, task.endDate);
5192
- nextStartISO = buildTaskRangeFromEnd(
5198
+ const { startDate: normalizedStart, endDate: normalizedEnd } = taskDateChangeMode === "free" ? normalizeTaskDates(
5199
+ normalizedInputEnd.getTime() < parseUTCDate(task.startDate).getTime() ? normalizedInputEnd : parseUTCDate(task.startDate),
5200
+ normalizedInputEnd
5201
+ ) : normalizeTaskDates(
5202
+ businessDays ? buildTaskRangeFromEnd(
5193
5203
  normalizedInputEnd,
5194
- duration,
5204
+ getDuration(task.startDate, task.endDate),
5195
5205
  true,
5196
5206
  weekendPredicate,
5197
5207
  -1
5198
- ).start.toISOString().split("T")[0];
5199
- } else {
5200
- const origStart = parseUTCDate(task.startDate);
5201
- const origEnd = parseUTCDate(task.endDate);
5202
- const durationMs = origEnd.getTime() - origStart.getTime();
5203
- nextStartISO = new Date(normalizedInputEnd.getTime() - durationMs).toISOString().split("T")[0];
5204
- }
5205
- const { startDate: normalizedStart, endDate: normalizedEnd } = normalizeTaskDates(nextStartISO, normalizedInputEnd);
5208
+ ).start.toISOString().split("T")[0] : new Date(
5209
+ normalizedInputEnd.getTime() - (parseUTCDate(task.endDate).getTime() - parseUTCDate(task.startDate).getTime())
5210
+ ).toISOString().split("T")[0],
5211
+ normalizedInputEnd
5212
+ );
5206
5213
  const clampedRange = clampTaskRangeForIncomingFS(
5207
5214
  task,
5208
5215
  /* @__PURE__ */ new Date(`${normalizedStart}T00:00:00.000Z`),
@@ -5231,8 +5238,19 @@ var TaskListRow = React9.memo(
5231
5238
  }
5232
5239
  ]);
5233
5240
  },
5234
- [task, onTasksChange, businessDays, getDuration, weekendPredicate, allTasks, isMilestone, emitMilestoneDateChange]
5241
+ [task, onTasksChange, businessDays, getDuration, weekendPredicate, allTasks, isMilestone, emitMilestoneDateChange, taskDateChangeMode]
5235
5242
  );
5243
+ const datePickerFooter = onTaskDateChangeModeChange ? /* @__PURE__ */ jsxs9("label", { className: "gantt-datepicker-mode-checkbox", children: [
5244
+ /* @__PURE__ */ jsx12(
5245
+ "input",
5246
+ {
5247
+ type: "checkbox",
5248
+ checked: taskDateChangeMode === "preserve-duration",
5249
+ onChange: (event) => onTaskDateChangeModeChange(event.target.checked ? "preserve-duration" : "free")
5250
+ }
5251
+ ),
5252
+ /* @__PURE__ */ jsx12("span", { children: "\u0421\u043E\u0445\u0440\u0430\u043D\u044F\u0442\u044C \u0434\u043B\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0441\u0442\u044C" })
5253
+ ] }) : null;
5236
5254
  const handleRowClickInternal = useCallback4(() => {
5237
5255
  onRowClick?.(task.id);
5238
5256
  }, [task.id, onRowClick]);
@@ -5300,7 +5318,7 @@ var TaskListRow = React9.memo(
5300
5318
  ),
5301
5319
  [taskListMenuCommands, task, isParent, isMilestoneRow]
5302
5320
  );
5303
- const hasContextMenu = visibleCustomMenuCommands.length > 0 || !!onDuplicateTask || !!onDelete || !!onTasksChange || isParent && !!onUngroupTask;
5321
+ const hasContextMenu = !hideTaskListRowActions && (visibleCustomMenuCommands.length > 0 || !!onDuplicateTask || !!onDelete || !!onTasksChange || isParent && !!onUngroupTask);
5304
5322
  const handleCustomMenuCommandClick = useCallback4(
5305
5323
  (command) => (e) => {
5306
5324
  e.stopPropagation();
@@ -5539,14 +5557,14 @@ var TaskListRow = React9.memo(
5539
5557
  className: "gantt-tl-cell gantt-tl-cell-number",
5540
5558
  onClick: handleNumberClick,
5541
5559
  children: [
5542
- /* @__PURE__ */ jsx12(
5560
+ onDragStart && /* @__PURE__ */ jsx12(
5543
5561
  "span",
5544
5562
  {
5545
5563
  className: "gantt-tl-drag-handle",
5546
5564
  draggable: true,
5547
5565
  onDragStart: (e) => {
5548
5566
  e.stopPropagation();
5549
- onDragStart?.(rowIndex, e);
5567
+ onDragStart(rowIndex, e);
5550
5568
  },
5551
5569
  onDragEnd: (e) => onDragEnd?.(e),
5552
5570
  onClick: (e) => e.stopPropagation(),
@@ -5742,7 +5760,7 @@ var TaskListRow = React9.memo(
5742
5760
  "aria-hidden": "true"
5743
5761
  }
5744
5762
  ),
5745
- !editingName && (onInsertAfter || onDelete || onPromoteTask || onDemoteTask || onUngroupTask || onDuplicateTask || onTasksChange || hasContextMenu) && /* @__PURE__ */ jsxs9("div", { className: `gantt-tl-name-actions${contextMenuOpen ? " gantt-tl-name-actions-open" : ""}`, children: [
5763
+ !editingName && !hideTaskListRowActions && (onInsertAfter || onDelete || onPromoteTask || onDemoteTask || onUngroupTask || onDuplicateTask || onTasksChange || hasContextMenu) && /* @__PURE__ */ jsxs9("div", { className: `gantt-tl-name-actions${contextMenuOpen ? " gantt-tl-name-actions-open" : ""}`, children: [
5746
5764
  onInsertAfter && /* @__PURE__ */ jsx12(
5747
5765
  "button",
5748
5766
  {
@@ -5931,7 +5949,8 @@ var TaskListRow = React9.memo(
5931
5949
  portal: true,
5932
5950
  disabled: task.locked,
5933
5951
  isWeekend: weekendPredicate,
5934
- businessDays
5952
+ businessDays,
5953
+ footer: datePickerFooter
5935
5954
  }
5936
5955
  )
5937
5956
  }
@@ -5950,7 +5969,8 @@ var TaskListRow = React9.memo(
5950
5969
  portal: true,
5951
5970
  disabled: task.locked,
5952
5971
  isWeekend: weekendPredicate,
5953
- businessDays
5972
+ businessDays,
5973
+ footer: datePickerFooter
5954
5974
  }
5955
5975
  )
5956
5976
  }
@@ -6259,9 +6279,52 @@ var TaskListRow = React9.memo(
6259
6279
  progress: progressCell,
6260
6280
  dependencies: dependenciesCell
6261
6281
  };
6282
+ const focusCustomCell = useCallback4((taskId, columnId) => {
6283
+ const overlay = rowRef.current?.closest(".gantt-tl-overlay");
6284
+ if (!overlay) {
6285
+ return;
6286
+ }
6287
+ const selector = `[data-gantt-task-row-id="${taskId}"] [data-custom-column-id="${columnId}"]`;
6288
+ const nextCell = overlay.querySelector(selector);
6289
+ nextCell?.focus();
6290
+ }, []);
6291
+ const moveActiveCustomCell = useCallback4((columnId, direction) => {
6292
+ const overlay = rowRef.current?.closest(".gantt-tl-overlay");
6293
+ if (!overlay || !resolvedColumns) {
6294
+ return;
6295
+ }
6296
+ const customColumnIds = resolvedColumns.filter((column) => !["selection", "number", "name", "startDate", "endDate", "duration", "progress", "dependencies"].includes(column.id)).map((column) => column.id);
6297
+ const columnIndex = customColumnIds.indexOf(columnId);
6298
+ if (columnIndex === -1) {
6299
+ return;
6300
+ }
6301
+ const rowElements = Array.from(
6302
+ overlay.querySelectorAll(".gantt-tl-row[data-gantt-task-row-id]")
6303
+ );
6304
+ const rowIds = rowElements.map((element) => element.dataset.ganttTaskRowId).filter((value) => Boolean(value));
6305
+ const rowIndex2 = rowIds.indexOf(task.id);
6306
+ if (rowIndex2 === -1) {
6307
+ return;
6308
+ }
6309
+ let nextRowIndex = rowIndex2;
6310
+ let nextColumnIndex = columnIndex;
6311
+ if (direction === "left") nextColumnIndex -= 1;
6312
+ if (direction === "right") nextColumnIndex += 1;
6313
+ if (direction === "up") nextRowIndex -= 1;
6314
+ if (direction === "down") nextRowIndex += 1;
6315
+ if (nextRowIndex < 0 || nextRowIndex >= rowIds.length || nextColumnIndex < 0 || nextColumnIndex >= customColumnIds.length) {
6316
+ return;
6317
+ }
6318
+ const nextCell = { taskId: rowIds[nextRowIndex], columnId: customColumnIds[nextColumnIndex] };
6319
+ onActiveCustomCellChange?.(nextCell);
6320
+ window.requestAnimationFrame(() => {
6321
+ focusCustomCell(nextCell.taskId, nextCell.columnId);
6322
+ });
6323
+ }, [focusCustomCell, onActiveCustomCellChange, resolvedColumns, task.id]);
6262
6324
  return /* @__PURE__ */ jsx12(
6263
6325
  "div",
6264
6326
  {
6327
+ ref: rowRef,
6265
6328
  "data-filter-match": isFilterMatch ? "true" : "false",
6266
6329
  className: [
6267
6330
  "gantt-tl-row",
@@ -6274,9 +6337,11 @@ var TaskListRow = React9.memo(
6274
6337
  isDragging ? "gantt-tl-row-dragging" : "",
6275
6338
  isDragOver ? "gantt-tl-row-drag-over" : "",
6276
6339
  isChild ? "gantt-tl-row-child" : "",
6277
- isParent ? "gantt-tl-row-parent" : ""
6340
+ isParent ? "gantt-tl-row-parent" : "",
6341
+ `gantt-tl-row-level-${rowFillLevel}`,
6342
+ isTotalRow ? "gantt-tl-row-total" : ""
6278
6343
  ].filter(Boolean).join(" "),
6279
- style: { minHeight: `${rowHeight}px`, position: "relative" },
6344
+ style: { height: `${rowHeight}px`, position: "relative" },
6280
6345
  "data-gantt-task-row-id": task.id,
6281
6346
  onClick: handleRowClickInternal,
6282
6347
  onKeyDown: handleRowKeyDown,
@@ -6288,43 +6353,120 @@ var TaskListRow = React9.memo(
6288
6353
  if (builtIn) return /* @__PURE__ */ jsx12(React9.Fragment, { children: builtIn }, col.id);
6289
6354
  const isEditing = editingColumnId === col.id;
6290
6355
  const editorFn = col.renderEditor;
6356
+ const isActiveCustomCell = activeCustomCell?.taskId === task.id && activeCustomCell?.columnId === col.id;
6357
+ const startEditingCustomCell = (startValue) => {
6358
+ if (!editorFn) return;
6359
+ onActiveCustomCellChange?.({ taskId: task.id, columnId: col.id });
6360
+ setEditingColumnStartValue(startValue);
6361
+ setEditingColumnId(col.id);
6362
+ };
6291
6363
  const columnContext = {
6292
6364
  task,
6293
6365
  rowIndex,
6294
6366
  isEditing,
6367
+ editStartValue: isEditing ? editingColumnStartValue : void 0,
6295
6368
  openEditor: () => {
6296
- if (editorFn) setEditingColumnId(col.id);
6369
+ startEditingCustomCell();
6297
6370
  },
6298
6371
  closeEditor: () => {
6299
- if (editingColumnId === col.id) setEditingColumnId(null);
6372
+ if (editingColumnId === col.id) {
6373
+ setEditingColumnId(null);
6374
+ setEditingColumnStartValue(void 0);
6375
+ onActiveCustomCellChange?.({ taskId: task.id, columnId: col.id });
6376
+ window.requestAnimationFrame(() => {
6377
+ focusCustomCell(task.id, col.id);
6378
+ });
6379
+ }
6300
6380
  },
6301
6381
  updateTask: (patch) => {
6302
6382
  onTasksChange?.([{ ...task, ...patch }]);
6383
+ onActiveCustomCellChange?.({ taskId: task.id, columnId: col.id });
6384
+ setEditingColumnStartValue(void 0);
6303
6385
  setEditingColumnId(null);
6386
+ window.requestAnimationFrame(() => {
6387
+ focusCustomCell(task.id, col.id);
6388
+ });
6304
6389
  }
6305
6390
  };
6306
6391
  return /* @__PURE__ */ jsx12(
6307
6392
  "div",
6308
6393
  {
6309
- className: "gantt-tl-cell gantt-tl-cell-custom",
6394
+ className: `gantt-tl-cell gantt-tl-cell-custom gantt-tl-cell-align-${col.align ?? "left"}`,
6310
6395
  "data-column-id": `custom:${col.id}`,
6311
6396
  "data-custom-column-id": col.id,
6397
+ "data-custom-column-active": isActiveCustomCell ? "true" : "false",
6312
6398
  "data-custom-column-editing": isEditing ? "true" : "false",
6313
6399
  "data-testid": `custom-cell-${col.id}`,
6314
- onClick: editorFn && !isEditing ? (e) => {
6400
+ tabIndex: editorFn ? 0 : -1,
6401
+ onFocus: editorFn ? () => {
6402
+ onActiveCustomCellChange?.({ taskId: task.id, columnId: col.id });
6403
+ } : void 0,
6404
+ onClick: editorFn ? (e) => {
6405
+ e.stopPropagation();
6406
+ onActiveCustomCellChange?.({ taskId: task.id, columnId: col.id });
6407
+ if (isEditing) {
6408
+ return;
6409
+ }
6410
+ e.currentTarget.focus();
6411
+ } : void 0,
6412
+ onDoubleClick: editorFn && !isEditing ? (e) => {
6315
6413
  e.stopPropagation();
6316
- setEditingColumnId(col.id);
6414
+ startEditingCustomCell();
6415
+ } : void 0,
6416
+ onKeyDown: editorFn && !isEditing ? (e) => {
6417
+ if (e.key === "ArrowLeft") {
6418
+ e.preventDefault();
6419
+ e.stopPropagation();
6420
+ moveActiveCustomCell(col.id, "left");
6421
+ return;
6422
+ }
6423
+ if (e.key === "ArrowRight") {
6424
+ e.preventDefault();
6425
+ e.stopPropagation();
6426
+ moveActiveCustomCell(col.id, "right");
6427
+ return;
6428
+ }
6429
+ if (e.key === "ArrowUp") {
6430
+ e.preventDefault();
6431
+ e.stopPropagation();
6432
+ moveActiveCustomCell(col.id, "up");
6433
+ return;
6434
+ }
6435
+ if (e.key === "ArrowDown") {
6436
+ e.preventDefault();
6437
+ e.stopPropagation();
6438
+ moveActiveCustomCell(col.id, "down");
6439
+ return;
6440
+ }
6441
+ if (e.key === "Enter" || e.key === "F2") {
6442
+ e.preventDefault();
6443
+ e.stopPropagation();
6444
+ startEditingCustomCell();
6445
+ return;
6446
+ }
6447
+ if (e.key === "Backspace" || e.key === "Delete") {
6448
+ e.preventDefault();
6449
+ e.stopPropagation();
6450
+ startEditingCustomCell("");
6451
+ return;
6452
+ }
6453
+ if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {
6454
+ e.preventDefault();
6455
+ e.stopPropagation();
6456
+ startEditingCustomCell(e.key);
6457
+ }
6317
6458
  } : void 0,
6318
6459
  style: { width: col.width ?? 120, minWidth: col.width ?? 120, flexShrink: 0 },
6319
6460
  children: isEditing && editorFn ? /* @__PURE__ */ jsx12(
6320
6461
  "div",
6321
6462
  {
6463
+ className: "gantt-tl-cell-custom-editor",
6322
6464
  "data-custom-column-editor": col.id,
6323
6465
  onMouseDown: (e) => e.stopPropagation(),
6324
6466
  onClick: (e) => e.stopPropagation(),
6325
6467
  children: editorFn(columnContext)
6326
6468
  }
6327
- ) : col.renderCell(columnContext)
6469
+ ) : /* @__PURE__ */ jsx12("div", { className: "gantt-tl-cell-custom-content", children: col.renderCell(columnContext) })
6328
6470
  },
6329
6471
  col.id
6330
6472
  );
@@ -6376,7 +6518,7 @@ var NewTaskRow = ({
6376
6518
  onCancel();
6377
6519
  }
6378
6520
  };
6379
- return /* @__PURE__ */ jsxs10("div", { className: "gantt-tl-row gantt-tl-row-new", style: { minHeight: `${rowHeight}px` }, children: [
6521
+ return /* @__PURE__ */ jsxs10("div", { className: "gantt-tl-row gantt-tl-row-new", style: { height: `${rowHeight}px` }, children: [
6380
6522
  /* @__PURE__ */ jsx13("div", { className: "gantt-tl-cell gantt-tl-cell-number" }),
6381
6523
  /* @__PURE__ */ jsx13("div", { className: "gantt-tl-cell gantt-tl-cell-name gantt-tl-cell-new-name", children: /* @__PURE__ */ jsx13(
6382
6524
  Input,
@@ -6610,6 +6752,7 @@ var TaskList = ({
6610
6752
  onDelete,
6611
6753
  onInsertAfter,
6612
6754
  onReorder,
6755
+ disableTaskDrag = false,
6613
6756
  editingTaskId: propEditingTaskId,
6614
6757
  enableAddTask = true,
6615
6758
  defaultTaskDurationDays = DEFAULT_TASK_DURATION_DAYS,
@@ -6630,9 +6773,14 @@ var TaskList = ({
6630
6773
  isFilterActive = false,
6631
6774
  additionalColumns,
6632
6775
  hiddenTaskListColumns,
6633
- taskListMenuCommands
6776
+ taskListMenuCommands,
6777
+ hideTaskListRowActions = false,
6778
+ rowContentLines = 1,
6779
+ taskDateChangeMode = "preserve-duration",
6780
+ onTaskDateChangeModeChange
6634
6781
  }) => {
6635
6782
  const [internalSelectedTaskIds, setInternalSelectedTaskIds] = useState6(/* @__PURE__ */ new Set());
6783
+ const [activeCustomCell, setActiveCustomCell] = useState6(null);
6636
6784
  const effectiveSelectedTaskIds = selectedTaskIds ?? internalSelectedTaskIds;
6637
6785
  const emitSelectedTaskIdsChange = useCallback5((nextSelectedTaskIds) => {
6638
6786
  if (!selectedTaskIds) {
@@ -6804,21 +6952,28 @@ var TaskList = ({
6804
6952
  onSelectedChipChange?.(chip);
6805
6953
  }, [onSelectedChipChange]);
6806
6954
  useEffect6(() => {
6807
- if (!selectingPredecessorFor && !selectedChip && !selectedTaskId) return;
6955
+ if (!selectingPredecessorFor && !selectedChip && !selectedTaskId && !activeCustomCell) return;
6808
6956
  const handleKeyDown = (e) => {
6809
6957
  if (e.key === "Escape") {
6810
6958
  setSelectingPredecessorFor(null);
6811
6959
  setSelectedChip(null);
6960
+ setActiveCustomCell(null);
6812
6961
  onSelectedChipChange?.(null);
6813
6962
  onTaskSelect?.(null);
6814
6963
  }
6815
6964
  };
6816
6965
  const handleMouseDown = (e) => {
6817
6966
  const target = e.target;
6818
- if (overlayRef.current?.contains(target)) return;
6967
+ if (overlayRef.current?.contains(target)) {
6968
+ if (activeCustomCell && !target.closest?.("[data-custom-column-id]")) {
6969
+ setActiveCustomCell(null);
6970
+ }
6971
+ return;
6972
+ }
6819
6973
  if (target.closest?.(".gantt-popover")) return;
6820
6974
  setSelectingPredecessorFor(null);
6821
6975
  setSelectedChip(null);
6976
+ setActiveCustomCell(null);
6822
6977
  onSelectedChipChange?.(null);
6823
6978
  onTaskSelect?.(null);
6824
6979
  };
@@ -6828,7 +6983,7 @@ var TaskList = ({
6828
6983
  document.removeEventListener("keydown", handleKeyDown);
6829
6984
  document.removeEventListener("mousedown", handleMouseDown, true);
6830
6985
  };
6831
- }, [selectingPredecessorFor, selectedChip, selectedTaskId, onTaskSelect, onSelectedChipChange]);
6986
+ }, [selectingPredecessorFor, selectedChip, selectedTaskId, activeCustomCell, onTaskSelect, onSelectedChipChange]);
6832
6987
  const handleAddDependency = useCallback5((successorTaskId, predecessorTaskId, linkType) => {
6833
6988
  if (successorTaskId === predecessorTaskId) return;
6834
6989
  if (areTasksHierarchicallyRelated(successorTaskId, predecessorTaskId, tasks)) {
@@ -7218,7 +7373,10 @@ var TaskList = ({
7218
7373
  {
7219
7374
  ref: overlayRef,
7220
7375
  className: `gantt-tl-overlay${show ? "" : " gantt-tl-hidden"}${hasRightShadow ? " gantt-tl-overlay-shadowed" : ""}`,
7221
- style: { "--tasklist-width": `${effectiveTaskListWidth}px` },
7376
+ style: {
7377
+ "--tasklist-width": `${effectiveTaskListWidth}px`,
7378
+ "--gantt-row-content-lines": String(Math.max(2, Math.floor(rowContentLines)))
7379
+ },
7222
7380
  children: /* @__PURE__ */ jsxs11("div", { className: "gantt-tl-table", children: [
7223
7381
  /* @__PURE__ */ jsx14("div", { className: "gantt-tl-header", style: { height: `${tableHeaderHeight}px` }, children: resolvedColumns.map((col) => {
7224
7382
  if (col.id === "selection") {
@@ -7298,7 +7456,7 @@ var TaskList = ({
7298
7456
  return /* @__PURE__ */ jsx14(
7299
7457
  "div",
7300
7458
  {
7301
- className: "gantt-tl-headerCell gantt-tl-headerCell-custom",
7459
+ className: `gantt-tl-headerCell gantt-tl-headerCell-custom gantt-tl-cell-align-${col.align ?? "left"}`,
7302
7460
  "data-column-id": `custom:${col.id}`,
7303
7461
  "data-custom-column-id": col.id,
7304
7462
  style: { width: col.width, minWidth: col.width, flexShrink: 0 },
@@ -7340,12 +7498,12 @@ var TaskList = ({
7340
7498
  onAdd,
7341
7499
  onInsertAfter: handleStartInsertAfter,
7342
7500
  editingTaskId: propEditingTaskId,
7343
- isDragging: draggingIndex === index,
7344
- isDragOver: dragOverIndex === index,
7345
- onDragStart: handleDragStart,
7346
- onDragOver: handleDragOver,
7347
- onDrop: handleDrop,
7348
- onDragEnd: handleDragEnd,
7501
+ isDragging: !disableTaskDrag && draggingIndex === index,
7502
+ isDragOver: !disableTaskDrag && dragOverIndex === index,
7503
+ onDragStart: disableTaskDrag ? void 0 : handleDragStart,
7504
+ onDragOver: disableTaskDrag ? void 0 : handleDragOver,
7505
+ onDrop: disableTaskDrag ? void 0 : handleDrop,
7506
+ onDragEnd: disableTaskDrag ? void 0 : handleDragEnd,
7349
7507
  collapsedParentIds,
7350
7508
  onToggleCollapse: handleToggleCollapse,
7351
7509
  onPromoteTask,
@@ -7366,7 +7524,12 @@ var TaskList = ({
7366
7524
  resolvedColumns,
7367
7525
  isTaskSelected: effectiveSelectedTaskIds.has(task.id),
7368
7526
  onTaskSelectionChange: handleToggleTaskSelection,
7369
- taskListMenuCommands
7527
+ activeCustomCell,
7528
+ onActiveCustomCellChange: setActiveCustomCell,
7529
+ taskListMenuCommands,
7530
+ hideTaskListRowActions,
7531
+ taskDateChangeMode,
7532
+ onTaskDateChangeModeChange
7370
7533
  }
7371
7534
  ),
7372
7535
  pendingInsertDisplayTaskId === task.id && /* @__PURE__ */ jsx14(
@@ -7392,25 +7555,25 @@ var TaskList = ({
7392
7555
  enableAddTask && onAdd && !isCreating && !pendingInsert && /* @__PURE__ */ jsx14(
7393
7556
  "button",
7394
7557
  {
7395
- className: `gantt-tl-add-btn${dragOverIndex === visibleTasks.length ? " gantt-tl-add-btn-drag-over" : ""}`,
7558
+ className: `gantt-tl-add-btn${!disableTaskDrag && dragOverIndex === visibleTasks.length ? " gantt-tl-add-btn-drag-over" : ""}`,
7396
7559
  onClick: () => {
7397
7560
  setPendingInsert(null);
7398
7561
  setIsCreating(true);
7399
7562
  },
7400
- onDragEnter: (e) => {
7563
+ onDragEnter: disableTaskDrag ? void 0 : (e) => {
7401
7564
  e.preventDefault();
7402
7565
  setDragOverIndex(visibleTasks.length);
7403
7566
  },
7404
- onDragOver: (e) => {
7567
+ onDragOver: disableTaskDrag ? void 0 : (e) => {
7405
7568
  e.preventDefault();
7406
7569
  e.dataTransfer.dropEffect = "move";
7407
7570
  setDragOverIndex(visibleTasks.length);
7408
7571
  },
7409
- onDragLeave: (e) => {
7572
+ onDragLeave: disableTaskDrag ? void 0 : (e) => {
7410
7573
  e.preventDefault();
7411
7574
  setDragOverIndex(null);
7412
7575
  },
7413
- onDrop: (e) => {
7576
+ onDrop: disableTaskDrag ? void 0 : (e) => {
7414
7577
  e.preventDefault();
7415
7578
  handleDrop(visibleTasks.length, e);
7416
7579
  },
@@ -9103,6 +9266,190 @@ function ResourceTimelineChart({
9103
9266
  ) });
9104
9267
  }
9105
9268
 
9269
+ // src/components/TableMatrix/TableMatrix.tsx
9270
+ import { useMemo as useMemo10 } from "react";
9271
+ import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
9272
+ function joinClasses(...values) {
9273
+ return values.filter(Boolean).join(" ");
9274
+ }
9275
+ function TableMatrix({
9276
+ tasks,
9277
+ allTasks = tasks,
9278
+ columns,
9279
+ columnGroups,
9280
+ rowHeight,
9281
+ headerHeight,
9282
+ selectedTaskId,
9283
+ onTaskSelect,
9284
+ onCellClick,
9285
+ highlightedTaskIds,
9286
+ filterMode = "highlight"
9287
+ }) {
9288
+ const gridTemplateColumns = useMemo10(
9289
+ () => columns.map((column) => `${column.width}px`).join(" "),
9290
+ [columns]
9291
+ );
9292
+ const totalWidth = useMemo10(
9293
+ () => columns.reduce((sum, column) => sum + column.width, 0),
9294
+ [columns]
9295
+ );
9296
+ const hasGroupHeader = useMemo10(
9297
+ () => columns.some((column) => !!column.groupId) || (columnGroups?.length ?? 0) > 0,
9298
+ [columnGroups, columns]
9299
+ );
9300
+ const groupMap = useMemo10(
9301
+ () => new Map((columnGroups ?? []).map((group) => [group.id, group])),
9302
+ [columnGroups]
9303
+ );
9304
+ const headerSpans = useMemo10(() => {
9305
+ if (!hasGroupHeader) return [];
9306
+ if (columnGroups?.some((group) => typeof group.width === "number")) {
9307
+ return columnGroups.map((group) => ({
9308
+ id: group.id,
9309
+ header: group.header,
9310
+ width: group.width ?? 0,
9311
+ className: group.className
9312
+ }));
9313
+ }
9314
+ const spans = [];
9315
+ for (const column of columns) {
9316
+ const groupId = column.groupId ?? column.id;
9317
+ const lastSpan = spans[spans.length - 1];
9318
+ if (lastSpan?.id === groupId) {
9319
+ lastSpan.width += column.width;
9320
+ continue;
9321
+ }
9322
+ const group = groupMap.get(groupId);
9323
+ spans.push({
9324
+ id: groupId,
9325
+ header: group?.header ?? column.header,
9326
+ width: column.width,
9327
+ className: group?.className
9328
+ });
9329
+ }
9330
+ return spans;
9331
+ }, [columns, groupMap, hasGroupHeader]);
9332
+ const headerContentHeight = Math.max(0, headerHeight - 1);
9333
+ const topRowHeight = hasGroupHeader ? Math.ceil(headerContentHeight / 2) : headerContentHeight;
9334
+ const bottomRowHeight = hasGroupHeader ? Math.floor(headerContentHeight / 2) : 0;
9335
+ const parentTaskIds = useMemo10(() => {
9336
+ const ids = /* @__PURE__ */ new Set();
9337
+ for (const task of allTasks) {
9338
+ if (task.parentId) {
9339
+ ids.add(task.parentId);
9340
+ }
9341
+ }
9342
+ return ids;
9343
+ }, [allTasks]);
9344
+ const nestingDepthMap = useMemo10(() => {
9345
+ const depthMap = /* @__PURE__ */ new Map();
9346
+ const taskById = new Map(allTasks.map((task) => [task.id, task]));
9347
+ const getDepth = (taskId, seen = /* @__PURE__ */ new Set()) => {
9348
+ if (depthMap.has(taskId)) return depthMap.get(taskId);
9349
+ if (seen.has(taskId)) return 0;
9350
+ const task = taskById.get(taskId);
9351
+ if (!task?.parentId || !taskById.has(task.parentId)) {
9352
+ depthMap.set(taskId, 0);
9353
+ return 0;
9354
+ }
9355
+ seen.add(taskId);
9356
+ const depth = getDepth(task.parentId, seen) + 1;
9357
+ depthMap.set(taskId, depth);
9358
+ return depth;
9359
+ };
9360
+ for (const task of allTasks) {
9361
+ getDepth(task.id);
9362
+ }
9363
+ return depthMap;
9364
+ }, [allTasks]);
9365
+ return /* @__PURE__ */ jsxs13("div", { className: "gantt-mx-root", style: { width: `${totalWidth}px` }, children: [
9366
+ /* @__PURE__ */ jsxs13("div", { className: "gantt-mx-header", style: { height: `${headerHeight}px` }, children: [
9367
+ hasGroupHeader && /* @__PURE__ */ jsx16(
9368
+ "div",
9369
+ {
9370
+ className: "gantt-mx-headerRow gantt-mx-headerGroupRow",
9371
+ style: { gridTemplateColumns: headerSpans.map((span) => `${span.width}px`).join(" "), height: `${topRowHeight}px` },
9372
+ children: headerSpans.map((span) => /* @__PURE__ */ jsx16("div", { className: joinClasses("gantt-mx-groupCell", span.className), children: span.header }, span.id))
9373
+ }
9374
+ ),
9375
+ /* @__PURE__ */ jsx16(
9376
+ "div",
9377
+ {
9378
+ className: "gantt-mx-headerRow",
9379
+ style: { gridTemplateColumns, height: `${hasGroupHeader ? bottomRowHeight : topRowHeight}px` },
9380
+ children: columns.map((column) => /* @__PURE__ */ jsx16(
9381
+ "div",
9382
+ {
9383
+ className: joinClasses(
9384
+ "gantt-mx-headerCell",
9385
+ column.headerClassName
9386
+ ),
9387
+ children: column.header
9388
+ },
9389
+ column.id
9390
+ ))
9391
+ }
9392
+ )
9393
+ ] }),
9394
+ /* @__PURE__ */ jsx16(
9395
+ "div",
9396
+ {
9397
+ className: "gantt-mx-body",
9398
+ style: { height: `${tasks.length * rowHeight}px` },
9399
+ children: tasks.map((task, index) => {
9400
+ const isHighlighted = filterMode === "highlight" && !!highlightedTaskIds?.has(task.id);
9401
+ const isParent = parentTaskIds.has(task.id);
9402
+ const nestingDepth = nestingDepthMap.get(task.id) ?? 0;
9403
+ const rowFillLevel = Math.min(nestingDepth, 2);
9404
+ const isTotal = Boolean(task.isTotal);
9405
+ return /* @__PURE__ */ jsx16(
9406
+ "div",
9407
+ {
9408
+ "data-gantt-task-row-id": task.id,
9409
+ className: joinClasses(
9410
+ "gantt-mx-row",
9411
+ task.parentId && "gantt-mx-row-child",
9412
+ isParent && "gantt-mx-row-parent",
9413
+ `gantt-mx-row-level-${rowFillLevel}`,
9414
+ isTotal && "gantt-mx-row-total",
9415
+ selectedTaskId === task.id && "gantt-mx-row-selected",
9416
+ isHighlighted && "gantt-mx-row-highlighted"
9417
+ ),
9418
+ style: {
9419
+ gridTemplateColumns,
9420
+ top: `${index * rowHeight}px`,
9421
+ height: `${rowHeight}px`
9422
+ },
9423
+ onClick: () => onTaskSelect?.(task.id),
9424
+ children: columns.map((column, columnIndex) => {
9425
+ const resolvedCellClassName = typeof column.cellClassName === "function" ? column.cellClassName(task) : column.cellClassName;
9426
+ return /* @__PURE__ */ jsx16(
9427
+ "div",
9428
+ {
9429
+ className: joinClasses(
9430
+ "gantt-mx-cell",
9431
+ onCellClick && "gantt-mx-cell-clickable",
9432
+ `gantt-mx-cellAlign-${column.align ?? "right"}`,
9433
+ column.className,
9434
+ resolvedCellClassName
9435
+ ),
9436
+ onClick: (event) => {
9437
+ onCellClick?.({ task, column, rowIndex: index, columnIndex, event });
9438
+ },
9439
+ children: column.renderCell(task)
9440
+ },
9441
+ `${task.id}:${column.id}`
9442
+ );
9443
+ })
9444
+ },
9445
+ task.id
9446
+ );
9447
+ })
9448
+ }
9449
+ )
9450
+ ] });
9451
+ }
9452
+
9106
9453
  // src/components/GanttChart/print.ts
9107
9454
  function getPrintDocumentTitle({
9108
9455
  header,
@@ -9441,13 +9788,13 @@ async function printGanttChart({
9441
9788
  }
9442
9789
 
9443
9790
  // src/components/GanttChart/GanttChart.tsx
9444
- import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
9791
+ import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
9445
9792
  var SCROLL_TO_ROW_CONTEXT_ROWS = 2;
9446
9793
  function GanttChartInner(props, ref) {
9447
9794
  if (props.mode === "resource-planner") {
9448
- return /* @__PURE__ */ jsx16(ResourceTimelineChart, { ...props });
9795
+ return /* @__PURE__ */ jsx17(ResourceTimelineChart, { ...props });
9449
9796
  }
9450
- return /* @__PURE__ */ jsx16(
9797
+ return /* @__PURE__ */ jsx17(
9451
9798
  TaskGanttChart,
9452
9799
  {
9453
9800
  ...props,
@@ -9456,9 +9803,9 @@ function GanttChartInner(props, ref) {
9456
9803
  );
9457
9804
  }
9458
9805
  function TaskGanttChartInner(props, ref) {
9806
+ const isTableMatrixMode = props.mode === "table-matrix";
9459
9807
  const {
9460
9808
  tasks,
9461
- dayWidth = 40,
9462
9809
  rowHeight = 40,
9463
9810
  headerHeight = 40,
9464
9811
  containerHeight,
@@ -9482,10 +9829,6 @@ function TaskGanttChartInner(props, ref) {
9482
9829
  onUngroupTask,
9483
9830
  enableAddTask = true,
9484
9831
  defaultTaskDurationDays,
9485
- viewMode = "day",
9486
- customDays,
9487
- isWeekend: isWeekend3,
9488
- businessDays = true,
9489
9832
  taskFilter,
9490
9833
  filterMode = "highlight",
9491
9834
  collapsedParentIds: externalCollapsedParentIds,
@@ -9498,24 +9841,44 @@ function TaskGanttChartInner(props, ref) {
9498
9841
  showChart = true,
9499
9842
  additionalColumns,
9500
9843
  hiddenTaskListColumns,
9501
- taskListMenuCommands
9844
+ taskListMenuCommands,
9845
+ hideTaskListRowActions = false,
9846
+ rowContentLines = 1,
9847
+ taskDateChangeMode: externalTaskDateChangeMode,
9848
+ onTaskDateChangeModeChange: externalOnTaskDateChangeModeChange
9502
9849
  } = props;
9850
+ const dayWidth = !isTableMatrixMode ? props.dayWidth ?? 40 : 40;
9851
+ const viewMode = !isTableMatrixMode ? props.viewMode ?? "day" : "day";
9852
+ const customDays = !isTableMatrixMode ? props.customDays : void 0;
9853
+ const isWeekend3 = !isTableMatrixMode ? props.isWeekend : void 0;
9854
+ const businessDays = !isTableMatrixMode ? props.businessDays ?? true : true;
9855
+ const matrixColumns = isTableMatrixMode ? props.matrixColumns : [];
9856
+ const matrixColumnGroups = isTableMatrixMode ? props.matrixColumnGroups : void 0;
9857
+ const onMatrixCellClick = isTableMatrixMode ? props.onMatrixCellClick : void 0;
9503
9858
  const containerRef = useRef9(null);
9504
9859
  const scrollContainerRef = useRef9(null);
9505
9860
  const scrollContentRef = useRef9(null);
9506
9861
  const clearSelectedTaskTimeoutRef = useRef9(null);
9507
9862
  const [selectedTaskId, setSelectedTaskId] = useState9(null);
9508
9863
  const [taskListHasRightShadow, setTaskListHasRightShadow] = useState9(false);
9864
+ const [internalTaskDateChangeMode, setInternalTaskDateChangeMode] = useState9("preserve-duration");
9509
9865
  const [selectedChip, setSelectedChip] = useState9(null);
9510
9866
  const [internalCollapsedParentIds, setInternalCollapsedParentIds] = useState9(/* @__PURE__ */ new Set());
9511
9867
  const collapsedParentIds = externalCollapsedParentIds ?? internalCollapsedParentIds;
9512
9868
  const [editingTaskId, setEditingTaskId] = useState9(null);
9513
- const normalizedTasks = useMemo10(() => normalizeHierarchyTasks(tasks), [tasks]);
9514
- const isCustomWeekend = useMemo10(
9869
+ const taskDateChangeMode = externalTaskDateChangeMode ?? internalTaskDateChangeMode;
9870
+ const handleTaskDateChangeMode = externalOnTaskDateChangeModeChange ?? setInternalTaskDateChangeMode;
9871
+ const resolvedRowContentLines = Math.max(1, Math.floor(rowContentLines));
9872
+ const effectiveRowHeight = useMemo11(
9873
+ () => Math.max(rowHeight, 10 + resolvedRowContentLines * 18),
9874
+ [resolvedRowContentLines, rowHeight]
9875
+ );
9876
+ const normalizedTasks = useMemo11(() => normalizeHierarchyTasks(tasks), [tasks]);
9877
+ const isCustomWeekend = useMemo11(
9515
9878
  () => createCustomDayPredicate({ customDays, isWeekend: isWeekend3 }),
9516
9879
  [customDays, isWeekend3]
9517
9880
  );
9518
- const dateRangeTasks = useMemo10(() => {
9881
+ const dateRangeTasks = useMemo11(() => {
9519
9882
  if (!showBaseline) {
9520
9883
  return normalizedTasks;
9521
9884
  }
@@ -9525,14 +9888,18 @@ function TaskGanttChartInner(props, ref) {
9525
9888
  endDate: task.baselineEndDate && parseUTCDate(task.baselineEndDate).getTime() > parseUTCDate(task.endDate).getTime() ? task.baselineEndDate : task.endDate
9526
9889
  }));
9527
9890
  }, [normalizedTasks, showBaseline]);
9528
- const dateRange = useMemo10(() => getMultiMonthDays(dateRangeTasks), [dateRangeTasks]);
9891
+ const dateRange = useMemo11(() => getMultiMonthDays(dateRangeTasks), [dateRangeTasks]);
9529
9892
  const [validationResult, setValidationResult] = useState9(null);
9530
9893
  const [cascadeOverrides, setCascadeOverrides] = useState9(/* @__PURE__ */ new Map());
9531
- const gridWidth = useMemo10(
9894
+ const gridWidth = useMemo11(
9532
9895
  () => Math.round(dateRange.length * dayWidth),
9533
9896
  [dateRange.length, dayWidth]
9534
9897
  );
9535
- const visibleTasks = useMemo10(() => {
9898
+ const matrixWidth = useMemo11(
9899
+ () => matrixColumns.reduce((sum, column) => sum + column.width, 0),
9900
+ [matrixColumns]
9901
+ );
9902
+ const visibleTasks = useMemo11(() => {
9536
9903
  const parentMap = new Map(normalizedTasks.map((t) => [t.id, t.parentId]));
9537
9904
  function isAnyAncestorCollapsed(parentId) {
9538
9905
  let current = parentId;
@@ -9548,11 +9915,11 @@ function TaskGanttChartInner(props, ref) {
9548
9915
  }
9549
9916
  return tasks2;
9550
9917
  }, [normalizedTasks, collapsedParentIds, filterMode, taskFilter]);
9551
- const matchedTaskIds = useMemo10(() => {
9918
+ const matchedTaskIds = useMemo11(() => {
9552
9919
  if (!taskFilter) return /* @__PURE__ */ new Set();
9553
9920
  return new Set(visibleTasks.filter(taskFilter).map((task) => task.id));
9554
9921
  }, [visibleTasks, taskFilter]);
9555
- const taskListHighlightedTaskIds = useMemo10(() => {
9922
+ const taskListHighlightedTaskIds = useMemo11(() => {
9556
9923
  if (filterMode === "hide") {
9557
9924
  return /* @__PURE__ */ new Set();
9558
9925
  }
@@ -9563,24 +9930,25 @@ function TaskGanttChartInner(props, ref) {
9563
9930
  matchedTaskIds.forEach((taskId) => mergedHighlightedTaskIds.add(taskId));
9564
9931
  return mergedHighlightedTaskIds;
9565
9932
  }, [filterMode, highlightedTaskIds, matchedTaskIds]);
9566
- const totalGridHeight = useMemo10(
9567
- () => visibleTasks.length * rowHeight,
9568
- [visibleTasks.length, rowHeight]
9933
+ const totalGridHeight = useMemo11(
9934
+ () => visibleTasks.length * effectiveRowHeight,
9935
+ [effectiveRowHeight, visibleTasks.length]
9569
9936
  );
9570
9937
  const timelineHeaderHeight = headerHeight + 1;
9571
- const monthStart = useMemo10(() => {
9938
+ const monthStart = useMemo11(() => {
9572
9939
  if (dateRange.length === 0) {
9573
9940
  return new Date(Date.UTC((/* @__PURE__ */ new Date()).getUTCFullYear(), (/* @__PURE__ */ new Date()).getUTCMonth(), 1));
9574
9941
  }
9575
9942
  const firstDay = dateRange[0];
9576
9943
  return new Date(Date.UTC(firstDay.getUTCFullYear(), firstDay.getUTCMonth(), 1));
9577
9944
  }, [dateRange]);
9578
- const todayInRange = useMemo10(() => {
9945
+ const todayInRange = useMemo11(() => {
9579
9946
  const now = /* @__PURE__ */ new Date();
9580
9947
  const today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
9581
9948
  return dateRange.some((day) => day.getTime() === today.getTime());
9582
9949
  }, [dateRange]);
9583
9950
  useEffect9(() => {
9951
+ if (isTableMatrixMode) return;
9584
9952
  const container = scrollContainerRef.current;
9585
9953
  if (!container || dateRange.length === 0) return;
9586
9954
  const now = /* @__PURE__ */ new Date();
@@ -9591,7 +9959,7 @@ function TaskGanttChartInner(props, ref) {
9591
9959
  const containerWidth = container.clientWidth;
9592
9960
  const scrollLeft = Math.round(todayOffset + dayWidth / 2 - containerWidth * 0.3);
9593
9961
  container.scrollLeft = Math.max(0, scrollLeft);
9594
- }, []);
9962
+ }, [dateRange, dayWidth, isTableMatrixMode]);
9595
9963
  useEffect9(() => {
9596
9964
  const container = scrollContainerRef.current;
9597
9965
  if (!container) return;
@@ -9605,6 +9973,7 @@ function TaskGanttChartInner(props, ref) {
9605
9973
  };
9606
9974
  }, []);
9607
9975
  const scrollToToday = useCallback8(() => {
9976
+ if (isTableMatrixMode) return;
9608
9977
  const container = scrollContainerRef.current;
9609
9978
  if (!container || dateRange.length === 0) return;
9610
9979
  const now = /* @__PURE__ */ new Date();
@@ -9615,8 +9984,18 @@ function TaskGanttChartInner(props, ref) {
9615
9984
  const containerWidth = container.clientWidth;
9616
9985
  const scrollLeft = Math.round(todayOffset + dayWidth / 2 - containerWidth * 0.3);
9617
9986
  container.scrollTo({ left: Math.max(0, scrollLeft), behavior: "smooth" });
9618
- }, [dateRange, dayWidth]);
9987
+ }, [dateRange, dayWidth, isTableMatrixMode]);
9619
9988
  const scrollToTask = useCallback8((taskId) => {
9989
+ if (isTableMatrixMode) {
9990
+ const container2 = scrollContainerRef.current;
9991
+ if (!container2) return;
9992
+ const rowIndex = visibleTasks.findIndex((visibleTask) => visibleTask.id === taskId);
9993
+ if (rowIndex === -1) return;
9994
+ const paddedRowIndex = Math.max(0, rowIndex - SCROLL_TO_ROW_CONTEXT_ROWS);
9995
+ container2.scrollTo({ top: Math.max(0, effectiveRowHeight * paddedRowIndex), behavior: "smooth" });
9996
+ setSelectedTaskId(taskId);
9997
+ return;
9998
+ }
9620
9999
  const container = scrollContainerRef.current;
9621
10000
  if (!container || dateRange.length === 0) return;
9622
10001
  const task = tasks.find((t) => t.id === taskId);
@@ -9632,7 +10011,7 @@ function TaskGanttChartInner(props, ref) {
9632
10011
  const taskOffset = taskIndex * dayWidth;
9633
10012
  const scrollLeft = Math.round(taskOffset - dayWidth * 2);
9634
10013
  container.scrollTo({ left: Math.max(0, scrollLeft), behavior: "smooth" });
9635
- }, [tasks, dateRange, dayWidth]);
10014
+ }, [dateRange, dayWidth, effectiveRowHeight, isTableMatrixMode, tasks, visibleTasks]);
9636
10015
  const scrollToRow = useCallback8((taskId, options = {}) => {
9637
10016
  const container = scrollContainerRef.current;
9638
10017
  if (!container) return;
@@ -9641,7 +10020,7 @@ function TaskGanttChartInner(props, ref) {
9641
10020
  const rowIndex = visibleTasks.findIndex((visibleTask) => visibleTask.id === task.id);
9642
10021
  if (rowIndex === -1) return;
9643
10022
  const paddedRowIndex = Math.max(0, rowIndex - SCROLL_TO_ROW_CONTEXT_ROWS);
9644
- const scrollTop = Math.max(0, rowHeight * paddedRowIndex);
10023
+ const scrollTop = Math.max(0, effectiveRowHeight * paddedRowIndex);
9645
10024
  const {
9646
10025
  select = true,
9647
10026
  behavior = "smooth",
@@ -9661,7 +10040,7 @@ function TaskGanttChartInner(props, ref) {
9661
10040
  }
9662
10041
  }
9663
10042
  container.scrollTo({ top: scrollTop, behavior });
9664
- }, [tasks, visibleTasks, rowHeight]);
10043
+ }, [effectiveRowHeight, tasks, visibleTasks]);
9665
10044
  const [dragGuideLines, setDragGuideLines] = useState9(null);
9666
10045
  const [draggedTaskOverride, setDraggedTaskOverride] = useState9(null);
9667
10046
  const [previewTasksById, setPreviewTasksById] = useState9(/* @__PURE__ */ new Map());
@@ -9766,7 +10145,7 @@ function TaskGanttChartInner(props, ref) {
9766
10145
  }
9767
10146
  onTasksChange?.(normalized);
9768
10147
  }, [onTasksChange, onReorder]);
9769
- const dependencyOverrides = useMemo10(() => {
10148
+ const dependencyOverrides = useMemo11(() => {
9770
10149
  const map = new Map(cascadeOverrides);
9771
10150
  if (draggedTaskOverride) {
9772
10151
  map.set(draggedTaskOverride.taskId, {
@@ -9780,11 +10159,11 @@ function TaskGanttChartInner(props, ref) {
9780
10159
  setCascadeOverrides(new Map(overrides));
9781
10160
  setPreviewTasksById(new Map(previewTasks.map((task) => [task.id, task])));
9782
10161
  }, []);
9783
- const previewNormalizedTasks = useMemo10(() => {
10162
+ const previewNormalizedTasks = useMemo11(() => {
9784
10163
  if (previewTasksById.size === 0) return normalizedTasks;
9785
10164
  return normalizedTasks.map((task) => previewTasksById.get(task.id) ?? task);
9786
10165
  }, [normalizedTasks, previewTasksById]);
9787
- const previewVisibleTasks = useMemo10(() => {
10166
+ const previewVisibleTasks = useMemo11(() => {
9788
10167
  if (previewTasksById.size === 0) return visibleTasks;
9789
10168
  return visibleTasks.map((task) => previewTasksById.get(task.id) ?? task);
9790
10169
  }, [visibleTasks, previewTasksById]);
@@ -9797,7 +10176,7 @@ function TaskGanttChartInner(props, ref) {
9797
10176
  const hoveredRowElementsRef = useRef9([]);
9798
10177
  const clearHoveredRows = useCallback8(() => {
9799
10178
  for (const element of hoveredRowElementsRef.current) {
9800
- element.classList.remove("gantt-tl-row-hovered", "gantt-tr-row-hovered");
10179
+ element.classList.remove("gantt-tl-row-hovered", "gantt-tr-row-hovered", "gantt-mx-row-hovered");
9801
10180
  }
9802
10181
  hoveredRowElementsRef.current = [];
9803
10182
  }, []);
@@ -9815,6 +10194,9 @@ function TaskGanttChartInner(props, ref) {
9815
10194
  if (element.classList.contains("gantt-tr-row")) {
9816
10195
  element.classList.add("gantt-tr-row-hovered");
9817
10196
  }
10197
+ if (element.classList.contains("gantt-mx-row")) {
10198
+ element.classList.add("gantt-mx-row-hovered");
10199
+ }
9818
10200
  }
9819
10201
  hoveredRowElementsRef.current = nextHoveredRows;
9820
10202
  }, [clearHoveredRows]);
@@ -9839,7 +10221,7 @@ function TaskGanttChartInner(props, ref) {
9839
10221
  return next;
9840
10222
  });
9841
10223
  }, []);
9842
- const allParentIds = useMemo10(() => {
10224
+ const allParentIds = useMemo11(() => {
9843
10225
  return new Set(
9844
10226
  normalizedTasks.filter((t) => isTaskParent(t.id, normalizedTasks)).map((t) => t.id)
9845
10227
  );
@@ -10051,188 +10433,219 @@ function TaskGanttChartInner(props, ref) {
10051
10433
  window.removeEventListener("mouseup", handlePanEnd);
10052
10434
  };
10053
10435
  }, []);
10054
- return /* @__PURE__ */ jsx16("div", { ref: containerRef, className: "gantt-container", children: /* @__PURE__ */ jsx16(
10436
+ return /* @__PURE__ */ jsx17(
10055
10437
  "div",
10056
10438
  {
10057
- ref: scrollContainerRef,
10058
- className: "gantt-scrollContainer",
10059
- style: { height: containerHeight ?? "auto", cursor: "grab" },
10060
- onMouseDown: handlePanStart,
10061
- children: /* @__PURE__ */ jsxs13(
10439
+ ref: containerRef,
10440
+ className: isTableMatrixMode ? "gantt-container gantt-container-tableMatrix" : "gantt-container",
10441
+ children: /* @__PURE__ */ jsx17(
10062
10442
  "div",
10063
10443
  {
10064
- ref: scrollContentRef,
10065
- className: "gantt-scrollContent",
10066
- onMouseOver: handleSharedRowHover,
10067
- onMouseLeave: clearHoveredRows,
10068
- children: [
10069
- /* @__PURE__ */ jsx16(
10070
- TaskList,
10071
- {
10072
- tasks: normalizedTasks,
10073
- rowHeight,
10074
- headerHeight,
10075
- taskListWidth,
10076
- onTasksChange: handleTaskChange,
10077
- selectedTaskId: selectedTaskId ?? void 0,
10078
- onTaskSelect: handleTaskSelect,
10079
- show: showTaskList,
10080
- hasRightShadow: taskListHasRightShadow,
10081
- disableTaskNameEditing,
10082
- disableDependencyEditing,
10083
- onScrollToTask: scrollToTask,
10084
- onSelectedChipChange: setSelectedChip,
10085
- onAdd,
10086
- onDelete: handleDelete,
10087
- onInsertAfter: handleInsertAfter,
10088
- onReorder: handleReorder,
10089
- editingTaskId,
10090
- enableAddTask,
10091
- defaultTaskDurationDays,
10092
- collapsedParentIds,
10093
- onToggleCollapse: handleToggleCollapse,
10094
- onPromoteTask: onPromoteTask ?? handlePromoteTask,
10095
- onDemoteTask: onDemoteTask ?? handleDemoteTask,
10096
- onUngroupTask: onUngroupTask ?? handleUngroupTask,
10097
- highlightedTaskIds: taskListHighlightedTaskIds,
10098
- enableTaskMultiSelect,
10099
- selectedTaskIds,
10100
- onSelectedTaskIdsChange,
10101
- customDays,
10102
- isWeekend: isWeekend3,
10103
- businessDays,
10104
- filterMode,
10105
- filteredTaskIds: matchedTaskIds,
10106
- isFilterActive: !!taskFilter,
10107
- additionalColumns,
10108
- hiddenTaskListColumns,
10109
- taskListMenuCommands
10110
- }
10111
- ),
10112
- /* @__PURE__ */ jsxs13(
10113
- "div",
10114
- {
10115
- className: showChart ? "gantt-chartSurface" : "gantt-chartSurface gantt-chart-hidden",
10116
- style: { minWidth: `${gridWidth}px`, flex: 1, display: showChart ? void 0 : "none" },
10117
- children: [
10118
- /* @__PURE__ */ jsx16(
10119
- "div",
10120
- {
10121
- className: "gantt-stickyHeader",
10122
- style: { width: `${gridWidth}px`, height: `${timelineHeaderHeight}px` },
10123
- children: /* @__PURE__ */ jsx16(
10124
- TimeScaleHeader_default,
10444
+ ref: scrollContainerRef,
10445
+ className: "gantt-scrollContainer",
10446
+ style: { height: containerHeight ?? "auto", cursor: "grab" },
10447
+ onMouseDown: handlePanStart,
10448
+ children: /* @__PURE__ */ jsxs14(
10449
+ "div",
10450
+ {
10451
+ ref: scrollContentRef,
10452
+ className: "gantt-scrollContent",
10453
+ onMouseOver: handleSharedRowHover,
10454
+ onMouseLeave: clearHoveredRows,
10455
+ children: [
10456
+ /* @__PURE__ */ jsx17(
10457
+ TaskList,
10458
+ {
10459
+ tasks: normalizedTasks,
10460
+ rowHeight: effectiveRowHeight,
10461
+ headerHeight,
10462
+ taskListWidth,
10463
+ onTasksChange: handleTaskChange,
10464
+ selectedTaskId: selectedTaskId ?? void 0,
10465
+ onTaskSelect: handleTaskSelect,
10466
+ show: showTaskList,
10467
+ hasRightShadow: taskListHasRightShadow,
10468
+ disableTaskNameEditing,
10469
+ disableDependencyEditing,
10470
+ onScrollToTask: scrollToTask,
10471
+ onSelectedChipChange: setSelectedChip,
10472
+ onAdd,
10473
+ onDelete: handleDelete,
10474
+ onInsertAfter: handleInsertAfter,
10475
+ onReorder: handleReorder,
10476
+ disableTaskDrag,
10477
+ editingTaskId,
10478
+ enableAddTask,
10479
+ defaultTaskDurationDays,
10480
+ collapsedParentIds,
10481
+ onToggleCollapse: handleToggleCollapse,
10482
+ onPromoteTask: onPromoteTask ?? handlePromoteTask,
10483
+ onDemoteTask: onDemoteTask ?? handleDemoteTask,
10484
+ onUngroupTask: onUngroupTask ?? handleUngroupTask,
10485
+ highlightedTaskIds: taskListHighlightedTaskIds,
10486
+ enableTaskMultiSelect,
10487
+ selectedTaskIds,
10488
+ onSelectedTaskIdsChange,
10489
+ customDays,
10490
+ isWeekend: isWeekend3,
10491
+ businessDays,
10492
+ filterMode,
10493
+ filteredTaskIds: matchedTaskIds,
10494
+ isFilterActive: !!taskFilter,
10495
+ additionalColumns,
10496
+ hiddenTaskListColumns,
10497
+ taskListMenuCommands,
10498
+ hideTaskListRowActions,
10499
+ rowContentLines: resolvedRowContentLines,
10500
+ taskDateChangeMode,
10501
+ onTaskDateChangeModeChange: handleTaskDateChangeMode
10502
+ }
10503
+ ),
10504
+ /* @__PURE__ */ jsx17(
10505
+ "div",
10506
+ {
10507
+ className: isTableMatrixMode || showChart ? "gantt-chartSurface" : "gantt-chartSurface gantt-chart-hidden",
10508
+ style: {
10509
+ minWidth: `${isTableMatrixMode ? matrixWidth : gridWidth}px`,
10510
+ flex: 1,
10511
+ display: isTableMatrixMode || showChart ? void 0 : "none"
10512
+ },
10513
+ children: isTableMatrixMode ? /* @__PURE__ */ jsx17(
10514
+ TableMatrix,
10515
+ {
10516
+ tasks: visibleTasks,
10517
+ allTasks: normalizedTasks,
10518
+ columns: matrixColumns,
10519
+ columnGroups: matrixColumnGroups,
10520
+ rowHeight: effectiveRowHeight,
10521
+ headerHeight: timelineHeaderHeight,
10522
+ selectedTaskId,
10523
+ onTaskSelect: handleTaskSelect,
10524
+ onCellClick: onMatrixCellClick,
10525
+ highlightedTaskIds: taskListHighlightedTaskIds,
10526
+ filterMode
10527
+ }
10528
+ ) : /* @__PURE__ */ jsxs14(Fragment4, { children: [
10529
+ /* @__PURE__ */ jsx17(
10530
+ "div",
10125
10531
  {
10126
- days: dateRange,
10127
- dayWidth,
10128
- headerHeight,
10129
- viewMode,
10130
- isCustomWeekend
10532
+ className: "gantt-stickyHeader",
10533
+ style: { width: `${gridWidth}px`, height: `${timelineHeaderHeight}px` },
10534
+ children: /* @__PURE__ */ jsx17(
10535
+ TimeScaleHeader_default,
10536
+ {
10537
+ days: dateRange,
10538
+ dayWidth,
10539
+ headerHeight,
10540
+ viewMode,
10541
+ isCustomWeekend
10542
+ }
10543
+ )
10131
10544
  }
10132
- )
10133
- }
10134
- ),
10135
- /* @__PURE__ */ jsxs13(
10136
- "div",
10137
- {
10138
- className: "gantt-taskArea",
10139
- style: {
10140
- position: "relative",
10141
- width: `${gridWidth}px`
10142
- },
10143
- children: [
10144
- /* @__PURE__ */ jsx16(
10145
- GridBackground_default,
10146
- {
10147
- dateRange,
10148
- dayWidth,
10149
- totalHeight: totalGridHeight,
10150
- viewMode,
10151
- isCustomWeekend
10152
- }
10153
- ),
10154
- todayInRange && /* @__PURE__ */ jsx16(TodayIndicator_default, { monthStart, dayWidth }),
10155
- /* @__PURE__ */ jsx16(
10156
- DependencyLines_default,
10157
- {
10158
- tasks: previewVisibleTasks,
10159
- allTasks: previewNormalizedTasks,
10160
- collapsedParentIds,
10161
- monthStart,
10162
- dayWidth,
10163
- rowHeight,
10164
- gridWidth,
10165
- dragOverrides: dependencyOverrides,
10166
- selectedDep: selectedChip,
10167
- businessDays,
10168
- weekendPredicate: isCustomWeekend
10169
- }
10170
- ),
10171
- dragGuideLines && /* @__PURE__ */ jsx16(
10172
- DragGuideLines_default,
10173
- {
10174
- isDragging: dragGuideLines.isDragging,
10175
- dragMode: dragGuideLines.dragMode,
10176
- left: dragGuideLines.left,
10177
- width: dragGuideLines.width,
10178
- totalHeight: totalGridHeight
10179
- }
10180
- ),
10181
- visibleTasks.map((task, index) => /* @__PURE__ */ jsx16(
10182
- TaskRow_default,
10183
- {
10184
- task,
10185
- monthStart,
10186
- dayWidth,
10187
- rowHeight,
10188
- onTasksChange: handleTaskChange,
10189
- onDragStateChange: (state) => {
10190
- if (state.isDragging) {
10191
- setDragGuideLines(state);
10192
- setDraggedTaskOverride({ taskId: task.id, left: state.left, width: state.width });
10193
- } else {
10194
- setDragGuideLines(null);
10195
- setDraggedTaskOverride(null);
10196
- }
10197
- },
10198
- rowIndex: index,
10199
- allTasks: normalizedTasks,
10200
- enableAutoSchedule: enableAutoSchedule ?? false,
10201
- disableConstraints: disableConstraints ?? false,
10202
- overridePosition: cascadeOverrides.get(task.id),
10203
- onCascadeProgress: handleCascadeProgress,
10204
- onCascade: handleCascade,
10205
- highlightExpiredTasks,
10206
- showBaseline,
10207
- isFilterMatch: filterMode === "highlight" ? matchedTaskIds.has(task.id) : false,
10208
- businessDays,
10209
- customDays,
10210
- isWeekend: isWeekend3,
10211
- disableTaskDrag,
10212
- viewMode
10545
+ ),
10546
+ /* @__PURE__ */ jsxs14(
10547
+ "div",
10548
+ {
10549
+ className: "gantt-taskArea",
10550
+ style: {
10551
+ position: "relative",
10552
+ width: `${gridWidth}px`
10213
10553
  },
10214
- task.id
10215
- ))
10216
- ]
10217
- }
10218
- )
10219
- ]
10220
- }
10221
- )
10222
- ]
10554
+ children: [
10555
+ /* @__PURE__ */ jsx17(
10556
+ GridBackground_default,
10557
+ {
10558
+ dateRange,
10559
+ dayWidth,
10560
+ totalHeight: totalGridHeight,
10561
+ viewMode,
10562
+ isCustomWeekend
10563
+ }
10564
+ ),
10565
+ todayInRange && /* @__PURE__ */ jsx17(TodayIndicator_default, { monthStart, dayWidth }),
10566
+ /* @__PURE__ */ jsx17(
10567
+ DependencyLines_default,
10568
+ {
10569
+ tasks: previewVisibleTasks,
10570
+ allTasks: previewNormalizedTasks,
10571
+ collapsedParentIds,
10572
+ monthStart,
10573
+ dayWidth,
10574
+ rowHeight: effectiveRowHeight,
10575
+ gridWidth,
10576
+ dragOverrides: dependencyOverrides,
10577
+ selectedDep: selectedChip,
10578
+ businessDays,
10579
+ weekendPredicate: isCustomWeekend
10580
+ }
10581
+ ),
10582
+ dragGuideLines && /* @__PURE__ */ jsx17(
10583
+ DragGuideLines_default,
10584
+ {
10585
+ isDragging: dragGuideLines.isDragging,
10586
+ dragMode: dragGuideLines.dragMode,
10587
+ left: dragGuideLines.left,
10588
+ width: dragGuideLines.width,
10589
+ totalHeight: totalGridHeight
10590
+ }
10591
+ ),
10592
+ visibleTasks.map((task, index) => /* @__PURE__ */ jsx17(
10593
+ TaskRow_default,
10594
+ {
10595
+ task,
10596
+ monthStart,
10597
+ dayWidth,
10598
+ rowHeight: effectiveRowHeight,
10599
+ onTasksChange: handleTaskChange,
10600
+ onDragStateChange: (state) => {
10601
+ if (state.isDragging) {
10602
+ setDragGuideLines(state);
10603
+ setDraggedTaskOverride({ taskId: task.id, left: state.left, width: state.width });
10604
+ } else {
10605
+ setDragGuideLines(null);
10606
+ setDraggedTaskOverride(null);
10607
+ }
10608
+ },
10609
+ rowIndex: index,
10610
+ allTasks: normalizedTasks,
10611
+ enableAutoSchedule: enableAutoSchedule ?? false,
10612
+ disableConstraints: disableConstraints ?? false,
10613
+ overridePosition: cascadeOverrides.get(task.id),
10614
+ onCascadeProgress: handleCascadeProgress,
10615
+ onCascade: handleCascade,
10616
+ highlightExpiredTasks,
10617
+ showBaseline,
10618
+ isFilterMatch: filterMode === "highlight" ? matchedTaskIds.has(task.id) : false,
10619
+ businessDays,
10620
+ customDays,
10621
+ isWeekend: isWeekend3,
10622
+ disableTaskDrag,
10623
+ viewMode
10624
+ },
10625
+ task.id
10626
+ ))
10627
+ ]
10628
+ }
10629
+ )
10630
+ ] })
10631
+ }
10632
+ )
10633
+ ]
10634
+ }
10635
+ )
10223
10636
  }
10224
10637
  )
10225
10638
  }
10226
- ) });
10639
+ );
10227
10640
  }
10228
10641
  var TaskGanttChart = forwardRef(TaskGanttChartInner);
10229
10642
  var GanttChart = forwardRef(GanttChartInner);
10230
10643
  GanttChart.displayName = "GanttChart";
10231
10644
 
10232
10645
  // src/components/ui/Button.tsx
10233
- import React14 from "react";
10234
- import { jsx as jsx17 } from "react/jsx-runtime";
10235
- var Button = React14.forwardRef(
10646
+ import React15 from "react";
10647
+ import { jsx as jsx18 } from "react/jsx-runtime";
10648
+ var Button = React15.forwardRef(
10236
10649
  ({ className, variant = "default", size = "default", children, ...props }, ref) => {
10237
10650
  const classes = [
10238
10651
  "gantt-btn",
@@ -10240,7 +10653,7 @@ var Button = React14.forwardRef(
10240
10653
  size !== "default" ? `gantt-btn-${size}` : "",
10241
10654
  className || ""
10242
10655
  ].filter(Boolean).join(" ");
10243
- return /* @__PURE__ */ jsx17("button", { ref, className: classes, ...props, children });
10656
+ return /* @__PURE__ */ jsx18("button", { ref, className: classes, ...props, children });
10244
10657
  }
10245
10658
  );
10246
10659
  Button.displayName = "Button";
@@ -10291,6 +10704,7 @@ export {
10291
10704
  PopoverContent,
10292
10705
  PopoverTrigger,
10293
10706
  ResourceTimelineChart,
10707
+ TableMatrix,
10294
10708
  TaskList,
10295
10709
  TaskRow_default as TaskRow,
10296
10710
  TimeScaleHeader_default as TimeScaleHeader,