From f5da8c6b75bdc302901ec99d25be60ade409ef65 Mon Sep 17 00:00:00 2001
From: Peter
Date: Mon, 4 Dec 2023 18:06:01 +0100
Subject: [PATCH 01/10] TSDoc for getViewportForBounds
---
packages/system/src/utils/general.ts | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/packages/system/src/utils/general.ts b/packages/system/src/utils/general.ts
index 2db59322..7480a5e9 100644
--- a/packages/system/src/utils/general.ts
+++ b/packages/system/src/utils/general.ts
@@ -8,8 +8,8 @@ import type {
NodeOrigin,
SnapGrid,
Transform,
- Viewport,
} from '../types';
+import { type Viewport } from '../types';
import { getNodePositionWithOrigin } from './graph';
export const clamp = (val: number, min = 0, max = 1): number => Math.min(Math.max(val, min), max);
@@ -155,6 +155,21 @@ export const rendererPointToPoint = ({ x, y }: XYPosition, [tx, ty, tScale]: Tra
};
};
+/**
+ * Returns a viewport that encloses the given bounds with optional padding.
+ * @remarks You can determine bounds eg. with {@link getNodesBounds} and {@link getBoundsOfRects}
+ * @param bounds - Bounds to fit inside viewport
+ * @param width - Width of the viewport
+ * @param height - Height of the viewport
+ * @param minZoom - Minimum zoom level of the resulting viewport
+ * @param maxZoom - Maximum zoom level of the resulting viewport
+ * @param padding - Optional padding around the bounds
+ * @returns A {@link Viewport} that encloses the given bounds which you can pass to {@link setViewport}
+ * @example
+ * const { x, y, zoomn } = getViewportForBounds(
+ { x: 0, y: 0, width: 100, height: 100},
+ 1200, 800, 0.5, 2);
+ */
export const getViewportForBounds = (
bounds: Rect,
width: number,
From 4accceb202a0ecc30ea2f527342b95e2626a497f Mon Sep 17 00:00:00 2001
From: Peter
Date: Tue, 5 Dec 2023 12:12:21 +0100
Subject: [PATCH 02/10] Added TSDocs for several public util functions &
converted comments to TSDocs for internal functions
---
.../system/src/utils/edges/bezier-edge.ts | 11 ++++
packages/system/src/utils/general.ts | 21 +++++---
packages/system/src/utils/graph.ts | 50 +++++++++++++++++--
3 files changed, 72 insertions(+), 10 deletions(-)
diff --git a/packages/system/src/utils/edges/bezier-edge.ts b/packages/system/src/utils/edges/bezier-edge.ts
index 810b07d7..a8ecae31 100644
--- a/packages/system/src/utils/edges/bezier-edge.ts
+++ b/packages/system/src/utils/edges/bezier-edge.ts
@@ -69,6 +69,17 @@ function getControlWithCurvature({ pos, x1, y1, x2, y2, c }: GetControlWithCurva
}
}
+/**
+ * Get a bezier path from source to target handle
+ * @param params.sourceX - The x position of the source handle
+ * @param params.sourceY - The y position of the source handle
+ * @param params.sourcePosition - The position of the source handle
+ * @param params.targetX - The x position of the target handle
+ * @param params.targetY - The y position of the target handle
+ * @param params.targetPosition - The position of the target handle
+ * @param params.curvature - The curvature of the bezier edge
+ * @returns A path string you can use in an SVG, the labelX and labelY position (center of path) and offsetX, offsetY between source handle and label
+ */
export function getBezierPath({
sourceX,
sourceY,
diff --git a/packages/system/src/utils/general.ts b/packages/system/src/utils/general.ts
index 7480a5e9..bc8f4dfe 100644
--- a/packages/system/src/utils/general.ts
+++ b/packages/system/src/utils/general.ts
@@ -19,8 +19,14 @@ export const clampPosition = (position: XYPosition = { x: 0, y: 0 }, extent: Coo
y: clamp(position.y, extent[0][1], extent[1][1]),
});
-// returns a number between 0 and 1 that represents the velocity of the movement
-// when the mouse is close to the edge of the canvas
+/**
+ * Calculates the velocity of panning when the mouse is close to the edge of the canvas
+ * @internal
+ * @param value - One dimensional poition of the mouse (x or y)
+ * @param min - Minimal position on canvas before panning starts
+ * @param max - Maximal position on canvas before panning starts
+ * @returns - A number between 0 and 1 that represents the velocity of panning
+ */
const calcAutoPanVelocity = (value: number, min: number, max: number): number => {
if (value < min) {
return clamp(Math.abs(value - min), 1, 50) / 50;
@@ -127,12 +133,12 @@ export const getPositionWithOrigin = ({
};
};
-export function snapPosition(position: XYPosition, snapGrid: SnapGrid = [1, 1]): XYPosition {
+export const snapPosition = (position: XYPosition, snapGrid: SnapGrid = [1, 1]): XYPosition => {
return {
x: snapGrid[0] * Math.round(position.x / snapGrid[0]),
y: snapGrid[1] * Math.round(position.y / snapGrid[1]),
};
-}
+};
export const pointToRendererPoint = (
{ x, y }: XYPosition,
@@ -157,16 +163,17 @@ export const rendererPointToPoint = ({ x, y }: XYPosition, [tx, ty, tScale]: Tra
/**
* Returns a viewport that encloses the given bounds with optional padding.
- * @remarks You can determine bounds eg. with {@link getNodesBounds} and {@link getBoundsOfRects}
+ * @public
+ * @remarks You can determine bounds of nodes with {@link getNodesBounds} and {@link getBoundsOfRects}
* @param bounds - Bounds to fit inside viewport
* @param width - Width of the viewport
* @param height - Height of the viewport
* @param minZoom - Minimum zoom level of the resulting viewport
* @param maxZoom - Maximum zoom level of the resulting viewport
* @param padding - Optional padding around the bounds
- * @returns A {@link Viewport} that encloses the given bounds which you can pass to {@link setViewport}
+ * @returns A transforned {@link Viewport} that encloses the given bounds which you can pass to e.g. {@link setViewport}
* @example
- * const { x, y, zoomn } = getViewportForBounds(
+ * const { x, y, zoom } = getViewportForBounds(
{ x: 0, y: 0, width: 100, height: 100},
1200, 800, 0.5, 2);
*/
diff --git a/packages/system/src/utils/graph.ts b/packages/system/src/utils/graph.ts
index 6a946a10..38d83dc2 100644
--- a/packages/system/src/utils/graph.ts
+++ b/packages/system/src/utils/graph.ts
@@ -26,14 +26,36 @@ import {
} from '../types';
import { errorMessages } from '../constants';
+/**
+ * Test whether an object is useable as an Edge
+ * @public
+ * @remarks In TypeScript this is a type guard that will narrow the type of whatever you pass in to Edge if it returns true
+ * @param element - The element to test
+ * @returns A boolean indicating whether the element is an Edge
+ */
export const isEdgeBase = (
element: NodeType | Connection | EdgeType
): element is EdgeType => 'id' in element && 'source' in element && 'target' in element;
+/**
+ * Test whether an object is useable as a Node
+ * @public
+ * @remarks In TypeScript this is a type guard that will narrow the type of whatever you pass in to Node if it returns true
+ * @param element - The element to test
+ * @returns A boolean indicating whether the element is an Node
+ */
export const isNodeBase = (
element: NodeType | Connection | EdgeType
): element is NodeType => 'id' in element && !('source' in element) && !('target' in element);
+/**
+ * Pass in a node, and get connected nodes where edge.source === node.id
+ * @public
+ * @param node - The node to get the connected nodes from
+ * @param nodes - The array of all nodes
+ * @param edges - The array of all edges
+ * @returns An array of nodes that are connected over eges where the source is the given node
+ */
export const getOutgoersBase = (
node: NodeType | { id: string },
nodes: NodeType[],
@@ -53,6 +75,14 @@ export const getOutgoersBase = outgoerIds.has(n.id));
};
+/**
+ * Pass in a node, and get connected nodes where edge.target === node.id
+ * @public
+ * @param node - The node to get the connected nodes from
+ * @param nodes - The array of all nodes
+ * @param edges - The array of all edges
+ * @returns An array of nodes that are connected over eges where the target is the given node
+ */
export const getIncomersBase = (
node: NodeType | { id: string },
nodes: NodeType[],
@@ -105,6 +135,14 @@ export const getNodePositionWithOrigin = (
};
};
+/**
+ * Determines a bounding box that contains all given nodes in an array
+ * @public
+ * @remarks Useful when combined with {@link getViewportForBounds} to calculate the correct transform to fit the given nodes in a viewport.
+ * @param nodes - Nodes to calculate the bounds for
+ * @param nodeOrigin - Origin of the nodes: [0, 0] - top left, [0.5, 0.5] - center
+ * @returns Bounding box enclosing all nodes
+ */
export const getNodesBounds = (nodes: NodeBase[], nodeOrigin: NodeOrigin = [0, 0]): Rect => {
if (nodes.length === 0) {
return { x: 0, y: 0, width: 0, height: 0 };
@@ -284,9 +322,15 @@ export function calcNextPosition(
};
}
-// helper function to get arrays of nodes and edges that can be deleted
-// you can pass in a list of nodes and edges that should be deleted
-// and the function only returns elements that are deletable and also handles connected nodes and child nodes
+/**
+ * Pass in nodes & edges to delete, get arrays of nodes and edges that actually can be deleted
+ * @internal
+ * @param param.nodesToRemove - The nodes to remove
+ * @param param.edgesToRemove - The edges to remove
+ * @param param.nodes - All nodes
+ * @param param.edges - All edges
+ * @returns matchingNodes: nodes that can be deleted, matchingEdges: edges that can be deleted
+ */
export function getElementsToRemove({
nodesToRemove,
edgesToRemove,
From b264c11c549db15587cac751812a51127894c396 Mon Sep 17 00:00:00 2001
From: Peter
Date: Tue, 5 Dec 2023 13:35:12 +0100
Subject: [PATCH 03/10] Added some more TSDocs for util functions
---
packages/react/src/utils/general.ts | 50 +++++++++++++++++++
.../system/src/utils/edges/bezier-edge.ts | 16 +++++-
packages/system/src/utils/edges/general.ts | 16 ++++++
.../system/src/utils/edges/smoothstep-edge.ts | 22 ++++++++
.../system/src/utils/edges/straight-edge.ts | 20 ++++++++
packages/system/src/utils/graph.ts | 6 +++
6 files changed, 128 insertions(+), 2 deletions(-)
diff --git a/packages/react/src/utils/general.ts b/packages/react/src/utils/general.ts
index e13247c1..af5443cd 100644
--- a/packages/react/src/utils/general.ts
+++ b/packages/react/src/utils/general.ts
@@ -10,10 +10,60 @@ import {
import type { Edge, Node } from '../types';
+/**
+ * Test whether an object is useable as a Node
+ * @public
+ * @remarks In TypeScript this is a type guard that will narrow the type of whatever you pass in to Node if it returns true
+ * @param element - The element to test
+ * @returns A boolean indicating whether the element is an Node
+ */
export const isNode = isNodeBase;
+
+/**
+ * Test whether an object is useable as an Edge
+ * @public
+ * @remarks In TypeScript this is a type guard that will narrow the type of whatever you pass in to Edge if it returns true
+ * @param element - The element to test
+ * @returns A boolean indicating whether the element is an Edge
+ */
export const isEdge = isEdgeBase;
+
+/**
+ * Pass in a node, and get connected nodes where edge.source === node.id
+ * @public
+ * @param node - The node to get the connected nodes from
+ * @param nodes - The array of all nodes
+ * @param edges - The array of all edges
+ * @returns An array of nodes that are connected over eges where the source is the given node
+ */
export const getOutgoers = getOutgoersBase;
+
+/**
+ * Pass in a node, and get connected nodes where edge.target === node.id
+ * @public
+ * @param node - The node to get the connected nodes from
+ * @param nodes - The array of all nodes
+ * @param edges - The array of all edges
+ * @returns An array of nodes that are connected over eges where the target is the given node
+ */
export const getIncomers = getIncomersBase;
+
+/**
+ * This util is a convenience function to add a new Edge to an array of edges
+ * @remarks It also performs some validation to make sure you don't add an invalid edge or duplicate an existing one.
+ * @public
+ * @param edgeParams - Either an Edge or a Connection you want to add
+ * @param edges - The array of all current edges
+ * @returns A new array of edges with the new edge added
+ */
export const addEdge = addEdgeBase;
+
export const updateEdge = updateEdgeBase;
+
+/**
+ * Get all connecting edges for a given set of nodes
+ * @param nodes - Nodes you want to get the connected edges for
+ * @param edges - All edges
+ * @returns Array of edges that connect any of the given nodes with each other
+ */
export const getConnectedEdges = getConnectedEdgesBase;
diff --git a/packages/system/src/utils/edges/bezier-edge.ts b/packages/system/src/utils/edges/bezier-edge.ts
index a8ecae31..640deffa 100644
--- a/packages/system/src/utils/edges/bezier-edge.ts
+++ b/packages/system/src/utils/edges/bezier-edge.ts
@@ -73,12 +73,24 @@ function getControlWithCurvature({ pos, x1, y1, x2, y2, c }: GetControlWithCurva
* Get a bezier path from source to target handle
* @param params.sourceX - The x position of the source handle
* @param params.sourceY - The y position of the source handle
- * @param params.sourcePosition - The position of the source handle
+ * @param params.sourcePosition - The position of the source handle (default: Position.Bottom)
* @param params.targetX - The x position of the target handle
* @param params.targetY - The y position of the target handle
- * @param params.targetPosition - The position of the target handle
+ * @param params.targetPosition - The position of the target handle (default: Position.Top)
* @param params.curvature - The curvature of the bezier edge
* @returns A path string you can use in an SVG, the labelX and labelY position (center of path) and offsetX, offsetY between source handle and label
+ * @example
+ * const source = { x: 0, y: 20 };
+ const target = { x: 150, y: 100 };
+
+ const [path, labelX, labelY, offsetX, offsetY] = getBezierPath({
+ sourceX: source.x,
+ sourceY: source.y,
+ sourcePosition: Position.Right,
+ targetX: target.x,
+ targetY: target.y,
+ targetPosition: Position.Left,
+});
*/
export function getBezierPath({
sourceX,
diff --git a/packages/system/src/utils/edges/general.ts b/packages/system/src/utils/edges/general.ts
index 9ffd8e24..42baa0dc 100644
--- a/packages/system/src/utils/edges/general.ts
+++ b/packages/system/src/utils/edges/general.ts
@@ -124,6 +124,14 @@ const connectionExists = (edge: EdgeBase, edges: EdgeBase[]) => {
);
};
+/**
+ * This util is a convenience function to add a new Edge to an array of edges
+ * @remarks It also performs some validation to make sure you don't add an invalid edge or duplicate an existing one.
+ * @public
+ * @param edgeParams - Either an Edge or a Connection you want to add
+ * @param edges - The array of all current edges
+ * @returns A new array of edges with the new edge added
+ */
export const addEdgeBase = (
edgeParams: EdgeType | Connection,
edges: EdgeType[]
@@ -163,6 +171,14 @@ export type UpdateEdgeOptions = {
shouldReplaceId?: boolean;
};
+/**
+ * A handy utility to update an existing Edge with new properties
+ * @param oldEdge - The edge you want to update
+ * @param newConnection - The new Connection you want to update the edge with
+ * @param edges - The array of all current edges
+ * @param options.shouldReplaceId -
+ * @returns
+ */
export const updateEdgeBase = (
oldEdge: EdgeType,
newConnection: Connection,
diff --git a/packages/system/src/utils/edges/smoothstep-edge.ts b/packages/system/src/utils/edges/smoothstep-edge.ts
index ba3e95a9..40954457 100644
--- a/packages/system/src/utils/edges/smoothstep-edge.ts
+++ b/packages/system/src/utils/edges/smoothstep-edge.ts
@@ -190,6 +190,28 @@ function getBend(a: XYPosition, b: XYPosition, c: XYPosition, size: number): str
return `L ${x},${y + bendSize * yDir}Q ${x},${y} ${x + bendSize * xDir},${y}`;
}
+/**
+ * Get a smooth step path from source to target handle
+ * @param params.sourceX - The x position of the source handle
+ * @param params.sourceY - The y position of the source handle
+ * @param params.sourcePosition - The position of the source handle (default: Position.Bottom)
+ * @param params.targetX - The x position of the target handle
+ * @param params.targetY - The y position of the target handle
+ * @param params.targetPosition - The position of the target handle (default: Position.Top)
+ * @returns A path string you can use in an SVG, the labelX and labelY position (center of path) and offsetX, offsetY between source handle and label
+ * @example
+ * const source = { x: 0, y: 20 };
+ const target = { x: 150, y: 100 };
+
+ const [path, labelX, labelY, offsetX, offsetY] = getSmoothStepPath({
+ sourceX: source.x,
+ sourceY: source.y,
+ sourcePosition: Position.Right,
+ targetX: target.x,
+ targetY: target.y,
+ targetPosition: Position.Left,
+ });
+ */
export function getSmoothStepPath({
sourceX,
sourceY,
diff --git a/packages/system/src/utils/edges/straight-edge.ts b/packages/system/src/utils/edges/straight-edge.ts
index 9cc6d928..9940bfea 100644
--- a/packages/system/src/utils/edges/straight-edge.ts
+++ b/packages/system/src/utils/edges/straight-edge.ts
@@ -7,6 +7,26 @@ export type GetStraightPathParams = {
targetY: number;
};
+/**
+ * Get a straight path from source to target handle
+ * @param params.sourceX - The x position of the source handle
+ * @param params.sourceY - The y position of the source handle
+ * @param params.targetX - The x position of the target handle
+ * @param params.targetY - The y position of the target handle
+ * @returns A path string you can use in an SVG, the labelX and labelY position (center of path) and offsetX, offsetY between source handle and label
+ * @example
+ * const source = { x: 0, y: 20 };
+ const target = { x: 150, y: 100 };
+
+ const [path, labelX, labelY, offsetX, offsetY] = getStraightPath({
+ sourceX: source.x,
+ sourceY: source.y,
+ sourcePosition: Position.Right,
+ targetX: target.x,
+ targetY: target.y,
+ targetPosition: Position.Left,
+ });
+ */
export function getStraightPath({
sourceX,
sourceY,
diff --git a/packages/system/src/utils/graph.ts b/packages/system/src/utils/graph.ts
index 38d83dc2..4732ff0b 100644
--- a/packages/system/src/utils/graph.ts
+++ b/packages/system/src/utils/graph.ts
@@ -208,6 +208,12 @@ export const getNodesInside = (
return visibleNodes;
};
+/**
+ * Get all connecting edges for a given set of nodes
+ * @param nodes - Nodes you want to get the connected edges for
+ * @param edges - All edges
+ * @returns Array of edges that connect any of the given nodes with each other
+ */
export const getConnectedEdgesBase = (
nodes: NodeType[],
edges: EdgeType[]
From 95dfd1d6deef2a3ac29d800e73baeab8d8ec7915 Mon Sep 17 00:00:00 2001
From: Peter
Date: Tue, 5 Dec 2023 13:46:59 +0100
Subject: [PATCH 04/10] Finished TSDocs for util functions in React
---
packages/react/src/utils/general.ts | 8 ++++++++
packages/system/src/utils/edges/general.ts | 6 +++---
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/packages/react/src/utils/general.ts b/packages/react/src/utils/general.ts
index af5443cd..aa96ff92 100644
--- a/packages/react/src/utils/general.ts
+++ b/packages/react/src/utils/general.ts
@@ -58,6 +58,14 @@ export const getIncomers = getIncomersBase;
*/
export const addEdge = addEdgeBase;
+/**
+ * A handy utility to update an existing Edge with new properties
+ * @param oldEdge - The edge you want to update
+ * @param newConnection - The new connection you want to update the edge with
+ * @param edges - The array of all current edges
+ * @param options.shouldReplaceId - should the id of the old edge be replaced with the new connection id
+ * @returns the updated edges array
+ */
export const updateEdge = updateEdgeBase;
/**
diff --git a/packages/system/src/utils/edges/general.ts b/packages/system/src/utils/edges/general.ts
index 42baa0dc..bfadb743 100644
--- a/packages/system/src/utils/edges/general.ts
+++ b/packages/system/src/utils/edges/general.ts
@@ -174,10 +174,10 @@ export type UpdateEdgeOptions = {
/**
* A handy utility to update an existing Edge with new properties
* @param oldEdge - The edge you want to update
- * @param newConnection - The new Connection you want to update the edge with
+ * @param newConnection - The new connection you want to update the edge with
* @param edges - The array of all current edges
- * @param options.shouldReplaceId -
- * @returns
+ * @param options.shouldReplaceId - should the id of the old edge be replaced with the new connection id
+ * @returns the updated edges array
*/
export const updateEdgeBase = (
oldEdge: EdgeType,
From 8ee3fb64ed805b405c7c6c9476f8ba8f3a4a76c8 Mon Sep 17 00:00:00 2001
From: Peter
Date: Tue, 5 Dec 2023 13:48:49 +0100
Subject: [PATCH 05/10] Added TSDoc for util functions in svelte
---
packages/svelte/src/lib/utils/index.ts | 58 ++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/packages/svelte/src/lib/utils/index.ts b/packages/svelte/src/lib/utils/index.ts
index 23b29448..a44f471d 100644
--- a/packages/svelte/src/lib/utils/index.ts
+++ b/packages/svelte/src/lib/utils/index.ts
@@ -10,10 +10,68 @@ import {
import type { Edge, Node } from '$lib/types';
+/**
+ * Test whether an object is useable as a Node
+ * @public
+ * @remarks In TypeScript this is a type guard that will narrow the type of whatever you pass in to Node if it returns true
+ * @param element - The element to test
+ * @returns A boolean indicating whether the element is an Node
+ */
export const isNode = isNodeBase;
+
+/**
+ * Test whether an object is useable as an Edge
+ * @public
+ * @remarks In TypeScript this is a type guard that will narrow the type of whatever you pass in to Edge if it returns true
+ * @param element - The element to test
+ * @returns A boolean indicating whether the element is an Edge
+ */
export const isEdge = isEdgeBase;
+
+/**
+ * Pass in a node, and get connected nodes where edge.source === node.id
+ * @public
+ * @param node - The node to get the connected nodes from
+ * @param nodes - The array of all nodes
+ * @param edges - The array of all edges
+ * @returns An array of nodes that are connected over eges where the source is the given node
+ */
export const getOutgoers = getOutgoersBase;
+
+/**
+ * Pass in a node, and get connected nodes where edge.target === node.id
+ * @public
+ * @param node - The node to get the connected nodes from
+ * @param nodes - The array of all nodes
+ * @param edges - The array of all edges
+ * @returns An array of nodes that are connected over eges where the target is the given node
+ */
export const getIncomers = getIncomersBase;
+
+/**
+ * This util is a convenience function to add a new Edge to an array of edges
+ * @remarks It also performs some validation to make sure you don't add an invalid edge or duplicate an existing one.
+ * @public
+ * @param edgeParams - Either an Edge or a Connection you want to add
+ * @param edges - The array of all current edges
+ * @returns A new array of edges with the new edge added
+ */
export const addEdge = addEdgeBase;
+
+/**
+ * A handy utility to update an existing Edge with new properties
+ * @param oldEdge - The edge you want to update
+ * @param newConnection - The new connection you want to update the edge with
+ * @param edges - The array of all current edges
+ * @param options.shouldReplaceId - should the id of the old edge be replaced with the new connection id
+ * @returns the updated edges array
+ */
export const updateEdge = updateEdgeBase;
+
+/**
+ * Get all connecting edges for a given set of nodes
+ * @param nodes - Nodes you want to get the connected edges for
+ * @param edges - All edges
+ * @returns Array of edges that connect any of the given nodes with each other
+ */
export const getConnectedEdges = getConnectedEdgesBase;
From 46815e546ae03dc4b6f644cecf961fbb93c6b2cd Mon Sep 17 00:00:00 2001
From: Peter
Date: Tue, 5 Dec 2023 14:26:55 +0100
Subject: [PATCH 06/10] TSDocs for applyNodeChanges & applyEdgeChanges
---
packages/react/src/utils/changes.ts | 40 +++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/packages/react/src/utils/changes.ts b/packages/react/src/utils/changes.ts
index c113ebe1..0cf87e6f 100644
--- a/packages/react/src/utils/changes.ts
+++ b/packages/react/src/utils/changes.ts
@@ -139,10 +139,50 @@ function applyChanges(changes: any[], elements: any[]): any[] {
}, initElements);
}
+/**
+ * Drop in function that applies node changes to an array of nodes.
+ * @public
+ * @remarks Various events on the component can produce an {@link NodeChange} that describes how to update the edges of your flow in some way.
+ If you don't need any custom behaviour, this util can be used to take an array of these changes and apply them to your edges.
+ * @param changes - Array of changes to apply
+ * @param nodes - Array of nodes to apply the changes to
+ * @returns Array of updated nodes
+ * @example
+ * const onNodesChange = useCallback(
+ (changes) => {
+ setNodes((oldNodes) => applyNodeChanges(changes, oldNodes));
+ },
+ [setNodes],
+ );
+
+ return (
+
+ );
+ */
export function applyNodeChanges(changes: NodeChange[], nodes: Node[]): Node[] {
return applyChanges(changes, nodes) as Node[];
}
+/**
+ * Drop in function that applies edge changes to an array of edges.
+ * @public
+ * @remarks Various events on the component can produce an {@link EdgeChange} that describes how to update the edges of your flow in some way.
+ If you don't need any custom behaviour, this util can be used to take an array of these changes and apply them to your edges.
+ * @param changes - Array of changes to apply
+ * @param edges - Array of edge to apply the changes to
+ * @returns Array of updated edges
+ * @example
+ * const onEdgesChange = useCallback(
+ (changes) => {
+ setEdges((oldEdges) => applyEdgeChanges(changes, oldEdges));
+ },
+ [setEdges],
+ );
+
+ return (
+
+ );
+ */
export function applyEdgeChanges(changes: EdgeChange[], edges: Edge[]): Edge[] {
return applyChanges(changes, edges) as Edge[];
}
From ba8ee0272ac937709068e5b53135ff8d3717562b Mon Sep 17 00:00:00 2001
From: moklick
Date: Wed, 6 Dec 2023 15:56:17 +0100
Subject: [PATCH 07/10] refactor(types): cleanup edge types
---
packages/react/src/types/component-props.ts | 3 +-
packages/react/src/types/edges.ts | 75 ++++++++++++---------
packages/react/src/types/nodes.ts | 69 +++++++++++--------
packages/svelte/src/lib/types/edges.ts | 49 ++++++++------
packages/system/src/types/edges.ts | 3 +-
5 files changed, 117 insertions(+), 82 deletions(-)
diff --git a/packages/react/src/types/component-props.ts b/packages/react/src/types/component-props.ts
index 770432f5..09f9a582 100644
--- a/packages/react/src/types/component-props.ts
+++ b/packages/react/src/types/component-props.ts
@@ -20,6 +20,7 @@ import type {
OnError,
IsValidConnection,
ColorMode,
+ SnapGrid,
} from '@xyflow/system';
import type {
@@ -110,7 +111,7 @@ export type ReactFlowProps = Omit, 'onError'> & {
multiSelectionKeyCode?: KeyCode | null;
zoomActivationKeyCode?: KeyCode | null;
snapToGrid?: boolean;
- snapGrid?: [number, number];
+ snapGrid?: SnapGrid;
onlyRenderVisibleElements?: boolean;
nodesDraggable?: boolean;
nodesConnectable?: boolean;
diff --git a/packages/react/src/types/edges.ts b/packages/react/src/types/edges.ts
index 287c277d..fecd7c7b 100644
--- a/packages/react/src/types/edges.ts
+++ b/packages/react/src/types/edges.ts
@@ -13,7 +13,6 @@ import type {
HandleElement,
ConnectionStatus,
EdgePosition,
- Optional,
StepPathOptions,
} from '@xyflow/system';
@@ -30,13 +29,13 @@ export type EdgeLabelOptions = {
export type EdgeUpdatable = boolean | HandleType;
-export type DefaultEdge = EdgeBase & {
- style?: CSSProperties;
- className?: string;
- sourceNode?: Node;
- targetNode?: Node;
- updatable?: EdgeUpdatable;
-} & EdgeLabelOptions;
+export type DefaultEdge = EdgeBase &
+ EdgeLabelOptions & {
+ style?: CSSProperties;
+ className?: string;
+ updatable?: EdgeUpdatable;
+ focusable?: boolean;
+ };
type SmoothStepEdgeType = DefaultEdge & {
type: 'smoothstep';
@@ -53,6 +52,9 @@ type StepEdgeType = DefaultEdge & {
pathOptions?: StepPathOptions;
};
+/**
+ * The Edge type is mainly used for the `edges` that get passed to the ReactFlow component.
+ */
export type Edge = DefaultEdge | SmoothStepEdgeType | BezierEdgeType | StepEdgeType;
export type EdgeMouseHandler = (event: ReactMouseEvent, edge: Edge) => void;
@@ -85,45 +87,58 @@ export type EdgeTextProps = HTMLAttributes &
y: number;
};
-// props that get passed to a custom edge
+/**
+ * Custom edge component props.
+ */
export type EdgeProps = Pick<
Edge,
'id' | 'animated' | 'data' | 'style' | 'selected' | 'source' | 'target'
> &
- Pick &
EdgePosition &
EdgeLabelOptions & {
+ interactionWidth?: number;
+ sourceHandleId?: string | null;
+ targetHandleId?: string | null;
markerStart?: string;
markerEnd?: string;
// @TODO: how can we get better types for pathOptions?
pathOptions?: any;
};
-export type BaseEdgeProps = Pick &
+/**
+ * BaseEdge component props.
+ */
+export type BaseEdgeProps = EdgeLabelOptions & {
+ id?: string;
+ interactionWidth?: number;
+ labelX?: number;
+ labelY?: number;
+ markerStart?: string;
+ markerEnd?: string;
+ path: string;
+ style?: CSSProperties;
+};
+
+export type EdgeComponentProps = EdgePosition &
EdgeLabelOptions & {
- id?: string;
- labelX?: number;
- labelY?: number;
- path: string;
+ id?: EdgeProps['id'];
+ markerStart?: EdgeProps['markerStart'];
+ markerEnd?: EdgeProps['markerEnd'];
+ interactionWidth?: EdgeProps['interactionWidth'];
+ style?: EdgeProps['style'];
+ sourceHandleId?: EdgeProps['sourceHandleId'];
+ targetHandleId?: EdgeProps['targetHandleId'];
};
-export type EdgeComponentProps = Optional, 'source' | 'target'>, 'id'>;
-
-export type StraightEdgeProps = Omit, 'sourcePosition' | 'targetPosition'>;
-
-export type SmoothStepEdgeProps = EdgeComponentProps & {
- pathOptions?: SmoothStepPathOptions;
+export type EdgeComponentWithPathOptions = EdgeComponentProps & {
+ pathOptions?: PathOptions;
};
-export type BezierEdgeProps = EdgeComponentProps & {
- pathOptions?: BezierPathOptions;
-};
-
-export type StepEdgeProps = EdgeComponentProps & {
- pathOptions?: StepPathOptions;
-};
-
-export type SimpleBezierEdgeProps = EdgeComponentProps;
+export type BezierEdgeProps = EdgeComponentWithPathOptions;
+export type SmoothStepEdgeProps = EdgeComponentWithPathOptions;
+export type StepEdgeProps = EdgeComponentWithPathOptions;
+export type StraightEdgeProps = Omit;
+export type SimpleBezierEdgeProps = EdgeComponentProps;
export type OnEdgeUpdateFunc = (oldEdge: Edge, newConnection: Connection) => void;
diff --git a/packages/react/src/types/nodes.ts b/packages/react/src/types/nodes.ts
index 29548666..4d10b76b 100644
--- a/packages/react/src/types/nodes.ts
+++ b/packages/react/src/types/nodes.ts
@@ -1,12 +1,25 @@
import type { CSSProperties, MouseEvent as ReactMouseEvent } from 'react';
import type { NodeBase, XYPosition } from '@xyflow/system';
+/**
+ * The node data structure that gets used for the nodes prop.
+ * @public
+ */
export type Node = NodeBase<
NodeData,
NodeType
> & {
+ /**
+ * Inline style object
+ */
style?: CSSProperties;
+ /**
+ * Inline style object
+ */
className?: string;
+ /**
+ * Inline style object
+ */
resizing?: boolean;
};
@@ -17,30 +30,32 @@ export type SelectionDragHandler = (event: ReactMouseEvent, nodes: Node[]) => vo
export type WrapNodeProps = Pick<
Node,
'id' | 'data' | 'style' | 'className' | 'dragHandle' | 'sourcePosition' | 'targetPosition' | 'hidden' | 'ariaLabel'
-> &
- Required, 'selected' | 'type' | 'zIndex'>> & {
- isConnectable: boolean;
- xPos: number;
- yPos: number;
- xPosOrigin: number;
- yPosOrigin: number;
- positionAbsolute: XYPosition;
- initialized: boolean;
- isSelectable: boolean;
- isDraggable: boolean;
- isFocusable: boolean;
- onClick?: NodeMouseHandler;
- onDoubleClick?: NodeMouseHandler;
- onMouseEnter?: NodeMouseHandler;
- onMouseMove?: NodeMouseHandler;
- onMouseLeave?: NodeMouseHandler;
- onContextMenu?: NodeMouseHandler;
- resizeObserver: ResizeObserver | null;
- isParent: boolean;
- noDragClassName: string;
- noPanClassName: string;
- rfId: string;
- disableKeyboardA11y: boolean;
- width?: number;
- height?: number;
- };
+> & {
+ type: string;
+ selected: boolean;
+ zIndex: number;
+ isConnectable: boolean;
+ xPos: number;
+ yPos: number;
+ xPosOrigin: number;
+ yPosOrigin: number;
+ positionAbsolute: XYPosition;
+ initialized: boolean;
+ isSelectable: boolean;
+ isDraggable: boolean;
+ isFocusable: boolean;
+ onClick?: NodeMouseHandler;
+ onDoubleClick?: NodeMouseHandler;
+ onMouseEnter?: NodeMouseHandler;
+ onMouseMove?: NodeMouseHandler;
+ onMouseLeave?: NodeMouseHandler;
+ onContextMenu?: NodeMouseHandler;
+ resizeObserver: ResizeObserver | null;
+ isParent: boolean;
+ noDragClassName: string;
+ noPanClassName: string;
+ rfId: string;
+ disableKeyboardA11y: boolean;
+ width?: number;
+ height?: number;
+};
diff --git a/packages/svelte/src/lib/types/edges.ts b/packages/svelte/src/lib/types/edges.ts
index 3f1f0e8d..c1d3778d 100644
--- a/packages/svelte/src/lib/types/edges.ts
+++ b/packages/svelte/src/lib/types/edges.ts
@@ -6,13 +6,12 @@ import type {
DefaultEdgeOptionsBase,
EdgePosition,
SmoothStepPathOptions,
- Optional,
StepPathOptions
} from '@xyflow/system';
import type { Node } from '$lib/types';
-export type DefaultEdge = Omit, 'focusable'> & {
+export type DefaultEdge = EdgeBase & {
label?: string;
labelStyle?: string;
style?: string;
@@ -34,12 +33,18 @@ type StepEdgeType = DefaultEdge & {
pathOptions?: StepPathOptions;
};
+/**
+ * The Edge type is mainly used for the `edges` that get passed to the SvelteFlow component.
+ */
export type Edge =
| DefaultEdge
| SmoothStepEdgeType
| BezierEdgeType
| StepEdgeType;
+/**
+ * Custom edge component props.
+ */
export type EdgeProps = Omit, 'sourceHandle' | 'targetHandle' | 'type'> &
EdgePosition & {
markerStart?: string;
@@ -48,30 +53,30 @@ export type EdgeProps = Omit, 'sourceHandle' | 'targetHandle' |
targetHandleId?: string | null;
};
-export type EdgeComponentProps = Optional<
- Omit<
- EdgeProps,
- 'source' | 'target' | 'sourceHandleId' | 'targetHandleId' | 'animated' | 'selected' | 'data'
- >,
- 'id'
->;
-
-export type BezierEdgeProps = EdgeComponentProps & {
- pathOptions?: BezierPathOptions;
+export type EdgeComponentProps = EdgePosition & {
+ id?: EdgeProps['id'];
+ hidden?: EdgeProps['hidden'];
+ deletable?: EdgeProps['deletable'];
+ selectable?: EdgeProps['selectable'];
+ markerStart?: EdgeProps['markerStart'];
+ markerEnd?: EdgeProps['markerEnd'];
+ zIndex?: EdgeProps['zIndex'];
+ ariaLabel?: EdgeProps['ariaLabel'];
+ interactionWidth?: EdgeProps['interactionWidth'];
+ label?: EdgeProps['label'];
+ labelStyle?: EdgeProps['labelStyle'];
+ style?: EdgeProps['style'];
+ class?: EdgeProps['class'];
};
-export type SmoothStepEdgeProps = EdgeComponentProps & {
- pathOptions?: SmoothStepPathOptions;
+export type EdgeComponentWithPathOptions = EdgeComponentProps & {
+ pathOptions?: PathOptions;
};
-export type StepEdgeProps = EdgeComponentProps & {
- pathOptions?: StepPathOptions;
-};
-
-export type StraightEdgeProps = Omit<
- EdgeComponentProps,
- 'sourcePosition' | 'targetPosition'
->;
+export type BezierEdgeProps = EdgeComponentWithPathOptions;
+export type SmoothStepEdgeProps = EdgeComponentWithPathOptions;
+export type StepEdgeProps = EdgeComponentWithPathOptions;
+export type StraightEdgeProps = Omit;
export type EdgeTypes = Record>>;
diff --git a/packages/system/src/types/edges.ts b/packages/system/src/types/edges.ts
index 65c8e641..5455b57a 100644
--- a/packages/system/src/types/edges.ts
+++ b/packages/system/src/types/edges.ts
@@ -19,7 +19,6 @@ export type EdgeBase = {
zIndex?: number;
ariaLabel?: string;
interactionWidth?: number;
- focusable?: boolean;
};
export type SmoothStepPathOptions = {
@@ -37,7 +36,7 @@ export type BezierPathOptions = {
export type DefaultEdgeOptionsBase = Omit<
EdgeType,
- 'id' | 'source' | 'target' | 'sourceHandle' | 'targetHandle' | 'sourceNode' | 'targetNode'
+ 'id' | 'source' | 'target' | 'sourceHandle' | 'targetHandle'
>;
export enum ConnectionLineType {
From 10f31e79e66419ce0280113caa50be5adb07de86 Mon Sep 17 00:00:00 2001
From: moklick
Date: Thu, 7 Dec 2023 12:24:03 +0100
Subject: [PATCH 08/10] refactor(types): use custom node type as generic
---
.../additional-components/MiniMap/types.ts | 16 ++---
packages/react/src/hooks/useNodes.ts | 4 +-
.../react/src/hooks/useNodesEdgesState.ts | 12 ++--
packages/react/src/hooks/useReactFlow.ts | 59 ++++++++--------
packages/react/src/types/changes.ts | 16 ++---
packages/react/src/types/edges.ts | 34 +++++++++-
packages/react/src/types/general.ts | 13 ++--
packages/react/src/types/instance.ts | 67 ++++++++++---------
packages/react/src/types/nodes.ts | 21 +++---
packages/react/src/utils/changes.ts | 8 +--
packages/svelte/src/lib/types/edges.ts | 18 +++++
packages/svelte/src/lib/types/nodes.ts | 8 +--
12 files changed, 160 insertions(+), 116 deletions(-)
diff --git a/packages/react/src/additional-components/MiniMap/types.ts b/packages/react/src/additional-components/MiniMap/types.ts
index 5667f7a8..3b24b08d 100644
--- a/packages/react/src/additional-components/MiniMap/types.ts
+++ b/packages/react/src/additional-components/MiniMap/types.ts
@@ -4,12 +4,12 @@ import type { PanelPosition, XYPosition } from '@xyflow/system';
import type { Node } from '../../types';
-export type GetMiniMapNodeAttribute = (node: Node) => string;
+export type GetMiniMapNodeAttribute = (node: NodeType) => string;
-export type MiniMapProps = Omit, 'onClick'> & {
- nodeColor?: string | GetMiniMapNodeAttribute;
- nodeStrokeColor?: string | GetMiniMapNodeAttribute;
- nodeClassName?: string | GetMiniMapNodeAttribute;
+export type MiniMapProps = Omit, 'onClick'> & {
+ nodeColor?: string | GetMiniMapNodeAttribute;
+ nodeStrokeColor?: string | GetMiniMapNodeAttribute;
+ nodeClassName?: string | GetMiniMapNodeAttribute;
nodeBorderRadius?: number;
nodeStrokeWidth?: number;
nodeComponent?: ComponentType;
@@ -18,7 +18,7 @@ export type MiniMapProps = Omit, '
maskStrokeWidth?: number;
position?: PanelPosition;
onClick?: (event: MouseEvent, position: XYPosition) => void;
- onNodeClick?: (event: MouseEvent, node: Node) => void;
+ onNodeClick?: (event: MouseEvent, node: NodeType) => void;
pannable?: boolean;
zoomable?: boolean;
ariaLabel?: string | null;
@@ -27,8 +27,8 @@ export type MiniMapProps = Omit, '
offsetScale?: number;
};
-export type MiniMapNodes = Pick<
- MiniMapProps,
+export type MiniMapNodes = Pick<
+ MiniMapProps,
'nodeColor' | 'nodeStrokeColor' | 'nodeClassName' | 'nodeBorderRadius' | 'nodeStrokeWidth' | 'nodeComponent'
> & {
onClick?: (event: MouseEvent, nodeId: string) => void;
diff --git a/packages/react/src/hooks/useNodes.ts b/packages/react/src/hooks/useNodes.ts
index cc75f142..1ccd1d85 100644
--- a/packages/react/src/hooks/useNodes.ts
+++ b/packages/react/src/hooks/useNodes.ts
@@ -5,8 +5,8 @@ import type { Node, ReactFlowState } from '../types';
const nodesSelector = (state: ReactFlowState) => state.nodes;
-function useNodes(): Node[] {
- const nodes = useStore(nodesSelector, shallow);
+function useNodes(): NodeType[] {
+ const nodes = useStore(nodesSelector, shallow) as NodeType[];
return nodes;
}
diff --git a/packages/react/src/hooks/useNodesEdgesState.ts b/packages/react/src/hooks/useNodesEdgesState.ts
index 19754aa4..5255c7dd 100644
--- a/packages/react/src/hooks/useNodesEdgesState.ts
+++ b/packages/react/src/hooks/useNodesEdgesState.ts
@@ -11,14 +11,14 @@ type OnChange = (changes: ChangesType[]) => void;
// const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
function createUseItemsState(
applyChanges: ApplyChanges
-): (
- initialItems: Node[]
-) => [Node[], Dispatch[]>>, OnChange];
+): (
+ initialItems: NodeType[]
+) => [NodeType[], Dispatch>, OnChange];
function createUseItemsState(
applyChanges: ApplyChanges
-): (
- initialItems: Edge[]
-) => [Edge[], Dispatch[]>>, OnChange];
+): (
+ initialItems: EdgeType[]
+) => [EdgeType[], Dispatch>, OnChange];
function createUseItemsState(
applyChanges: ApplyChanges
): (initialItems: any[]) => [any[], Dispatch>, OnChange] {
diff --git a/packages/react/src/hooks/useReactFlow.ts b/packages/react/src/hooks/useReactFlow.ts
index 44e29c14..2875ca03 100644
--- a/packages/react/src/hooks/useReactFlow.ts
+++ b/packages/react/src/hooks/useReactFlow.ts
@@ -26,31 +26,34 @@ import type {
} from '../types';
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
-export default function useReactFlow(): ReactFlowInstance {
+export default function useReactFlow(): ReactFlowInstance<
+ NodeType,
+ EdgeType
+> {
const viewportHelper = useViewportHelper();
const store = useStoreApi();
- const getNodes = useCallback>(() => {
- return store.getState().nodes.map((n) => ({ ...n }));
+ const getNodes = useCallback>(() => {
+ return store.getState().nodes.map((n) => ({ ...n })) as NodeType[];
}, []);
- const getNode = useCallback>((id) => {
- return store.getState().nodeLookup.get(id);
+ const getNode = useCallback>((id) => {
+ return store.getState().nodeLookup.get(id) as NodeType;
}, []);
- const getEdges = useCallback>(() => {
+ const getEdges = useCallback>(() => {
const { edges = [] } = store.getState();
- return edges.map((e) => ({ ...e }));
+ return edges.map((e) => ({ ...e })) as EdgeType[];
}, []);
- const getEdge = useCallback>((id) => {
+ const getEdge = useCallback>((id) => {
const { edges = [] } = store.getState();
- return edges.find((e) => e.id === id);
+ return edges.find((e) => e.id === id) as EdgeType;
}, []);
- const setNodes = useCallback>((payload) => {
+ const setNodes = useCallback>((payload) => {
const { nodes, setNodes, hasDefaultNodes, onNodesChange } = store.getState();
- const nextNodes = typeof payload === 'function' ? payload(nodes) : payload;
+ const nextNodes = typeof payload === 'function' ? payload(nodes as NodeType[]) : payload;
if (hasDefaultNodes) {
setNodes(nextNodes);
@@ -58,14 +61,14 @@ export default function useReactFlow(): ReactFlo
const changes =
nextNodes.length === 0
? nodes.map((node) => ({ type: 'remove', id: node.id } as NodeRemoveChange))
- : nextNodes.map((node) => ({ item: node, type: 'reset' } as NodeResetChange));
+ : nextNodes.map((node) => ({ item: node, type: 'reset' } as NodeResetChange));
onNodesChange(changes);
}
}, []);
- const setEdges = useCallback>((payload) => {
+ const setEdges = useCallback>((payload) => {
const { edges = [], setEdges, hasDefaultEdges, onEdgesChange } = store.getState();
- const nextEdges = typeof payload === 'function' ? payload(edges) : payload;
+ const nextEdges = typeof payload === 'function' ? payload(edges as EdgeType[]) : payload;
if (hasDefaultEdges) {
setEdges(nextEdges);
@@ -73,12 +76,12 @@ export default function useReactFlow(): ReactFlo
const changes =
nextEdges.length === 0
? edges.map((edge) => ({ type: 'remove', id: edge.id } as EdgeRemoveChange))
- : nextEdges.map((edge) => ({ item: edge, type: 'reset' } as EdgeResetChange));
+ : nextEdges.map((edge) => ({ item: edge, type: 'reset' } as EdgeResetChange));
onEdgesChange(changes);
}
}, []);
- const addNodes = useCallback>((payload) => {
+ const addNodes = useCallback>((payload) => {
const nodes = Array.isArray(payload) ? payload : [payload];
const { nodes: currentNodes, hasDefaultNodes, onNodesChange, setNodes } = store.getState();
@@ -86,29 +89,29 @@ export default function useReactFlow(): ReactFlo
const nextNodes = [...currentNodes, ...nodes];
setNodes(nextNodes);
} else if (onNodesChange) {
- const changes = nodes.map((node) => ({ item: node, type: 'add' } as NodeAddChange));
+ const changes = nodes.map((node) => ({ item: node, type: 'add' } as NodeAddChange));
onNodesChange(changes);
}
}, []);
- const addEdges = useCallback>((payload) => {
+ const addEdges = useCallback>((payload) => {
const nextEdges = Array.isArray(payload) ? payload : [payload];
const { edges = [], setEdges, hasDefaultEdges, onEdgesChange } = store.getState();
if (hasDefaultEdges) {
setEdges([...edges, ...nextEdges]);
} else if (onEdgesChange) {
- const changes = nextEdges.map((edge) => ({ item: edge, type: 'add' } as EdgeAddChange));
+ const changes = nextEdges.map((edge) => ({ item: edge, type: 'add' } as EdgeAddChange));
onEdgesChange(changes);
}
}, []);
- const toObject = useCallback>(() => {
+ const toObject = useCallback>(() => {
const { nodes = [], edges = [], transform } = store.getState();
const [x, y, zoom] = transform;
return {
- nodes: nodes.map((n) => ({ ...n })),
- edges: edges.map((e) => ({ ...e })),
+ nodes: nodes.map((n) => ({ ...n })) as NodeType[],
+ edges: edges.map((e) => ({ ...e })) as EdgeType[],
viewport: {
x,
y,
@@ -180,11 +183,9 @@ export default function useReactFlow(): ReactFlo
}, []);
const getNodeRect = useCallback(
- (
- nodeOrRect: Node | { id: Node['id'] } | Rect
- ): [Rect | null, Node | null | undefined, boolean] => {
+ (nodeOrRect: NodeType | { id: Node['id'] } | Rect): [Rect | null, NodeType | null | undefined, boolean] => {
const isRect = isRectObject(nodeOrRect);
- const node = isRect ? null : store.getState().nodeLookup.get(nodeOrRect.id);
+ const node = isRect ? null : (store.getState().nodeLookup.get(nodeOrRect.id) as NodeType);
if (!isRect && !node) {
[null, null, isRect];
@@ -197,7 +198,7 @@ export default function useReactFlow(): ReactFlo
[]
);
- const getIntersectingNodes = useCallback>(
+ const getIntersectingNodes = useCallback>(
(nodeOrRect, partially = true, nodes) => {
const [nodeRect, node, isRect] = getNodeRect(nodeOrRect);
@@ -215,12 +216,12 @@ export default function useReactFlow(): ReactFlo
const partiallyVisible = partially && overlappingArea > 0;
return partiallyVisible || overlappingArea >= nodeRect.width * nodeRect.height;
- });
+ }) as NodeType[];
},
[]
);
- const isNodeIntersecting = useCallback>(
+ const isNodeIntersecting = useCallback>(
(nodeOrRect, area, partially = true) => {
const [nodeRect] = getNodeRect(nodeOrRect);
diff --git a/packages/react/src/types/changes.ts b/packages/react/src/types/changes.ts
index 69ee0f1f..440a4c6b 100644
--- a/packages/react/src/types/changes.ts
+++ b/packages/react/src/types/changes.ts
@@ -30,13 +30,13 @@ export type NodeRemoveChange = {
type: 'remove';
};
-export type NodeAddChange = {
- item: Node;
+export type NodeAddChange = {
+ item: NodeType;
type: 'add';
};
-export type NodeResetChange = {
- item: Node;
+export type NodeResetChange = {
+ item: NodeType;
type: 'reset';
};
@@ -50,12 +50,12 @@ export type NodeChange =
export type EdgeSelectionChange = NodeSelectionChange;
export type EdgeRemoveChange = NodeRemoveChange;
-export type EdgeAddChange = {
- item: Edge;
+export type EdgeAddChange = {
+ item: EdgeType;
type: 'add';
};
-export type EdgeResetChange = {
- item: Edge;
+export type EdgeResetChange = {
+ item: EdgeType;
type: 'reset';
};
export type EdgeChange = EdgeSelectionChange | EdgeRemoveChange | EdgeAddChange | EdgeResetChange;
diff --git a/packages/react/src/types/edges.ts b/packages/react/src/types/edges.ts
index fecd7c7b..836087fc 100644
--- a/packages/react/src/types/edges.ts
+++ b/packages/react/src/types/edges.ts
@@ -1,6 +1,13 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
-import type { CSSProperties, HTMLAttributes, ReactNode, MouseEvent as ReactMouseEvent, ComponentType } from 'react';
+import type {
+ CSSProperties,
+ HTMLAttributes,
+ ReactNode,
+ MouseEvent as ReactMouseEvent,
+ ComponentType,
+ MemoExoticComponent,
+} from 'react';
import type {
EdgeBase,
BezierPathOptions,
@@ -119,6 +126,9 @@ export type BaseEdgeProps = EdgeLabelOptions & {
style?: CSSProperties;
};
+/**
+ * Helper type for edge components that get exported by the library.
+ */
export type EdgeComponentProps = EdgePosition &
EdgeLabelOptions & {
id?: EdgeProps['id'];
@@ -134,10 +144,29 @@ export type EdgeComponentWithPathOptions = EdgeComponentProps & {
pathOptions?: PathOptions;
};
+/**
+ * BezierEdge component props
+ */
export type BezierEdgeProps = EdgeComponentWithPathOptions;
+
+/**
+ * SmoothStepEdge component props
+ */
export type SmoothStepEdgeProps = EdgeComponentWithPathOptions;
+
+/**
+ * StepEdge component props
+ */
export type StepEdgeProps = EdgeComponentWithPathOptions;
+
+/**
+ * StraightEdge component props
+ */
export type StraightEdgeProps = Omit;
+
+/**
+ * SimpleBezier component props
+ */
export type SimpleBezierEdgeProps = EdgeComponentProps;
export type OnEdgeUpdateFunc = (oldEdge: Edge, newConnection: Connection) => void;
@@ -157,3 +186,6 @@ export type ConnectionLineComponentProps = {
};
export type ConnectionLineComponent = ComponentType;
+
+export type EdgeTypes = { [key: string]: ComponentType };
+export type EdgeTypesWrapped = { [key: string]: MemoExoticComponent> };
diff --git a/packages/react/src/types/general.ts b/packages/react/src/types/general.ts
index b2e7098a..a212b057 100644
--- a/packages/react/src/types/general.ts
+++ b/packages/react/src/types/general.ts
@@ -1,9 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
-import type { ComponentType, MemoExoticComponent } from 'react';
import {
FitViewParamsBase,
FitViewOptionsBase,
- NodeProps,
ZoomInOut,
ZoomTo,
SetViewport,
@@ -14,7 +12,7 @@ import {
XYPosition,
} from '@xyflow/system';
-import type { NodeChange, EdgeChange, Node, WrapNodeProps, Edge, EdgeProps, WrapEdgeProps, ReactFlowInstance } from '.';
+import type { NodeChange, EdgeChange, Node, Edge, ReactFlowInstance } from '.';
export type OnNodesChange = (changes: NodeChange[]) => void;
export type OnEdgesChange = (changes: EdgeChange[]) => void;
@@ -23,11 +21,6 @@ export type OnNodesDelete = (nodes: Node[]) => void;
export type OnEdgesDelete = (edges: Edge[]) => void;
export type OnDelete = (params: { nodes: Node[]; edges: Edge[] }) => void;
-export type NodeTypes = { [key: string]: ComponentType };
-export type NodeTypesWrapped = { [key: string]: MemoExoticComponent> };
-export type EdgeTypes = { [key: string]: ComponentType };
-export type EdgeTypesWrapped = { [key: string]: MemoExoticComponent> };
-
export type UnselectNodesAndEdgesParams = {
nodes?: Node[];
edges?: Edge[];
@@ -43,7 +36,9 @@ export type OnSelectionChangeFunc = (params: OnSelectionChangeParams) => void;
export type FitViewParams = FitViewParamsBase;
export type FitViewOptions = FitViewOptionsBase;
export type FitView = (fitViewOptions?: FitViewOptions) => boolean;
-export type OnInit = (reactFlowInstance: ReactFlowInstance) => void;
+export type OnInit = (
+ reactFlowInstance: ReactFlowInstance
+) => void;
export type ViewportHelperFunctions = {
zoomIn: ZoomInOut;
diff --git a/packages/react/src/types/instance.ts b/packages/react/src/types/instance.ts
index f229ec87..6ac81e04 100644
--- a/packages/react/src/types/instance.ts
+++ b/packages/react/src/types/instance.ts
@@ -3,9 +3,9 @@
import type { Rect, Viewport } from '@xyflow/system';
import type { Node, Edge, ViewportHelperFunctions } from '.';
-export type ReactFlowJsonObject = {
- nodes: Node[];
- edges: Edge[];
+export type ReactFlowJsonObject = {
+ nodes: NodeType[];
+ edges: EdgeType[];
viewport: Viewport;
};
@@ -15,30 +15,33 @@ export type DeleteElementsOptions = {
};
export namespace Instance {
- export type GetNodes = () => Node[];
- export type SetNodes = (
- payload: Node[] | ((nodes: Node[]) => Node[])
+ export type GetNodes = () => NodeType[];
+ export type SetNodes = (
+ payload: NodeType[] | ((nodes: NodeType[]) => NodeType[])
) => void;
- export type AddNodes = (payload: Node[] | Node