From 1ba3c0e91f01b8d5f23822b790e5cfaf3f1cb3b2 Mon Sep 17 00:00:00 2001 From: moklick Date: Fri, 3 Feb 2023 19:08:10 +0100 Subject: [PATCH 1/9] fix(nodes): if draggable equals false node is also not draggable with selection --- examples/vite-app/src/examples/Basic/index.tsx | 1 + packages/core/src/hooks/useDrag/index.ts | 5 +++-- packages/core/src/hooks/useDrag/utils.ts | 14 ++++++++++++-- packages/core/src/hooks/useUpdateNodePositions.ts | 6 ++++-- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/examples/vite-app/src/examples/Basic/index.tsx b/examples/vite-app/src/examples/Basic/index.tsx index 52d22025..67bbc0fd 100644 --- a/examples/vite-app/src/examples/Basic/index.tsx +++ b/examples/vite-app/src/examples/Basic/index.tsx @@ -22,6 +22,7 @@ const initialNodes: Node[] = [ data: { label: 'Node 1' }, position: { x: 250, y: 5 }, className: 'light', + draggable: false, }, { id: '2', diff --git a/packages/core/src/hooks/useDrag/index.ts b/packages/core/src/hooks/useDrag/index.ts index c6f3d269..22d06daf 100644 --- a/packages/core/src/hooks/useDrag/index.ts +++ b/packages/core/src/hooks/useDrag/index.ts @@ -133,10 +133,11 @@ function useDrag({ const { nodeInternals, multiSelectionActive, + domNode, + nodesDraggable, unselectNodesAndEdges, onNodeDragStart, onSelectionDragStart, - domNode, } = store.getState(); const onStart = nodeId ? onNodeDragStart : wrapSelectionDragFunc(onSelectionDragStart); @@ -157,7 +158,7 @@ function useDrag({ const pointerPos = getPointerPosition(event); lastPos.current = pointerPos; - dragItems.current = getDragItems(nodeInternals, pointerPos, nodeId); + dragItems.current = getDragItems(nodeInternals, nodesDraggable, pointerPos, nodeId); if (onStart && dragItems.current) { const [currentNode, nodes] = getEventHandlerParams({ diff --git a/packages/core/src/hooks/useDrag/utils.ts b/packages/core/src/hooks/useDrag/utils.ts index ed40053b..5ef3b3b2 100644 --- a/packages/core/src/hooks/useDrag/utils.ts +++ b/packages/core/src/hooks/useDrag/utils.ts @@ -36,9 +36,19 @@ export function hasSelector(target: Element, selector: string, nodeRef: RefObjec } // looks for all selected nodes and created a NodeDragItem for each of them -export function getDragItems(nodeInternals: NodeInternals, mousePos: XYPosition, nodeId?: string): NodeDragItem[] { +export function getDragItems( + nodeInternals: NodeInternals, + nodesDraggable: boolean, + mousePos: XYPosition, + nodeId?: string +): NodeDragItem[] { return Array.from(nodeInternals.values()) - .filter((n) => (n.selected || n.id === nodeId) && (!n.parentNode || !isParentSelected(n, nodeInternals))) + .filter( + (n) => + (n.selected || n.id === nodeId) && + (!n.parentNode || !isParentSelected(n, nodeInternals)) && + (n.draggable || (nodesDraggable && typeof n.draggable === 'undefined')) + ) .map((n) => ({ id: n.id, position: n.position || { x: 0, y: 0 }, diff --git a/packages/core/src/hooks/useUpdateNodePositions.ts b/packages/core/src/hooks/useUpdateNodePositions.ts index 131f85cd..0ab89157 100644 --- a/packages/core/src/hooks/useUpdateNodePositions.ts +++ b/packages/core/src/hooks/useUpdateNodePositions.ts @@ -7,9 +7,11 @@ function useUpdateNodePositions() { const store = useStoreApi(); const updatePositions = useCallback((params: { x: number; y: number; isShiftPressed: boolean }) => { - const { nodeInternals, nodeExtent, updateNodePositions, getNodes, snapToGrid, snapGrid, onError } = + const { nodeInternals, nodeExtent, updateNodePositions, getNodes, snapToGrid, snapGrid, onError, nodesDraggable } = store.getState(); - const selectedNodes = getNodes().filter((n) => n.selected); + const selectedNodes = getNodes().filter( + (n) => n.selected && (n.draggable || (nodesDraggable && typeof n.draggable === 'undefined')) + ); // by default a node moves 5px on each key press, or 20px if shift is pressed // if snap grid is enabled, we use that for the velocity. const xVelo = snapToGrid ? snapGrid[0] : 5; From be8097acadca3054c3b236ce4296fc516010ef8c Mon Sep 17 00:00:00 2001 From: moklick Date: Fri, 3 Feb 2023 19:14:04 +0100 Subject: [PATCH 2/9] chore(changeset): add --- .changeset/fast-chefs-explode.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fast-chefs-explode.md diff --git a/.changeset/fast-chefs-explode.md b/.changeset/fast-chefs-explode.md new file mode 100644 index 00000000..4866ec9e --- /dev/null +++ b/.changeset/fast-chefs-explode.md @@ -0,0 +1,5 @@ +--- +'@reactflow/core': patch +--- + +When node is not draggable, you can't move it with a selection either From c48efe969f7b964a3713aff321b9fa4946b31ca2 Mon Sep 17 00:00:00 2001 From: moklick Date: Fri, 3 Feb 2023 20:40:32 +0100 Subject: [PATCH 3/9] fix(ios): connection error + dont snap invalid connection lines --- .../examples/Validation/validation.module.css | 4 +- .../core/src/components/Handle/handler.ts | 71 +++++++++---------- packages/core/src/components/Handle/utils.ts | 17 +++-- 3 files changed, 48 insertions(+), 44 deletions(-) diff --git a/examples/vite-app/src/examples/Validation/validation.module.css b/examples/vite-app/src/examples/Validation/validation.module.css index 4ffc8b0b..37333aae 100644 --- a/examples/vite-app/src/examples/Validation/validation.module.css +++ b/examples/vite-app/src/examples/Validation/validation.module.css @@ -24,10 +24,10 @@ background: #fff; } -.validationflow :global .react-flow__handle-connecting { +.validationflow :global .connecting { background: #ff6060; } -.validationflow :global .react-flow__handle-valid { +.validationflow :global .valid { background: #55dd99; } diff --git a/packages/core/src/components/Handle/handler.ts b/packages/core/src/components/Handle/handler.ts index 03bf698c..5c35e48a 100644 --- a/packages/core/src/components/Handle/handler.ts +++ b/packages/core/src/components/Handle/handler.ts @@ -2,7 +2,7 @@ import type { MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } fro import { StoreApi } from 'zustand'; import { getHostForElement, calcAutoPan, getEventPosition } from '../../utils'; -import type { OnConnect, HandleType, ReactFlowState } from '../../types'; +import type { OnConnect, HandleType, ReactFlowState, Connection } from '../../types'; import { pointToRendererPoint, rendererPointToPoint } from '../../utils/graph'; import { ConnectionHandle, @@ -65,6 +65,8 @@ export function handlePointerDown({ let prevActiveHandle: Element; let connectionPosition = getEventPosition(event, containerBounds); let autoPanStarted = false; + let connection: Connection | null = null; + let isValid = false; const handleLookup = getHandleLookup({ nodes: getNodes(), @@ -108,23 +110,7 @@ export function handlePointerDown({ autoPanStarted = true; } - setState({ - connectionPosition: prevClosestHandle - ? rendererPointToPoint( - { - x: prevClosestHandle.x, - y: prevClosestHandle.y, - }, - transform - ) - : connectionPosition, - }); - - if (!prevClosestHandle) { - return resetRecentHandle(prevActiveHandle); - } - - const { connection, handleDomNode, isValid } = isValidHandle( + const { handleDomNode, ...result } = isValidHandle( event, prevClosestHandle, connectionMode, @@ -135,33 +121,39 @@ export function handlePointerDown({ doc ); + setState({ + connectionPosition: + prevClosestHandle && isValid + ? rendererPointToPoint( + { + x: prevClosestHandle.x, + y: prevClosestHandle.y, + }, + transform + ) + : connectionPosition, + }); + + if (!prevClosestHandle) { + return resetRecentHandle(prevActiveHandle); + } + + connection = result.connection; + isValid = result.isValid; + if (connection.source !== connection.target && handleDomNode) { resetRecentHandle(prevActiveHandle); prevActiveHandle = handleDomNode; - handleDomNode.classList.add('react-flow__handle-connecting'); + // @todo: remove the old class names "react-flow__handle-" in the next major version + handleDomNode.classList.add('connecting', 'react-flow__handle-connecting'); + handleDomNode.classList.toggle('valid', isValid); handleDomNode.classList.toggle('react-flow__handle-valid', isValid); } } function onPointerUp(event: MouseEvent | TouchEvent) { - cancelAnimationFrame(autoPanId); - autoPanStarted = false; - - if (prevClosestHandle) { - const { connection, isValid } = isValidHandle( - event, - prevClosestHandle, - connectionMode, - nodeId, - handleId, - isTarget ? 'target' : 'source', - isValidConnection, - doc - ); - - if (isValid) { - onConnect?.(connection); - } + if (connection && isValid) { + onConnect?.(connection); } onConnectEnd?.(event); @@ -171,8 +163,11 @@ export function handlePointerDown({ } resetRecentHandle(prevActiveHandle); - cancelConnection(); + cancelAnimationFrame(autoPanId); + autoPanStarted = false; + isValid = false; + connection = null; doc.removeEventListener('mousemove', onPointerMove as EventListener); doc.removeEventListener('mouseup', onPointerUp as EventListener); diff --git a/packages/core/src/components/Handle/utils.ts b/packages/core/src/components/Handle/utils.ts index 0b391e37..235abc92 100644 --- a/packages/core/src/components/Handle/utils.ts +++ b/packages/core/src/components/Handle/utils.ts @@ -61,10 +61,12 @@ type Result = { connection: Connection; }; +const nullConnection: Connection = { source: null, target: null, sourceHandle: null, targetHandle: null }; + // checks if and returns connection in fom of an object { source: 123, target: 312 } export function isValidHandle( event: MouseEvent | TouchEvent | ReactMouseEvent | ReactTouchEvent, - handle: Pick, + handle: Pick | null, connectionMode: ConnectionMode, fromNodeId: string, fromHandleId: string | null, @@ -72,6 +74,14 @@ export function isValidHandle( isValidConnection: ValidConnectionFunc, doc: Document | ShadowRoot ) { + if (!handle) { + return { + handleDomNode: null, + isValid: false, + connection: nullConnection, + }; + } + const isTarget = fromType === 'target'; const handleDomNode = doc.querySelector( `.react-flow__handle[data-id="${handle?.nodeId}-${handle?.id}-${handle?.type}"]` @@ -83,7 +93,7 @@ export function isValidHandle( const result: Result = { handleDomNode: handleToCheck, isValid: false, - connection: { source: null, target: null, sourceHandle: null, targetHandle: null }, + connection: nullConnection, }; if (handleToCheck) { @@ -155,6 +165,5 @@ export function getHandleType( } export function resetRecentHandle(handleDomNode: Element): void { - handleDomNode?.classList.remove('react-flow__handle-valid'); - handleDomNode?.classList.remove('react-flow__handle-connecting'); + handleDomNode?.classList.remove('valid', 'connecting', 'react-flow__handle-valid', 'react-flow__handle-connecting'); } From 3b6348a8d1573afb39576327318bc172e33393c2 Mon Sep 17 00:00:00 2001 From: moklick Date: Fri, 3 Feb 2023 20:43:08 +0100 Subject: [PATCH 4/9] chore(changeset): add --- .changeset/sour-impalas-admire.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/sour-impalas-admire.md diff --git a/.changeset/sour-impalas-admire.md b/.changeset/sour-impalas-admire.md new file mode 100644 index 00000000..598f8049 --- /dev/null +++ b/.changeset/sour-impalas-admire.md @@ -0,0 +1,5 @@ +--- +'@reactflow/core': patch +--- + +fix(ios): connection error + dont snap invalid connection lines From 23d1e65a72c00450ba790f1a0edb2902166ad8a2 Mon Sep 17 00:00:00 2001 From: moklick Date: Fri, 3 Feb 2023 21:10:44 +0100 Subject: [PATCH 5/9] feat(connection-line): add status class (valid or invalid) while in connection radius --- .../examples/Validation/validation.module.css | 8 ++++++ .../src/components/ConnectionLine/index.tsx | 26 ++++++++++++++++--- .../core/src/components/Handle/handler.ts | 7 +++-- packages/core/src/components/Handle/utils.ts | 14 +++++++++- packages/core/src/store/index.ts | 1 + packages/core/src/store/initialState.ts | 1 + packages/core/src/types/edges.ts | 3 ++- packages/core/src/types/general.ts | 3 +++ 8 files changed, 55 insertions(+), 8 deletions(-) diff --git a/examples/vite-app/src/examples/Validation/validation.module.css b/examples/vite-app/src/examples/Validation/validation.module.css index 37333aae..63d58eee 100644 --- a/examples/vite-app/src/examples/Validation/validation.module.css +++ b/examples/vite-app/src/examples/Validation/validation.module.css @@ -31,3 +31,11 @@ .validationflow :global .valid { background: #55dd99; } + +.validationflow :global .valid .react-flow__connection-path { + stroke: #55dd99; +} + +.validationflow :global .invalid .react-flow__connection-path { + stroke: #ff6060; +} diff --git a/packages/core/src/components/ConnectionLine/index.tsx b/packages/core/src/components/ConnectionLine/index.tsx index fae0c3b1..45ec7937 100644 --- a/packages/core/src/components/ConnectionLine/index.tsx +++ b/packages/core/src/components/ConnectionLine/index.tsx @@ -1,12 +1,19 @@ import { CSSProperties, useCallback } from 'react'; import { shallow } from 'zustand/shallow'; +import cc from 'classcat'; import { useStore } from '../../hooks/useStore'; import { getBezierPath } from '../Edges/BezierEdge'; import { getSmoothStepPath } from '../Edges/SmoothStepEdge'; import { getSimpleBezierPath } from '../Edges/SimpleBezierEdge'; import { internalsSymbol } from '../../utils'; -import type { ConnectionLineComponent, HandleType, ReactFlowState, ReactFlowStore } from '../../types'; +import type { + ConnectionLineComponent, + ConnectionStatus, + HandleType, + ReactFlowState, + ReactFlowStore, +} from '../../types'; import { Position, ConnectionLineType, ConnectionMode } from '../../types'; type ConnectionLineProps = { @@ -15,6 +22,7 @@ type ConnectionLineProps = { type: ConnectionLineType; style?: CSSProperties; CustomComponent?: ConnectionLineComponent; + connectionStatus: ConnectionStatus | null; }; const oppositePosition = { @@ -30,6 +38,7 @@ const ConnectionLine = ({ style, type = ConnectionLineType.Bezier, CustomComponent, + connectionStatus, }: ConnectionLineProps) => { const { fromNode, handleId, toX, toY, connectionMode } = useStore( useCallback( @@ -80,6 +89,7 @@ const ConnectionLine = ({ toY={toY} fromPosition={fromPosition} toPosition={toPosition} + connectionStatus={connectionStatus} /> ); } @@ -127,12 +137,13 @@ const selector = (s: ReactFlowState) => ({ nodeId: s.connectionNodeId, handleType: s.connectionHandleType, nodesConnectable: s.nodesConnectable, + connectionStatus: s.connectionStatus, width: s.width, height: s.height, }); function ConnectionLineWrapper({ containerStyle, style, type, component }: ConnectionLineWrapperProps) { - const { nodeId, handleType, nodesConnectable, width, height } = useStore(selector, shallow); + const { nodeId, handleType, nodesConnectable, width, height, connectionStatus } = useStore(selector, shallow); const isValid = !!(nodeId && handleType && width && nodesConnectable); if (!isValid) { @@ -146,8 +157,15 @@ function ConnectionLineWrapper({ containerStyle, style, type, component }: Conne height={height} className="react-flow__edges react-flow__connectionline react-flow__container" > - - + + ); diff --git a/packages/core/src/components/Handle/handler.ts b/packages/core/src/components/Handle/handler.ts index 5c35e48a..5c54118f 100644 --- a/packages/core/src/components/Handle/handler.ts +++ b/packages/core/src/components/Handle/handler.ts @@ -2,11 +2,12 @@ import type { MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } fro import { StoreApi } from 'zustand'; import { getHostForElement, calcAutoPan, getEventPosition } from '../../utils'; -import type { OnConnect, HandleType, ReactFlowState, Connection } from '../../types'; +import type { OnConnect, HandleType, ReactFlowState, Connection, ConnectionStatus } from '../../types'; import { pointToRendererPoint, rendererPointToPoint } from '../../utils/graph'; import { ConnectionHandle, getClosestHandle, + getConnectionStatus, getHandleLookup, getHandleType, isValidHandle, @@ -91,6 +92,7 @@ export function handlePointerDown({ connectionNodeId: nodeId, connectionHandleId: handleId, connectionHandleType: handleType, + connectionStatus: null, }); onConnectStart?.(event, { nodeId, handleId, handleType }); @@ -123,7 +125,7 @@ export function handlePointerDown({ setState({ connectionPosition: - prevClosestHandle && isValid + prevClosestHandle && result.isValid ? rendererPointToPoint( { x: prevClosestHandle.x, @@ -132,6 +134,7 @@ export function handlePointerDown({ transform ) : connectionPosition, + connectionStatus: getConnectionStatus(!!prevClosestHandle, result.isValid), }); if (!prevClosestHandle) { diff --git a/packages/core/src/components/Handle/utils.ts b/packages/core/src/components/Handle/utils.ts index 235abc92..89e58c49 100644 --- a/packages/core/src/components/Handle/utils.ts +++ b/packages/core/src/components/Handle/utils.ts @@ -1,6 +1,6 @@ import { MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } from 'react'; -import { ConnectionMode } from '../../types'; +import { ConnectionMode, ConnectionStatus } from '../../types'; import { getEventPosition, internalsSymbol } from '../../utils'; import type { Connection, HandleType, XYPosition, Node, NodeHandleBounds } from '../../types'; @@ -167,3 +167,15 @@ export function getHandleType( export function resetRecentHandle(handleDomNode: Element): void { handleDomNode?.classList.remove('valid', 'connecting', 'react-flow__handle-valid', 'react-flow__handle-connecting'); } + +export function getConnectionStatus(isInsideConnectionRadius: boolean, isHandleValid: boolean) { + let connectionStatus = null; + + if (isHandleValid) { + connectionStatus = 'valid'; + } else if (isInsideConnectionRadius && !isHandleValid) { + connectionStatus = 'invalid'; + } + + return connectionStatus as ConnectionStatus; +} diff --git a/packages/core/src/store/index.ts b/packages/core/src/store/index.ts index 8b17111c..c85225db 100644 --- a/packages/core/src/store/index.ts +++ b/packages/core/src/store/index.ts @@ -274,6 +274,7 @@ const createRFStore = () => connectionNodeId: initialState.connectionNodeId, connectionHandleId: initialState.connectionHandleId, connectionHandleType: initialState.connectionHandleType, + connectionStatus: initialState.connectionStatus, }), reset: () => set({ ...initialState }), })); diff --git a/packages/core/src/store/initialState.ts b/packages/core/src/store/initialState.ts index afccec2b..99e9d298 100644 --- a/packages/core/src/store/initialState.ts +++ b/packages/core/src/store/initialState.ts @@ -32,6 +32,7 @@ const initialState: ReactFlowStore = { connectionHandleId: null, connectionHandleType: 'source', connectionPosition: { x: 0, y: 0 }, + connectionStatus: null, connectionMode: ConnectionMode.Strict, domNode: null, paneDragging: false, diff --git a/packages/core/src/types/edges.ts b/packages/core/src/types/edges.ts index c2202788..143c7fa6 100644 --- a/packages/core/src/types/edges.ts +++ b/packages/core/src/types/edges.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import type { CSSProperties, ComponentType, HTMLAttributes, ReactNode, MouseEvent as ReactMouseEvent } from 'react'; -import { Position } from '.'; +import { ConnectionStatus, Position } from '.'; import type { Connection, HandleElement, HandleType, Node } from '.'; type EdgeLabelOptions = { @@ -155,6 +155,7 @@ export type ConnectionLineComponentProps = { toY: number; fromPosition: Position; toPosition: Position; + connectionStatus: ConnectionStatus | null; }; export type ConnectionLineComponent = ComponentType; diff --git a/packages/core/src/types/general.ts b/packages/core/src/types/general.ts index 9dbd3dce..4abfa405 100644 --- a/packages/core/src/types/general.ts +++ b/packages/core/src/types/general.ts @@ -61,6 +61,8 @@ export interface Connection { targetHandle: string | null; } +export type ConnectionStatus = 'valid' | 'invalid'; + export enum ConnectionMode { Strict = 'strict', Loose = 'loose', @@ -166,6 +168,7 @@ export type ReactFlowStore = { connectionHandleId: string | null; connectionHandleType: HandleType | null; connectionPosition: XYPosition; + connectionStatus: ConnectionStatus | null; connectionMode: ConnectionMode; snapToGrid: boolean; From 1527795d18c3af38c8ec7059436ea0fbf6c27bbd Mon Sep 17 00:00:00 2001 From: moklick Date: Fri, 3 Feb 2023 21:13:35 +0100 Subject: [PATCH 6/9] chore(changeset): add --- .changeset/silent-suits-smell.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/silent-suits-smell.md diff --git a/.changeset/silent-suits-smell.md b/.changeset/silent-suits-smell.md new file mode 100644 index 00000000..d7cff697 --- /dev/null +++ b/.changeset/silent-suits-smell.md @@ -0,0 +1,5 @@ +--- +'@reactflow/core': patch +--- + +connection: add status class (valid or invalid) while in connection radius From 7a652fc17c61a16057d0207cf9189834d90a24bd Mon Sep 17 00:00:00 2001 From: moklick Date: Sun, 5 Feb 2023 21:58:30 +0100 Subject: [PATCH 7/9] chore(connections): get fresh ref of onConnectEnd --- packages/core/src/components/Handle/handler.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/core/src/components/Handle/handler.ts b/packages/core/src/components/Handle/handler.ts index 5c54118f..6c484edb 100644 --- a/packages/core/src/components/Handle/handler.ts +++ b/packages/core/src/components/Handle/handler.ts @@ -2,7 +2,7 @@ import type { MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } fro import { StoreApi } from 'zustand'; import { getHostForElement, calcAutoPan, getEventPosition } from '../../utils'; -import type { OnConnect, HandleType, ReactFlowState, Connection, ConnectionStatus } from '../../types'; +import type { OnConnect, HandleType, ReactFlowState, Connection } from '../../types'; import { pointToRendererPoint, rendererPointToPoint } from '../../utils/graph'; import { ConnectionHandle, @@ -46,7 +46,6 @@ export function handlePointerDown({ autoPanOnConnect, connectionRadius, onConnectStart, - onConnectEnd, panBy, getNodes, cancelConnection, @@ -159,7 +158,9 @@ export function handlePointerDown({ onConnect?.(connection); } - onConnectEnd?.(event); + // it's important to get a fresh reference from the store here + // in order to get the latest state of onConnectEnd + getState().onConnectEnd?.(event); if (edgeUpdaterType) { onEdgeUpdateEnd?.(event); From b07d940daccb8f8517de856dfd4890635333231e Mon Sep 17 00:00:00 2001 From: moklick Date: Sun, 5 Feb 2023 22:04:02 +0100 Subject: [PATCH 8/9] chore(connections): check if handle + connection radius --- packages/core/src/components/Handle/handler.ts | 2 +- packages/core/src/components/Handle/utils.ts | 12 ++---------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/packages/core/src/components/Handle/handler.ts b/packages/core/src/components/Handle/handler.ts index 6c484edb..9b8855a3 100644 --- a/packages/core/src/components/Handle/handler.ts +++ b/packages/core/src/components/Handle/handler.ts @@ -136,7 +136,7 @@ export function handlePointerDown({ connectionStatus: getConnectionStatus(!!prevClosestHandle, result.isValid), }); - if (!prevClosestHandle) { + if (!prevClosestHandle && !result.isValid) { return resetRecentHandle(prevActiveHandle); } diff --git a/packages/core/src/components/Handle/utils.ts b/packages/core/src/components/Handle/utils.ts index 89e58c49..58263781 100644 --- a/packages/core/src/components/Handle/utils.ts +++ b/packages/core/src/components/Handle/utils.ts @@ -74,14 +74,6 @@ export function isValidHandle( isValidConnection: ValidConnectionFunc, doc: Document | ShadowRoot ) { - if (!handle) { - return { - handleDomNode: null, - isValid: false, - connection: nullConnection, - }; - } - const isTarget = fromType === 'target'; const handleDomNode = doc.querySelector( `.react-flow__handle[data-id="${handle?.nodeId}-${handle?.id}-${handle?.type}"]` @@ -102,9 +94,9 @@ export function isValidHandle( const handleId = handleToCheck.getAttribute('data-handleid'); const connection: Connection = { - source: isTarget ? handle.nodeId : fromNodeId, + source: isTarget ? handleNodeId : fromNodeId, sourceHandle: isTarget ? handleId : fromHandleId, - target: isTarget ? fromNodeId : handle.nodeId, + target: isTarget ? fromNodeId : handleNodeId, targetHandle: isTarget ? fromHandleId : handleId, }; From ecf5ccbb5c865aa039f634e5109b18c1eade876d Mon Sep 17 00:00:00 2001 From: moklick Date: Sun, 5 Feb 2023 22:14:03 +0100 Subject: [PATCH 9/9] chore(packages): bump --- .changeset/fast-chefs-explode.md | 5 ----- .changeset/silent-suits-smell.md | 5 ----- .changeset/sour-impalas-admire.md | 5 ----- packages/background/CHANGELOG.md | 7 +++++++ packages/background/package.json | 2 +- packages/controls/CHANGELOG.md | 7 +++++++ packages/controls/package.json | 2 +- packages/core/CHANGELOG.md | 10 ++++++++++ packages/core/package.json | 2 +- packages/minimap/CHANGELOG.md | 7 +++++++ packages/minimap/package.json | 2 +- packages/node-toolbar/CHANGELOG.md | 7 +++++++ packages/node-toolbar/package.json | 2 +- packages/reactflow/CHANGELOG.md | 17 +++++++++++++++++ packages/reactflow/package.json | 2 +- 15 files changed, 61 insertions(+), 21 deletions(-) delete mode 100644 .changeset/fast-chefs-explode.md delete mode 100644 .changeset/silent-suits-smell.md delete mode 100644 .changeset/sour-impalas-admire.md diff --git a/.changeset/fast-chefs-explode.md b/.changeset/fast-chefs-explode.md deleted file mode 100644 index 4866ec9e..00000000 --- a/.changeset/fast-chefs-explode.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@reactflow/core': patch ---- - -When node is not draggable, you can't move it with a selection either diff --git a/.changeset/silent-suits-smell.md b/.changeset/silent-suits-smell.md deleted file mode 100644 index d7cff697..00000000 --- a/.changeset/silent-suits-smell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@reactflow/core': patch ---- - -connection: add status class (valid or invalid) while in connection radius diff --git a/.changeset/sour-impalas-admire.md b/.changeset/sour-impalas-admire.md deleted file mode 100644 index 598f8049..00000000 --- a/.changeset/sour-impalas-admire.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@reactflow/core': patch ---- - -fix(ios): connection error + dont snap invalid connection lines diff --git a/packages/background/CHANGELOG.md b/packages/background/CHANGELOG.md index faa7accb..1f12e5b2 100644 --- a/packages/background/CHANGELOG.md +++ b/packages/background/CHANGELOG.md @@ -1,5 +1,12 @@ # @reactflow/background +## 11.1.6 + +### Patch Changes + +- Updated dependencies [[`be8097ac`](https://github.com/wbkd/react-flow/commit/be8097acadca3054c3b236ce4296fc516010ef8c), [`1527795d`](https://github.com/wbkd/react-flow/commit/1527795d18c3af38c8ec7059436ea0fbf6c27bbd), [`3b6348a8`](https://github.com/wbkd/react-flow/commit/3b6348a8d1573afb39576327318bc172e33393c2)]: + - @reactflow/core@11.5.3 + ## 11.1.5 ### Patch Changes diff --git a/packages/background/package.json b/packages/background/package.json index dc8213f2..e840a1ae 100644 --- a/packages/background/package.json +++ b/packages/background/package.json @@ -1,6 +1,6 @@ { "name": "@reactflow/background", - "version": "11.1.5", + "version": "11.1.6", "description": "Background component with different variants for React Flow", "keywords": [ "react", diff --git a/packages/controls/CHANGELOG.md b/packages/controls/CHANGELOG.md index 64f29130..acf969a7 100644 --- a/packages/controls/CHANGELOG.md +++ b/packages/controls/CHANGELOG.md @@ -1,5 +1,12 @@ # @reactflow/controls +## 11.1.6 + +### Patch Changes + +- Updated dependencies [[`be8097ac`](https://github.com/wbkd/react-flow/commit/be8097acadca3054c3b236ce4296fc516010ef8c), [`1527795d`](https://github.com/wbkd/react-flow/commit/1527795d18c3af38c8ec7059436ea0fbf6c27bbd), [`3b6348a8`](https://github.com/wbkd/react-flow/commit/3b6348a8d1573afb39576327318bc172e33393c2)]: + - @reactflow/core@11.5.3 + ## 11.1.5 ### Patch Changes diff --git a/packages/controls/package.json b/packages/controls/package.json index dd7d69ad..dd8008f8 100644 --- a/packages/controls/package.json +++ b/packages/controls/package.json @@ -1,6 +1,6 @@ { "name": "@reactflow/controls", - "version": "11.1.5", + "version": "11.1.6", "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 742ac7c0..7f5e7d0b 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,15 @@ # @reactflow/core +## 11.5.3 + +This release fixes some issues with the newly introduced connection radius feature. We are now not only checking the radius but the handle itself too (like in the old version). That means that you can connect to a handle that is bigger than the connection radius. We are also not snapping connections anymore when they are not valid and pass a status class to the connection line that says if the current connection is valid or not. More over we fixed a connection issue with iOS. + +### Patch Changes + +- [#2800](https://github.com/wbkd/react-flow/pull/2800) [`be8097ac`](https://github.com/wbkd/react-flow/commit/be8097acadca3054c3b236ce4296fc516010ef8c) - When node is not draggable, you can't move it with a selection either +- [#2803](https://github.com/wbkd/react-flow/pull/2803) [`1527795d`](https://github.com/wbkd/react-flow/commit/1527795d18c3af38c8ec7059436ea0fbf6c27bbd) - connection: add status class (valid or invalid) while in connection radius +- [#2801](https://github.com/wbkd/react-flow/pull/2801) [`3b6348a8`](https://github.com/wbkd/react-flow/commit/3b6348a8d1573afb39576327318bc172e33393c2) - fix(ios): connection error + dont snap invalid connection lines, check handle and connection radius + ## 11.5.2 ### Patch Changes diff --git a/packages/core/package.json b/packages/core/package.json index db3f7b1a..9171521e 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@reactflow/core", - "version": "11.5.2", + "version": "11.5.3", "description": "Core components and util functions of React Flow.", "keywords": [ "react", diff --git a/packages/minimap/CHANGELOG.md b/packages/minimap/CHANGELOG.md index 503661bc..f3b94881 100644 --- a/packages/minimap/CHANGELOG.md +++ b/packages/minimap/CHANGELOG.md @@ -1,5 +1,12 @@ # @reactflow/minimap +## 11.3.6 + +### Patch Changes + +- Updated dependencies [[`be8097ac`](https://github.com/wbkd/react-flow/commit/be8097acadca3054c3b236ce4296fc516010ef8c), [`1527795d`](https://github.com/wbkd/react-flow/commit/1527795d18c3af38c8ec7059436ea0fbf6c27bbd), [`3b6348a8`](https://github.com/wbkd/react-flow/commit/3b6348a8d1573afb39576327318bc172e33393c2)]: + - @reactflow/core@11.5.3 + ## 11.3.5 ### Patch Changes diff --git a/packages/minimap/package.json b/packages/minimap/package.json index b0a99560..08d9c59a 100644 --- a/packages/minimap/package.json +++ b/packages/minimap/package.json @@ -1,6 +1,6 @@ { "name": "@reactflow/minimap", - "version": "11.3.5", + "version": "11.3.6", "description": "Minimap component for React Flow.", "keywords": [ "react", diff --git a/packages/node-toolbar/CHANGELOG.md b/packages/node-toolbar/CHANGELOG.md index 4160a858..4c15ad33 100644 --- a/packages/node-toolbar/CHANGELOG.md +++ b/packages/node-toolbar/CHANGELOG.md @@ -1,5 +1,12 @@ # @reactflow/node-toolbar +## 1.1.6 + +### Patch Changes + +- Updated dependencies [[`be8097ac`](https://github.com/wbkd/react-flow/commit/be8097acadca3054c3b236ce4296fc516010ef8c), [`1527795d`](https://github.com/wbkd/react-flow/commit/1527795d18c3af38c8ec7059436ea0fbf6c27bbd), [`3b6348a8`](https://github.com/wbkd/react-flow/commit/3b6348a8d1573afb39576327318bc172e33393c2)]: + - @reactflow/core@11.5.3 + ## 1.1.5 ### Patch Changes diff --git a/packages/node-toolbar/package.json b/packages/node-toolbar/package.json index 993e3909..3788fd33 100644 --- a/packages/node-toolbar/package.json +++ b/packages/node-toolbar/package.json @@ -1,6 +1,6 @@ { "name": "@reactflow/node-toolbar", - "version": "1.1.5", + "version": "1.1.6", "description": "A toolbar component for React Flow that can be attached to a node.", "keywords": [ "react", diff --git a/packages/reactflow/CHANGELOG.md b/packages/reactflow/CHANGELOG.md index 3e83a008..4201ed0b 100644 --- a/packages/reactflow/CHANGELOG.md +++ b/packages/reactflow/CHANGELOG.md @@ -1,5 +1,22 @@ # reactflow +## 11.5.4 + +This release fixes some issues with the newly introduced connection radius feature. We are now not only checking the radius but the handle itself too (like in the old version). That means that you can connect to a handle that is bigger than the connection radius. We are also not snapping connections anymore when they are not valid and pass a status class to the connection line that says if the current connection is valid or not. More over we fixed a connection issue with iOS. + +### Patch Changes + +- [#2800](https://github.com/wbkd/react-flow/pull/2800) [`be8097ac`](https://github.com/wbkd/react-flow/commit/be8097acadca3054c3b236ce4296fc516010ef8c) - When node is not draggable, you can't move it with a selection either +- [#2803](https://github.com/wbkd/react-flow/pull/2803) [`1527795d`](https://github.com/wbkd/react-flow/commit/1527795d18c3af38c8ec7059436ea0fbf6c27bbd) - connection: add status class (valid or invalid) while in connection radius +- [#2801](https://github.com/wbkd/react-flow/pull/2801) [`3b6348a8`](https://github.com/wbkd/react-flow/commit/3b6348a8d1573afb39576327318bc172e33393c2) - fix(ios): connection error + dont snap invalid connection lines, check handle and connection radius + +- Updated dependencies [[`be8097ac`](https://github.com/wbkd/react-flow/commit/be8097acadca3054c3b236ce4296fc516010ef8c), [`1527795d`](https://github.com/wbkd/react-flow/commit/1527795d18c3af38c8ec7059436ea0fbf6c27bbd), [`3b6348a8`](https://github.com/wbkd/react-flow/commit/3b6348a8d1573afb39576327318bc172e33393c2)]: + - @reactflow/core@11.5.3 + - @reactflow/background@11.1.6 + - @reactflow/controls@11.1.6 + - @reactflow/minimap@11.3.6 + - @reactflow/node-toolbar@1.1.6 + ## 11.5.3 ### Patch Changes diff --git a/packages/reactflow/package.json b/packages/reactflow/package.json index f2e35e8c..593e37b1 100644 --- a/packages/reactflow/package.json +++ b/packages/reactflow/package.json @@ -1,6 +1,6 @@ { "name": "reactflow", - "version": "11.5.3", + "version": "11.5.4", "description": "A highly customizable React library for building node-based editors and interactive flow charts", "keywords": [ "react",