gantt-lib 0.100.0 → 0.102.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -340,7 +340,9 @@ interface TableMatrixColumnGroup {
340
340
  interface TableMatrixColumn<TTask extends Task = Task> {
341
341
  id: string;
342
342
  header: React$1.ReactNode;
343
- width: number;
343
+ width?: number | 'auto';
344
+ minWidth?: number;
345
+ maxWidth?: number;
344
346
  groupId?: string;
345
347
  align?: 'left' | 'center' | 'right';
346
348
  className?: string;
@@ -362,13 +364,14 @@ interface TableMatrixProps<TTask extends Task = Task> {
362
364
  columnGroups?: Array<TableMatrixColumnGroup>;
363
365
  rowHeight: number;
364
366
  headerHeight: number;
367
+ bodyMinHeight?: number | string;
365
368
  selectedTaskId?: string | null;
366
369
  onTaskSelect?: (taskId: string | null) => void;
367
370
  onCellClick?: (context: TableMatrixCellClickContext<TTask>) => void;
368
371
  highlightedTaskIds?: Set<string>;
369
372
  filterMode?: 'highlight' | 'hide';
370
373
  }
371
- declare function TableMatrix<TTask extends Task = Task>({ tasks, allTasks, columns, columnGroups, rowHeight, headerHeight, selectedTaskId, onTaskSelect, onCellClick, highlightedTaskIds, filterMode, }: TableMatrixProps<TTask>): react_jsx_runtime.JSX.Element;
374
+ declare function TableMatrix<TTask extends Task = Task>({ tasks, allTasks, columns, columnGroups, rowHeight, headerHeight, bodyMinHeight, selectedTaskId, onTaskSelect, onCellClick, highlightedTaskIds, filterMode, }: TableMatrixProps<TTask>): react_jsx_runtime.JSX.Element;
372
375
 
373
376
  /**
374
377
  * Task data structure for Gantt chart
@@ -874,6 +877,8 @@ interface TaskListProps {
874
877
  hideTaskListRowActions?: boolean;
875
878
  /** Global number of visible content lines used to size every row consistently. */
876
879
  rowContentLines?: number;
880
+ /** Optional minimum height for the data body area below the sticky header. */
881
+ bodyMinHeight?: number | string;
877
882
  /** How task-list date pickers apply start/end edits */
878
883
  taskDateChangeMode?: TaskDateChangeMode;
879
884
  /** Controlled callback for task-list date picker mode changes */
package/dist/index.d.ts CHANGED
@@ -340,7 +340,9 @@ interface TableMatrixColumnGroup {
340
340
  interface TableMatrixColumn<TTask extends Task = Task> {
341
341
  id: string;
342
342
  header: React$1.ReactNode;
343
- width: number;
343
+ width?: number | 'auto';
344
+ minWidth?: number;
345
+ maxWidth?: number;
344
346
  groupId?: string;
345
347
  align?: 'left' | 'center' | 'right';
346
348
  className?: string;
@@ -362,13 +364,14 @@ interface TableMatrixProps<TTask extends Task = Task> {
362
364
  columnGroups?: Array<TableMatrixColumnGroup>;
363
365
  rowHeight: number;
364
366
  headerHeight: number;
367
+ bodyMinHeight?: number | string;
365
368
  selectedTaskId?: string | null;
366
369
  onTaskSelect?: (taskId: string | null) => void;
367
370
  onCellClick?: (context: TableMatrixCellClickContext<TTask>) => void;
368
371
  highlightedTaskIds?: Set<string>;
369
372
  filterMode?: 'highlight' | 'hide';
370
373
  }
371
- declare function TableMatrix<TTask extends Task = Task>({ tasks, allTasks, columns, columnGroups, rowHeight, headerHeight, selectedTaskId, onTaskSelect, onCellClick, highlightedTaskIds, filterMode, }: TableMatrixProps<TTask>): react_jsx_runtime.JSX.Element;
374
+ declare function TableMatrix<TTask extends Task = Task>({ tasks, allTasks, columns, columnGroups, rowHeight, headerHeight, bodyMinHeight, selectedTaskId, onTaskSelect, onCellClick, highlightedTaskIds, filterMode, }: TableMatrixProps<TTask>): react_jsx_runtime.JSX.Element;
372
375
 
373
376
  /**
374
377
  * Task data structure for Gantt chart
@@ -874,6 +877,8 @@ interface TaskListProps {
874
877
  hideTaskListRowActions?: boolean;
875
878
  /** Global number of visible content lines used to size every row consistently. */
876
879
  rowContentLines?: number;
880
+ /** Optional minimum height for the data body area below the sticky header. */
881
+ bodyMinHeight?: number | string;
877
882
  /** How task-list date pickers apply start/end edits */
878
883
  taskDateChangeMode?: TaskDateChangeMode;
879
884
  /** Controlled callback for task-list date picker mode changes */
package/dist/index.js CHANGED
@@ -6892,6 +6892,7 @@ var TaskList = ({
6892
6892
  taskListMenuCommands,
6893
6893
  hideTaskListRowActions = false,
6894
6894
  rowContentLines = 1,
6895
+ bodyMinHeight,
6895
6896
  taskDateChangeMode = "preserve-duration",
6896
6897
  onTaskDateChangeModeChange
6897
6898
  }) => {
@@ -7581,84 +7582,94 @@ var TaskList = ({
7581
7582
  col.id
7582
7583
  );
7583
7584
  }) }),
7584
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "gantt-tl-body", style: { height: `${totalHeight}px` }, children: visibleTasks.map((task, index) => {
7585
- const previousVisibleTask = index > 0 ? visibleTasks[index - 1] : void 0;
7586
- const canDemoteTask = index === 0 || !task.parentId || previousVisibleTask?.id !== task.parentId;
7587
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react12.default.Fragment, { children: [
7588
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7589
- TaskListRow,
7590
- {
7591
- task,
7592
- rowIndex: index,
7593
- taskNumber: originalTaskNumberMap[task.id] || "",
7594
- taskNumberMap: originalTaskNumberMap,
7595
- rowHeight,
7596
- onTasksChange,
7597
- selectedTaskId,
7598
- onRowClick: handleRowClick,
7599
- disableTaskNameEditing,
7600
- disableDependencyEditing,
7601
- allTasks: tasks,
7602
- activeLinkType,
7603
- onSetActiveLinkType: setActiveLinkType,
7604
- selectingPredecessorFor,
7605
- dependencyPickMode,
7606
- onSetDependencyPickMode: setDependencyPickMode,
7607
- onSetSelectingPredecessorFor: setSelectingPredecessorFor,
7608
- onAddDependency: handleAddDependency,
7609
- onRemoveDependency: handleRemoveDependency,
7610
- selectedChip,
7611
- onChipSelect: handleChipSelect,
7612
- onScrollToTask,
7613
- onDelete,
7614
- onAdd,
7615
- onInsertAfter: handleStartInsertAfter,
7616
- editingTaskId: propEditingTaskId,
7617
- isDragging: !disableTaskDrag && draggingIndex === index,
7618
- isDragOver: !disableTaskDrag && dragOverIndex === index,
7619
- onDragStart: disableTaskDrag ? void 0 : handleDragStart,
7620
- onDragOver: disableTaskDrag ? void 0 : handleDragOver,
7621
- onDrop: disableTaskDrag ? void 0 : handleDrop,
7622
- onDragEnd: disableTaskDrag ? void 0 : handleDragEnd,
7623
- collapsedParentIds,
7624
- onToggleCollapse: handleToggleCollapse,
7625
- onPromoteTask,
7626
- onDemoteTask: onDemoteTask ? handleDemoteWrapper : void 0,
7627
- onUngroupTask,
7628
- onDuplicateTask: onReorder ? handleDuplicateTask : void 0,
7629
- canDemoteTask,
7630
- isLastChild: lastChildIds.has(task.id),
7631
- nestingDepth: nestingDepthMap.get(task.id) ?? 0,
7632
- hasVisibleChildren: visibleParentIds.has(task.id),
7633
- ancestorLineModes: ancestorLineModesMap.get(task.id) ?? [],
7634
- customDays,
7635
- isWeekend: isWeekend3,
7636
- businessDays,
7637
- defaultTaskDurationDays,
7638
- isFilterMatch: filterMode === "highlight" ? highlightedTaskIds.has(task.id) : false,
7639
- isFilterHideMode: filterMode === "hide" && isFilterActive,
7640
- resolvedColumns,
7641
- isTaskSelected: effectiveSelectedTaskIds.has(task.id),
7642
- onTaskSelectionChange: handleToggleTaskSelection,
7643
- activeCustomCell,
7644
- onActiveCustomCellChange: setActiveCustomCell,
7645
- taskListMenuCommands,
7646
- hideTaskListRowActions,
7647
- taskDateChangeMode,
7648
- onTaskDateChangeModeChange
7649
- }
7650
- ),
7651
- pendingInsertDisplayTaskId === task.id && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7652
- NewTaskRow,
7653
- {
7654
- rowHeight,
7655
- onConfirm: handleConfirmInsertedTask,
7656
- onCancel: handleCancelInsertedTask,
7657
- nestingDepth: pendingInsert?.nestingDepth ?? 0
7658
- }
7659
- )
7660
- ] }, task.id);
7661
- }) }),
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
+ ),
7662
7673
  isCreating && !pendingInsert && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7663
7674
  NewTaskRow,
7664
7675
  {
@@ -9385,9 +9396,20 @@ function ResourceTimelineChart({
9385
9396
  // src/components/TableMatrix/TableMatrix.tsx
9386
9397
  var import_react15 = require("react");
9387
9398
  var import_jsx_runtime16 = require("react/jsx-runtime");
9399
+ var AUTO_COLUMN_MIN_WIDTH = 72;
9400
+ var AUTO_COLUMN_MAX_WIDTH = 180;
9388
9401
  function joinClasses(...values) {
9389
9402
  return values.filter(Boolean).join(" ");
9390
9403
  }
9404
+ function clampWidth(width, minWidth, maxWidth) {
9405
+ return Math.min(maxWidth, Math.max(minWidth, Math.ceil(width)));
9406
+ }
9407
+ function getAutoMinWidth(column) {
9408
+ return column.minWidth ?? AUTO_COLUMN_MIN_WIDTH;
9409
+ }
9410
+ function getAutoMaxWidth(column) {
9411
+ return column.maxWidth ?? AUTO_COLUMN_MAX_WIDTH;
9412
+ }
9391
9413
  function TableMatrix({
9392
9414
  tasks,
9393
9415
  allTasks = tasks,
@@ -9395,19 +9417,62 @@ function TableMatrix({
9395
9417
  columnGroups,
9396
9418
  rowHeight,
9397
9419
  headerHeight,
9420
+ bodyMinHeight,
9398
9421
  selectedTaskId,
9399
9422
  onTaskSelect,
9400
9423
  onCellClick,
9401
9424
  highlightedTaskIds,
9402
9425
  filterMode = "highlight"
9403
9426
  }) {
9404
- const gridTemplateColumns = (0, import_react15.useMemo)(
9405
- () => columns.map((column) => `${column.width}px`).join(" "),
9427
+ const measureRef = (0, import_react15.useRef)(null);
9428
+ const [measuredAutoWidths, setMeasuredAutoWidths] = (0, import_react15.useState)([]);
9429
+ const hasAutoWidthColumns = (0, import_react15.useMemo)(
9430
+ () => columns.some((column) => typeof column.width !== "number"),
9406
9431
  [columns]
9407
9432
  );
9433
+ (0, import_react15.useLayoutEffect)(() => {
9434
+ if (!hasAutoWidthColumns) {
9435
+ setMeasuredAutoWidths([]);
9436
+ return;
9437
+ }
9438
+ const measureRoot = measureRef.current;
9439
+ if (!measureRoot) return;
9440
+ const nextWidths = columns.map((column, columnIndex) => {
9441
+ if (typeof column.width === "number") return void 0;
9442
+ const minWidth = getAutoMinWidth(column);
9443
+ const maxWidth = getAutoMaxWidth(column);
9444
+ const elements = measureRoot.querySelectorAll(`[data-gantt-mx-measure-column="${columnIndex}"]`);
9445
+ let measuredWidth = minWidth;
9446
+ elements.forEach((element) => {
9447
+ measuredWidth = Math.max(
9448
+ measuredWidth,
9449
+ element.getBoundingClientRect().width,
9450
+ element.scrollWidth
9451
+ );
9452
+ });
9453
+ return clampWidth(measuredWidth, minWidth, maxWidth);
9454
+ });
9455
+ setMeasuredAutoWidths((previousWidths) => {
9456
+ const changed = nextWidths.length !== previousWidths.length || nextWidths.some((width, index) => width !== previousWidths[index]);
9457
+ return changed ? nextWidths : previousWidths;
9458
+ });
9459
+ }, [columns, hasAutoWidthColumns, tasks]);
9460
+ const resolvedColumnWidths = (0, import_react15.useMemo)(
9461
+ () => columns.map((column, index) => {
9462
+ if (typeof column.width === "number") return column.width;
9463
+ const minWidth = getAutoMinWidth(column);
9464
+ const maxWidth = getAutoMaxWidth(column);
9465
+ return clampWidth(measuredAutoWidths[index] ?? minWidth, minWidth, maxWidth);
9466
+ }),
9467
+ [columns, measuredAutoWidths]
9468
+ );
9469
+ const gridTemplateColumns = (0, import_react15.useMemo)(
9470
+ () => resolvedColumnWidths.map((width) => `${width}px`).join(" "),
9471
+ [resolvedColumnWidths]
9472
+ );
9408
9473
  const totalWidth = (0, import_react15.useMemo)(
9409
- () => columns.reduce((sum, column) => sum + column.width, 0),
9410
- [columns]
9474
+ () => resolvedColumnWidths.reduce((sum, width) => sum + width, 0),
9475
+ [resolvedColumnWidths]
9411
9476
  );
9412
9477
  const hasGroupHeader = (0, import_react15.useMemo)(
9413
9478
  () => columns.some((column) => !!column.groupId) || (columnGroups?.length ?? 0) > 0,
@@ -9419,7 +9484,7 @@ function TableMatrix({
9419
9484
  );
9420
9485
  const headerSpans = (0, import_react15.useMemo)(() => {
9421
9486
  if (!hasGroupHeader) return [];
9422
- if (columnGroups?.some((group) => typeof group.width === "number")) {
9487
+ if (!hasAutoWidthColumns && columnGroups?.some((group) => typeof group.width === "number")) {
9423
9488
  return columnGroups.map((group) => ({
9424
9489
  id: group.id,
9425
9490
  header: group.header,
@@ -9432,19 +9497,21 @@ function TableMatrix({
9432
9497
  const groupId = column.groupId ?? column.id;
9433
9498
  const lastSpan = spans[spans.length - 1];
9434
9499
  if (lastSpan?.id === groupId) {
9435
- lastSpan.width += column.width;
9500
+ lastSpan.width = (lastSpan.width ?? 0) + resolvedColumnWidths[columns.indexOf(column)];
9501
+ lastSpan.columnSpan = (lastSpan.columnSpan ?? 1) + 1;
9436
9502
  continue;
9437
9503
  }
9438
9504
  const group = groupMap.get(groupId);
9439
9505
  spans.push({
9440
9506
  id: groupId,
9441
9507
  header: group?.header ?? column.header,
9442
- width: column.width,
9508
+ width: resolvedColumnWidths[columns.indexOf(column)],
9509
+ columnSpan: 1,
9443
9510
  className: group?.className
9444
9511
  });
9445
9512
  }
9446
9513
  return spans;
9447
- }, [columns, groupMap, hasGroupHeader]);
9514
+ }, [columns, columnGroups, groupMap, hasAutoWidthColumns, hasGroupHeader, resolvedColumnWidths]);
9448
9515
  const headerContentHeight = Math.max(0, headerHeight - 1);
9449
9516
  const topRowHeight = hasGroupHeader ? Math.ceil(headerContentHeight / 2) : headerContentHeight;
9450
9517
  const bottomRowHeight = hasGroupHeader ? Math.floor(headerContentHeight / 2) : 0;
@@ -9479,13 +9546,44 @@ function TableMatrix({
9479
9546
  return depthMap;
9480
9547
  }, [allTasks]);
9481
9548
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "gantt-mx-root", style: { width: `${totalWidth}px` }, children: [
9549
+ hasAutoWidthColumns && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { ref: measureRef, className: "gantt-mx-measure", "aria-hidden": "true", children: [
9550
+ columns.map((column, columnIndex) => typeof column.width === "number" ? null : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
9551
+ "div",
9552
+ {
9553
+ "data-gantt-mx-measure-column": columnIndex,
9554
+ className: "gantt-mx-measureCell gantt-mx-headerCell",
9555
+ children: column.header
9556
+ },
9557
+ `header:${column.id}`
9558
+ )),
9559
+ tasks.map((task) => columns.map((column, columnIndex) => typeof column.width === "number" ? null : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
9560
+ "div",
9561
+ {
9562
+ "data-gantt-mx-measure-column": columnIndex,
9563
+ className: "gantt-mx-measureCell gantt-mx-cell",
9564
+ children: column.renderCell(task)
9565
+ },
9566
+ `${task.id}:${column.id}`
9567
+ )))
9568
+ ] }),
9482
9569
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "gantt-mx-header", style: { height: `${headerHeight}px` }, children: [
9483
9570
  hasGroupHeader && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
9484
9571
  "div",
9485
9572
  {
9486
9573
  className: "gantt-mx-headerRow gantt-mx-headerGroupRow",
9487
- style: { gridTemplateColumns: headerSpans.map((span) => `${span.width}px`).join(" "), height: `${topRowHeight}px` },
9488
- children: headerSpans.map((span) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: joinClasses("gantt-mx-groupCell", span.className), children: span.header }, span.id))
9574
+ style: {
9575
+ gridTemplateColumns: hasAutoWidthColumns ? gridTemplateColumns : headerSpans.map((span) => `${span.width ?? 0}px`).join(" "),
9576
+ height: `${topRowHeight}px`
9577
+ },
9578
+ children: headerSpans.map((span) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
9579
+ "div",
9580
+ {
9581
+ className: joinClasses("gantt-mx-groupCell", span.className),
9582
+ style: hasAutoWidthColumns ? { gridColumn: `span ${span.columnSpan ?? 1}` } : void 0,
9583
+ children: span.header
9584
+ },
9585
+ span.id
9586
+ ))
9489
9587
  }
9490
9588
  ),
9491
9589
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
@@ -9500,6 +9598,7 @@ function TableMatrix({
9500
9598
  "gantt-mx-headerCell",
9501
9599
  column.headerClassName
9502
9600
  ),
9601
+ style: column.minWidth !== void 0 ? { minWidth: `${column.minWidth}px` } : void 0,
9503
9602
  children: column.header
9504
9603
  },
9505
9604
  column.id
@@ -9511,7 +9610,10 @@ function TableMatrix({
9511
9610
  "div",
9512
9611
  {
9513
9612
  className: "gantt-mx-body",
9514
- style: { height: `${tasks.length * rowHeight}px` },
9613
+ style: {
9614
+ height: `${tasks.length * rowHeight}px`,
9615
+ minHeight: bodyMinHeight
9616
+ },
9515
9617
  children: tasks.map((task, index) => {
9516
9618
  const isHighlighted = filterMode === "highlight" && !!highlightedTaskIds?.has(task.id);
9517
9619
  const isParent = parentTaskIds.has(task.id);
@@ -9534,7 +9636,8 @@ function TableMatrix({
9534
9636
  style: {
9535
9637
  gridTemplateColumns,
9536
9638
  top: `${index * rowHeight}px`,
9537
- height: `${rowHeight}px`
9639
+ height: `${rowHeight}px`,
9640
+ width: `${totalWidth}px`
9538
9641
  },
9539
9642
  onClick: () => onTaskSelect?.(task.id),
9540
9643
  children: columns.map((column, columnIndex) => {
@@ -9549,6 +9652,7 @@ function TableMatrix({
9549
9652
  column.className,
9550
9653
  resolvedCellClassName
9551
9654
  ),
9655
+ style: column.minWidth !== void 0 ? { minWidth: `${column.minWidth}px` } : void 0,
9552
9656
  onClick: (event) => {
9553
9657
  onCellClick?.({ task, column, rowIndex: index, columnIndex, event });
9554
9658
  },
@@ -10012,7 +10116,10 @@ function TaskGanttChartInner(props, ref) {
10012
10116
  [dateRange.length, dayWidth]
10013
10117
  );
10014
10118
  const matrixWidth = (0, import_react16.useMemo)(
10015
- () => matrixColumns.reduce((sum, column) => sum + column.width, 0),
10119
+ () => matrixColumns.reduce((sum, column) => {
10120
+ if (typeof column.width !== "number") return void 0;
10121
+ return sum !== void 0 ? sum + column.width : void 0;
10122
+ }, 0),
10016
10123
  [matrixColumns]
10017
10124
  );
10018
10125
  const visibleTasks = (0, import_react16.useMemo)(() => {
@@ -10051,6 +10158,15 @@ function TaskGanttChartInner(props, ref) {
10051
10158
  [effectiveRowHeight, visibleTasks.length]
10052
10159
  );
10053
10160
  const timelineHeaderHeight = headerHeight + 1;
10161
+ const tableBodyMinHeight = (0, import_react16.useMemo)(() => {
10162
+ if (!isTableMatrixMode || containerHeight === void 0) {
10163
+ return void 0;
10164
+ }
10165
+ if (typeof containerHeight === "number") {
10166
+ return Math.max(0, containerHeight - timelineHeaderHeight);
10167
+ }
10168
+ return `calc(${containerHeight} - ${timelineHeaderHeight}px)`;
10169
+ }, [containerHeight, isTableMatrixMode, timelineHeaderHeight]);
10054
10170
  const monthStart = (0, import_react16.useMemo)(() => {
10055
10171
  if (dateRange.length === 0) {
10056
10172
  return new Date(Date.UTC((/* @__PURE__ */ new Date()).getUTCFullYear(), (/* @__PURE__ */ new Date()).getUTCMonth(), 1));
@@ -10613,6 +10729,7 @@ function TaskGanttChartInner(props, ref) {
10613
10729
  taskListMenuCommands,
10614
10730
  hideTaskListRowActions,
10615
10731
  rowContentLines: resolvedRowContentLines,
10732
+ bodyMinHeight: tableBodyMinHeight,
10616
10733
  taskDateChangeMode,
10617
10734
  onTaskDateChangeModeChange: handleTaskDateChangeMode
10618
10735
  }
@@ -10622,8 +10739,9 @@ function TaskGanttChartInner(props, ref) {
10622
10739
  {
10623
10740
  className: isTableMatrixMode || showChart ? "gantt-chartSurface" : "gantt-chartSurface gantt-chart-hidden",
10624
10741
  style: {
10625
- minWidth: `${isTableMatrixMode ? matrixWidth : gridWidth}px`,
10626
- flex: 1,
10742
+ minWidth: isTableMatrixMode ? matrixWidth !== void 0 ? `${matrixWidth}px` : void 0 : `${gridWidth}px`,
10743
+ width: isTableMatrixMode ? matrixWidth !== void 0 ? `${matrixWidth}px` : "max-content" : void 0,
10744
+ flex: isTableMatrixMode ? "0 0 auto" : 1,
10627
10745
  display: isTableMatrixMode || showChart ? void 0 : "none"
10628
10746
  },
10629
10747
  children: isTableMatrixMode ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
@@ -10635,6 +10753,7 @@ function TaskGanttChartInner(props, ref) {
10635
10753
  columnGroups: matrixColumnGroups,
10636
10754
  rowHeight: effectiveRowHeight,
10637
10755
  headerHeight: timelineHeaderHeight,
10756
+ bodyMinHeight: tableBodyMinHeight,
10638
10757
  selectedTaskId,
10639
10758
  onTaskSelect: handleTaskSelect,
10640
10759
  onCellClick: onMatrixCellClick,