reactflow-edge-routing 0.1.8 → 0.1.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reactflow-edge-routing",
3
- "version": "0.1.8",
3
+ "version": "0.1.11",
4
4
  "description": "Orthogonal edge routing for React Flow using obstacle-router. Edges route around nodes while pins stay fixed at their anchor points.",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
package/src/index.ts CHANGED
@@ -34,7 +34,7 @@ export { useEdgeRouting } from "./use-edge-routing";
34
34
  export type { UseEdgeRoutingOptions, UseEdgeRoutingResult } from "./use-edge-routing";
35
35
 
36
36
  export { useRoutedEdgePath } from "./use-routed-edge-path";
37
- export type { UseRoutedEdgePathParams } from "./use-routed-edge-path";
37
+ export type { UseRoutedEdgePathParams, RoutePinPoints } from "./use-routed-edge-path";
38
38
 
39
39
  // Collision resolution
40
40
  export { resolveCollisions } from "./resolve-collisions";
@@ -200,7 +200,7 @@ function getConnType(connectorType: ConnectorType | undefined): number {
200
200
  /** Get the Router flags for the connector type. */
201
201
  function getRouterFlags(connectorType: ConnectorType | undefined): number {
202
202
  switch (connectorType) {
203
- case "polyline": return PolyLineRouting | OrthogonalRouting;
203
+ case "polyline": return PolyLineRouting;
204
204
  default: return OrthogonalRouting;
205
205
  }
206
206
  }
@@ -737,13 +737,16 @@ function configureRouter(router: AvoidRouter, options: AvoidRouterOptions): void
737
737
  }
738
738
 
739
739
  // --- Routing options ---
740
- router.setRoutingOption(nudgeOrthogonalSegmentsConnectedToShapesOpt, options.nudgeOrthogonalSegmentsConnectedToShapes ?? true);
741
- router.setRoutingOption(nudgeSharedPathsWithCommonEndPointOpt, options.nudgeSharedPathsWithCommonEndPoint ?? true);
742
- router.setRoutingOption(performUnifyingNudgingPreprocessingStepOpt, options.performUnifyingNudgingPreprocessingStep ?? true);
743
- router.setRoutingOption(nudgeOrthogonalTouchingColinearSegmentsOpt, options.nudgeOrthogonalTouchingColinearSegments ?? false);
744
- router.setRoutingOption(improveHyperedgeRoutesMovingJunctionsOpt, options.improveHyperedgeRoutesMovingJunctions ?? true);
745
- router.setRoutingOption(penaliseOrthogonalSharedPathsAtConnEndsOpt, options.penaliseOrthogonalSharedPathsAtConnEnds ?? false);
746
- router.setRoutingOption(improveHyperedgeRoutesMovingAddingAndDeletingJunctionsOpt, options.improveHyperedgeRoutesMovingAddingAndDeletingJunctions ?? false);
740
+ // Orthogonal nudging options only apply to orthogonal/bezier routing.
741
+ // Enabling them for polyline connectors corrupts the routed paths.
742
+ const isPolyline = options.connectorType === "polyline";
743
+ router.setRoutingOption(nudgeOrthogonalSegmentsConnectedToShapesOpt, isPolyline ? false : (options.nudgeOrthogonalSegmentsConnectedToShapes ?? true));
744
+ router.setRoutingOption(nudgeSharedPathsWithCommonEndPointOpt, isPolyline ? false : (options.nudgeSharedPathsWithCommonEndPoint ?? true));
745
+ router.setRoutingOption(performUnifyingNudgingPreprocessingStepOpt, isPolyline ? false : (options.performUnifyingNudgingPreprocessingStep ?? true));
746
+ router.setRoutingOption(nudgeOrthogonalTouchingColinearSegmentsOpt, isPolyline ? false : (options.nudgeOrthogonalTouchingColinearSegments ?? false));
747
+ router.setRoutingOption(improveHyperedgeRoutesMovingJunctionsOpt, isPolyline ? false : (options.improveHyperedgeRoutesMovingJunctions ?? true));
748
+ router.setRoutingOption(penaliseOrthogonalSharedPathsAtConnEndsOpt, isPolyline ? false : (options.penaliseOrthogonalSharedPathsAtConnEnds ?? false));
749
+ router.setRoutingOption(improveHyperedgeRoutesMovingAddingAndDeletingJunctionsOpt, isPolyline ? false : (options.improveHyperedgeRoutesMovingAddingAndDeletingJunctions ?? false));
747
750
  }
748
751
 
749
752
  // ---- Routing helpers ----
@@ -56,8 +56,13 @@ function getFallback(
56
56
  return getStraightPath({ sourceX, sourceY, targetX, targetY });
57
57
  }
58
58
 
59
+ export type RoutePinPoints = {
60
+ sourceX: number; sourceY: number;
61
+ targetX: number; targetY: number;
62
+ };
63
+
59
64
  /**
60
- * Returns [path, labelX, labelY, wasRouted, controlPoints] for a routed edge.
65
+ * Returns [path, labelX, labelY, wasRouted, controlPoints, pinPoints] for a routed edge.
61
66
  *
62
67
  * - While a connected node is being dragged → dashed fallback
63
68
  * - If a routed path exists for this edge → solid routed path
@@ -67,10 +72,13 @@ function getFallback(
67
72
  * the source and target anchor points). Use them to build an editable edge on
68
73
  * top of auto-routing — e.g. render draggable handles at each waypoint.
69
74
  * When no route is available (fallback), `controlPoints` is an empty array.
75
+ *
76
+ * `pinPoints` are the exact source/target positions the router snapped to.
77
+ * Falls back to the passed-in sourceX/Y, targetX/Y when no route is available.
70
78
  */
71
79
  export function useRoutedEdgePath(
72
80
  params: UseRoutedEdgePathParams
73
- ): [path: string, labelX: number, labelY: number, wasRouted: boolean, controlPoints: { x: number; y: number }[]] {
81
+ ): [path: string, labelX: number, labelY: number, wasRouted: boolean, controlPoints: { x: number; y: number }[], pinPoints: RoutePinPoints] {
74
82
  const {
75
83
  id, sourceX, sourceY, targetX, targetY,
76
84
  sourcePosition, targetPosition,
@@ -81,6 +89,8 @@ export function useRoutedEdgePath(
81
89
  const draggingNodeIds = useEdgeRoutingStore((s) => s.draggingNodeIds);
82
90
 
83
91
  return useMemo(() => {
92
+ const fallbackPins: RoutePinPoints = { sourceX, sourceY, targetX, targetY };
93
+
84
94
  // If a connected node is being dragged, show fallback
85
95
  const isDragging =
86
96
  draggingNodeIds.size > 0 &&
@@ -89,7 +99,7 @@ export function useRoutedEdgePath(
89
99
 
90
100
  if (isDragging) {
91
101
  const [path, lx, ly] = getFallback(sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, connectorType, params.borderRadius, offset);
92
- return [path, lx, ly, false, []];
102
+ return [path, lx, ly, false, [], fallbackPins];
93
103
  }
94
104
 
95
105
  // If we have a routed path, use it (no stale check — trust the router)
@@ -99,11 +109,15 @@ export function useRoutedEdgePath(
99
109
  const controlPoints = route.points && route.points.length > 2
100
110
  ? route.points.slice(1, -1)
101
111
  : [];
102
- return [route.path, route.labelX, route.labelY, true, controlPoints];
112
+ const pins: RoutePinPoints = {
113
+ sourceX: route.sourceX, sourceY: route.sourceY,
114
+ targetX: route.targetX, targetY: route.targetY,
115
+ };
116
+ return [route.path, route.labelX, route.labelY, true, controlPoints, pins];
103
117
  }
104
118
 
105
119
  // No route yet — show fallback
106
120
  const [path, lx, ly] = getFallback(sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, connectorType, params.borderRadius, offset);
107
- return [path, lx, ly, false, []];
121
+ return [path, lx, ly, false, [], fallbackPins];
108
122
  }, [route, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, offset, connectorType, params.borderRadius, source, target, draggingNodeIds]);
109
123
  }