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.d.mts CHANGED
@@ -1422,6 +1422,10 @@ declare const pixelsToDate: (pixels: number, monthStart: Date, dayWidth: number)
1422
1422
  * @returns Total grid width in pixels
1423
1423
  */
1424
1424
  declare const calculateGridWidth: (daysInMonth: number, dayWidth: number) => number;
1425
+ /** Floor for an edge resize zone: below this a bar edge is hard to grab. */
1426
+ declare const MIN_EDGE_ZONE_PX = 8;
1427
+ /** Guaranteed central strip that always stays available for moving the bar. */
1428
+ declare const MIN_MOVE_ZONE_PX = 16;
1425
1429
  /**
1426
1430
  * Detect which edge zone the cursor is in on a task bar
1427
1431
  * @param clientX - Mouse X coordinate relative to viewport
@@ -1612,4 +1616,4 @@ interface ResourceTimelineLayoutResult<TItem extends ResourceTimelineItem = Reso
1612
1616
  }
1613
1617
  declare const layoutResourceTimelineItems: <TItem extends ResourceTimelineItem = ResourceTimelineItem>(resources: Array<ResourceTimelineResource<TItem>>, options: ResourceTimelineLayoutOptions) => ResourceTimelineLayoutResult<TItem>;
1614
1618
 
1615
- export { type BuiltInTaskListColumnId, Button, type ButtonProps, Calendar, type CalendarProps, type CustomDayConfig, type CustomDayPredicateConfig, DatePicker, type DatePickerProps, DragGuideLines, type ExportToPdfHeaderOptions, type ExportToPdfOptions, GanttChart, type GanttChartHandle, type GanttChartProps, GanttDateRange, type GanttModeProps, GanttScheduleIntent, GenerationSkeletonRows, type GenerationSkeletonRowsProps, type GenerationSkeletonTaskListLayout, type GenerationSkeletonVariant, GridBackground, Input, type InputProps, type MonthBlock, type PlanFactCellCommitContext, type PlanFactCellKind, PlanFactMatrix, type PlanFactModeProps, Popover, PopoverContent, type PopoverContentProps, type PopoverProps, PopoverTrigger, type ReorderDropPlacement, type ReorderDropTarget, ResourcePlannerChartProps, ResourceTimelineChart, type ResourceTimelineConflictRange, ResourceTimelineItem, type ResourceTimelineLayoutDiagnostic, type ResourceTimelineLayoutItem, type ResourceTimelineLayoutOptions, type ResourceTimelineLayoutResult, type ResourceTimelineLayoutRow, ResourceTimelineResource, ScaleTaskSubtreeResult, TableMatrix, type TableMatrixCellClickContext, type TableMatrixColumn, type TableMatrixColumnGroup, type TableMatrixDateOverlay, type TableMatrixModeProps, type Task, TaskDateChangeMode, type TaskDependency, TaskList, type TaskListColumn, type TaskListColumnContext, type TaskListColumnId, type TaskListColumnWidthMap, type TaskListMenuCommand, type TaskListProps, type TaskPredicate, TaskRow, TimeScaleHeader, TimelineMarker, TodayIndicator, ValidationResult, type VisibleReorderPlan, type VisibleReorderPosition, type WeekBlock, type WeekSpan, type WithoutDepsOptions, type YearSpan, addBusinessDays, and, calculateBezierPath, calculateDependencyPath, calculateGridLines, calculateGridWidth, calculateMilestoneConnectionBounds, calculateMilestoneGeometry, calculateMonthGridLines, calculateOrthogonalPath, calculateTaskBar, calculateWeekGridLines, calculateWeekendBlocks, clampDateRangeForIncomingFS, createCustomDayPredicate, createDateKey, detectEdgeZone, expired, flattenHierarchy, formatDateLabel, formatDateRangeLabel, getBusinessDaysCount, getCursorForPosition, getDateRangeDays, getDayOffset, getMonthBlocks, getMonthDays, getMonthSpans, getMultiMonthDays, getTodayLocalUtcDate, getVisibleReorderPlan, getVisibleReorderPosition, getWeekBlocks, getWeekSpans, getYearSpans, inDateRange, isTaskExpired, isToday, isWeekend, layoutResourceTimelineItems, nameContains, normalizeHierarchyTasks, normalizeTaskDates, not, or, parseUTCDate, pixelsToDate, progressInRange, resolveDateRangeFromPixels, resolveTaskHorizontalGeometry, subtractBusinessDays, useTaskDrag, withoutDeps };
1619
+ export { type BuiltInTaskListColumnId, Button, type ButtonProps, Calendar, type CalendarProps, type CustomDayConfig, type CustomDayPredicateConfig, DatePicker, type DatePickerProps, DragGuideLines, type ExportToPdfHeaderOptions, type ExportToPdfOptions, GanttChart, type GanttChartHandle, type GanttChartProps, GanttDateRange, type GanttModeProps, GanttScheduleIntent, GenerationSkeletonRows, type GenerationSkeletonRowsProps, type GenerationSkeletonTaskListLayout, type GenerationSkeletonVariant, GridBackground, Input, type InputProps, MIN_EDGE_ZONE_PX, MIN_MOVE_ZONE_PX, type MonthBlock, type PlanFactCellCommitContext, type PlanFactCellKind, PlanFactMatrix, type PlanFactModeProps, Popover, PopoverContent, type PopoverContentProps, type PopoverProps, PopoverTrigger, type ReorderDropPlacement, type ReorderDropTarget, ResourcePlannerChartProps, ResourceTimelineChart, type ResourceTimelineConflictRange, ResourceTimelineItem, type ResourceTimelineLayoutDiagnostic, type ResourceTimelineLayoutItem, type ResourceTimelineLayoutOptions, type ResourceTimelineLayoutResult, type ResourceTimelineLayoutRow, ResourceTimelineResource, ScaleTaskSubtreeResult, TableMatrix, type TableMatrixCellClickContext, type TableMatrixColumn, type TableMatrixColumnGroup, type TableMatrixDateOverlay, type TableMatrixModeProps, type Task, TaskDateChangeMode, type TaskDependency, TaskList, type TaskListColumn, type TaskListColumnContext, type TaskListColumnId, type TaskListColumnWidthMap, type TaskListMenuCommand, type TaskListProps, type TaskPredicate, TaskRow, TimeScaleHeader, TimelineMarker, TodayIndicator, ValidationResult, type VisibleReorderPlan, type VisibleReorderPosition, type WeekBlock, type WeekSpan, type WithoutDepsOptions, type YearSpan, addBusinessDays, and, calculateBezierPath, calculateDependencyPath, calculateGridLines, calculateGridWidth, calculateMilestoneConnectionBounds, calculateMilestoneGeometry, calculateMonthGridLines, calculateOrthogonalPath, calculateTaskBar, calculateWeekGridLines, calculateWeekendBlocks, clampDateRangeForIncomingFS, createCustomDayPredicate, createDateKey, detectEdgeZone, expired, flattenHierarchy, formatDateLabel, formatDateRangeLabel, getBusinessDaysCount, getCursorForPosition, getDateRangeDays, getDayOffset, getMonthBlocks, getMonthDays, getMonthSpans, getMultiMonthDays, getTodayLocalUtcDate, getVisibleReorderPlan, getVisibleReorderPosition, getWeekBlocks, getWeekSpans, getYearSpans, inDateRange, isTaskExpired, isToday, isWeekend, layoutResourceTimelineItems, nameContains, normalizeHierarchyTasks, normalizeTaskDates, not, or, parseUTCDate, pixelsToDate, progressInRange, resolveDateRangeFromPixels, resolveTaskHorizontalGeometry, subtractBusinessDays, useTaskDrag, withoutDeps };
package/dist/index.d.ts CHANGED
@@ -1422,6 +1422,10 @@ declare const pixelsToDate: (pixels: number, monthStart: Date, dayWidth: number)
1422
1422
  * @returns Total grid width in pixels
1423
1423
  */
1424
1424
  declare const calculateGridWidth: (daysInMonth: number, dayWidth: number) => number;
1425
+ /** Floor for an edge resize zone: below this a bar edge is hard to grab. */
1426
+ declare const MIN_EDGE_ZONE_PX = 8;
1427
+ /** Guaranteed central strip that always stays available for moving the bar. */
1428
+ declare const MIN_MOVE_ZONE_PX = 16;
1425
1429
  /**
1426
1430
  * Detect which edge zone the cursor is in on a task bar
1427
1431
  * @param clientX - Mouse X coordinate relative to viewport
@@ -1612,4 +1616,4 @@ interface ResourceTimelineLayoutResult<TItem extends ResourceTimelineItem = Reso
1612
1616
  }
1613
1617
  declare const layoutResourceTimelineItems: <TItem extends ResourceTimelineItem = ResourceTimelineItem>(resources: Array<ResourceTimelineResource<TItem>>, options: ResourceTimelineLayoutOptions) => ResourceTimelineLayoutResult<TItem>;
1614
1618
 
1615
- export { type BuiltInTaskListColumnId, Button, type ButtonProps, Calendar, type CalendarProps, type CustomDayConfig, type CustomDayPredicateConfig, DatePicker, type DatePickerProps, DragGuideLines, type ExportToPdfHeaderOptions, type ExportToPdfOptions, GanttChart, type GanttChartHandle, type GanttChartProps, GanttDateRange, type GanttModeProps, GanttScheduleIntent, GenerationSkeletonRows, type GenerationSkeletonRowsProps, type GenerationSkeletonTaskListLayout, type GenerationSkeletonVariant, GridBackground, Input, type InputProps, type MonthBlock, type PlanFactCellCommitContext, type PlanFactCellKind, PlanFactMatrix, type PlanFactModeProps, Popover, PopoverContent, type PopoverContentProps, type PopoverProps, PopoverTrigger, type ReorderDropPlacement, type ReorderDropTarget, ResourcePlannerChartProps, ResourceTimelineChart, type ResourceTimelineConflictRange, ResourceTimelineItem, type ResourceTimelineLayoutDiagnostic, type ResourceTimelineLayoutItem, type ResourceTimelineLayoutOptions, type ResourceTimelineLayoutResult, type ResourceTimelineLayoutRow, ResourceTimelineResource, ScaleTaskSubtreeResult, TableMatrix, type TableMatrixCellClickContext, type TableMatrixColumn, type TableMatrixColumnGroup, type TableMatrixDateOverlay, type TableMatrixModeProps, type Task, TaskDateChangeMode, type TaskDependency, TaskList, type TaskListColumn, type TaskListColumnContext, type TaskListColumnId, type TaskListColumnWidthMap, type TaskListMenuCommand, type TaskListProps, type TaskPredicate, TaskRow, TimeScaleHeader, TimelineMarker, TodayIndicator, ValidationResult, type VisibleReorderPlan, type VisibleReorderPosition, type WeekBlock, type WeekSpan, type WithoutDepsOptions, type YearSpan, addBusinessDays, and, calculateBezierPath, calculateDependencyPath, calculateGridLines, calculateGridWidth, calculateMilestoneConnectionBounds, calculateMilestoneGeometry, calculateMonthGridLines, calculateOrthogonalPath, calculateTaskBar, calculateWeekGridLines, calculateWeekendBlocks, clampDateRangeForIncomingFS, createCustomDayPredicate, createDateKey, detectEdgeZone, expired, flattenHierarchy, formatDateLabel, formatDateRangeLabel, getBusinessDaysCount, getCursorForPosition, getDateRangeDays, getDayOffset, getMonthBlocks, getMonthDays, getMonthSpans, getMultiMonthDays, getTodayLocalUtcDate, getVisibleReorderPlan, getVisibleReorderPosition, getWeekBlocks, getWeekSpans, getYearSpans, inDateRange, isTaskExpired, isToday, isWeekend, layoutResourceTimelineItems, nameContains, normalizeHierarchyTasks, normalizeTaskDates, not, or, parseUTCDate, pixelsToDate, progressInRange, resolveDateRangeFromPixels, resolveTaskHorizontalGeometry, subtractBusinessDays, useTaskDrag, withoutDeps };
1619
+ export { type BuiltInTaskListColumnId, Button, type ButtonProps, Calendar, type CalendarProps, type CustomDayConfig, type CustomDayPredicateConfig, DatePicker, type DatePickerProps, DragGuideLines, type ExportToPdfHeaderOptions, type ExportToPdfOptions, GanttChart, type GanttChartHandle, type GanttChartProps, GanttDateRange, type GanttModeProps, GanttScheduleIntent, GenerationSkeletonRows, type GenerationSkeletonRowsProps, type GenerationSkeletonTaskListLayout, type GenerationSkeletonVariant, GridBackground, Input, type InputProps, MIN_EDGE_ZONE_PX, MIN_MOVE_ZONE_PX, type MonthBlock, type PlanFactCellCommitContext, type PlanFactCellKind, PlanFactMatrix, type PlanFactModeProps, Popover, PopoverContent, type PopoverContentProps, type PopoverProps, PopoverTrigger, type ReorderDropPlacement, type ReorderDropTarget, ResourcePlannerChartProps, ResourceTimelineChart, type ResourceTimelineConflictRange, ResourceTimelineItem, type ResourceTimelineLayoutDiagnostic, type ResourceTimelineLayoutItem, type ResourceTimelineLayoutOptions, type ResourceTimelineLayoutResult, type ResourceTimelineLayoutRow, ResourceTimelineResource, ScaleTaskSubtreeResult, TableMatrix, type TableMatrixCellClickContext, type TableMatrixColumn, type TableMatrixColumnGroup, type TableMatrixDateOverlay, type TableMatrixModeProps, type Task, TaskDateChangeMode, type TaskDependency, TaskList, type TaskListColumn, type TaskListColumnContext, type TaskListColumnId, type TaskListColumnWidthMap, type TaskListMenuCommand, type TaskListProps, type TaskPredicate, TaskRow, TimeScaleHeader, TimelineMarker, TodayIndicator, ValidationResult, type VisibleReorderPlan, type VisibleReorderPosition, type WeekBlock, type WeekSpan, type WithoutDepsOptions, type YearSpan, addBusinessDays, and, calculateBezierPath, calculateDependencyPath, calculateGridLines, calculateGridWidth, calculateMilestoneConnectionBounds, calculateMilestoneGeometry, calculateMonthGridLines, calculateOrthogonalPath, calculateTaskBar, calculateWeekGridLines, calculateWeekendBlocks, clampDateRangeForIncomingFS, createCustomDayPredicate, createDateKey, detectEdgeZone, expired, flattenHierarchy, formatDateLabel, formatDateRangeLabel, getBusinessDaysCount, getCursorForPosition, getDateRangeDays, getDayOffset, getMonthBlocks, getMonthDays, getMonthSpans, getMultiMonthDays, getTodayLocalUtcDate, getVisibleReorderPlan, getVisibleReorderPosition, getWeekBlocks, getWeekSpans, getYearSpans, inDateRange, isTaskExpired, isToday, isWeekend, layoutResourceTimelineItems, nameContains, normalizeHierarchyTasks, normalizeTaskDates, not, or, parseUTCDate, pixelsToDate, progressInRange, resolveDateRangeFromPixels, resolveTaskHorizontalGeometry, subtractBusinessDays, useTaskDrag, withoutDeps };
package/dist/index.js CHANGED
@@ -42,6 +42,8 @@ __export(index_exports, {
42
42
  GenerationSkeletonRows: () => GenerationSkeleton_default,
43
43
  GridBackground: () => GridBackground_default,
44
44
  Input: () => Input,
45
+ MIN_EDGE_ZONE_PX: () => MIN_EDGE_ZONE_PX,
46
+ MIN_MOVE_ZONE_PX: () => MIN_MOVE_ZONE_PX,
45
47
  PlanFactMatrix: () => PlanFactMatrix,
46
48
  Popover: () => Popover,
47
49
  PopoverContent: () => PopoverContent,
@@ -3389,19 +3391,20 @@ var pixelsToDate = (pixels, monthStart, dayWidth) => {
3389
3391
  var calculateGridWidth = (daysInMonth, dayWidth) => {
3390
3392
  return Math.round(daysInMonth * dayWidth);
3391
3393
  };
3394
+ var MIN_EDGE_ZONE_PX = 8;
3395
+ var MIN_MOVE_ZONE_PX = 16;
3392
3396
  var detectEdgeZone = (clientX, taskBarElement, edgeZoneWidth = 12) => {
3393
3397
  const rect = taskBarElement.getBoundingClientRect();
3394
3398
  const relativeX = Math.round(clientX - rect.left);
3395
3399
  const width = Math.round(rect.width);
3396
- if (width <= 2 * edgeZoneWidth) {
3397
- const distanceToLeft = relativeX;
3398
- const distanceToRight = width - relativeX;
3399
- return distanceToLeft <= distanceToRight ? "left" : "right";
3400
- }
3401
- if (relativeX >= 0 && relativeX <= edgeZoneWidth) {
3400
+ const effectiveZone = Math.max(
3401
+ MIN_EDGE_ZONE_PX,
3402
+ Math.min(edgeZoneWidth, (width - MIN_MOVE_ZONE_PX) / 2)
3403
+ );
3404
+ if (relativeX >= 0 && relativeX <= effectiveZone) {
3402
3405
  return "left";
3403
3406
  }
3404
- if (relativeX >= width - edgeZoneWidth && relativeX <= width) {
3407
+ if (relativeX >= width - effectiveZone && relativeX <= width) {
3405
3408
  return "right";
3406
3409
  }
3407
3410
  return "move";
@@ -4021,8 +4024,7 @@ var useTaskDrag = (options) => {
4021
4024
  locked = false,
4022
4025
  disableTaskDrag = false,
4023
4026
  businessDays = true,
4024
- weekendPredicate,
4025
- viewMode = "day"
4027
+ weekendPredicate
4026
4028
  } = options;
4027
4029
  const rawHookTask = allTasks.find((t) => t.id === taskId);
4028
4030
  const hookTask = rawHookTask ? normalizeTaskDatesForType(rawHookTask) : void 0;
@@ -4294,23 +4296,18 @@ var useTaskDrag = (options) => {
4294
4296
  if (effectiveLocked) return;
4295
4297
  const target = e.currentTarget;
4296
4298
  const currentTask = allTasks.find((t) => t.id === taskId);
4297
- const isSingleDayTask = !!currentTask && !isMilestoneTask(currentTask) && !isTaskParent(taskId, allTasks) && currentWidth <= dayWidth && viewMode === "day";
4298
4299
  let mode = null;
4299
- if (isSingleDayTask) {
4300
- mode = "move";
4301
- } else {
4302
- const edgeZone = detectEdgeZone(e.clientX, target, edgeZoneWidth);
4303
- switch (edgeZone) {
4304
- case "left":
4305
- mode = "resize-left";
4306
- break;
4307
- case "right":
4308
- mode = "resize-right";
4309
- break;
4310
- case "move":
4311
- mode = "move";
4312
- break;
4313
- }
4300
+ const edgeZone = detectEdgeZone(e.clientX, target, edgeZoneWidth);
4301
+ switch (edgeZone) {
4302
+ case "left":
4303
+ mode = "resize-left";
4304
+ break;
4305
+ case "right":
4306
+ mode = "resize-right";
4307
+ break;
4308
+ case "move":
4309
+ mode = "move";
4310
+ break;
4314
4311
  }
4315
4312
  if (mode === "resize-left" || mode === "resize-right") {
4316
4313
  if (currentTask && isMilestoneTask(currentTask)) {
@@ -4360,7 +4357,7 @@ var useTaskDrag = (options) => {
4360
4357
  cascadeContext: shouldBuildCascadeContext ? createCascadeContext(allTasks) : void 0,
4361
4358
  scheduleIntentMode: Boolean(onScheduleIntent)
4362
4359
  };
4363
- }, [edgeZoneWidth, currentLeft, currentWidth, dayWidth, monthStart, taskId, onDragStateChange, handleProgress, handleComplete, handleCancel, allTasks, disableConstraints, deferCascadePreview, onCascadeProgress, onCascade, effectiveLocked, viewMode]);
4360
+ }, [edgeZoneWidth, currentLeft, currentWidth, dayWidth, monthStart, taskId, onDragStateChange, handleProgress, handleComplete, handleCancel, allTasks, disableConstraints, deferCascadePreview, onCascadeProgress, onCascade, effectiveLocked]);
4364
4361
  const handleMouseDown = (0, import_react2.useCallback)((e) => {
4365
4362
  startDrag(e);
4366
4363
  }, [startDrag]);
@@ -4379,14 +4376,13 @@ var useTaskDrag = (options) => {
4379
4376
  }
4380
4377
  const target = e.currentTarget;
4381
4378
  const currentTask = allTasks.find((t) => t.id === taskId);
4382
- const isSingleDayTask = !!currentTask && !isMilestoneTask(currentTask) && !isTaskParent(taskId, allTasks) && currentWidth <= dayWidth && viewMode === "day";
4383
- if (isSingleDayTask || currentTask && isMilestoneTask(currentTask)) {
4379
+ if (currentTask && isMilestoneTask(currentTask)) {
4384
4380
  setHoverCursor("grab");
4385
4381
  return;
4386
4382
  }
4387
4383
  const edgeZone = detectEdgeZone(e.clientX, target, edgeZoneWidth);
4388
4384
  setHoverCursor(edgeZone === "move" ? "grab" : "ew-resize");
4389
- }, [disableTaskDrag, locked, isDragging, allTasks, taskId, currentWidth, dayWidth, viewMode, edgeZoneWidth]);
4385
+ }, [disableTaskDrag, locked, isDragging, allTasks, taskId, edgeZoneWidth]);
4390
4386
  const handleMouseLeave = (0, import_react2.useCallback)(() => {
4391
4387
  setHoverCursor(disableTaskDrag ? "grab" : locked ? "not-allowed" : isDragging ? "grabbing" : "grab");
4392
4388
  }, [disableTaskDrag, locked, isDragging]);
@@ -4677,7 +4673,7 @@ var TaskRow = import_react3.default.memo(
4677
4673
  "data-task-id": task.id,
4678
4674
  "data-port-side": "left",
4679
4675
  className: `gantt-tr-dependencyPort gantt-tr-dependencyPortLeft ${milestone ? "gantt-tr-dependencyPortMilestone" : ""} ${isParent ? "gantt-tr-dependencyPortParent" : ""} ${isDependencyDragActive ? "gantt-tr-dependencyPortDragActive" : ""}`,
4680
- style: { left: `${visualLeft - 21}px` },
4676
+ style: { left: `${visualLeft - 24}px` },
4681
4677
  "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}`,
4682
4678
  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",
4683
4679
  onPointerDown: (event) => onDependencyPortPointerDown(task.id, "left", event)
@@ -5394,18 +5390,18 @@ var LINK_TYPE_LABELS_RU = {
5394
5390
  FF: "\u041E\u041E",
5395
5391
  SF: "\u041D\u041E"
5396
5392
  };
5393
+ var fmt = (n) => Math.round(n * 100) / 100;
5397
5394
  function getPath(drag) {
5398
5395
  const from = drag.source;
5399
5396
  const to = drag.current;
5400
5397
  const direction = to.y >= from.y ? 1 : -1;
5401
5398
  const bend = Math.max(18, Math.abs(to.y - from.y) * 0.45);
5402
- const middleX = Math.round((from.x + to.x) / 2);
5403
5399
  if (Math.abs(to.y - from.y) < 2) {
5404
- return `M ${Math.round(from.x)} ${Math.round(from.y)} H ${Math.round(to.x)}`;
5400
+ return `M ${fmt(from.x)} ${fmt(from.y)} H ${fmt(to.x)}`;
5405
5401
  }
5406
5402
  return [
5407
- `M ${Math.round(from.x)} ${Math.round(from.y)}`,
5408
- `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)}`
5403
+ `M ${fmt(from.x)} ${fmt(from.y)}`,
5404
+ `C ${fmt(from.x)} ${fmt(from.y + bend * direction)}, ${fmt(to.x)} ${fmt(to.y - bend * direction)}, ${fmt(to.x)} ${fmt(to.y)}`
5409
5405
  ].join(" ");
5410
5406
  }
5411
5407
  var DependencyCreationOverlay = ({ drag, width, height }) => {
@@ -8871,6 +8867,38 @@ function resolveTaskListColumns(builtIn, custom, hiddenColumnIds = []) {
8871
8867
  return filterHiddenColumns(result);
8872
8868
  }
8873
8869
 
8870
+ // src/components/TaskList/taskNumbering.ts
8871
+ function buildTaskNumberMap(tasks) {
8872
+ const numberById = /* @__PURE__ */ new Map();
8873
+ const indexById = /* @__PURE__ */ new Map();
8874
+ for (let i = 0; i < tasks.length; i++) {
8875
+ indexById.set(tasks[i].id, i);
8876
+ }
8877
+ let rootNumber = 0;
8878
+ const siblingCountByParent = /* @__PURE__ */ new Map();
8879
+ for (let i = 0; i < tasks.length; i++) {
8880
+ const task = tasks[i];
8881
+ if (!task.parentId) {
8882
+ rootNumber += 1;
8883
+ numberById.set(task.id, String(rootNumber));
8884
+ continue;
8885
+ }
8886
+ if (!indexById.has(task.parentId)) {
8887
+ numberById.set(task.id, String(i + 1));
8888
+ continue;
8889
+ }
8890
+ const parentNumber = numberById.get(task.parentId);
8891
+ if (parentNumber === void 0) {
8892
+ numberById.set(task.id, String(i + 1));
8893
+ continue;
8894
+ }
8895
+ const siblingNumber = (siblingCountByParent.get(task.parentId) ?? 0) + 1;
8896
+ siblingCountByParent.set(task.parentId, siblingNumber);
8897
+ numberById.set(task.id, `${parentNumber}.${siblingNumber}`);
8898
+ }
8899
+ return numberById;
8900
+ }
8901
+
8874
8902
  // src/components/TaskList/TaskList.tsx
8875
8903
  var import_jsx_runtime17 = require("react/jsx-runtime");
8876
8904
  var LINK_TYPE_ORDER2 = ["FS", "SS", "FF", "SF"];
@@ -8956,31 +8984,6 @@ function getNearestVisibleDropAnchorBefore(visibleTasks, movedIds, startIndex) {
8956
8984
  }
8957
8985
  return null;
8958
8986
  }
8959
- function getTaskNumber(tasks, taskIndex) {
8960
- const task = tasks[taskIndex];
8961
- if (!task) return "";
8962
- if (!task.parentId) {
8963
- let rootIndex = 0;
8964
- for (let i = 0; i < taskIndex; i++) {
8965
- if (!tasks[i].parentId) {
8966
- rootIndex++;
8967
- }
8968
- }
8969
- return String(rootIndex + 1);
8970
- }
8971
- const parentIndex = tasks.findIndex((t) => t.id === task.parentId);
8972
- if (parentIndex === -1) {
8973
- return String(taskIndex + 1);
8974
- }
8975
- const parentNumber = getTaskNumber(tasks, parentIndex);
8976
- let siblingIndex = 0;
8977
- for (let i = 0; i < taskIndex; i++) {
8978
- if (tasks[i].parentId === task.parentId) {
8979
- siblingIndex++;
8980
- }
8981
- }
8982
- return `${parentNumber}.${siblingIndex + 1}`;
8983
- }
8984
8987
  function normalizeColumnWidthMap(widths) {
8985
8988
  if (!widths) {
8986
8989
  return {};
@@ -9157,9 +9160,7 @@ var TaskList = ({
9157
9160
  [rowHeight, skeletonRowCount, visibleTasks.length]
9158
9161
  );
9159
9162
  const visibleTaskNumberMap = (0, import_react14.useMemo)(
9160
- () => Object.fromEntries(
9161
- visibleTasks.map((task, index) => [task.id, String(getTaskNumber(visibleTasks, index))])
9162
- ),
9163
+ () => Object.fromEntries(buildTaskNumberMap(visibleTasks)),
9163
9164
  [visibleTasks]
9164
9165
  );
9165
9166
  const visibleTaskIds = (0, import_react14.useMemo)(() => visibleTasks.map((task) => task.id), [visibleTasks]);
@@ -9201,13 +9202,7 @@ var TaskList = ({
9201
9202
  emitSelectedTaskIdsChange(nextSelectedTaskIds);
9202
9203
  }, [effectiveSelectedTaskIds, emitSelectedTaskIdsChange, visibleTaskIds]);
9203
9204
  const originalTaskNumberMap = (0, import_react14.useMemo)(
9204
- () => {
9205
- const numberMap = /* @__PURE__ */ new Map();
9206
- for (let i = 0; i < orderedTasks.length; i++) {
9207
- numberMap.set(orderedTasks[i].id, getTaskNumber(orderedTasks, i));
9208
- }
9209
- return Object.fromEntries(numberMap);
9210
- },
9205
+ () => Object.fromEntries(buildTaskNumberMap(orderedTasks)),
9211
9206
  [orderedTasks]
9212
9207
  );
9213
9208
  const nestingDepthMap = (0, import_react14.useMemo)(() => {
@@ -14298,10 +14293,14 @@ function TaskGanttChartInner(props, ref) {
14298
14293
  const rect = element.getBoundingClientRect();
14299
14294
  const side = element.getAttribute("data-port-side");
14300
14295
  return {
14301
- // The port hit-area is deliberately outside the bar. Anchor the preview
14302
- // to the actual bar boundary instead of the center of that outside zone.
14303
- x: Math.round((side === "left" ? rect.right - 6 : rect.left + 6) - chartRect.left),
14304
- y: Math.round(rect.top + rect.height / 2 - chartRect.top)
14296
+ // Anchor the preview at the port dot's center so the dragged polyline
14297
+ // ends exactly on the link handle. The dot core is 8px and sits 4px
14298
+ // inside the 24px zone from the bar side (see TaskRow.css), which puts
14299
+ // its center 8px off the button edge adjacent to the bar. No rounding:
14300
+ // the CSS ball centers at a fractional position, and a rounded SVG
14301
+ // coordinate landed ~1px off it.
14302
+ x: (side === "left" ? rect.right - 8 : rect.left + 8) - chartRect.left,
14303
+ y: rect.top + rect.height / 2 - chartRect.top
14305
14304
  };
14306
14305
  }, []);
14307
14306
  const getVisualDependencyType = (0, import_react19.useCallback)((sourceSide, targetSide) => {
@@ -15811,6 +15810,8 @@ var nameContains = (substring, caseSensitive = false) => (task) => {
15811
15810
  GenerationSkeletonRows,
15812
15811
  GridBackground,
15813
15812
  Input,
15813
+ MIN_EDGE_ZONE_PX,
15814
+ MIN_MOVE_ZONE_PX,
15814
15815
  PlanFactMatrix,
15815
15816
  Popover,
15816
15817
  PopoverContent,