diff --git a/examples/vite-app/src/App/index.tsx b/examples/vite-app/src/App/index.tsx index 33347757..02eaac1e 100644 --- a/examples/vite-app/src/App/index.tsx +++ b/examples/vite-app/src/App/index.tsx @@ -9,6 +9,7 @@ import CustomNode from '../examples/CustomNode'; import DefaultNodes from '../examples/DefaultNodes'; import DragHandle from '../examples/DragHandle'; import DragNDrop from '../examples/DragNDrop'; +import EasyConnect from '../examples/EasyConnect'; import Edges from '../examples/Edges'; import EdgeRenderer from '../examples/EdgeRenderer'; import EdgeTypes from '../examples/EdgeTypes'; @@ -96,6 +97,11 @@ const routes: IRoute[] = [ path: '/dragndrop', component: DragNDrop, }, + { + name: 'EasyConnect', + path: '/easy-connect', + component: EasyConnect, + }, { name: 'Edges', path: '/edges', diff --git a/examples/vite-app/src/examples/EasyConnect/CustomConnectionLine.tsx b/examples/vite-app/src/examples/EasyConnect/CustomConnectionLine.tsx new file mode 100644 index 00000000..ea671570 --- /dev/null +++ b/examples/vite-app/src/examples/EasyConnect/CustomConnectionLine.tsx @@ -0,0 +1,19 @@ +import { ConnectionLineComponentProps, getStraightPath } from 'reactflow'; + +function CustomConnectionLine({ fromX, fromY, toX, toY, connectionLineStyle }: ConnectionLineComponentProps) { + const [edgePath] = getStraightPath({ + sourceX: fromX, + sourceY: fromY, + targetX: toX, + targetY: toY, + }); + + return ( + + + + + ); +} + +export default CustomConnectionLine; diff --git a/examples/vite-app/src/examples/EasyConnect/CustomNode.tsx b/examples/vite-app/src/examples/EasyConnect/CustomNode.tsx new file mode 100644 index 00000000..49c1adb9 --- /dev/null +++ b/examples/vite-app/src/examples/EasyConnect/CustomNode.tsx @@ -0,0 +1,27 @@ +import { Handle, NodeProps, Position, ReactFlowState, useStore } from 'reactflow'; + +const connectionNodeIdSelector = (state: ReactFlowState) => state.connectionNodeId; + +export default function CustomNode({ id }: NodeProps) { + const connectionNodeId = useStore(connectionNodeIdSelector); + const isTarget = connectionNodeId && connectionNodeId !== id; + + const targetHandleStyle = { zIndex: isTarget ? 3 : 1 }; + const label = isTarget ? 'Drop here' : 'Drag to connect'; + + return ( +
+
+ + + {label} +
+
+ ); +} diff --git a/examples/vite-app/src/examples/EasyConnect/FloatingEdge.tsx b/examples/vite-app/src/examples/EasyConnect/FloatingEdge.tsx new file mode 100644 index 00000000..4b1038f0 --- /dev/null +++ b/examples/vite-app/src/examples/EasyConnect/FloatingEdge.tsx @@ -0,0 +1,26 @@ +import { useCallback } from 'react'; +import { useStore, getStraightPath, EdgeProps } from 'reactflow'; + +import { getEdgeParams } from './utils.js'; + +function FloatingEdge({ id, source, target, markerEnd, style }: EdgeProps) { + const sourceNode = useStore(useCallback((store) => store.nodeInternals.get(source), [source])); + const targetNode = useStore(useCallback((store) => store.nodeInternals.get(target), [target])); + + if (!sourceNode || !targetNode) { + return null; + } + + const { sx, sy, tx, ty } = getEdgeParams(sourceNode, targetNode); + + const [edgePath] = getStraightPath({ + sourceX: sx, + sourceY: sy, + targetX: tx, + targetY: ty, + }); + + return ; +} + +export default FloatingEdge; diff --git a/examples/vite-app/src/examples/EasyConnect/index.tsx b/examples/vite-app/src/examples/EasyConnect/index.tsx new file mode 100644 index 00000000..1e26ae3d --- /dev/null +++ b/examples/vite-app/src/examples/EasyConnect/index.tsx @@ -0,0 +1,85 @@ +import { useCallback } from 'react'; +import ReactFlow, { Node, Edge, addEdge, useNodesState, useEdgesState, MarkerType, OnConnect } from 'reactflow'; + +import CustomNode from './CustomNode'; +import FloatingEdge from './FloatingEdge'; +import CustomConnectionLine from './CustomConnectionLine'; + +import 'reactflow/dist/style.css'; +import './style.css'; + +const initialNodes: Node[] = [ + { + id: '1', + type: 'custom', + position: { x: 0, y: 0 }, + data: {}, + }, + { + id: '2', + type: 'custom', + position: { x: 250, y: 320 }, + data: {}, + }, + { + id: '3', + type: 'custom', + position: { x: 40, y: 300 }, + data: {}, + }, + { + id: '4', + type: 'custom', + position: { x: 300, y: 0 }, + data: {}, + }, +]; + +const initialEdges: Edge[] = []; + +const connectionLineStyle = { + strokeWidth: 3, + stroke: 'black', +}; + +const nodeTypes = { + custom: CustomNode, +}; + +const edgeTypes = { + floating: FloatingEdge, +}; + +const defaultEdgeOptions = { + style: { strokeWidth: 3, stroke: 'black' }, + type: 'floating', + markerEnd: { + type: MarkerType.ArrowClosed, + color: 'black', + }, +}; + +const EasyConnectExample = () => { + const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); + const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); + + const onConnect: OnConnect = useCallback((params) => setEdges((eds) => addEdge(params, eds)), [setEdges]); + + return ( + + ); +}; + +export default EasyConnectExample; diff --git a/examples/vite-app/src/examples/EasyConnect/style.css b/examples/vite-app/src/examples/EasyConnect/style.css new file mode 100644 index 00000000..c2ebc0a2 --- /dev/null +++ b/examples/vite-app/src/examples/EasyConnect/style.css @@ -0,0 +1,54 @@ +.customNodeBody { + width: 150px; + height: 80px; + border: 3px solid black; + position: relative; + overflow: hidden; + border-radius: 10px; + display: flex; + justify-content: center; + align-items: center; + font-weight: bold; +} + +.customNode:before { + content: ''; + position: absolute; + top: -10px; + left: 50%; + height: 20px; + width: 40px; + transform: translate(-50%, 0); + background: #d6d5e6; + z-index: 1000; + line-height: 1; + border-radius: 4px; + color: #fff; + font-size: 9px; + border: 2px solid #222138; +} + +div.sourceHandle { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + border-radius: 0; + transform: none; + border: none; + opacity: 0; +} + +div.targetHandle { + width: 100%; + height: 100%; + background: blue; + position: absolute; + top: 0; + left: 0; + border-radius: 0; + transform: none; + border: none; + opacity: 0; +} diff --git a/examples/vite-app/src/examples/EasyConnect/utils.tsx b/examples/vite-app/src/examples/EasyConnect/utils.tsx new file mode 100644 index 00000000..02bf2eaf --- /dev/null +++ b/examples/vite-app/src/examples/EasyConnect/utils.tsx @@ -0,0 +1,102 @@ +import { Node, Position, MarkerType, XYPosition } from 'reactflow'; + +// this helper function returns the intersection point +// of the line between the center of the intersectionNode and the target node +function getNodeIntersection(intersectionNode: Node, targetNode: Node) { + // https://math.stackexchange.com/questions/1724792/an-algorithm-for-finding-the-intersection-point-between-a-center-of-vision-and-a + const { + width: intersectionNodeWidth, + height: intersectionNodeHeight, + positionAbsolute: intersectionNodePosition, + } = intersectionNode; + const targetPosition = targetNode.positionAbsolute!; + + const w = intersectionNodeWidth! / 2; + const h = intersectionNodeHeight! / 2; + + const x2 = intersectionNodePosition!.x + w; + const y2 = intersectionNodePosition!.y + h; + const x1 = targetPosition.x + w; + const y1 = targetPosition.y + h; + + const xx1 = (x1 - x2) / (2 * w) - (y1 - y2) / (2 * h); + const yy1 = (x1 - x2) / (2 * w) + (y1 - y2) / (2 * h); + const a = 1 / (Math.abs(xx1) + Math.abs(yy1)); + const xx3 = a * xx1; + const yy3 = a * yy1; + const x = w * (xx3 + yy3) + x2; + const y = h * (-xx3 + yy3) + y2; + + return { x, y }; +} + +// returns the position (top,right,bottom or right) passed node compared to the intersection point +function getEdgePosition(node: Node, intersectionPoint: XYPosition) { + const n = { ...node.positionAbsolute, ...node }; + const nx = Math.round(n.x!); + const ny = Math.round(n.y!); + const px = Math.round(intersectionPoint.x); + const py = Math.round(intersectionPoint.y); + + if (px <= nx + 1) { + return Position.Left; + } + if (px >= nx + n.width! - 1) { + return Position.Right; + } + if (py <= ny + 1) { + return Position.Top; + } + if (py >= n.y! + n.height! - 1) { + return Position.Bottom; + } + + return Position.Top; +} + +// returns the parameters (sx, sy, tx, ty, sourcePos, targetPos) you need to create an edge +export function getEdgeParams(source: Node, target: Node) { + const sourceIntersectionPoint = getNodeIntersection(source, target); + const targetIntersectionPoint = getNodeIntersection(target, source); + + const sourcePos = getEdgePosition(source, sourceIntersectionPoint); + const targetPos = getEdgePosition(target, targetIntersectionPoint); + + return { + sx: sourceIntersectionPoint.x, + sy: sourceIntersectionPoint.y, + tx: targetIntersectionPoint.x, + ty: targetIntersectionPoint.y, + sourcePos, + targetPos, + }; +} + +export function createNodesAndEdges() { + const nodes = []; + const edges = []; + const center = { x: window.innerWidth / 2, y: window.innerHeight / 2 }; + + nodes.push({ id: 'target', data: { label: 'Target' }, position: center }); + + for (let i = 0; i < 8; i++) { + const degrees = i * (360 / 8); + const radians = degrees * (Math.PI / 180); + const x = 250 * Math.cos(radians) + center.x; + const y = 250 * Math.sin(radians) + center.y; + + nodes.push({ id: `${i}`, data: { label: 'Source' }, position: { x, y } }); + + edges.push({ + id: `edge-${i}`, + target: 'target', + source: `${i}`, + type: 'floating', + markerEnd: { + type: MarkerType.Arrow, + }, + }); + } + + return { nodes, edges }; +} diff --git a/examples/vite-app/src/examples/Validation/index.tsx b/examples/vite-app/src/examples/Validation/index.tsx index b11c1f92..1488b48c 100644 --- a/examples/vite-app/src/examples/Validation/index.tsx +++ b/examples/vite-app/src/examples/Validation/index.tsx @@ -1,16 +1,17 @@ -import React, { FC, useCallback, useState } from 'react'; +import { FC, useCallback, useState } from 'react'; import ReactFlow, { addEdge, Handle, Connection, Position, Node, - Edge, NodeProps, NodeTypes, useNodesState, useEdgesState, - OnConnectStartParams, + OnConnectStart, + OnConnectEnd, + OnConnect, } from 'reactflow'; import styles from './validation.module.css'; @@ -49,24 +50,24 @@ const ValidationFlow = () => { const [nodes, , onNodesChange] = useNodesState(initialNodes); const [edges, setEdges, onEdgesChange] = useEdgesState([]); - const onConnectStart = useCallback( - (event: React.MouseEvent, params: OnConnectStartParams) => { + const onConnectStart: OnConnectStart = useCallback( + (event, params) => { console.log('on connect start', params, event, value); setValue(1); }, [value] ); - const onConnect = useCallback( - (params: Connection | Edge) => { + const onConnect: OnConnect = useCallback( + (params) => { console.log('on connect', params); setEdges((eds) => addEdge(params, eds)); }, [setEdges] ); - const onConnectEnd = useCallback( - (event: MouseEvent) => { + const onConnectEnd: OnConnectEnd = useCallback( + (event) => { console.log('on connect end', event, value); setValue(0); }, diff --git a/packages/background/CHANGELOG.md b/packages/background/CHANGELOG.md index f2393bec..cea0e140 100644 --- a/packages/background/CHANGELOG.md +++ b/packages/background/CHANGELOG.md @@ -1,5 +1,12 @@ # @reactflow/background +## 11.1.4 + +### Patch Changes + +- Updated dependencies [[`71153534`](https://github.com/wbkd/react-flow/commit/7115353418ebc7f7c81ab0e861200972bbf7dbd5)]: + - @reactflow/core@11.5.1 + ## 11.1.3 ### Patch Changes diff --git a/packages/background/package.json b/packages/background/package.json index 2865139e..159d178f 100644 --- a/packages/background/package.json +++ b/packages/background/package.json @@ -1,6 +1,6 @@ { "name": "@reactflow/background", - "version": "11.1.3", + "version": "11.1.4", "description": "Background component with different variants for React Flow", "keywords": [ "react", diff --git a/packages/controls/CHANGELOG.md b/packages/controls/CHANGELOG.md index 7f2d9b92..805064ca 100644 --- a/packages/controls/CHANGELOG.md +++ b/packages/controls/CHANGELOG.md @@ -1,5 +1,12 @@ # @reactflow/controls +## 11.1.4 + +### Patch Changes + +- Updated dependencies [[`71153534`](https://github.com/wbkd/react-flow/commit/7115353418ebc7f7c81ab0e861200972bbf7dbd5)]: + - @reactflow/core@11.5.1 + ## 11.1.3 ### Patch Changes diff --git a/packages/controls/package.json b/packages/controls/package.json index 7bc80d2d..ff673326 100644 --- a/packages/controls/package.json +++ b/packages/controls/package.json @@ -1,6 +1,6 @@ { "name": "@reactflow/controls", - "version": "11.1.3", + "version": "11.1.4", "description": "Component to control the viewport of a React Flow instance", "keywords": [ "react", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index cd591566..c9aa9662 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,11 @@ # @reactflow/core +## 11.5.1 + +### Patch Changes + +- [#2783](https://github.com/wbkd/react-flow/pull/2783) [`71153534`](https://github.com/wbkd/react-flow/commit/7115353418ebc7f7c81ab0e861200972bbf7dbd5) - connections: check handle below mouse before using connection radius + ## 11.5.0 Lot's of improvements are coming with this release! @@ -8,23 +14,24 @@ Lot's of improvements are coming with this release! - **Auto pan**: When you drag a node, a selection or the connection line to the border of the pane, it will pan into that direction. That makes it easier to connect far away nodes for example. If you don't like it you can set `autoPnaOnNodeDrag` and `autoPanOnConnect` to false. - **Touch devices**: It's finally possibleto connect nodes with the connection line on touch devices. In combination with the new auto pan and connection radius the overall UX is way better. - **Errors**: We added an `onError` prop to get notified when an error like "couldn't find source handle" happens. This is useful if you want to log errors for example. -- **Node type**: We added a second param to the generic `Node` type. You can not only pass `NodeData` but also the type as a second param: +- **Node type**: We added a second param to the generic `Node` type. You can not only pass `NodeData` but also the type as a second param: + ```ts -type MyCustomNode = Node +type MyCustomNode = Node; ``` + This makes it easier to work with different custom nodes and data types. ### Minor Changes -- [#2754](https://github.com/wbkd/react-flow/pull/2754) [`e96309b6`](https://github.com/wbkd/react-flow/commit/e96309b6a57b1071faeebf7b0547fef7fd418694) - Add auto pan for connecting and node dragging and `connectionRadius` +- [#2754](https://github.com/wbkd/react-flow/pull/2754) [`e96309b6`](https://github.com/wbkd/react-flow/commit/e96309b6a57b1071faeebf7b0547fef7fd418694) - Add auto pan for connecting and node dragging and `connectionRadius` - [#2773](https://github.com/wbkd/react-flow/pull/2773) - Add `onError` prop to get notified when an error happens ### Patch Changes -- [#2763](https://github.com/wbkd/react-flow/pull/2763) [`85003b01`](https://github.com/wbkd/react-flow/commit/85003b01add71ea852bd5b0d2f1e7496050a6b52) - Connecting nodes: Enable connections on touch devices +- [#2763](https://github.com/wbkd/react-flow/pull/2763) [`85003b01`](https://github.com/wbkd/react-flow/commit/85003b01add71ea852bd5b0d2f1e7496050a6b52) - Connecting nodes: Enable connections on touch devices - [#2620](https://github.com/wbkd/react-flow/pull/2620) - Thanks [RichSchulz](https://github.com/RichSchulz)! - Types: improve typing for node type - ## 11.4.2 ### Patch Changes diff --git a/packages/core/package.json b/packages/core/package.json index 8529d098..2c33c3e3 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@reactflow/core", - "version": "11.5.0", + "version": "11.5.1", "description": "Core components and util functions of React Flow.", "keywords": [ "react", diff --git a/packages/core/src/components/Handle/handler.ts b/packages/core/src/components/Handle/handler.ts index 180b6027..03bf698c 100644 --- a/packages/core/src/components/Handle/handler.ts +++ b/packages/core/src/components/Handle/handler.ts @@ -125,6 +125,7 @@ export function handlePointerDown({ } const { connection, handleDomNode, isValid } = isValidHandle( + event, prevClosestHandle, connectionMode, nodeId, @@ -148,6 +149,7 @@ export function handlePointerDown({ if (prevClosestHandle) { const { connection, isValid } = isValidHandle( + event, prevClosestHandle, connectionMode, nodeId, diff --git a/packages/core/src/components/Handle/index.tsx b/packages/core/src/components/Handle/index.tsx index 59d2bd7f..dab16653 100644 --- a/packages/core/src/components/Handle/index.tsx +++ b/packages/core/src/components/Handle/index.tsx @@ -102,6 +102,7 @@ const Handle = forwardRef( const doc = getHostForElement(event.target as HTMLElement); const { connection, isValid } = isValidHandle( + event, { nodeId, id: handleId, diff --git a/packages/core/src/components/Handle/utils.ts b/packages/core/src/components/Handle/utils.ts index 439ccc7a..0b391e37 100644 --- a/packages/core/src/components/Handle/utils.ts +++ b/packages/core/src/components/Handle/utils.ts @@ -1,5 +1,7 @@ +import { MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } from 'react'; + import { ConnectionMode } from '../../types'; -import { internalsSymbol } from '../../utils'; +import { getEventPosition, internalsSymbol } from '../../utils'; import type { Connection, HandleType, XYPosition, Node, NodeHandleBounds } from '../../types'; export type ConnectionHandle = { @@ -61,6 +63,7 @@ type Result = { // checks if and returns connection in fom of an object { source: 123, target: 312 } export function isValidHandle( + event: MouseEvent | TouchEvent | ReactMouseEvent | ReactTouchEvent, handle: Pick, connectionMode: ConnectionMode, fromNodeId: string, @@ -73,23 +76,26 @@ export function isValidHandle( const handleDomNode = doc.querySelector( `.react-flow__handle[data-id="${handle?.nodeId}-${handle?.id}-${handle?.type}"]` ); + const { x, y } = getEventPosition(event); + const handleBelow = doc.elementFromPoint(x, y); + const handleToCheck = handleBelow?.classList.contains('react-flow__handle') ? handleBelow : handleDomNode; + const result: Result = { - handleDomNode, + handleDomNode: handleToCheck, isValid: false, connection: { source: null, target: null, sourceHandle: null, targetHandle: null }, }; - if (handleDomNode) { - const handleIsTarget = handle.type === 'target'; - const handleIsSource = handle.type === 'source'; - const handleNodeId = handleDomNode.getAttribute('data-nodeid'); - const handleId = handleDomNode.getAttribute('data-handleid'); + if (handleToCheck) { + const handleType = getHandleType(undefined, handleToCheck); + const handleNodeId = handleToCheck.getAttribute('data-nodeid'); + const handleId = handleToCheck.getAttribute('data-handleid'); const connection: Connection = { source: isTarget ? handle.nodeId : fromNodeId, - sourceHandle: isTarget ? handle.id : fromHandleId, + sourceHandle: isTarget ? handleId : fromHandleId, target: isTarget ? fromNodeId : handle.nodeId, - targetHandle: isTarget ? fromHandleId : handle.id, + targetHandle: isTarget ? fromHandleId : handleId, }; result.connection = connection; @@ -97,7 +103,7 @@ export function isValidHandle( // in strict mode we don't allow target to target or source to source connections const isValid = connectionMode === ConnectionMode.Strict - ? (isTarget && handleIsSource) || (!isTarget && handleIsTarget) + ? (isTarget && handleType === 'source') || (!isTarget && handleType === 'target') : handleNodeId !== fromNodeId || handleId !== fromHandleId; if (isValid) { diff --git a/packages/minimap/CHANGELOG.md b/packages/minimap/CHANGELOG.md index 58e60248..bb90acb4 100644 --- a/packages/minimap/CHANGELOG.md +++ b/packages/minimap/CHANGELOG.md @@ -1,5 +1,12 @@ # @reactflow/minimap +## 11.3.4 + +### Patch Changes + +- Updated dependencies [[`71153534`](https://github.com/wbkd/react-flow/commit/7115353418ebc7f7c81ab0e861200972bbf7dbd5)]: + - @reactflow/core@11.5.1 + ## 11.3.3 ### Patch Changes diff --git a/packages/minimap/package.json b/packages/minimap/package.json index f9e8e4e7..27d0b8fc 100644 --- a/packages/minimap/package.json +++ b/packages/minimap/package.json @@ -1,6 +1,6 @@ { "name": "@reactflow/minimap", - "version": "11.3.3", + "version": "11.3.4", "description": "Minimap component for React Flow.", "keywords": [ "react", diff --git a/packages/node-toolbar/CHANGELOG.md b/packages/node-toolbar/CHANGELOG.md index e4abf4de..158645f0 100644 --- a/packages/node-toolbar/CHANGELOG.md +++ b/packages/node-toolbar/CHANGELOG.md @@ -1,5 +1,12 @@ # @reactflow/node-toolbar +## 1.1.4 + +### Patch Changes + +- Updated dependencies [[`71153534`](https://github.com/wbkd/react-flow/commit/7115353418ebc7f7c81ab0e861200972bbf7dbd5)]: + - @reactflow/core@11.5.1 + ## 1.1.3 ### Patch Changes diff --git a/packages/node-toolbar/package.json b/packages/node-toolbar/package.json index 3d85c85f..4aedc34e 100644 --- a/packages/node-toolbar/package.json +++ b/packages/node-toolbar/package.json @@ -1,6 +1,6 @@ { "name": "@reactflow/node-toolbar", - "version": "1.1.3", + "version": "1.1.4", "description": "A toolbar component for React Flow that can be attached to a node.", "keywords": [ "react", @@ -36,7 +36,7 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "@reactflow/core": "workspace:^11.3.3", + "@reactflow/core": "workspace:*", "classcat": "^5.0.3", "zustand": "^4.3.1" }, diff --git a/packages/reactflow/CHANGELOG.md b/packages/reactflow/CHANGELOG.md index b804b880..1f8112dd 100644 --- a/packages/reactflow/CHANGELOG.md +++ b/packages/reactflow/CHANGELOG.md @@ -1,5 +1,18 @@ # reactflow +## 11.5.2 + +### Patch Changes + +- [#2783](https://github.com/wbkd/react-flow/pull/2783) [`71153534`](https://github.com/wbkd/react-flow/commit/7115353418ebc7f7c81ab0e861200972bbf7dbd5) - connections: check handle below mouse before using connection radius + +- Updated dependencies [[`71153534`](https://github.com/wbkd/react-flow/commit/7115353418ebc7f7c81ab0e861200972bbf7dbd5)]: + - @reactflow/core@11.5.1 + - @reactflow/background@11.1.4 + - @reactflow/controls@11.1.4 + - @reactflow/minimap@11.3.4 + - @reactflow/node-toolbar@1.1.4 + ## 11.5.1 ### Minor Changes @@ -8,26 +21,28 @@ ## 11.5.0 -Lot's of improvements are coming with this release! +Lot's of improvements are coming with this release! - **Connecting radius**: No need to drop a connection line on top of handle anymore. You only need to be close to the handle. That radius can be configured with the `connectionRadius` prop. - **Auto pan**: When you drag a node, a selection or the connection line to the border of the pane, it will pan into that direction. That makes it easier to connect far away nodes for example. If you don't like it you can set `autoPnaOnNodeDrag` and `autoPanOnConnect` to false. - **Touch devices**: It's finally possibleto connect nodes with the connection line on touch devices. In combination with the new auto pan and connection radius the overall UX is way better. - **Errors**: We added an `onError` prop to get notified when an error like "couldn't find source handle" happens. This is useful if you want to log errors for example. -- **Node type**: We added a second param to the generic `Node` type. You can not only pass `NodeData` but also the type as a second param: +- **Node type**: We added a second param to the generic `Node` type. You can not only pass `NodeData` but also the type as a second param: + ```ts -type MyCustomNode = Node +type MyCustomNode = Node; ``` + This makes it easier to work with different custom nodes and data types. ### Minor Changes -- [#2754](https://github.com/wbkd/react-flow/pull/2754) [`e96309b6`](https://github.com/wbkd/react-flow/commit/e96309b6a57b1071faeebf7b0547fef7fd418694) - Add auto pan for connecting and node dragging and `connectionRadius` +- [#2754](https://github.com/wbkd/react-flow/pull/2754) [`e96309b6`](https://github.com/wbkd/react-flow/commit/e96309b6a57b1071faeebf7b0547fef7fd418694) - Add auto pan for connecting and node dragging and `connectionRadius` - [#2773](https://github.com/wbkd/react-flow/pull/2773) - Add `onError` prop to get notified when an error happens ### Patch Changes -- [#2763](https://github.com/wbkd/react-flow/pull/2763) [`85003b01`](https://github.com/wbkd/react-flow/commit/85003b01add71ea852bd5b0d2f1e7496050a6b52) - Connecting nodes: Enable connections on touch devices +- [#2763](https://github.com/wbkd/react-flow/pull/2763) [`85003b01`](https://github.com/wbkd/react-flow/commit/85003b01add71ea852bd5b0d2f1e7496050a6b52) - Connecting nodes: Enable connections on touch devices - [#2620](https://github.com/wbkd/react-flow/pull/2620) - Thanks [RichSchulz](https://github.com/RichSchulz)! - Types: improve typing for node type - Updated dependencies [[`e96309b6`](https://github.com/wbkd/react-flow/commit/e96309b6a57b1071faeebf7b0547fef7fd418694), [`85003b01`](https://github.com/wbkd/react-flow/commit/85003b01add71ea852bd5b0d2f1e7496050a6b52), [`4c516882`](https://github.com/wbkd/react-flow/commit/4c516882d2bbf426c1832a53ad40763cc1abef92)]: diff --git a/packages/reactflow/package.json b/packages/reactflow/package.json index 1e1b4e60..254c56dd 100644 --- a/packages/reactflow/package.json +++ b/packages/reactflow/package.json @@ -1,6 +1,6 @@ { "name": "reactflow", - "version": "11.5.1", + "version": "11.5.2", "description": "A highly customizable React library for building node-based editors and interactive flow charts", "keywords": [ "react",