gantt-lib 0.87.0 → 0.88.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -2152,6 +2152,46 @@ function clampDateRangeForIncomingFS(task, range, allTasks, mode, businessDays,
2152
2152
  // src/hooks/useTaskDrag.ts
2153
2153
  var globalActiveDrag = null;
2154
2154
  var globalRafId = null;
2155
+ var globalLockedCursor = null;
2156
+ var GLOBAL_CURSOR_STYLE_ID = "gantt-global-drag-cursor-style";
2157
+ function ensureGlobalCursorStyle() {
2158
+ if (typeof document === "undefined") return;
2159
+ if (document.getElementById(GLOBAL_CURSOR_STYLE_ID)) return;
2160
+ const style = document.createElement("style");
2161
+ style.id = GLOBAL_CURSOR_STYLE_ID;
2162
+ style.textContent = `
2163
+ html.gantt-global-cursor-grabbing,
2164
+ html.gantt-global-cursor-grabbing *,
2165
+ html.gantt-global-cursor-grabbing *::before,
2166
+ html.gantt-global-cursor-grabbing *::after {
2167
+ cursor: grabbing !important;
2168
+ }
2169
+
2170
+ html.gantt-global-cursor-resize,
2171
+ html.gantt-global-cursor-resize *,
2172
+ html.gantt-global-cursor-resize *::before,
2173
+ html.gantt-global-cursor-resize *::after {
2174
+ cursor: ew-resize !important;
2175
+ }
2176
+ `;
2177
+ document.head.appendChild(style);
2178
+ }
2179
+ function applyGlobalCursor(cursor) {
2180
+ if (typeof document === "undefined") return;
2181
+ ensureGlobalCursorStyle();
2182
+ globalLockedCursor = cursor;
2183
+ document.documentElement.classList.remove("gantt-global-cursor-grabbing", "gantt-global-cursor-resize");
2184
+ document.documentElement.classList.add(cursor === "grabbing" ? "gantt-global-cursor-grabbing" : "gantt-global-cursor-resize");
2185
+ document.body.style.cursor = cursor;
2186
+ document.documentElement.style.cursor = cursor;
2187
+ }
2188
+ function clearGlobalCursor() {
2189
+ if (typeof document === "undefined") return;
2190
+ globalLockedCursor = null;
2191
+ document.documentElement.classList.remove("gantt-global-cursor-grabbing", "gantt-global-cursor-resize");
2192
+ document.body.style.cursor = "";
2193
+ document.documentElement.style.cursor = "";
2194
+ }
2155
2195
  function getDayOffsetFromMonthStart(date, monthStart) {
2156
2196
  return Math.round(
2157
2197
  (Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()) - Date.UTC(monthStart.getUTCFullYear(), monthStart.getUTCMonth(), monthStart.getUTCDate())) / (24 * 60 * 60 * 1e3)
@@ -2162,6 +2202,7 @@ function completeDrag() {
2162
2202
  cancelAnimationFrame(globalRafId);
2163
2203
  globalRafId = null;
2164
2204
  }
2205
+ clearGlobalCursor();
2165
2206
  if (globalActiveDrag) {
2166
2207
  globalActiveDrag.onCascadeProgress?.(/* @__PURE__ */ new Map(), []);
2167
2208
  const { onComplete, currentLeft, currentWidth, mode } = globalActiveDrag;
@@ -2174,6 +2215,7 @@ function cancelDrag() {
2174
2215
  cancelAnimationFrame(globalRafId);
2175
2216
  globalRafId = null;
2176
2217
  }
2218
+ clearGlobalCursor();
2177
2219
  if (globalActiveDrag) {
2178
2220
  const { onCancel } = globalActiveDrag;
2179
2221
  globalActiveDrag = null;
@@ -2383,7 +2425,8 @@ var useTaskDrag = (options) => {
2383
2425
  locked = false,
2384
2426
  disableTaskDrag = false,
2385
2427
  businessDays = true,
2386
- weekendPredicate
2428
+ weekendPredicate,
2429
+ viewMode = "day"
2387
2430
  } = options;
2388
2431
  const rawHookTask = allTasks.find((t) => t.id === taskId);
2389
2432
  const hookTask = rawHookTask ? normalizeTaskDatesForType(rawHookTask) : void 0;
@@ -2394,6 +2437,7 @@ var useTaskDrag = (options) => {
2394
2437
  const [dragMode, setDragMode] = useState(null);
2395
2438
  const [currentLeft, setCurrentLeft] = useState(0);
2396
2439
  const [currentWidth, setCurrentWidth] = useState(0);
2440
+ const [hoverCursor, setHoverCursor] = useState("grab");
2397
2441
  const getInitialPosition = useCallback(() => {
2398
2442
  const getUTCDayDifference2 = (date1, date2) => {
2399
2443
  const ms1 = Date.UTC(
@@ -2572,28 +2616,33 @@ var useTaskDrag = (options) => {
2572
2616
  }
2573
2617
  };
2574
2618
  }, []);
2575
- const handleMouseDown = useCallback((e) => {
2619
+ const startDrag = useCallback((e) => {
2576
2620
  if (effectiveLocked) return;
2577
2621
  const target = e.currentTarget;
2578
- const edgeZone = detectEdgeZone(e.clientX, target, edgeZoneWidth);
2622
+ const currentTask = allTasks.find((t) => t.id === taskId);
2623
+ const isSingleDayTask = !!currentTask && !isMilestoneTask(currentTask) && !isTaskParent(taskId, allTasks) && currentWidth <= dayWidth && viewMode === "day";
2579
2624
  let mode = null;
2580
- switch (edgeZone) {
2581
- case "left":
2582
- mode = "resize-left";
2583
- break;
2584
- case "right":
2585
- mode = "resize-right";
2586
- break;
2587
- case "move":
2588
- mode = "move";
2589
- break;
2625
+ if (isSingleDayTask) {
2626
+ mode = "move";
2627
+ } else {
2628
+ const edgeZone = detectEdgeZone(e.clientX, target, edgeZoneWidth);
2629
+ switch (edgeZone) {
2630
+ case "left":
2631
+ mode = "resize-left";
2632
+ break;
2633
+ case "right":
2634
+ mode = "resize-right";
2635
+ break;
2636
+ case "move":
2637
+ mode = "move";
2638
+ break;
2639
+ }
2590
2640
  }
2591
2641
  if (mode === "resize-left" || mode === "resize-right") {
2592
- const currentTask2 = allTasks.find((t) => t.id === taskId);
2593
- if (currentTask2 && isTaskParent(taskId, allTasks)) {
2642
+ if (currentTask && isTaskParent(taskId, allTasks)) {
2594
2643
  mode = "move";
2595
2644
  }
2596
- if (currentTask2 && isMilestoneTask(currentTask2)) {
2645
+ if (currentTask && isMilestoneTask(currentTask)) {
2597
2646
  mode = "move";
2598
2647
  }
2599
2648
  }
@@ -2605,6 +2654,7 @@ var useTaskDrag = (options) => {
2605
2654
  isOwnerRef.current = true;
2606
2655
  setIsDragging(true);
2607
2656
  setDragMode(mode);
2657
+ applyGlobalCursor(mode === "move" ? "grabbing" : "ew-resize");
2608
2658
  if (onDragStateChange) {
2609
2659
  onDragStateChange({
2610
2660
  isDragging: true,
@@ -2614,10 +2664,10 @@ var useTaskDrag = (options) => {
2614
2664
  });
2615
2665
  }
2616
2666
  ensureGlobalListeners();
2617
- const currentTask = allTasks.find((t) => t.id === taskId);
2667
+ const dragTask = allTasks.find((t) => t.id === taskId);
2618
2668
  let hierarchyChain = [];
2619
- if (currentTask) {
2620
- const taskParentId = currentTask.parentId;
2669
+ if (dragTask) {
2670
+ const taskParentId = dragTask.parentId;
2621
2671
  if (taskParentId) {
2622
2672
  const parentTask = allTasks.find((t) => t.id === taskParentId);
2623
2673
  if (parentTask) {
@@ -2654,15 +2704,44 @@ var useTaskDrag = (options) => {
2654
2704
  businessDays,
2655
2705
  weekendPredicate
2656
2706
  };
2657
- }, [edgeZoneWidth, currentLeft, currentWidth, dayWidth, monthStart, taskId, onDragStateChange, handleProgress, handleComplete, handleCancel, allTasks, disableConstraints, onCascadeProgress, onCascade, effectiveLocked]);
2707
+ }, [edgeZoneWidth, currentLeft, currentWidth, dayWidth, monthStart, taskId, onDragStateChange, handleProgress, handleComplete, handleCancel, allTasks, disableConstraints, onCascadeProgress, onCascade, effectiveLocked, viewMode]);
2708
+ const handleMouseDown = useCallback((e) => {
2709
+ startDrag(e);
2710
+ }, [startDrag]);
2711
+ const handleMouseMove = useCallback((e) => {
2712
+ if (disableTaskDrag) {
2713
+ setHoverCursor("grab");
2714
+ return;
2715
+ }
2716
+ if (locked) {
2717
+ setHoverCursor("not-allowed");
2718
+ return;
2719
+ }
2720
+ if (isDragging) {
2721
+ setHoverCursor("grabbing");
2722
+ return;
2723
+ }
2724
+ const target = e.currentTarget;
2725
+ const currentTask = allTasks.find((t) => t.id === taskId);
2726
+ const isSingleDayTask = !!currentTask && !isMilestoneTask(currentTask) && !isTaskParent(taskId, allTasks) && currentWidth <= dayWidth && viewMode === "day";
2727
+ if (isSingleDayTask || currentTask && (isTaskParent(taskId, allTasks) || isMilestoneTask(currentTask))) {
2728
+ setHoverCursor("grab");
2729
+ return;
2730
+ }
2731
+ const edgeZone = detectEdgeZone(e.clientX, target, edgeZoneWidth);
2732
+ setHoverCursor(edgeZone === "move" ? "grab" : "ew-resize");
2733
+ }, [disableTaskDrag, locked, isDragging, allTasks, taskId, currentWidth, dayWidth, viewMode, edgeZoneWidth]);
2734
+ const handleMouseLeave = useCallback(() => {
2735
+ setHoverCursor(disableTaskDrag ? "grab" : locked ? "not-allowed" : isDragging ? "grabbing" : "grab");
2736
+ }, [disableTaskDrag, locked, isDragging]);
2658
2737
  const getCursorStyle = useCallback(() => {
2659
2738
  if (disableTaskDrag) return "grab";
2660
2739
  if (locked) return "not-allowed";
2661
2740
  if (isDragging) {
2662
- return "grabbing";
2741
+ return dragMode === "move" ? "grabbing" : "ew-resize";
2663
2742
  }
2664
- return "grab";
2665
- }, [disableTaskDrag, locked, isDragging]);
2743
+ return hoverCursor;
2744
+ }, [disableTaskDrag, locked, isDragging, dragMode, hoverCursor]);
2666
2745
  return {
2667
2746
  isDragging,
2668
2747
  dragMode,
@@ -2670,6 +2749,8 @@ var useTaskDrag = (options) => {
2670
2749
  currentWidth,
2671
2750
  dragHandleProps: {
2672
2751
  onMouseDown: handleMouseDown,
2752
+ onMouseMove: handleMouseMove,
2753
+ onMouseLeave: handleMouseLeave,
2673
2754
  style: {
2674
2755
  cursor: getCursorStyle(),
2675
2756
  userSelect: "none"
@@ -2681,10 +2762,10 @@ var useTaskDrag = (options) => {
2681
2762
  // src/components/TaskRow/TaskRow.tsx
2682
2763
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
2683
2764
  var arePropsEqual = (prevProps, nextProps) => {
2684
- return prevProps.task.id === nextProps.task.id && prevProps.task.name === nextProps.task.name && prevProps.task.startDate === nextProps.task.startDate && prevProps.task.endDate === nextProps.task.endDate && prevProps.task.baselineStartDate === nextProps.task.baselineStartDate && prevProps.task.baselineEndDate === nextProps.task.baselineEndDate && prevProps.task.type === nextProps.task.type && prevProps.task.color === nextProps.task.color && prevProps.task.progress === nextProps.task.progress && prevProps.task.accepted === nextProps.task.accepted && prevProps.monthStart.getTime() === nextProps.monthStart.getTime() && prevProps.dayWidth === nextProps.dayWidth && prevProps.rowHeight === nextProps.rowHeight && prevProps.overridePosition?.left === nextProps.overridePosition?.left && prevProps.overridePosition?.width === nextProps.overridePosition?.width && prevProps.allTasks === nextProps.allTasks && prevProps.disableConstraints === nextProps.disableConstraints && prevProps.task.locked === nextProps.task.locked && prevProps.task.divider === nextProps.task.divider && prevProps.highlightExpiredTasks === nextProps.highlightExpiredTasks && prevProps.showBaseline === nextProps.showBaseline && prevProps.isFilterMatch === nextProps.isFilterMatch && prevProps.businessDays === nextProps.businessDays && prevProps.customDays === nextProps.customDays && prevProps.isWeekend === nextProps.isWeekend && prevProps.disableTaskDrag === nextProps.disableTaskDrag;
2765
+ return prevProps.task.id === nextProps.task.id && prevProps.task.name === nextProps.task.name && prevProps.task.startDate === nextProps.task.startDate && prevProps.task.endDate === nextProps.task.endDate && prevProps.task.baselineStartDate === nextProps.task.baselineStartDate && prevProps.task.baselineEndDate === nextProps.task.baselineEndDate && prevProps.task.type === nextProps.task.type && prevProps.task.color === nextProps.task.color && prevProps.task.progress === nextProps.task.progress && prevProps.task.accepted === nextProps.task.accepted && prevProps.monthStart.getTime() === nextProps.monthStart.getTime() && prevProps.dayWidth === nextProps.dayWidth && prevProps.rowHeight === nextProps.rowHeight && prevProps.overridePosition?.left === nextProps.overridePosition?.left && prevProps.overridePosition?.width === nextProps.overridePosition?.width && prevProps.allTasks === nextProps.allTasks && prevProps.disableConstraints === nextProps.disableConstraints && prevProps.task.locked === nextProps.task.locked && prevProps.task.divider === nextProps.task.divider && prevProps.highlightExpiredTasks === nextProps.highlightExpiredTasks && prevProps.showBaseline === nextProps.showBaseline && prevProps.isFilterMatch === nextProps.isFilterMatch && prevProps.businessDays === nextProps.businessDays && prevProps.customDays === nextProps.customDays && prevProps.isWeekend === nextProps.isWeekend && prevProps.disableTaskDrag === nextProps.disableTaskDrag && prevProps.viewMode === nextProps.viewMode;
2685
2766
  };
2686
2767
  var TaskRow = React2.memo(
2687
- ({ task, monthStart, dayWidth, rowHeight, onTasksChange, onDragStateChange, rowIndex, allTasks, enableAutoSchedule, disableConstraints, overridePosition, onCascadeProgress, onCascade, divider, highlightExpiredTasks, showBaseline = false, isFilterMatch = false, businessDays, customDays, isWeekend: isWeekend3, disableTaskDrag = false }) => {
2768
+ ({ task, monthStart, dayWidth, rowHeight, onTasksChange, onDragStateChange, rowIndex, allTasks, enableAutoSchedule, disableConstraints, overridePosition, onCascadeProgress, onCascade, divider, highlightExpiredTasks, showBaseline = false, isFilterMatch = false, businessDays, customDays, isWeekend: isWeekend3, disableTaskDrag = false, viewMode = "day" }) => {
2688
2769
  const defaultParentBarColor = "#782FC4";
2689
2770
  const { divider: taskDivider } = task;
2690
2771
  const normalizedTask = useMemo2(() => normalizeTaskDatesForType(task), [task]);
@@ -2797,7 +2878,8 @@ var TaskRow = React2.memo(
2797
2878
  onCascadeProgress,
2798
2879
  onCascade,
2799
2880
  businessDays,
2800
- weekendPredicate
2881
+ weekendPredicate,
2882
+ viewMode
2801
2883
  });
2802
2884
  const displayLeft = overridePosition?.left ?? (isDragging ? currentLeft : left);
2803
2885
  const displayWidth = overridePosition?.width ?? (isDragging ? currentWidth : width);
@@ -2873,6 +2955,8 @@ var TaskRow = React2.memo(
2873
2955
  userSelect: dragHandleProps.style.userSelect
2874
2956
  },
2875
2957
  onMouseDown: dragHandleProps.onMouseDown,
2958
+ onMouseMove: dragHandleProps.onMouseMove,
2959
+ onMouseLeave: dragHandleProps.onMouseLeave,
2876
2960
  children: [
2877
2961
  !milestone && progressWidth > 0 && progressWidth < 100 && /* @__PURE__ */ jsx2(
2878
2962
  "div",
@@ -10053,7 +10137,8 @@ function TaskGanttChartInner(props, ref) {
10053
10137
  businessDays,
10054
10138
  customDays,
10055
10139
  isWeekend: isWeekend3,
10056
- disableTaskDrag
10140
+ disableTaskDrag,
10141
+ viewMode
10057
10142
  },
10058
10143
  task.id
10059
10144
  ))