gantt-task-react-v 1.4.3 → 1.4.5

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.
@@ -11727,9 +11727,9 @@ const generateTrianglePoints = (x, y, width, isLeftDirected) => {
11727
11727
  ${x - width},${y - width}
11728
11728
  ${x - width},${y + width}`;
11729
11729
  };
11730
- const arrow_clickable = "_arrow_clickable_m4fqb_1";
11731
- const mainPath = "_mainPath_m4fqb_11";
11732
- const clickZone = "_clickZone_m4fqb_57";
11730
+ const arrow_clickable = "_arrow_clickable_1xrbf_1";
11731
+ const mainPath = "_mainPath_1xrbf_11";
11732
+ const clickZone = "_clickZone_1xrbf_57";
11733
11733
  const styles$a = {
11734
11734
  arrow_clickable,
11735
11735
  mainPath,
@@ -11826,8 +11826,8 @@ const ArrowInner = (props) => {
11826
11826
  onDoubleClick,
11827
11827
  children: [
11828
11828
  onArrowDoubleClick && /* @__PURE__ */ jsx("path", { d: path, className: styles$a.clickZone }),
11829
- /* @__PURE__ */ jsx("path", { className: styles$a.mainPath, d: path }),
11830
- /* @__PURE__ */ jsx("polygon", { className: "polygon", points: trianglePoints })
11829
+ /* @__PURE__ */ jsx("path", { className: `${styles$a.mainPath} arrowMainPath`, d: path }),
11830
+ /* @__PURE__ */ jsx("polygon", { className: "polygon arrowPolygon", points: trianglePoints })
11831
11831
  ]
11832
11832
  }
11833
11833
  ) });
@@ -11863,28 +11863,44 @@ const roundedPath = (points, radius) => {
11863
11863
  d += ` L ${last[0]} ${last[1]}`;
11864
11864
  return d;
11865
11865
  };
11866
- const ARROW_CORNER_RADIUS = 8;
11867
- const MAX_EXTRA_INDENT = 20;
11868
- const CONNECTION_SPREAD_RATIO = 0.35;
11869
- const MAX_CORRIDOR_SPREAD = 20;
11866
+ const ARROW_CORNER_RADIUS = 5;
11867
+ const connectionPosition = (index2, total) => {
11868
+ if (total <= 1)
11869
+ return 0.5;
11870
+ return index2 / (total - 1);
11871
+ };
11870
11872
  const drownPathAndTriangle = (indexForm, fromX1, fromX2, fromY, isTaskFromLeftSide, indexTo, toX1, toX2, toY, isTaskToLeftSide, fullRowHeight, taskHeight, arrowIndent, fromConnectionIndex, fromTotalConnections, toConnectionIndex, toTotalConnections) => {
11871
11873
  const isDownDirected = indexTo > indexForm;
11872
- const fromVertOffset = fromTotalConnections <= 1 ? 0 : (fromConnectionIndex / (fromTotalConnections - 1) - 0.5) * taskHeight * CONNECTION_SPREAD_RATIO;
11873
- const toVertOffset = toTotalConnections <= 1 ? 0 : (toConnectionIndex / (toTotalConnections - 1) - 0.5) * taskHeight * CONNECTION_SPREAD_RATIO;
11874
- const fromIndentSpacing = fromTotalConnections <= 1 ? 0 : MAX_EXTRA_INDENT / (fromTotalConnections - 1);
11875
- const toIndentSpacing = toTotalConnections <= 1 ? 0 : MAX_EXTRA_INDENT / (toTotalConnections - 1);
11876
- const fromIndent = arrowIndent + fromConnectionIndex * fromIndentSpacing;
11877
- const toIndent = arrowIndent + toConnectionIndex * toIndentSpacing;
11878
- const corridorHash = (fromConnectionIndex * 7 + toConnectionIndex * 13) % 11 / 10;
11879
- const corridorSpread = Math.min(fullRowHeight * 0.35, MAX_CORRIDOR_SPREAD);
11880
- const corridorOffset = (corridorHash - 0.5) * corridorSpread;
11881
- const horizontalDockingY = isDownDirected ? (indexForm + 1) * fullRowHeight + corridorOffset : indexForm * fullRowHeight + corridorOffset;
11882
- const taskFromEndPositionX = isTaskFromLeftSide ? fromX1 - fromIndent : fromX2 + fromIndent;
11883
- const taskToEndPositionX = isTaskToLeftSide ? toX1 - toIndent : toX2 + toIndent;
11874
+ const isSameRow = indexForm === indexTo;
11875
+ const vertSpreadRange = taskHeight * 0.8;
11876
+ const fromPos = connectionPosition(fromConnectionIndex, fromTotalConnections);
11877
+ const toPos = connectionPosition(toConnectionIndex, toTotalConnections);
11878
+ const fromVertOffset = (fromPos - 0.5) * vertSpreadRange;
11879
+ const toVertOffset = (toPos - 0.5) * vertSpreadRange;
11884
11880
  const startX = isTaskFromLeftSide ? fromX1 : fromX2;
11885
11881
  const startY = fromY + taskHeight / 2 + fromVertOffset;
11886
11882
  const endX = isTaskToLeftSide ? toX1 : toX2;
11887
11883
  const endY = toY + taskHeight / 2 + toVertOffset;
11884
+ const fromIndent = arrowIndent + fromConnectionIndex * 8;
11885
+ const toIndent = arrowIndent + toConnectionIndex * 8;
11886
+ const taskFromEndPositionX = isTaskFromLeftSide ? fromX1 - fromIndent : fromX2 + fromIndent;
11887
+ const taskToEndPositionX = isTaskToLeftSide ? toX1 - toIndent : toX2 + toIndent;
11888
+ const totalArrowsInCorridor = Math.max(
11889
+ fromTotalConnections,
11890
+ toTotalConnections,
11891
+ 1
11892
+ );
11893
+ const corridorIndex = (fromConnectionIndex + toConnectionIndex) % Math.max(totalArrowsInCorridor, 1);
11894
+ const corridorPos = connectionPosition(corridorIndex, totalArrowsInCorridor);
11895
+ const corridorRange = fullRowHeight * 0.7;
11896
+ const corridorBase = isDownDirected ? (indexForm + 1) * fullRowHeight - corridorRange * 0.15 : indexForm * fullRowHeight + corridorRange * 0.15;
11897
+ const corridorOffset = (corridorPos - 0.5) * corridorRange;
11898
+ let horizontalDockingY;
11899
+ if (isSameRow) {
11900
+ horizontalDockingY = isTaskFromLeftSide ? fromY + taskHeight + 6 + fromConnectionIndex * 4 : fromY - 6 - fromConnectionIndex * 4;
11901
+ } else {
11902
+ horizontalDockingY = corridorBase + corridorOffset;
11903
+ }
11888
11904
  const rawWaypoints = [
11889
11905
  [startX, startY],
11890
11906
  [taskFromEndPositionX, startY],
@@ -13187,6 +13203,13 @@ const TaskGanttContentInner = (props) => {
13187
13203
  getDate,
13188
13204
  startColumnIndex
13189
13205
  ]);
13206
+ const [hoveredTaskId, setHoveredTaskId] = useState(null);
13207
+ const handleTaskHover = useCallback((taskId) => {
13208
+ setHoveredTaskId(taskId);
13209
+ }, []);
13210
+ const handleTaskLeave = useCallback(() => {
13211
+ setHoveredTaskId(null);
13212
+ }, []);
13190
13213
  const [renderedTasks, renderedArrows, renderedSelectedTasks] = useMemo(() => {
13191
13214
  if (!renderedRowIndexes) {
13192
13215
  return [null, null, null];
@@ -13289,6 +13312,8 @@ const TaskGanttContentInner = (props) => {
13289
13312
  y: safeLevelY,
13290
13313
  width: Math.max(safeContainerWidth, 0),
13291
13314
  height: fullRowHeight,
13315
+ onMouseEnter: () => handleTaskHover(task.id),
13316
+ onMouseLeave: handleTaskLeave,
13292
13317
  children: /* @__PURE__ */ jsx(
13293
13318
  TaskItem,
13294
13319
  {
@@ -13417,6 +13442,8 @@ const TaskGanttContentInner = (props) => {
13417
13442
  y: containerY,
13418
13443
  width: safeArrowContainerWidth,
13419
13444
  height: containerHeight,
13445
+ "data-from-id": source.id,
13446
+ "data-to-id": taskId,
13420
13447
  children: /* @__PURE__ */ jsx(
13421
13448
  Arrow,
13422
13449
  {
@@ -13501,6 +13528,8 @@ const TaskGanttContentInner = (props) => {
13501
13528
  y: containerY,
13502
13529
  width: safeArrowContainerWidth,
13503
13530
  height: containerHeight,
13531
+ "data-from-id": taskId,
13532
+ "data-to-id": dependent.id,
13504
13533
  children: /* @__PURE__ */ jsx(
13505
13534
  Arrow,
13506
13535
  {
@@ -13598,6 +13627,8 @@ const TaskGanttContentInner = (props) => {
13598
13627
  y: containerY,
13599
13628
  width: safeCW,
13600
13629
  height: containerHeight,
13630
+ "data-from-id": source.id,
13631
+ "data-to-id": taskId,
13601
13632
  children: /* @__PURE__ */ jsx(
13602
13633
  Arrow,
13603
13634
  {
@@ -13675,9 +13706,35 @@ const TaskGanttContentInner = (props) => {
13675
13706
  visibleTasksMirror,
13676
13707
  onArrowDoubleClick,
13677
13708
  showProgress,
13678
- progressColor
13709
+ progressColor,
13710
+ handleTaskHover,
13711
+ handleTaskLeave
13679
13712
  ]);
13713
+ const arrowHighlightStyle = useMemo(() => {
13714
+ if (!hoveredTaskId)
13715
+ return null;
13716
+ const safeId = CSS.escape(hoveredTaskId);
13717
+ return /* @__PURE__ */ jsx("style", { children: `
13718
+ g.arrows svg { opacity: 0.08 !important; transition: opacity 0.15s; }
13719
+ g.arrows svg[data-from-id="${safeId}"],
13720
+ g.arrows svg[data-to-id="${safeId}"] {
13721
+ opacity: 1 !important;
13722
+ }
13723
+ g.arrows svg[data-from-id="${safeId}"] .arrowMainPath,
13724
+ g.arrows svg[data-to-id="${safeId}"] .arrowMainPath {
13725
+ opacity: 1 !important;
13726
+ stroke-width: 2px !important;
13727
+ stroke: var(--gantt-arrow-hover-color, #1976D2) !important;
13728
+ }
13729
+ g.arrows svg[data-from-id="${safeId}"] .arrowPolygon,
13730
+ g.arrows svg[data-to-id="${safeId}"] .arrowPolygon {
13731
+ fill: var(--gantt-arrow-hover-color, #1976D2) !important;
13732
+ opacity: 1 !important;
13733
+ }
13734
+ ` });
13735
+ }, [hoveredTaskId]);
13680
13736
  return /* @__PURE__ */ jsxs("g", { className: "content", children: [
13737
+ arrowHighlightStyle,
13681
13738
  renderedSelectedTasks,
13682
13739
  /* @__PURE__ */ jsx("g", { children: renderedHolidays }),
13683
13740
  /* @__PURE__ */ jsx(
@@ -11744,9 +11744,9 @@
11744
11744
  ${x - width},${y - width}
11745
11745
  ${x - width},${y + width}`;
11746
11746
  };
11747
- const arrow_clickable = "_arrow_clickable_m4fqb_1";
11748
- const mainPath = "_mainPath_m4fqb_11";
11749
- const clickZone = "_clickZone_m4fqb_57";
11747
+ const arrow_clickable = "_arrow_clickable_1xrbf_1";
11748
+ const mainPath = "_mainPath_1xrbf_11";
11749
+ const clickZone = "_clickZone_1xrbf_57";
11750
11750
  const styles$a = {
11751
11751
  arrow_clickable,
11752
11752
  mainPath,
@@ -11843,8 +11843,8 @@
11843
11843
  onDoubleClick,
11844
11844
  children: [
11845
11845
  onArrowDoubleClick && /* @__PURE__ */ jsxRuntime.jsx("path", { d: path, className: styles$a.clickZone }),
11846
- /* @__PURE__ */ jsxRuntime.jsx("path", { className: styles$a.mainPath, d: path }),
11847
- /* @__PURE__ */ jsxRuntime.jsx("polygon", { className: "polygon", points: trianglePoints })
11846
+ /* @__PURE__ */ jsxRuntime.jsx("path", { className: `${styles$a.mainPath} arrowMainPath`, d: path }),
11847
+ /* @__PURE__ */ jsxRuntime.jsx("polygon", { className: "polygon arrowPolygon", points: trianglePoints })
11848
11848
  ]
11849
11849
  }
11850
11850
  ) });
@@ -11880,28 +11880,44 @@
11880
11880
  d += ` L ${last[0]} ${last[1]}`;
11881
11881
  return d;
11882
11882
  };
11883
- const ARROW_CORNER_RADIUS = 8;
11884
- const MAX_EXTRA_INDENT = 20;
11885
- const CONNECTION_SPREAD_RATIO = 0.35;
11886
- const MAX_CORRIDOR_SPREAD = 20;
11883
+ const ARROW_CORNER_RADIUS = 5;
11884
+ const connectionPosition = (index2, total) => {
11885
+ if (total <= 1)
11886
+ return 0.5;
11887
+ return index2 / (total - 1);
11888
+ };
11887
11889
  const drownPathAndTriangle = (indexForm, fromX1, fromX2, fromY, isTaskFromLeftSide, indexTo, toX1, toX2, toY, isTaskToLeftSide, fullRowHeight, taskHeight, arrowIndent, fromConnectionIndex, fromTotalConnections, toConnectionIndex, toTotalConnections) => {
11888
11890
  const isDownDirected = indexTo > indexForm;
11889
- const fromVertOffset = fromTotalConnections <= 1 ? 0 : (fromConnectionIndex / (fromTotalConnections - 1) - 0.5) * taskHeight * CONNECTION_SPREAD_RATIO;
11890
- const toVertOffset = toTotalConnections <= 1 ? 0 : (toConnectionIndex / (toTotalConnections - 1) - 0.5) * taskHeight * CONNECTION_SPREAD_RATIO;
11891
- const fromIndentSpacing = fromTotalConnections <= 1 ? 0 : MAX_EXTRA_INDENT / (fromTotalConnections - 1);
11892
- const toIndentSpacing = toTotalConnections <= 1 ? 0 : MAX_EXTRA_INDENT / (toTotalConnections - 1);
11893
- const fromIndent = arrowIndent + fromConnectionIndex * fromIndentSpacing;
11894
- const toIndent = arrowIndent + toConnectionIndex * toIndentSpacing;
11895
- const corridorHash = (fromConnectionIndex * 7 + toConnectionIndex * 13) % 11 / 10;
11896
- const corridorSpread = Math.min(fullRowHeight * 0.35, MAX_CORRIDOR_SPREAD);
11897
- const corridorOffset = (corridorHash - 0.5) * corridorSpread;
11898
- const horizontalDockingY = isDownDirected ? (indexForm + 1) * fullRowHeight + corridorOffset : indexForm * fullRowHeight + corridorOffset;
11899
- const taskFromEndPositionX = isTaskFromLeftSide ? fromX1 - fromIndent : fromX2 + fromIndent;
11900
- const taskToEndPositionX = isTaskToLeftSide ? toX1 - toIndent : toX2 + toIndent;
11891
+ const isSameRow = indexForm === indexTo;
11892
+ const vertSpreadRange = taskHeight * 0.8;
11893
+ const fromPos = connectionPosition(fromConnectionIndex, fromTotalConnections);
11894
+ const toPos = connectionPosition(toConnectionIndex, toTotalConnections);
11895
+ const fromVertOffset = (fromPos - 0.5) * vertSpreadRange;
11896
+ const toVertOffset = (toPos - 0.5) * vertSpreadRange;
11901
11897
  const startX = isTaskFromLeftSide ? fromX1 : fromX2;
11902
11898
  const startY = fromY + taskHeight / 2 + fromVertOffset;
11903
11899
  const endX = isTaskToLeftSide ? toX1 : toX2;
11904
11900
  const endY = toY + taskHeight / 2 + toVertOffset;
11901
+ const fromIndent = arrowIndent + fromConnectionIndex * 8;
11902
+ const toIndent = arrowIndent + toConnectionIndex * 8;
11903
+ const taskFromEndPositionX = isTaskFromLeftSide ? fromX1 - fromIndent : fromX2 + fromIndent;
11904
+ const taskToEndPositionX = isTaskToLeftSide ? toX1 - toIndent : toX2 + toIndent;
11905
+ const totalArrowsInCorridor = Math.max(
11906
+ fromTotalConnections,
11907
+ toTotalConnections,
11908
+ 1
11909
+ );
11910
+ const corridorIndex = (fromConnectionIndex + toConnectionIndex) % Math.max(totalArrowsInCorridor, 1);
11911
+ const corridorPos = connectionPosition(corridorIndex, totalArrowsInCorridor);
11912
+ const corridorRange = fullRowHeight * 0.7;
11913
+ const corridorBase = isDownDirected ? (indexForm + 1) * fullRowHeight - corridorRange * 0.15 : indexForm * fullRowHeight + corridorRange * 0.15;
11914
+ const corridorOffset = (corridorPos - 0.5) * corridorRange;
11915
+ let horizontalDockingY;
11916
+ if (isSameRow) {
11917
+ horizontalDockingY = isTaskFromLeftSide ? fromY + taskHeight + 6 + fromConnectionIndex * 4 : fromY - 6 - fromConnectionIndex * 4;
11918
+ } else {
11919
+ horizontalDockingY = corridorBase + corridorOffset;
11920
+ }
11905
11921
  const rawWaypoints = [
11906
11922
  [startX, startY],
11907
11923
  [taskFromEndPositionX, startY],
@@ -13204,6 +13220,13 @@
13204
13220
  getDate,
13205
13221
  startColumnIndex
13206
13222
  ]);
13223
+ const [hoveredTaskId, setHoveredTaskId] = React.useState(null);
13224
+ const handleTaskHover = React.useCallback((taskId) => {
13225
+ setHoveredTaskId(taskId);
13226
+ }, []);
13227
+ const handleTaskLeave = React.useCallback(() => {
13228
+ setHoveredTaskId(null);
13229
+ }, []);
13207
13230
  const [renderedTasks, renderedArrows, renderedSelectedTasks] = React.useMemo(() => {
13208
13231
  if (!renderedRowIndexes) {
13209
13232
  return [null, null, null];
@@ -13306,6 +13329,8 @@
13306
13329
  y: safeLevelY,
13307
13330
  width: Math.max(safeContainerWidth, 0),
13308
13331
  height: fullRowHeight,
13332
+ onMouseEnter: () => handleTaskHover(task.id),
13333
+ onMouseLeave: handleTaskLeave,
13309
13334
  children: /* @__PURE__ */ jsxRuntime.jsx(
13310
13335
  TaskItem,
13311
13336
  {
@@ -13434,6 +13459,8 @@
13434
13459
  y: containerY,
13435
13460
  width: safeArrowContainerWidth,
13436
13461
  height: containerHeight,
13462
+ "data-from-id": source.id,
13463
+ "data-to-id": taskId,
13437
13464
  children: /* @__PURE__ */ jsxRuntime.jsx(
13438
13465
  Arrow,
13439
13466
  {
@@ -13518,6 +13545,8 @@
13518
13545
  y: containerY,
13519
13546
  width: safeArrowContainerWidth,
13520
13547
  height: containerHeight,
13548
+ "data-from-id": taskId,
13549
+ "data-to-id": dependent.id,
13521
13550
  children: /* @__PURE__ */ jsxRuntime.jsx(
13522
13551
  Arrow,
13523
13552
  {
@@ -13615,6 +13644,8 @@
13615
13644
  y: containerY,
13616
13645
  width: safeCW,
13617
13646
  height: containerHeight,
13647
+ "data-from-id": source.id,
13648
+ "data-to-id": taskId,
13618
13649
  children: /* @__PURE__ */ jsxRuntime.jsx(
13619
13650
  Arrow,
13620
13651
  {
@@ -13692,9 +13723,35 @@
13692
13723
  visibleTasksMirror,
13693
13724
  onArrowDoubleClick,
13694
13725
  showProgress,
13695
- progressColor
13726
+ progressColor,
13727
+ handleTaskHover,
13728
+ handleTaskLeave
13696
13729
  ]);
13730
+ const arrowHighlightStyle = React.useMemo(() => {
13731
+ if (!hoveredTaskId)
13732
+ return null;
13733
+ const safeId = CSS.escape(hoveredTaskId);
13734
+ return /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
13735
+ g.arrows svg { opacity: 0.08 !important; transition: opacity 0.15s; }
13736
+ g.arrows svg[data-from-id="${safeId}"],
13737
+ g.arrows svg[data-to-id="${safeId}"] {
13738
+ opacity: 1 !important;
13739
+ }
13740
+ g.arrows svg[data-from-id="${safeId}"] .arrowMainPath,
13741
+ g.arrows svg[data-to-id="${safeId}"] .arrowMainPath {
13742
+ opacity: 1 !important;
13743
+ stroke-width: 2px !important;
13744
+ stroke: var(--gantt-arrow-hover-color, #1976D2) !important;
13745
+ }
13746
+ g.arrows svg[data-from-id="${safeId}"] .arrowPolygon,
13747
+ g.arrows svg[data-to-id="${safeId}"] .arrowPolygon {
13748
+ fill: var(--gantt-arrow-hover-color, #1976D2) !important;
13749
+ opacity: 1 !important;
13750
+ }
13751
+ ` });
13752
+ }, [hoveredTaskId]);
13697
13753
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { className: "content", children: [
13754
+ arrowHighlightStyle,
13698
13755
  renderedSelectedTasks,
13699
13756
  /* @__PURE__ */ jsxRuntime.jsx("g", { children: renderedHolidays }),
13700
13757
  /* @__PURE__ */ jsxRuntime.jsx(
package/dist/style.css CHANGED
@@ -439,38 +439,38 @@
439
439
  ._calendarDragging_15t8b_85 {
440
440
  cursor: ew-resize;
441
441
  }
442
- ._arrow_clickable_m4fqb_1 {
442
+ ._arrow_clickable_1xrbf_1 {
443
443
  cursor: pointer;
444
444
  }
445
445
 
446
446
  /*noinspection CssUnresolvedCustomProperty*/
447
- ._arrow_clickable_m4fqb_1:hover ._mainPath_m4fqb_11 {
447
+ ._arrow_clickable_1xrbf_1:hover ._mainPath_1xrbf_11 {
448
448
  filter: var(--gantt-hover-filter);
449
449
  stroke: var(--gantt-arrow-hover-color, red);
450
- stroke-width: 2.5px;
450
+ stroke-width: 2px;
451
451
  opacity: 1;
452
452
  }
453
453
 
454
454
  /*noinspection CssUnresolvedCustomProperty*/
455
- ._arrow_clickable_m4fqb_1:hover polygon {
455
+ ._arrow_clickable_1xrbf_1:hover polygon {
456
456
  fill: var(--gantt-arrow-hover-color, red);
457
457
  }
458
458
 
459
- ._mainPath_m4fqb_11 {
459
+ ._mainPath_1xrbf_11 {
460
460
  fill: none;
461
- stroke-width: 1.4px;
461
+ stroke-width: 1.2px;
462
462
  stroke-linecap: round;
463
463
  stroke-linejoin: round;
464
- opacity: 0.7;
464
+ opacity: 0.35;
465
465
  transition:
466
466
  stroke-width 0.15s ease,
467
467
  opacity 0.15s ease;
468
468
  }
469
469
 
470
- ._clickZone_m4fqb_57 {
470
+ ._clickZone_1xrbf_57 {
471
471
  fill: none;
472
472
  stroke: transparent;
473
- stroke-width: 10px;
473
+ stroke-width: 12px;
474
474
  }
475
475
  ._relationLine_wh2qy_1 {
476
476
  /*noinspection CssUnresolvedCustomProperty*/
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gantt-task-react-v",
3
- "version": "1.4.3",
3
+ "version": "1.4.5",
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",