Merge pull request #5617 from akre54/edgeid-override

Allow getEdgeId to be overridden
This commit is contained in:
Moritz Klack
2025-11-25 10:43:58 +01:00
committed by GitHub
2 changed files with 38 additions and 4 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@xyflow/system': patch
---
Allow custom `getEdgeId` function in `addEdge` and `reconnectEdge` options to enable custom edge ID schemes.
+33 -4
View File
@@ -84,7 +84,19 @@ export function isEdgeVisible({ sourceNode, targetNode, width, height, transform
return getOverlappingArea(viewRect, boxToRect(edgeBox)) > 0; return getOverlappingArea(viewRect, boxToRect(edgeBox)) > 0;
} }
const getEdgeId = ({ source, sourceHandle, target, targetHandle }: Connection | EdgeBase): string => /**
* Type for a custom edge ID generator function.
* @public
*/
export type GetEdgeId = (params: Connection | EdgeBase) => string;
/**
* The default edge ID generator function. Generates an ID based on the source, target, and handles.
* @public
* @param params - The connection or edge to generate an ID for.
* @returns The generated edge ID.
*/
export const getEdgeId = ({ source, sourceHandle, target, targetHandle }: Connection | EdgeBase): string =>
`xy-edge__${source}${sourceHandle || ''}-${target}${targetHandle || ''}`; `xy-edge__${source}${sourceHandle || ''}-${target}${targetHandle || ''}`;
const connectionExists = (edge: EdgeBase, edges: EdgeBase[]) => { const connectionExists = (edge: EdgeBase, edges: EdgeBase[]) => {
@@ -97,11 +109,19 @@ const connectionExists = (edge: EdgeBase, edges: EdgeBase[]) => {
); );
}; };
export type AddEdgeOptions = {
/**
* Custom function to generate edge IDs. If not provided, the default `getEdgeId` function is used.
*/
getEdgeId?: GetEdgeId;
};
/** /**
* This util is a convenience function to add a new Edge to an array of edges. It also performs some validation to make sure you don't add an invalid edge or duplicate an existing one. * This util is a convenience function to add a new Edge to an array of edges. It also performs some validation to make sure you don't add an invalid edge or duplicate an existing one.
* @public * @public
* @param edgeParams - Either an `Edge` or a `Connection` you want to add. * @param edgeParams - Either an `Edge` or a `Connection` you want to add.
* @param edges - The array of all current edges. * @param edges - The array of all current edges.
* @param options - Optional configuration object.
* @returns A new array of edges with the new edge added. * @returns A new array of edges with the new edge added.
* *
* @remarks If an edge with the same `target` and `source` already exists (and the same * @remarks If an edge with the same `target` and `source` already exists (and the same
@@ -111,7 +131,8 @@ const connectionExists = (edge: EdgeBase, edges: EdgeBase[]) => {
*/ */
export const addEdge = <EdgeType extends EdgeBase>( export const addEdge = <EdgeType extends EdgeBase>(
edgeParams: EdgeType | Connection, edgeParams: EdgeType | Connection,
edges: EdgeType[] edges: EdgeType[],
options: AddEdgeOptions = {}
): EdgeType[] => { ): EdgeType[] => {
if (!edgeParams.source || !edgeParams.target) { if (!edgeParams.source || !edgeParams.target) {
devWarn('006', errorMessages['error006']()); devWarn('006', errorMessages['error006']());
@@ -119,13 +140,15 @@ export const addEdge = <EdgeType extends EdgeBase>(
return edges; return edges;
} }
const edgeIdGenerator = options.getEdgeId || getEdgeId;
let edge: EdgeType; let edge: EdgeType;
if (isEdgeBase(edgeParams)) { if (isEdgeBase(edgeParams)) {
edge = { ...edgeParams }; edge = { ...edgeParams };
} else { } else {
edge = { edge = {
...edgeParams, ...edgeParams,
id: getEdgeId(edgeParams), id: edgeIdGenerator(edgeParams),
} as EdgeType; } as EdgeType;
} }
@@ -150,6 +173,10 @@ export type ReconnectEdgeOptions = {
* @default true * @default true
*/ */
shouldReplaceId?: boolean; shouldReplaceId?: boolean;
/**
* Custom function to generate edge IDs. If not provided, the default `getEdgeId` function is used.
*/
getEdgeId?: GetEdgeId;
}; };
/** /**
@@ -190,10 +217,12 @@ export const reconnectEdge = <EdgeType extends EdgeBase>(
return edges; return edges;
} }
const edgeIdGenerator = options.getEdgeId || getEdgeId;
// Remove old edge and create the new edge with parameters of old edge. // Remove old edge and create the new edge with parameters of old edge.
const edge = { const edge = {
...rest, ...rest,
id: options.shouldReplaceId ? getEdgeId(newConnection) : oldEdgeId, id: options.shouldReplaceId ? edgeIdGenerator(newConnection) : oldEdgeId,
source: newConnection.source, source: newConnection.source,
target: newConnection.target, target: newConnection.target,
sourceHandle: newConnection.sourceHandle, sourceHandle: newConnection.sourceHandle,