gantt-task-react-v 1.6.16 → 1.6.17

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.
@@ -43,5 +43,6 @@ export type TaskListProps = {
43
43
  canToggleColumns?: boolean;
44
44
  onColumnVisibilityChange?: OnColumnVisibilityChange;
45
45
  tableBottom?: TableRenderBottomProps;
46
+ onTaskInlineEdit?: (task: RenderTask, columnId: string, newValue: unknown) => void;
46
47
  };
47
48
  export declare const TaskList: React.NamedExoticComponent<TaskListProps>;
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+ import type { ColumnEditType } from "../../../types";
3
+ export interface InlineEditCellProps {
4
+ value: unknown;
5
+ editType?: ColumnEditType;
6
+ editOptions?: {
7
+ value: string;
8
+ label: string;
9
+ }[];
10
+ onCommit: (value: unknown) => void;
11
+ onCancel: () => void;
12
+ }
13
+ /**
14
+ * Built-in inline editor rendered inside a table cell.
15
+ * Supports text, number, date, and select types.
16
+ */
17
+ export declare const InlineEditCell: React.FC<InlineEditCellProps>;
@@ -4589,7 +4589,7 @@ const tooltipDefaultContainerTexts = "_tooltipDefaultContainerTexts_16o9s_17";
4589
4589
  const tooltipDefaultContainerParagraph = "_tooltipDefaultContainerParagraph_16o9s_31";
4590
4590
  const tooltipDetailsContainer = "_tooltipDetailsContainer_16o9s_47";
4591
4591
  const tooltipDetailsContainerHidden = "_tooltipDetailsContainerHidden_16o9s_71";
4592
- const styles$n = {
4592
+ const styles$o = {
4593
4593
  tooltipDefaultContainer,
4594
4594
  tooltipDefaultContainerTexts,
4595
4595
  tooltipDefaultContainerParagraph,
@@ -4632,26 +4632,26 @@ const StandardTooltipContent = ({ task }) => {
4632
4632
  return /* @__PURE__ */ jsxs(
4633
4633
  "div",
4634
4634
  {
4635
- className: styles$n.tooltipDefaultContainer,
4635
+ className: styles$o.tooltipDefaultContainer,
4636
4636
  style: { fontSize: "var(--gantt-font-size)" },
4637
4637
  children: [
4638
4638
  /* @__PURE__ */ jsx("b", { style: { fontSize: "var(--gantt-font-size)" }, children: `${task.name}: ${task.start.getDate()}-${task.start.getMonth() + 1}-${task.start.getFullYear()} - ${task.end.getDate()}-${task.end.getMonth() + 1}-${task.end.getFullYear()}` }),
4639
- /* @__PURE__ */ jsxs("div", { className: styles$n.tooltipDefaultContainerTexts, children: [
4639
+ /* @__PURE__ */ jsxs("div", { className: styles$o.tooltipDefaultContainerTexts, children: [
4640
4640
  task.end.getTime() - task.start.getTime() !== 0 && /* @__PURE__ */ jsx(
4641
4641
  "p",
4642
4642
  {
4643
- className: styles$n.tooltipDefaultContainerParagraph,
4643
+ className: styles$o.tooltipDefaultContainerParagraph,
4644
4644
  children: `${locale.tooltip.duration},: ${~~((task.end.getTime() - task.start.getTime()) / (1e3 * 60 * 60 * 24))} ${locale.suffix.days}`
4645
4645
  }
4646
4646
  ),
4647
- !!locale.tooltip.progress && /* @__PURE__ */ jsx("p", { className: styles$n.tooltipDefaultContainerParagraph, children: !!task.progress && `${locale.tooltip.progress}: ${task.progress} %` })
4647
+ !!locale.tooltip.progress && /* @__PURE__ */ jsx("p", { className: styles$o.tooltipDefaultContainerParagraph, children: !!task.progress && `${locale.tooltip.progress}: ${task.progress} %` })
4648
4648
  ] })
4649
4649
  ]
4650
4650
  }
4651
4651
  );
4652
4652
  };
4653
4653
  const scroll = "_scroll_hp3qb_1";
4654
- const styles$m = {
4654
+ const styles$n = {
4655
4655
  scroll
4656
4656
  };
4657
4657
  const VerticalScroll = ({
@@ -4672,7 +4672,7 @@ const VerticalScroll = ({
4672
4672
  marginLeft: rtl ? void 0 : "-1rem",
4673
4673
  pointerEvents: isChangeInProgress ? "none" : void 0
4674
4674
  },
4675
- className: styles$m.scroll,
4675
+ className: styles$n.scroll,
4676
4676
  onScroll,
4677
4677
  ref: verticalScrollbarRef,
4678
4678
  children: /* @__PURE__ */ jsx("div", { style: { height: ganttFullHeight, width: 1 } })
@@ -4750,7 +4750,7 @@ const dragging = "_dragging_16z6n_15";
4750
4750
  const taskListExpander = "_taskListExpander_16z6n_23";
4751
4751
  const taskListEmptyExpander = "_taskListEmptyExpander_16z6n_45";
4752
4752
  const taskName = "_taskName_16z6n_55";
4753
- const styles$l = {
4753
+ const styles$m = {
4754
4754
  taskListNameWrapper,
4755
4755
  dragging,
4756
4756
  taskListExpander,
@@ -4827,7 +4827,7 @@ const TitleColumn = ({
4827
4827
  "div",
4828
4828
  {
4829
4829
  "data-testid": `title-table-cell-${name}`,
4830
- className: `${styles$l.taskListNameWrapper}`,
4830
+ className: `${styles$m.taskListNameWrapper}`,
4831
4831
  style: {
4832
4832
  paddingLeft: depth * nestedTaskNameOffset
4833
4833
  },
@@ -4836,7 +4836,7 @@ const TitleColumn = ({
4836
4836
  /* @__PURE__ */ jsx(
4837
4837
  "div",
4838
4838
  {
4839
- className: `gantt-expander ${styles$l.taskListExpander} ${!hasChildren ? styles$l.taskListEmptyExpander : ""}`,
4839
+ className: `gantt-expander ${styles$m.taskListExpander} ${!hasChildren ? styles$m.taskListEmptyExpander : ""}`,
4840
4840
  style: {
4841
4841
  left: depth * nestedTaskNameOffset
4842
4842
  },
@@ -4847,7 +4847,7 @@ const TitleColumn = ({
4847
4847
  /* @__PURE__ */ jsxs(
4848
4848
  "div",
4849
4849
  {
4850
- className: styles$l.taskName,
4850
+ className: styles$m.taskName,
4851
4851
  style: { fontWeight: isProject ? "bold" : "regular" },
4852
4852
  children: [
4853
4853
  isShowTaskNumbers && /* @__PURE__ */ jsxs("b", { children: [
@@ -4902,7 +4902,7 @@ const DependenciesColumn = ({
4902
4902
  return /* @__PURE__ */ jsx(Fragment, { children: dependencies.map(({ name }) => name).join(", ") });
4903
4903
  };
4904
4904
  const button = "_button_l55x0_1";
4905
- const styles$k = {
4905
+ const styles$l = {
4906
4906
  button
4907
4907
  };
4908
4908
  const DeleteIcon = (props) => /* @__PURE__ */ jsxs(
@@ -4936,7 +4936,7 @@ const DeleteColumn = ({
4936
4936
  e.stopPropagation();
4937
4937
  },
4938
4938
  onClick,
4939
- className: styles$k.button,
4939
+ className: styles$l.button,
4940
4940
  children: (icons == null ? void 0 : icons.renderDeleteIcon) ? icons.renderDeleteIcon() : /* @__PURE__ */ jsx(DeleteIcon, {})
4941
4941
  }
4942
4942
  );
@@ -4971,7 +4971,7 @@ const EditColumn = ({
4971
4971
  e.stopPropagation();
4972
4972
  },
4973
4973
  onClick,
4974
- className: styles$k.button,
4974
+ className: styles$l.button,
4975
4975
  children: (icons == null ? void 0 : icons.renderEditIcon) ? icons.renderEditIcon() : /* @__PURE__ */ jsx(EditIcon, {})
4976
4976
  }
4977
4977
  );
@@ -5012,7 +5012,7 @@ const AddColumn = ({
5012
5012
  e.stopPropagation();
5013
5013
  },
5014
5014
  onClick,
5015
- className: styles$k.button,
5015
+ className: styles$l.button,
5016
5016
  children: (icons == null ? void 0 : icons.renderAddIcon) ? icons.renderAddIcon() : /* @__PURE__ */ jsx(AddIcon, {})
5017
5017
  }
5018
5018
  );
@@ -5545,7 +5545,7 @@ const checkbox = "_checkbox_rjfhl_141";
5545
5545
  const columnLabel = "_columnLabel_rjfhl_157";
5546
5546
  const dropdownTitle = "_dropdownTitle_rjfhl_169";
5547
5547
  const divider = "_divider_rjfhl_211";
5548
- const styles$j = {
5548
+ const styles$k = {
5549
5549
  toggleWrapper,
5550
5550
  toggleButton,
5551
5551
  dropdown,
@@ -5621,38 +5621,38 @@ const ColumnVisibilityToggleInner = ({
5621
5621
  if (toggleableColumns.length === 0) {
5622
5622
  return null;
5623
5623
  }
5624
- return /* @__PURE__ */ jsxs("div", { className: styles$j.toggleWrapper, ref: wrapperRef, children: [
5624
+ return /* @__PURE__ */ jsxs("div", { className: styles$k.toggleWrapper, ref: wrapperRef, children: [
5625
5625
  /* @__PURE__ */ jsx(
5626
5626
  "button",
5627
5627
  {
5628
- className: styles$j.toggleButton,
5628
+ className: styles$k.toggleButton,
5629
5629
  onClick: toggleDropdown,
5630
5630
  title: "Toggle column visibility",
5631
5631
  type: "button",
5632
5632
  children: /* @__PURE__ */ jsx(ColumnsIcon, {})
5633
5633
  }
5634
5634
  ),
5635
- isOpen && /* @__PURE__ */ jsxs("div", { className: styles$j.dropdown, children: [
5636
- /* @__PURE__ */ jsx("div", { className: styles$j.dropdownTitle, children: "Columns" }),
5637
- /* @__PURE__ */ jsx("div", { className: styles$j.divider }),
5635
+ isOpen && /* @__PURE__ */ jsxs("div", { className: styles$k.dropdown, children: [
5636
+ /* @__PURE__ */ jsx("div", { className: styles$k.dropdownTitle, children: "Columns" }),
5637
+ /* @__PURE__ */ jsx("div", { className: styles$k.divider }),
5638
5638
  toggleableColumns.map((column) => {
5639
5639
  const isVisible = !column.hidden;
5640
5640
  return /* @__PURE__ */ jsxs(
5641
5641
  "label",
5642
5642
  {
5643
- className: styles$j.dropdownItem,
5643
+ className: styles$k.dropdownItem,
5644
5644
  onClick: (e) => e.stopPropagation(),
5645
5645
  children: [
5646
5646
  /* @__PURE__ */ jsx(
5647
5647
  "input",
5648
5648
  {
5649
5649
  type: "checkbox",
5650
- className: styles$j.checkbox,
5650
+ className: styles$k.checkbox,
5651
5651
  checked: isVisible,
5652
5652
  onChange: () => handleToggle(column.id, !!column.hidden)
5653
5653
  }
5654
5654
  ),
5655
- /* @__PURE__ */ jsx("span", { className: styles$j.columnLabel, children: column.title || column.id })
5655
+ /* @__PURE__ */ jsx("span", { className: styles$k.columnLabel, children: column.title || column.id })
5656
5656
  ]
5657
5657
  },
5658
5658
  column.id
@@ -5668,7 +5668,7 @@ const ganttTable_HeaderMoveTask = "_ganttTable_HeaderMoveTask_5goa0_27";
5668
5668
  const ganttTable_HeaderSeparator = "_ganttTable_HeaderSeparator_5goa0_39";
5669
5669
  const ganttTable_HeaderItem = "_ganttTable_HeaderItem_5goa0_53";
5670
5670
  const resizer = "_resizer_5goa0_77";
5671
- const styles$i = {
5671
+ const styles$j = {
5672
5672
  ganttTable,
5673
5673
  ganttTable_Header,
5674
5674
  ganttTable_HeaderMoveTask,
@@ -5720,7 +5720,7 @@ const TaskListTableHeadersDefaultInner = ({
5720
5720
  return /* @__PURE__ */ jsx(
5721
5721
  "div",
5722
5722
  {
5723
- className: styles$i.ganttTable,
5723
+ className: styles$j.ganttTable,
5724
5724
  style: {
5725
5725
  fontFamily: "var(--gantt-font-family)",
5726
5726
  fontSize: "var(--gantt-font-size)"
@@ -5728,18 +5728,18 @@ const TaskListTableHeadersDefaultInner = ({
5728
5728
  children: /* @__PURE__ */ jsxs(
5729
5729
  "div",
5730
5730
  {
5731
- className: styles$i.ganttTable_Header,
5731
+ className: styles$j.ganttTable_Header,
5732
5732
  style: {
5733
5733
  height: headerHeight - 2
5734
5734
  },
5735
5735
  children: [
5736
- canMoveTasks && /* @__PURE__ */ jsx("div", { className: styles$i.ganttTable_HeaderMoveTask }),
5736
+ canMoveTasks && /* @__PURE__ */ jsx("div", { className: styles$j.ganttTable_HeaderMoveTask }),
5737
5737
  columns.map(({ title: title2, width, canResize }, index2) => {
5738
5738
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
5739
5739
  index2 > 0 && !!title2 && /* @__PURE__ */ jsx(
5740
5740
  "div",
5741
5741
  {
5742
- className: styles$i.ganttTable_HeaderSeparator,
5742
+ className: styles$j.ganttTable_HeaderSeparator,
5743
5743
  style: {
5744
5744
  height: headerHeight * 0.5,
5745
5745
  marginTop: headerHeight * 0.2
@@ -5750,7 +5750,7 @@ const TaskListTableHeadersDefaultInner = ({
5750
5750
  "div",
5751
5751
  {
5752
5752
  "data-testid": `table-column-header-${title2}`,
5753
- className: styles$i.ganttTable_HeaderItem,
5753
+ className: styles$j.ganttTable_HeaderItem,
5754
5754
  style: {
5755
5755
  minWidth: width,
5756
5756
  maxWidth: width,
@@ -5762,7 +5762,7 @@ const TaskListTableHeadersDefaultInner = ({
5762
5762
  "div",
5763
5763
  {
5764
5764
  "data-testid": `table-column-header-resize-handle-${title2}`,
5765
- className: styles$i.resizer,
5765
+ className: styles$j.resizer,
5766
5766
  onMouseDown: (event) => {
5767
5767
  onColumnResizeStart(index2, event.clientX);
5768
5768
  },
@@ -5782,7 +5782,7 @@ const TaskListTableHeadersDefaultInner = ({
5782
5782
  canToggleColumns && /* @__PURE__ */ jsx(
5783
5783
  "div",
5784
5784
  {
5785
- className: styles$i.ganttTable_HeaderItem,
5785
+ className: styles$j.ganttTable_HeaderItem,
5786
5786
  style: { minWidth: 28, maxWidth: 28 },
5787
5787
  children: /* @__PURE__ */ jsx(
5788
5788
  ColumnVisibilityToggle,
@@ -9990,7 +9990,7 @@ function normalizeLocalDisabled(localDisabled, globalDisabled) {
9990
9990
  }
9991
9991
  [KeyboardCode.Down, KeyboardCode.Right, KeyboardCode.Up, KeyboardCode.Left];
9992
9992
  const taskListWrapper$1 = "_taskListWrapper_196te_3";
9993
- const styles$h = {
9993
+ const styles$i = {
9994
9994
  taskListWrapper: taskListWrapper$1
9995
9995
  };
9996
9996
  function getDragDepth(offset2, indentationWidth2) {
@@ -10176,7 +10176,7 @@ const dragIndicator = "_dragIndicator_1yqtr_99";
10176
10176
  const dragIndicatorIcon = "_dragIndicatorIcon_1yqtr_119";
10177
10177
  const isCut = "_isCut_1yqtr_135";
10178
10178
  const taskListCell = "_taskListCell_1yqtr_167";
10179
- const styles$g = {
10179
+ const styles$h = {
10180
10180
  taskListTableRow,
10181
10181
  isAfter,
10182
10182
  isBefore,
@@ -10202,6 +10202,105 @@ const DragIndicatorIcon = (props) => /* @__PURE__ */ jsxs(
10202
10202
  ]
10203
10203
  }
10204
10204
  );
10205
+ const inlineEditWrapper = "_inlineEditWrapper_118p4_1";
10206
+ const inlineEditInput = "_inlineEditInput_118p4_19";
10207
+ const styles$g = {
10208
+ inlineEditWrapper,
10209
+ inlineEditInput
10210
+ };
10211
+ const InlineEditCell = ({
10212
+ value,
10213
+ editType = "text",
10214
+ editOptions,
10215
+ onCommit,
10216
+ onCancel
10217
+ }) => {
10218
+ const inputRef = useRef(null);
10219
+ const [localValue, setLocalValue] = useState(
10220
+ () => formatForInput(value, editType)
10221
+ );
10222
+ useEffect(() => {
10223
+ const el = inputRef.current;
10224
+ if (el) {
10225
+ el.focus();
10226
+ if ("select" in el && editType !== "select") {
10227
+ el.select();
10228
+ }
10229
+ }
10230
+ }, [editType]);
10231
+ const commitValue = useCallback(() => {
10232
+ const parsed = parseFromInput(localValue, editType);
10233
+ onCommit(parsed);
10234
+ }, [localValue, editType, onCommit]);
10235
+ const handleKeyDown = useCallback(
10236
+ (e) => {
10237
+ if (e.key === "Enter") {
10238
+ e.preventDefault();
10239
+ commitValue();
10240
+ } else if (e.key === "Escape") {
10241
+ e.preventDefault();
10242
+ onCancel();
10243
+ }
10244
+ e.stopPropagation();
10245
+ },
10246
+ [commitValue, onCancel]
10247
+ );
10248
+ const handleBlur = useCallback(() => {
10249
+ commitValue();
10250
+ }, [commitValue]);
10251
+ const stopPropagation2 = useCallback((e) => {
10252
+ e.stopPropagation();
10253
+ }, []);
10254
+ if (editType === "select") {
10255
+ return /* @__PURE__ */ jsx("div", { className: styles$g.inlineEditWrapper, onMouseDown: stopPropagation2, children: /* @__PURE__ */ jsx(
10256
+ "select",
10257
+ {
10258
+ ref: inputRef,
10259
+ className: styles$g.inlineEditInput,
10260
+ value: localValue,
10261
+ onChange: (e) => setLocalValue(e.target.value),
10262
+ onKeyDown: handleKeyDown,
10263
+ onBlur: handleBlur,
10264
+ children: editOptions == null ? void 0 : editOptions.map((opt) => /* @__PURE__ */ jsx("option", { value: opt.value, children: opt.label }, opt.value))
10265
+ }
10266
+ ) });
10267
+ }
10268
+ return /* @__PURE__ */ jsx("div", { className: styles$g.inlineEditWrapper, onMouseDown: stopPropagation2, children: /* @__PURE__ */ jsx(
10269
+ "input",
10270
+ {
10271
+ ref: inputRef,
10272
+ className: styles$g.inlineEditInput,
10273
+ type: editType === "number" ? "number" : editType === "date" ? "date" : "text",
10274
+ value: localValue,
10275
+ onChange: (e) => setLocalValue(e.target.value),
10276
+ onKeyDown: handleKeyDown,
10277
+ onBlur: handleBlur
10278
+ }
10279
+ ) });
10280
+ };
10281
+ function formatForInput(value, editType) {
10282
+ if (value == null)
10283
+ return "";
10284
+ if (editType === "date") {
10285
+ if (value instanceof Date) {
10286
+ return value.toISOString().slice(0, 10);
10287
+ }
10288
+ if (typeof value === "string")
10289
+ return value.slice(0, 10);
10290
+ }
10291
+ return String(value);
10292
+ }
10293
+ function parseFromInput(raw, editType) {
10294
+ if (editType === "number") {
10295
+ const n = Number(raw);
10296
+ return Number.isNaN(n) ? raw : n;
10297
+ }
10298
+ if (editType === "date") {
10299
+ const d = new Date(raw);
10300
+ return Number.isNaN(d.getTime()) ? raw : d;
10301
+ }
10302
+ return raw;
10303
+ }
10205
10304
  const TaskListTableRowInner = forwardRef(
10206
10305
  (props, ref) => {
10207
10306
  const {
@@ -10234,9 +10333,11 @@ const TaskListTableRowInner = forwardRef(
10234
10333
  task,
10235
10334
  moveHandleProps,
10236
10335
  isOverlay: isOverlay2,
10237
- moveOverPosition
10336
+ moveOverPosition,
10337
+ onTaskInlineEdit
10238
10338
  } = props;
10239
10339
  const { id, comparisonLevel = 1 } = task;
10340
+ const [editingColumnId, setEditingColumnId] = useState(null);
10240
10341
  const onRootMouseDown = useCallback(
10241
10342
  (event) => {
10242
10343
  event.preventDefault();
@@ -10329,18 +10430,18 @@ const TaskListTableRowInner = forwardRef(
10329
10430
  return isSelected ? "var(--gantt-table-selected-task-background-color)" : isEven ? "var(--gantt-table-even-background-color)" : void 0;
10330
10431
  }, [isEven, isOverlay2, isSelected]);
10331
10432
  const rowClassName = useMemo(() => {
10332
- const classNames = [styles$g.taskListTableRow];
10433
+ const classNames = [styles$h.taskListTableRow];
10333
10434
  if (moveOverPosition === "after") {
10334
- classNames.push(styles$g.isAfter);
10435
+ classNames.push(styles$h.isAfter);
10335
10436
  }
10336
10437
  if (moveOverPosition === "before") {
10337
- classNames.push(styles$g.isBefore);
10438
+ classNames.push(styles$h.isBefore);
10338
10439
  }
10339
10440
  if (isOverlay2 && !isDragging) {
10340
- classNames.push(styles$g.isOverlay);
10441
+ classNames.push(styles$h.isOverlay);
10341
10442
  }
10342
10443
  if (isCut2) {
10343
- classNames.push(styles$g.isCut);
10444
+ classNames.push(styles$h.isCut);
10344
10445
  }
10345
10446
  return classNames.join(" ");
10346
10447
  }, [isCut2, moveOverPosition, isOverlay2, isDragging]);
@@ -10389,20 +10490,72 @@ const TaskListTableRowInner = forwardRef(
10389
10490
  },
10390
10491
  onContextMenu,
10391
10492
  children: [
10392
- task.type !== "project" && task.id !== "no-project-asigned" && !isOverlay2 && moveHandleProps ? /* @__PURE__ */ jsx("div", { className: `${styles$g.dragIndicator}`, ...moveHandleProps, children: /* @__PURE__ */ jsx(DragIndicatorIcon, { className: styles$g.dragIndicatorIcon }) }) : /* @__PURE__ */ jsx("div", {}),
10393
- columns.map(({ id: id2, component: Component, width }, index2) => {
10493
+ task.type !== "project" && task.id !== "no-project-asigned" && !isOverlay2 && moveHandleProps ? /* @__PURE__ */ jsx("div", { className: `${styles$h.dragIndicator}`, ...moveHandleProps, children: /* @__PURE__ */ jsx(DragIndicatorIcon, { className: styles$h.dragIndicatorIcon }) }) : /* @__PURE__ */ jsx("div", {}),
10494
+ columns.map((col, index2) => {
10495
+ const { id: colId, component: Component, width } = col;
10496
+ const isEditingCell = editingColumnId === colId;
10497
+ const resolveValue = (c) => {
10498
+ const t = columnData.task;
10499
+ if (c.getValueFromTask)
10500
+ return c.getValueFromTask(t);
10501
+ if (t.type !== "empty" && t.payload && c.id in t.payload)
10502
+ return t.payload[c.id];
10503
+ return t[c.id];
10504
+ };
10505
+ const handleStartEdit = () => {
10506
+ if (col.editable && onTaskInlineEdit) {
10507
+ setEditingColumnId(colId);
10508
+ }
10509
+ };
10510
+ const handleCommitEdit = (newValue) => {
10511
+ setEditingColumnId(null);
10512
+ if (onTaskInlineEdit) {
10513
+ onTaskInlineEdit(task, colId, newValue);
10514
+ }
10515
+ };
10516
+ const handleCancelEdit = () => {
10517
+ setEditingColumnId(null);
10518
+ };
10519
+ const cellColumnData = {
10520
+ ...columnData,
10521
+ isEditing: isEditingCell,
10522
+ onStartEdit: handleStartEdit,
10523
+ onCommitEdit: handleCommitEdit,
10524
+ onCancelEdit: handleCancelEdit
10525
+ };
10394
10526
  return /* @__PURE__ */ jsx(
10395
10527
  "div",
10396
10528
  {
10397
- className: styles$g.taskListCell,
10529
+ className: styles$h.taskListCell,
10398
10530
  style: {
10399
10531
  minWidth: width,
10400
10532
  maxWidth: width,
10401
10533
  ...pinnedStyles[index2]
10402
10534
  },
10403
- children: /* @__PURE__ */ jsx(Component, { data: columnData })
10535
+ onDoubleClick: col.editable && onTaskInlineEdit && !isEditingCell ? (e) => {
10536
+ e.stopPropagation();
10537
+ handleStartEdit();
10538
+ } : void 0,
10539
+ children: isEditingCell ? col.editComponent ? /* @__PURE__ */ jsx(
10540
+ col.editComponent,
10541
+ {
10542
+ data: cellColumnData,
10543
+ value: resolveValue(col),
10544
+ onCommit: handleCommitEdit,
10545
+ onCancel: handleCancelEdit
10546
+ }
10547
+ ) : /* @__PURE__ */ jsx(
10548
+ InlineEditCell,
10549
+ {
10550
+ value: resolveValue(col),
10551
+ editType: col.editType,
10552
+ editOptions: col.editOptions,
10553
+ onCommit: handleCommitEdit,
10554
+ onCancel: handleCancelEdit
10555
+ }
10556
+ ) : /* @__PURE__ */ jsx(Component, { data: cellColumnData })
10404
10557
  },
10405
- `${id2}-${index2}`
10558
+ `${colId}-${index2}`
10406
10559
  );
10407
10560
  })
10408
10561
  ]
@@ -10805,7 +10958,7 @@ const TaskListSortableTableDefaultInner = (props) => {
10805
10958
  children: /* @__PURE__ */ jsx(
10806
10959
  "div",
10807
10960
  {
10808
- className: styles$h.taskListWrapper,
10961
+ className: styles$i.taskListWrapper,
10809
10962
  style: {
10810
10963
  fontFamily: "var(--gantt-font-family)",
10811
10964
  fontSize: "var(--gantt-font-size)"
@@ -10968,7 +11121,8 @@ const TaskListInner = ({
10968
11121
  canReorderTasks,
10969
11122
  canToggleColumns,
10970
11123
  onColumnVisibilityChange,
10971
- tableBottom
11124
+ tableBottom,
11125
+ onTaskInlineEdit
10972
11126
  }) => {
10973
11127
  const [
10974
11128
  allColumns,
@@ -11028,7 +11182,8 @@ const TaskListInner = ({
11028
11182
  scrollToTask,
11029
11183
  selectTaskOnMouseDown,
11030
11184
  task,
11031
- depth
11185
+ depth,
11186
+ onTaskInlineEdit
11032
11187
  };
11033
11188
  },
11034
11189
  [
@@ -11052,7 +11207,8 @@ const TaskListInner = ({
11052
11207
  onExpanderClick,
11053
11208
  scrollToTask,
11054
11209
  selectTaskOnMouseDown,
11055
- selectedIdsMirror
11210
+ selectedIdsMirror,
11211
+ onTaskInlineEdit
11056
11212
  ]
11057
11213
  );
11058
11214
  const RenderTaskListTable = canReorderTasks ? TaskListSortableTable : TaskListTable;
@@ -4606,7 +4606,7 @@
4606
4606
  const tooltipDefaultContainerParagraph = "_tooltipDefaultContainerParagraph_16o9s_31";
4607
4607
  const tooltipDetailsContainer = "_tooltipDetailsContainer_16o9s_47";
4608
4608
  const tooltipDetailsContainerHidden = "_tooltipDetailsContainerHidden_16o9s_71";
4609
- const styles$n = {
4609
+ const styles$o = {
4610
4610
  tooltipDefaultContainer,
4611
4611
  tooltipDefaultContainerTexts,
4612
4612
  tooltipDefaultContainerParagraph,
@@ -4649,26 +4649,26 @@
4649
4649
  return /* @__PURE__ */ jsxRuntime.jsxs(
4650
4650
  "div",
4651
4651
  {
4652
- className: styles$n.tooltipDefaultContainer,
4652
+ className: styles$o.tooltipDefaultContainer,
4653
4653
  style: { fontSize: "var(--gantt-font-size)" },
4654
4654
  children: [
4655
4655
  /* @__PURE__ */ jsxRuntime.jsx("b", { style: { fontSize: "var(--gantt-font-size)" }, children: `${task.name}: ${task.start.getDate()}-${task.start.getMonth() + 1}-${task.start.getFullYear()} - ${task.end.getDate()}-${task.end.getMonth() + 1}-${task.end.getFullYear()}` }),
4656
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles$n.tooltipDefaultContainerTexts, children: [
4656
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles$o.tooltipDefaultContainerTexts, children: [
4657
4657
  task.end.getTime() - task.start.getTime() !== 0 && /* @__PURE__ */ jsxRuntime.jsx(
4658
4658
  "p",
4659
4659
  {
4660
- className: styles$n.tooltipDefaultContainerParagraph,
4660
+ className: styles$o.tooltipDefaultContainerParagraph,
4661
4661
  children: `${locale.tooltip.duration},: ${~~((task.end.getTime() - task.start.getTime()) / (1e3 * 60 * 60 * 24))} ${locale.suffix.days}`
4662
4662
  }
4663
4663
  ),
4664
- !!locale.tooltip.progress && /* @__PURE__ */ jsxRuntime.jsx("p", { className: styles$n.tooltipDefaultContainerParagraph, children: !!task.progress && `${locale.tooltip.progress}: ${task.progress} %` })
4664
+ !!locale.tooltip.progress && /* @__PURE__ */ jsxRuntime.jsx("p", { className: styles$o.tooltipDefaultContainerParagraph, children: !!task.progress && `${locale.tooltip.progress}: ${task.progress} %` })
4665
4665
  ] })
4666
4666
  ]
4667
4667
  }
4668
4668
  );
4669
4669
  };
4670
4670
  const scroll = "_scroll_hp3qb_1";
4671
- const styles$m = {
4671
+ const styles$n = {
4672
4672
  scroll
4673
4673
  };
4674
4674
  const VerticalScroll = ({
@@ -4689,7 +4689,7 @@
4689
4689
  marginLeft: rtl ? void 0 : "-1rem",
4690
4690
  pointerEvents: isChangeInProgress ? "none" : void 0
4691
4691
  },
4692
- className: styles$m.scroll,
4692
+ className: styles$n.scroll,
4693
4693
  onScroll,
4694
4694
  ref: verticalScrollbarRef,
4695
4695
  children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: ganttFullHeight, width: 1 } })
@@ -4767,7 +4767,7 @@
4767
4767
  const taskListExpander = "_taskListExpander_16z6n_23";
4768
4768
  const taskListEmptyExpander = "_taskListEmptyExpander_16z6n_45";
4769
4769
  const taskName = "_taskName_16z6n_55";
4770
- const styles$l = {
4770
+ const styles$m = {
4771
4771
  taskListNameWrapper,
4772
4772
  dragging,
4773
4773
  taskListExpander,
@@ -4844,7 +4844,7 @@
4844
4844
  "div",
4845
4845
  {
4846
4846
  "data-testid": `title-table-cell-${name}`,
4847
- className: `${styles$l.taskListNameWrapper}`,
4847
+ className: `${styles$m.taskListNameWrapper}`,
4848
4848
  style: {
4849
4849
  paddingLeft: depth * nestedTaskNameOffset
4850
4850
  },
@@ -4853,7 +4853,7 @@
4853
4853
  /* @__PURE__ */ jsxRuntime.jsx(
4854
4854
  "div",
4855
4855
  {
4856
- className: `gantt-expander ${styles$l.taskListExpander} ${!hasChildren ? styles$l.taskListEmptyExpander : ""}`,
4856
+ className: `gantt-expander ${styles$m.taskListExpander} ${!hasChildren ? styles$m.taskListEmptyExpander : ""}`,
4857
4857
  style: {
4858
4858
  left: depth * nestedTaskNameOffset
4859
4859
  },
@@ -4864,7 +4864,7 @@
4864
4864
  /* @__PURE__ */ jsxRuntime.jsxs(
4865
4865
  "div",
4866
4866
  {
4867
- className: styles$l.taskName,
4867
+ className: styles$m.taskName,
4868
4868
  style: { fontWeight: isProject ? "bold" : "regular" },
4869
4869
  children: [
4870
4870
  isShowTaskNumbers && /* @__PURE__ */ jsxRuntime.jsxs("b", { children: [
@@ -4919,7 +4919,7 @@
4919
4919
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: dependencies.map(({ name }) => name).join(", ") });
4920
4920
  };
4921
4921
  const button = "_button_l55x0_1";
4922
- const styles$k = {
4922
+ const styles$l = {
4923
4923
  button
4924
4924
  };
4925
4925
  const DeleteIcon = (props) => /* @__PURE__ */ jsxRuntime.jsxs(
@@ -4953,7 +4953,7 @@
4953
4953
  e.stopPropagation();
4954
4954
  },
4955
4955
  onClick,
4956
- className: styles$k.button,
4956
+ className: styles$l.button,
4957
4957
  children: (icons == null ? void 0 : icons.renderDeleteIcon) ? icons.renderDeleteIcon() : /* @__PURE__ */ jsxRuntime.jsx(DeleteIcon, {})
4958
4958
  }
4959
4959
  );
@@ -4988,7 +4988,7 @@
4988
4988
  e.stopPropagation();
4989
4989
  },
4990
4990
  onClick,
4991
- className: styles$k.button,
4991
+ className: styles$l.button,
4992
4992
  children: (icons == null ? void 0 : icons.renderEditIcon) ? icons.renderEditIcon() : /* @__PURE__ */ jsxRuntime.jsx(EditIcon, {})
4993
4993
  }
4994
4994
  );
@@ -5029,7 +5029,7 @@
5029
5029
  e.stopPropagation();
5030
5030
  },
5031
5031
  onClick,
5032
- className: styles$k.button,
5032
+ className: styles$l.button,
5033
5033
  children: (icons == null ? void 0 : icons.renderAddIcon) ? icons.renderAddIcon() : /* @__PURE__ */ jsxRuntime.jsx(AddIcon, {})
5034
5034
  }
5035
5035
  );
@@ -5562,7 +5562,7 @@
5562
5562
  const columnLabel = "_columnLabel_rjfhl_157";
5563
5563
  const dropdownTitle = "_dropdownTitle_rjfhl_169";
5564
5564
  const divider = "_divider_rjfhl_211";
5565
- const styles$j = {
5565
+ const styles$k = {
5566
5566
  toggleWrapper,
5567
5567
  toggleButton,
5568
5568
  dropdown,
@@ -5638,38 +5638,38 @@
5638
5638
  if (toggleableColumns.length === 0) {
5639
5639
  return null;
5640
5640
  }
5641
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles$j.toggleWrapper, ref: wrapperRef, children: [
5641
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles$k.toggleWrapper, ref: wrapperRef, children: [
5642
5642
  /* @__PURE__ */ jsxRuntime.jsx(
5643
5643
  "button",
5644
5644
  {
5645
- className: styles$j.toggleButton,
5645
+ className: styles$k.toggleButton,
5646
5646
  onClick: toggleDropdown,
5647
5647
  title: "Toggle column visibility",
5648
5648
  type: "button",
5649
5649
  children: /* @__PURE__ */ jsxRuntime.jsx(ColumnsIcon, {})
5650
5650
  }
5651
5651
  ),
5652
- isOpen && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles$j.dropdown, children: [
5653
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles$j.dropdownTitle, children: "Columns" }),
5654
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles$j.divider }),
5652
+ isOpen && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles$k.dropdown, children: [
5653
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles$k.dropdownTitle, children: "Columns" }),
5654
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles$k.divider }),
5655
5655
  toggleableColumns.map((column) => {
5656
5656
  const isVisible = !column.hidden;
5657
5657
  return /* @__PURE__ */ jsxRuntime.jsxs(
5658
5658
  "label",
5659
5659
  {
5660
- className: styles$j.dropdownItem,
5660
+ className: styles$k.dropdownItem,
5661
5661
  onClick: (e) => e.stopPropagation(),
5662
5662
  children: [
5663
5663
  /* @__PURE__ */ jsxRuntime.jsx(
5664
5664
  "input",
5665
5665
  {
5666
5666
  type: "checkbox",
5667
- className: styles$j.checkbox,
5667
+ className: styles$k.checkbox,
5668
5668
  checked: isVisible,
5669
5669
  onChange: () => handleToggle(column.id, !!column.hidden)
5670
5670
  }
5671
5671
  ),
5672
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles$j.columnLabel, children: column.title || column.id })
5672
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles$k.columnLabel, children: column.title || column.id })
5673
5673
  ]
5674
5674
  },
5675
5675
  column.id
@@ -5685,7 +5685,7 @@
5685
5685
  const ganttTable_HeaderSeparator = "_ganttTable_HeaderSeparator_5goa0_39";
5686
5686
  const ganttTable_HeaderItem = "_ganttTable_HeaderItem_5goa0_53";
5687
5687
  const resizer = "_resizer_5goa0_77";
5688
- const styles$i = {
5688
+ const styles$j = {
5689
5689
  ganttTable,
5690
5690
  ganttTable_Header,
5691
5691
  ganttTable_HeaderMoveTask,
@@ -5737,7 +5737,7 @@
5737
5737
  return /* @__PURE__ */ jsxRuntime.jsx(
5738
5738
  "div",
5739
5739
  {
5740
- className: styles$i.ganttTable,
5740
+ className: styles$j.ganttTable,
5741
5741
  style: {
5742
5742
  fontFamily: "var(--gantt-font-family)",
5743
5743
  fontSize: "var(--gantt-font-size)"
@@ -5745,18 +5745,18 @@
5745
5745
  children: /* @__PURE__ */ jsxRuntime.jsxs(
5746
5746
  "div",
5747
5747
  {
5748
- className: styles$i.ganttTable_Header,
5748
+ className: styles$j.ganttTable_Header,
5749
5749
  style: {
5750
5750
  height: headerHeight - 2
5751
5751
  },
5752
5752
  children: [
5753
- canMoveTasks && /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles$i.ganttTable_HeaderMoveTask }),
5753
+ canMoveTasks && /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles$j.ganttTable_HeaderMoveTask }),
5754
5754
  columns.map(({ title: title2, width, canResize }, index2) => {
5755
5755
  return /* @__PURE__ */ jsxRuntime.jsxs(React.Fragment, { children: [
5756
5756
  index2 > 0 && !!title2 && /* @__PURE__ */ jsxRuntime.jsx(
5757
5757
  "div",
5758
5758
  {
5759
- className: styles$i.ganttTable_HeaderSeparator,
5759
+ className: styles$j.ganttTable_HeaderSeparator,
5760
5760
  style: {
5761
5761
  height: headerHeight * 0.5,
5762
5762
  marginTop: headerHeight * 0.2
@@ -5767,7 +5767,7 @@
5767
5767
  "div",
5768
5768
  {
5769
5769
  "data-testid": `table-column-header-${title2}`,
5770
- className: styles$i.ganttTable_HeaderItem,
5770
+ className: styles$j.ganttTable_HeaderItem,
5771
5771
  style: {
5772
5772
  minWidth: width,
5773
5773
  maxWidth: width,
@@ -5779,7 +5779,7 @@
5779
5779
  "div",
5780
5780
  {
5781
5781
  "data-testid": `table-column-header-resize-handle-${title2}`,
5782
- className: styles$i.resizer,
5782
+ className: styles$j.resizer,
5783
5783
  onMouseDown: (event) => {
5784
5784
  onColumnResizeStart(index2, event.clientX);
5785
5785
  },
@@ -5799,7 +5799,7 @@
5799
5799
  canToggleColumns && /* @__PURE__ */ jsxRuntime.jsx(
5800
5800
  "div",
5801
5801
  {
5802
- className: styles$i.ganttTable_HeaderItem,
5802
+ className: styles$j.ganttTable_HeaderItem,
5803
5803
  style: { minWidth: 28, maxWidth: 28 },
5804
5804
  children: /* @__PURE__ */ jsxRuntime.jsx(
5805
5805
  ColumnVisibilityToggle,
@@ -10007,7 +10007,7 @@
10007
10007
  }
10008
10008
  [KeyboardCode.Down, KeyboardCode.Right, KeyboardCode.Up, KeyboardCode.Left];
10009
10009
  const taskListWrapper$1 = "_taskListWrapper_196te_3";
10010
- const styles$h = {
10010
+ const styles$i = {
10011
10011
  taskListWrapper: taskListWrapper$1
10012
10012
  };
10013
10013
  function getDragDepth(offset2, indentationWidth2) {
@@ -10193,7 +10193,7 @@
10193
10193
  const dragIndicatorIcon = "_dragIndicatorIcon_1yqtr_119";
10194
10194
  const isCut = "_isCut_1yqtr_135";
10195
10195
  const taskListCell = "_taskListCell_1yqtr_167";
10196
- const styles$g = {
10196
+ const styles$h = {
10197
10197
  taskListTableRow,
10198
10198
  isAfter,
10199
10199
  isBefore,
@@ -10219,6 +10219,105 @@
10219
10219
  ]
10220
10220
  }
10221
10221
  );
10222
+ const inlineEditWrapper = "_inlineEditWrapper_118p4_1";
10223
+ const inlineEditInput = "_inlineEditInput_118p4_19";
10224
+ const styles$g = {
10225
+ inlineEditWrapper,
10226
+ inlineEditInput
10227
+ };
10228
+ const InlineEditCell = ({
10229
+ value,
10230
+ editType = "text",
10231
+ editOptions,
10232
+ onCommit,
10233
+ onCancel
10234
+ }) => {
10235
+ const inputRef = React.useRef(null);
10236
+ const [localValue, setLocalValue] = React.useState(
10237
+ () => formatForInput(value, editType)
10238
+ );
10239
+ React.useEffect(() => {
10240
+ const el = inputRef.current;
10241
+ if (el) {
10242
+ el.focus();
10243
+ if ("select" in el && editType !== "select") {
10244
+ el.select();
10245
+ }
10246
+ }
10247
+ }, [editType]);
10248
+ const commitValue = React.useCallback(() => {
10249
+ const parsed = parseFromInput(localValue, editType);
10250
+ onCommit(parsed);
10251
+ }, [localValue, editType, onCommit]);
10252
+ const handleKeyDown = React.useCallback(
10253
+ (e) => {
10254
+ if (e.key === "Enter") {
10255
+ e.preventDefault();
10256
+ commitValue();
10257
+ } else if (e.key === "Escape") {
10258
+ e.preventDefault();
10259
+ onCancel();
10260
+ }
10261
+ e.stopPropagation();
10262
+ },
10263
+ [commitValue, onCancel]
10264
+ );
10265
+ const handleBlur = React.useCallback(() => {
10266
+ commitValue();
10267
+ }, [commitValue]);
10268
+ const stopPropagation2 = React.useCallback((e) => {
10269
+ e.stopPropagation();
10270
+ }, []);
10271
+ if (editType === "select") {
10272
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles$g.inlineEditWrapper, onMouseDown: stopPropagation2, children: /* @__PURE__ */ jsxRuntime.jsx(
10273
+ "select",
10274
+ {
10275
+ ref: inputRef,
10276
+ className: styles$g.inlineEditInput,
10277
+ value: localValue,
10278
+ onChange: (e) => setLocalValue(e.target.value),
10279
+ onKeyDown: handleKeyDown,
10280
+ onBlur: handleBlur,
10281
+ children: editOptions == null ? void 0 : editOptions.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt.value, children: opt.label }, opt.value))
10282
+ }
10283
+ ) });
10284
+ }
10285
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles$g.inlineEditWrapper, onMouseDown: stopPropagation2, children: /* @__PURE__ */ jsxRuntime.jsx(
10286
+ "input",
10287
+ {
10288
+ ref: inputRef,
10289
+ className: styles$g.inlineEditInput,
10290
+ type: editType === "number" ? "number" : editType === "date" ? "date" : "text",
10291
+ value: localValue,
10292
+ onChange: (e) => setLocalValue(e.target.value),
10293
+ onKeyDown: handleKeyDown,
10294
+ onBlur: handleBlur
10295
+ }
10296
+ ) });
10297
+ };
10298
+ function formatForInput(value, editType) {
10299
+ if (value == null)
10300
+ return "";
10301
+ if (editType === "date") {
10302
+ if (value instanceof Date) {
10303
+ return value.toISOString().slice(0, 10);
10304
+ }
10305
+ if (typeof value === "string")
10306
+ return value.slice(0, 10);
10307
+ }
10308
+ return String(value);
10309
+ }
10310
+ function parseFromInput(raw, editType) {
10311
+ if (editType === "number") {
10312
+ const n = Number(raw);
10313
+ return Number.isNaN(n) ? raw : n;
10314
+ }
10315
+ if (editType === "date") {
10316
+ const d = new Date(raw);
10317
+ return Number.isNaN(d.getTime()) ? raw : d;
10318
+ }
10319
+ return raw;
10320
+ }
10222
10321
  const TaskListTableRowInner = React.forwardRef(
10223
10322
  (props, ref) => {
10224
10323
  const {
@@ -10251,9 +10350,11 @@
10251
10350
  task,
10252
10351
  moveHandleProps,
10253
10352
  isOverlay: isOverlay2,
10254
- moveOverPosition
10353
+ moveOverPosition,
10354
+ onTaskInlineEdit
10255
10355
  } = props;
10256
10356
  const { id, comparisonLevel = 1 } = task;
10357
+ const [editingColumnId, setEditingColumnId] = React.useState(null);
10257
10358
  const onRootMouseDown = React.useCallback(
10258
10359
  (event) => {
10259
10360
  event.preventDefault();
@@ -10346,18 +10447,18 @@
10346
10447
  return isSelected ? "var(--gantt-table-selected-task-background-color)" : isEven ? "var(--gantt-table-even-background-color)" : void 0;
10347
10448
  }, [isEven, isOverlay2, isSelected]);
10348
10449
  const rowClassName = React.useMemo(() => {
10349
- const classNames = [styles$g.taskListTableRow];
10450
+ const classNames = [styles$h.taskListTableRow];
10350
10451
  if (moveOverPosition === "after") {
10351
- classNames.push(styles$g.isAfter);
10452
+ classNames.push(styles$h.isAfter);
10352
10453
  }
10353
10454
  if (moveOverPosition === "before") {
10354
- classNames.push(styles$g.isBefore);
10455
+ classNames.push(styles$h.isBefore);
10355
10456
  }
10356
10457
  if (isOverlay2 && !isDragging) {
10357
- classNames.push(styles$g.isOverlay);
10458
+ classNames.push(styles$h.isOverlay);
10358
10459
  }
10359
10460
  if (isCut2) {
10360
- classNames.push(styles$g.isCut);
10461
+ classNames.push(styles$h.isCut);
10361
10462
  }
10362
10463
  return classNames.join(" ");
10363
10464
  }, [isCut2, moveOverPosition, isOverlay2, isDragging]);
@@ -10406,20 +10507,72 @@
10406
10507
  },
10407
10508
  onContextMenu,
10408
10509
  children: [
10409
- task.type !== "project" && task.id !== "no-project-asigned" && !isOverlay2 && moveHandleProps ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${styles$g.dragIndicator}`, ...moveHandleProps, children: /* @__PURE__ */ jsxRuntime.jsx(DragIndicatorIcon, { className: styles$g.dragIndicatorIcon }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", {}),
10410
- columns.map(({ id: id2, component: Component, width }, index2) => {
10510
+ task.type !== "project" && task.id !== "no-project-asigned" && !isOverlay2 && moveHandleProps ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${styles$h.dragIndicator}`, ...moveHandleProps, children: /* @__PURE__ */ jsxRuntime.jsx(DragIndicatorIcon, { className: styles$h.dragIndicatorIcon }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", {}),
10511
+ columns.map((col, index2) => {
10512
+ const { id: colId, component: Component, width } = col;
10513
+ const isEditingCell = editingColumnId === colId;
10514
+ const resolveValue = (c) => {
10515
+ const t = columnData.task;
10516
+ if (c.getValueFromTask)
10517
+ return c.getValueFromTask(t);
10518
+ if (t.type !== "empty" && t.payload && c.id in t.payload)
10519
+ return t.payload[c.id];
10520
+ return t[c.id];
10521
+ };
10522
+ const handleStartEdit = () => {
10523
+ if (col.editable && onTaskInlineEdit) {
10524
+ setEditingColumnId(colId);
10525
+ }
10526
+ };
10527
+ const handleCommitEdit = (newValue) => {
10528
+ setEditingColumnId(null);
10529
+ if (onTaskInlineEdit) {
10530
+ onTaskInlineEdit(task, colId, newValue);
10531
+ }
10532
+ };
10533
+ const handleCancelEdit = () => {
10534
+ setEditingColumnId(null);
10535
+ };
10536
+ const cellColumnData = {
10537
+ ...columnData,
10538
+ isEditing: isEditingCell,
10539
+ onStartEdit: handleStartEdit,
10540
+ onCommitEdit: handleCommitEdit,
10541
+ onCancelEdit: handleCancelEdit
10542
+ };
10411
10543
  return /* @__PURE__ */ jsxRuntime.jsx(
10412
10544
  "div",
10413
10545
  {
10414
- className: styles$g.taskListCell,
10546
+ className: styles$h.taskListCell,
10415
10547
  style: {
10416
10548
  minWidth: width,
10417
10549
  maxWidth: width,
10418
10550
  ...pinnedStyles[index2]
10419
10551
  },
10420
- children: /* @__PURE__ */ jsxRuntime.jsx(Component, { data: columnData })
10552
+ onDoubleClick: col.editable && onTaskInlineEdit && !isEditingCell ? (e) => {
10553
+ e.stopPropagation();
10554
+ handleStartEdit();
10555
+ } : void 0,
10556
+ children: isEditingCell ? col.editComponent ? /* @__PURE__ */ jsxRuntime.jsx(
10557
+ col.editComponent,
10558
+ {
10559
+ data: cellColumnData,
10560
+ value: resolveValue(col),
10561
+ onCommit: handleCommitEdit,
10562
+ onCancel: handleCancelEdit
10563
+ }
10564
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
10565
+ InlineEditCell,
10566
+ {
10567
+ value: resolveValue(col),
10568
+ editType: col.editType,
10569
+ editOptions: col.editOptions,
10570
+ onCommit: handleCommitEdit,
10571
+ onCancel: handleCancelEdit
10572
+ }
10573
+ ) : /* @__PURE__ */ jsxRuntime.jsx(Component, { data: cellColumnData })
10421
10574
  },
10422
- `${id2}-${index2}`
10575
+ `${colId}-${index2}`
10423
10576
  );
10424
10577
  })
10425
10578
  ]
@@ -10822,7 +10975,7 @@
10822
10975
  children: /* @__PURE__ */ jsxRuntime.jsx(
10823
10976
  "div",
10824
10977
  {
10825
- className: styles$h.taskListWrapper,
10978
+ className: styles$i.taskListWrapper,
10826
10979
  style: {
10827
10980
  fontFamily: "var(--gantt-font-family)",
10828
10981
  fontSize: "var(--gantt-font-size)"
@@ -10985,7 +11138,8 @@
10985
11138
  canReorderTasks,
10986
11139
  canToggleColumns,
10987
11140
  onColumnVisibilityChange,
10988
- tableBottom
11141
+ tableBottom,
11142
+ onTaskInlineEdit
10989
11143
  }) => {
10990
11144
  const [
10991
11145
  allColumns,
@@ -11045,7 +11199,8 @@
11045
11199
  scrollToTask,
11046
11200
  selectTaskOnMouseDown,
11047
11201
  task,
11048
- depth
11202
+ depth,
11203
+ onTaskInlineEdit
11049
11204
  };
11050
11205
  },
11051
11206
  [
@@ -11069,7 +11224,8 @@
11069
11224
  onExpanderClick,
11070
11225
  scrollToTask,
11071
11226
  selectTaskOnMouseDown,
11072
- selectedIdsMirror
11227
+ selectedIdsMirror,
11228
+ onTaskInlineEdit
11073
11229
  ]
11074
11230
  );
11075
11231
  const RenderTaskListTable = canReorderTasks ? TaskListSortableTable : TaskListTable;
package/dist/style.css CHANGED
@@ -389,6 +389,33 @@
389
389
  overflow: hidden;
390
390
  text-overflow: ellipsis;
391
391
  }
392
+ ._inlineEditWrapper_118p4_1 {
393
+ display: flex;
394
+ align-items: center;
395
+ width: 100%;
396
+ height: 100%;
397
+ padding: 0 4px;
398
+ box-sizing: border-box;
399
+ }
400
+
401
+ ._inlineEditInput_118p4_19 {
402
+ width: 100%;
403
+ height: 80%;
404
+ border: 1px solid var(--gantt-table-selected-task-background-color, #1976d2);
405
+ border-radius: 2px;
406
+ outline: none;
407
+ padding: 2px 4px;
408
+ font-family: inherit;
409
+ font-size: inherit;
410
+ box-sizing: border-box;
411
+ background: #fff;
412
+ }
413
+
414
+ ._inlineEditInput_118p4_19:focus {
415
+ border-color: var(--gantt-table-selected-task-background-color, #1976d2);
416
+ box-shadow: 0 0 0 1px
417
+ var(--gantt-table-selected-task-background-color, #1976d2);
418
+ }
392
419
  /*noinspection CssUnresolvedCustomProperty*/
393
420
  ._taskListWrapper_196te_3 {
394
421
  display: table;
@@ -190,6 +190,10 @@ export type TaskListTableRowProps = {
190
190
  selectTaskOnMouseDown: (taskId: string, event: MouseEvent) => void;
191
191
  style?: CSSProperties;
192
192
  task: RenderTask;
193
+ /**
194
+ * Callback when a cell value is committed via inline editing.
195
+ */
196
+ onTaskInlineEdit?: (task: RenderTask, columnId: string, newValue: unknown) => void;
193
197
  };
194
198
  export interface TaskListHeaderProps {
195
199
  headerHeight: number;
@@ -198,6 +198,11 @@ export interface GanttTaskListProps {
198
198
  * Invokes on double click on a task list row. Receives the task data.
199
199
  */
200
200
  onDoubleClickTaskRow?: (task: RenderTask) => void;
201
+ /**
202
+ * Callback when a cell value is committed via inline editing.
203
+ * Return a promise that resolves to the updated task, or void.
204
+ */
205
+ onTaskInlineEdit?: (task: RenderTask, columnId: string, newValue: unknown) => void | Promise<void>;
201
206
  }
202
207
  export interface TableRenderBottomProps {
203
208
  height?: number;
@@ -449,10 +454,44 @@ export type ColumnData = {
449
454
  isShowTaskNumbers: boolean;
450
455
  onExpanderClick: (task: Task) => void;
451
456
  task: RenderTask;
457
+ /**
458
+ * Whether this cell is currently in inline-edit mode.
459
+ */
460
+ isEditing?: boolean;
461
+ /**
462
+ * Call to enter inline-edit mode for this column/cell.
463
+ */
464
+ onStartEdit?: () => void;
465
+ /**
466
+ * Commit the edited value. `value` is the new raw value for the column.
467
+ */
468
+ onCommitEdit?: (value: unknown) => void;
469
+ /**
470
+ * Cancel inline editing and revert to display mode.
471
+ */
472
+ onCancelEdit?: () => void;
452
473
  };
453
474
  export type ColumnProps = {
454
475
  data: ColumnData;
455
476
  };
477
+ /**
478
+ * The type of inline editor to render when no custom `editComponent` is provided.
479
+ * - `"text"` – a plain text input (default)
480
+ * - `"date"` – a date input (`<input type="date">`)
481
+ * - `"number"` – a numeric input
482
+ * - `"select"` – a `<select>` dropdown (provide `editOptions`)
483
+ */
484
+ export type ColumnEditType = "text" | "date" | "number" | "select";
485
+ export type EditColumnProps = {
486
+ /** Current column data (task, etc.) */
487
+ data: ColumnData;
488
+ /** Current raw value of the cell */
489
+ value: unknown;
490
+ /** Called with the new value when editing is finished */
491
+ onCommit: (value: unknown) => void;
492
+ /** Called to cancel editing */
493
+ onCancel: () => void;
494
+ };
456
495
  export type Column = {
457
496
  id: string;
458
497
  component: ComponentType<ColumnProps>;
@@ -468,6 +507,31 @@ export type Column = {
468
507
  * Hide this column from the table. Defaults to false.
469
508
  */
470
509
  hidden?: boolean;
510
+ /**
511
+ * Enable inline editing for this column. Defaults to false.
512
+ */
513
+ editable?: boolean;
514
+ /**
515
+ * The built-in editor type. Defaults to `"text"`.
516
+ */
517
+ editType?: ColumnEditType;
518
+ /**
519
+ * Options for the `"select"` edit type.
520
+ */
521
+ editOptions?: {
522
+ value: string;
523
+ label: string;
524
+ }[];
525
+ /**
526
+ * Custom edit component. When provided it replaces the built-in editor.
527
+ */
528
+ editComponent?: ComponentType<EditColumnProps>;
529
+ /**
530
+ * Resolve the raw value from the task for this column.
531
+ * Used by the built-in editor and passed to custom `editComponent`.
532
+ * Falls back to `task.payload?.[column.id]` then `(task as any)[column.id]`.
533
+ */
534
+ getValueFromTask?: (task: RenderTask) => unknown;
471
535
  };
472
536
  export type OnResizeColumn = (nextColumns: readonly Column[], columnIndex: number, deltaWidth: number) => void;
473
537
  export type OnColumnVisibilityChange = (columnId: string, hidden: boolean) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gantt-task-react-v",
3
- "version": "1.6.16",
3
+ "version": "1.6.17",
4
4
  "description": "Interactive Gantt Chart for React with TypeScript.",
5
5
  "author": "aguilanbon",
6
6
  "homepage": "https://github.com/aguilanbon/gantt-task-react-v",