gantt-lib 0.135.7 → 0.135.9

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
@@ -3241,19 +3241,20 @@ var pixelsToDate = (pixels, monthStart, dayWidth) => {
3241
3241
  var calculateGridWidth = (daysInMonth, dayWidth) => {
3242
3242
  return Math.round(daysInMonth * dayWidth);
3243
3243
  };
3244
+ var MIN_EDGE_ZONE_PX = 8;
3245
+ var MIN_MOVE_ZONE_PX = 16;
3244
3246
  var detectEdgeZone = (clientX, taskBarElement, edgeZoneWidth = 12) => {
3245
3247
  const rect = taskBarElement.getBoundingClientRect();
3246
3248
  const relativeX = Math.round(clientX - rect.left);
3247
3249
  const width = Math.round(rect.width);
3248
- if (width <= 2 * edgeZoneWidth) {
3249
- const distanceToLeft = relativeX;
3250
- const distanceToRight = width - relativeX;
3251
- return distanceToLeft <= distanceToRight ? "left" : "right";
3252
- }
3253
- if (relativeX >= 0 && relativeX <= edgeZoneWidth) {
3250
+ const effectiveZone = Math.max(
3251
+ MIN_EDGE_ZONE_PX,
3252
+ Math.min(edgeZoneWidth, (width - MIN_MOVE_ZONE_PX) / 2)
3253
+ );
3254
+ if (relativeX >= 0 && relativeX <= effectiveZone) {
3254
3255
  return "left";
3255
3256
  }
3256
- if (relativeX >= width - edgeZoneWidth && relativeX <= width) {
3257
+ if (relativeX >= width - effectiveZone && relativeX <= width) {
3257
3258
  return "right";
3258
3259
  }
3259
3260
  return "move";
@@ -3873,8 +3874,7 @@ var useTaskDrag = (options) => {
3873
3874
  locked = false,
3874
3875
  disableTaskDrag = false,
3875
3876
  businessDays = true,
3876
- weekendPredicate,
3877
- viewMode = "day"
3877
+ weekendPredicate
3878
3878
  } = options;
3879
3879
  const rawHookTask = allTasks.find((t) => t.id === taskId);
3880
3880
  const hookTask = rawHookTask ? normalizeTaskDatesForType(rawHookTask) : void 0;
@@ -4146,23 +4146,18 @@ var useTaskDrag = (options) => {
4146
4146
  if (effectiveLocked) return;
4147
4147
  const target = e.currentTarget;
4148
4148
  const currentTask = allTasks.find((t) => t.id === taskId);
4149
- const isSingleDayTask = !!currentTask && !isMilestoneTask(currentTask) && !isTaskParent(taskId, allTasks) && currentWidth <= dayWidth && viewMode === "day";
4150
4149
  let mode = null;
4151
- if (isSingleDayTask) {
4152
- mode = "move";
4153
- } else {
4154
- const edgeZone = detectEdgeZone(e.clientX, target, edgeZoneWidth);
4155
- switch (edgeZone) {
4156
- case "left":
4157
- mode = "resize-left";
4158
- break;
4159
- case "right":
4160
- mode = "resize-right";
4161
- break;
4162
- case "move":
4163
- mode = "move";
4164
- break;
4165
- }
4150
+ const edgeZone = detectEdgeZone(e.clientX, target, edgeZoneWidth);
4151
+ switch (edgeZone) {
4152
+ case "left":
4153
+ mode = "resize-left";
4154
+ break;
4155
+ case "right":
4156
+ mode = "resize-right";
4157
+ break;
4158
+ case "move":
4159
+ mode = "move";
4160
+ break;
4166
4161
  }
4167
4162
  if (mode === "resize-left" || mode === "resize-right") {
4168
4163
  if (currentTask && isMilestoneTask(currentTask)) {
@@ -4212,7 +4207,7 @@ var useTaskDrag = (options) => {
4212
4207
  cascadeContext: shouldBuildCascadeContext ? createCascadeContext(allTasks) : void 0,
4213
4208
  scheduleIntentMode: Boolean(onScheduleIntent)
4214
4209
  };
4215
- }, [edgeZoneWidth, currentLeft, currentWidth, dayWidth, monthStart, taskId, onDragStateChange, handleProgress, handleComplete, handleCancel, allTasks, disableConstraints, deferCascadePreview, onCascadeProgress, onCascade, effectiveLocked, viewMode]);
4210
+ }, [edgeZoneWidth, currentLeft, currentWidth, dayWidth, monthStart, taskId, onDragStateChange, handleProgress, handleComplete, handleCancel, allTasks, disableConstraints, deferCascadePreview, onCascadeProgress, onCascade, effectiveLocked]);
4216
4211
  const handleMouseDown = useCallback((e) => {
4217
4212
  startDrag(e);
4218
4213
  }, [startDrag]);
@@ -4231,14 +4226,13 @@ var useTaskDrag = (options) => {
4231
4226
  }
4232
4227
  const target = e.currentTarget;
4233
4228
  const currentTask = allTasks.find((t) => t.id === taskId);
4234
- const isSingleDayTask = !!currentTask && !isMilestoneTask(currentTask) && !isTaskParent(taskId, allTasks) && currentWidth <= dayWidth && viewMode === "day";
4235
- if (isSingleDayTask || currentTask && isMilestoneTask(currentTask)) {
4229
+ if (currentTask && isMilestoneTask(currentTask)) {
4236
4230
  setHoverCursor("grab");
4237
4231
  return;
4238
4232
  }
4239
4233
  const edgeZone = detectEdgeZone(e.clientX, target, edgeZoneWidth);
4240
4234
  setHoverCursor(edgeZone === "move" ? "grab" : "ew-resize");
4241
- }, [disableTaskDrag, locked, isDragging, allTasks, taskId, currentWidth, dayWidth, viewMode, edgeZoneWidth]);
4235
+ }, [disableTaskDrag, locked, isDragging, allTasks, taskId, edgeZoneWidth]);
4242
4236
  const handleMouseLeave = useCallback(() => {
4243
4237
  setHoverCursor(disableTaskDrag ? "grab" : locked ? "not-allowed" : isDragging ? "grabbing" : "grab");
4244
4238
  }, [disableTaskDrag, locked, isDragging]);
@@ -4529,7 +4523,7 @@ var TaskRow = React2.memo(
4529
4523
  "data-task-id": task.id,
4530
4524
  "data-port-side": "left",
4531
4525
  className: `gantt-tr-dependencyPort gantt-tr-dependencyPortLeft ${milestone ? "gantt-tr-dependencyPortMilestone" : ""} ${isParent ? "gantt-tr-dependencyPortParent" : ""} ${isDependencyDragActive ? "gantt-tr-dependencyPortDragActive" : ""}`,
4532
- style: { left: `${visualLeft - 21}px` },
4526
+ style: { left: `${visualLeft - 24}px` },
4533
4527
  "aria-label": `\u041D\u0430\u0447\u0430\u0442\u044C \u0441\u0432\u044F\u0437\u044C \u043E\u0442 \u043B\u0435\u0432\u043E\u0433\u043E \u043A\u0440\u0430\u044F: ${task.name}`,
4534
4528
  title: "\u041F\u043E\u0442\u044F\u043D\u0438\u0442\u0435 \u043A \u043A\u0440\u0430\u044E \u0434\u0440\u0443\u0433\u043E\u0439 \u043F\u043E\u043B\u043E\u0441\u044B, \u0447\u0442\u043E\u0431\u044B \u0441\u043E\u0437\u0434\u0430\u0442\u044C \u0441\u0432\u044F\u0437\u044C",
4535
4529
  onPointerDown: (event) => onDependencyPortPointerDown(task.id, "left", event)
@@ -5246,18 +5240,18 @@ var LINK_TYPE_LABELS_RU = {
5246
5240
  FF: "\u041E\u041E",
5247
5241
  SF: "\u041D\u041E"
5248
5242
  };
5243
+ var fmt = (n) => Math.round(n * 100) / 100;
5249
5244
  function getPath(drag) {
5250
5245
  const from = drag.source;
5251
5246
  const to = drag.current;
5252
5247
  const direction = to.y >= from.y ? 1 : -1;
5253
5248
  const bend = Math.max(18, Math.abs(to.y - from.y) * 0.45);
5254
- const middleX = Math.round((from.x + to.x) / 2);
5255
5249
  if (Math.abs(to.y - from.y) < 2) {
5256
- return `M ${Math.round(from.x)} ${Math.round(from.y)} H ${Math.round(to.x)}`;
5250
+ return `M ${fmt(from.x)} ${fmt(from.y)} H ${fmt(to.x)}`;
5257
5251
  }
5258
5252
  return [
5259
- `M ${Math.round(from.x)} ${Math.round(from.y)}`,
5260
- `C ${Math.round(from.x)} ${Math.round(from.y + bend * direction)}, ${Math.round(to.x)} ${Math.round(to.y - bend * direction)}, ${Math.round(to.x)} ${Math.round(to.y)}`
5253
+ `M ${fmt(from.x)} ${fmt(from.y)}`,
5254
+ `C ${fmt(from.x)} ${fmt(from.y + bend * direction)}, ${fmt(to.x)} ${fmt(to.y - bend * direction)}, ${fmt(to.x)} ${fmt(to.y)}`
5261
5255
  ].join(" ");
5262
5256
  }
5263
5257
  var DependencyCreationOverlay = ({ drag, width, height }) => {
@@ -8747,6 +8741,38 @@ function resolveTaskListColumns(builtIn, custom, hiddenColumnIds = []) {
8747
8741
  return filterHiddenColumns(result);
8748
8742
  }
8749
8743
 
8744
+ // src/components/TaskList/taskNumbering.ts
8745
+ function buildTaskNumberMap(tasks) {
8746
+ const numberById = /* @__PURE__ */ new Map();
8747
+ const indexById = /* @__PURE__ */ new Map();
8748
+ for (let i = 0; i < tasks.length; i++) {
8749
+ indexById.set(tasks[i].id, i);
8750
+ }
8751
+ let rootNumber = 0;
8752
+ const siblingCountByParent = /* @__PURE__ */ new Map();
8753
+ for (let i = 0; i < tasks.length; i++) {
8754
+ const task = tasks[i];
8755
+ if (!task.parentId) {
8756
+ rootNumber += 1;
8757
+ numberById.set(task.id, String(rootNumber));
8758
+ continue;
8759
+ }
8760
+ if (!indexById.has(task.parentId)) {
8761
+ numberById.set(task.id, String(i + 1));
8762
+ continue;
8763
+ }
8764
+ const parentNumber = numberById.get(task.parentId);
8765
+ if (parentNumber === void 0) {
8766
+ numberById.set(task.id, String(i + 1));
8767
+ continue;
8768
+ }
8769
+ const siblingNumber = (siblingCountByParent.get(task.parentId) ?? 0) + 1;
8770
+ siblingCountByParent.set(task.parentId, siblingNumber);
8771
+ numberById.set(task.id, `${parentNumber}.${siblingNumber}`);
8772
+ }
8773
+ return numberById;
8774
+ }
8775
+
8750
8776
  // src/components/TaskList/TaskList.tsx
8751
8777
  import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
8752
8778
  var LINK_TYPE_ORDER2 = ["FS", "SS", "FF", "SF"];
@@ -8832,31 +8858,6 @@ function getNearestVisibleDropAnchorBefore(visibleTasks, movedIds, startIndex) {
8832
8858
  }
8833
8859
  return null;
8834
8860
  }
8835
- function getTaskNumber(tasks, taskIndex) {
8836
- const task = tasks[taskIndex];
8837
- if (!task) return "";
8838
- if (!task.parentId) {
8839
- let rootIndex = 0;
8840
- for (let i = 0; i < taskIndex; i++) {
8841
- if (!tasks[i].parentId) {
8842
- rootIndex++;
8843
- }
8844
- }
8845
- return String(rootIndex + 1);
8846
- }
8847
- const parentIndex = tasks.findIndex((t) => t.id === task.parentId);
8848
- if (parentIndex === -1) {
8849
- return String(taskIndex + 1);
8850
- }
8851
- const parentNumber = getTaskNumber(tasks, parentIndex);
8852
- let siblingIndex = 0;
8853
- for (let i = 0; i < taskIndex; i++) {
8854
- if (tasks[i].parentId === task.parentId) {
8855
- siblingIndex++;
8856
- }
8857
- }
8858
- return `${parentNumber}.${siblingIndex + 1}`;
8859
- }
8860
8861
  function normalizeColumnWidthMap(widths) {
8861
8862
  if (!widths) {
8862
8863
  return {};
@@ -9033,9 +9034,7 @@ var TaskList = ({
9033
9034
  [rowHeight, skeletonRowCount, visibleTasks.length]
9034
9035
  );
9035
9036
  const visibleTaskNumberMap = useMemo9(
9036
- () => Object.fromEntries(
9037
- visibleTasks.map((task, index) => [task.id, String(getTaskNumber(visibleTasks, index))])
9038
- ),
9037
+ () => Object.fromEntries(buildTaskNumberMap(visibleTasks)),
9039
9038
  [visibleTasks]
9040
9039
  );
9041
9040
  const visibleTaskIds = useMemo9(() => visibleTasks.map((task) => task.id), [visibleTasks]);
@@ -9077,13 +9076,7 @@ var TaskList = ({
9077
9076
  emitSelectedTaskIdsChange(nextSelectedTaskIds);
9078
9077
  }, [effectiveSelectedTaskIds, emitSelectedTaskIdsChange, visibleTaskIds]);
9079
9078
  const originalTaskNumberMap = useMemo9(
9080
- () => {
9081
- const numberMap = /* @__PURE__ */ new Map();
9082
- for (let i = 0; i < orderedTasks.length; i++) {
9083
- numberMap.set(orderedTasks[i].id, getTaskNumber(orderedTasks, i));
9084
- }
9085
- return Object.fromEntries(numberMap);
9086
- },
9079
+ () => Object.fromEntries(buildTaskNumberMap(orderedTasks)),
9087
9080
  [orderedTasks]
9088
9081
  );
9089
9082
  const nestingDepthMap = useMemo9(() => {
@@ -14174,10 +14167,14 @@ function TaskGanttChartInner(props, ref) {
14174
14167
  const rect = element.getBoundingClientRect();
14175
14168
  const side = element.getAttribute("data-port-side");
14176
14169
  return {
14177
- // The port hit-area is deliberately outside the bar. Anchor the preview
14178
- // to the actual bar boundary instead of the center of that outside zone.
14179
- x: Math.round((side === "left" ? rect.right - 6 : rect.left + 6) - chartRect.left),
14180
- y: Math.round(rect.top + rect.height / 2 - chartRect.top)
14170
+ // Anchor the preview at the port dot's center so the dragged polyline
14171
+ // ends exactly on the link handle. The dot core is 8px and sits 4px
14172
+ // inside the 24px zone from the bar side (see TaskRow.css), which puts
14173
+ // its center 8px off the button edge adjacent to the bar. No rounding:
14174
+ // the CSS ball centers at a fractional position, and a rounded SVG
14175
+ // coordinate landed ~1px off it.
14176
+ x: (side === "left" ? rect.right - 8 : rect.left + 8) - chartRect.left,
14177
+ y: rect.top + rect.height / 2 - chartRect.top
14181
14178
  };
14182
14179
  }, []);
14183
14180
  const getVisualDependencyType = useCallback10((sourceSide, targetSide) => {
@@ -15686,6 +15683,8 @@ export {
15686
15683
  GenerationSkeleton_default as GenerationSkeletonRows,
15687
15684
  GridBackground_default as GridBackground,
15688
15685
  Input,
15686
+ MIN_EDGE_ZONE_PX,
15687
+ MIN_MOVE_ZONE_PX,
15689
15688
  PlanFactMatrix,
15690
15689
  Popover,
15691
15690
  PopoverContent,