From 85993cfbf87ec6732c555da9af65f2ce58097ede Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 3 May 2023 11:41:07 +0200 Subject: [PATCH 01/17] fix(autopan): respect translate contraints --- packages/core/src/hooks/useDrag/index.ts | 5 +++-- packages/core/src/store/index.ts | 11 +++++++++-- packages/core/src/types/general.ts | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/core/src/hooks/useDrag/index.ts b/packages/core/src/hooks/useDrag/index.ts index 8821ab4a..346828fb 100644 --- a/packages/core/src/hooks/useDrag/index.ts +++ b/packages/core/src/hooks/useDrag/index.ts @@ -119,8 +119,9 @@ function useDrag({ lastPos.current.x = (lastPos.current.x ?? 0) - xMovement / transform[2]; lastPos.current.y = (lastPos.current.y ?? 0) - yMovement / transform[2]; - updateNodes(lastPos.current as XYPosition); - panBy({ x: xMovement, y: yMovement }); + if (panBy({ x: xMovement, y: yMovement })) { + updateNodes(lastPos.current as XYPosition); + } } autoPanId.current = requestAnimationFrame(autoPan); }; diff --git a/packages/core/src/store/index.ts b/packages/core/src/store/index.ts index f4365d45..5c152969 100644 --- a/packages/core/src/store/index.ts +++ b/packages/core/src/store/index.ts @@ -252,11 +252,11 @@ const createRFStore = () => nodeInternals: new Map(nodeInternals), }); }, - panBy: (delta: XYPosition) => { + panBy: (delta: XYPosition): boolean => { const { transform, width, height, d3Zoom, d3Selection, translateExtent } = get(); if (!d3Zoom || !d3Selection || (!delta.x && !delta.y)) { - return; + return false; } const nextTransform = zoomIdentity.translate(transform[0] + delta.x, transform[1] + delta.y).scale(transform[2]); @@ -268,6 +268,13 @@ const createRFStore = () => const constrainedTransform = d3Zoom?.constrain()(nextTransform, extent, translateExtent); d3Zoom.transform(d3Selection, constrainedTransform); + + const transformChanged = + transform[0] !== constrainedTransform.x || + transform[1] !== constrainedTransform.y || + transform[2] !== constrainedTransform.k; + + return transformChanged; }, cancelConnection: () => set({ diff --git a/packages/core/src/types/general.ts b/packages/core/src/types/general.ts index f57a1ea7..9803d4a0 100644 --- a/packages/core/src/types/general.ts +++ b/packages/core/src/types/general.ts @@ -252,7 +252,7 @@ export type ReactFlowActions = { cancelConnection: () => void; reset: () => void; triggerNodeChanges: (changes: NodeChange[]) => void; - panBy: (delta: XYPosition) => void; + panBy: (delta: XYPosition) => boolean; }; export type ReactFlowState = ReactFlowStore & ReactFlowActions; From a3fa164c34cc820c79bb031c9fd97b72a3546614 Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 3 May 2023 11:45:53 +0200 Subject: [PATCH 02/17] chore(changeset): add --- .changeset/strange-geckos-shake.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/strange-geckos-shake.md diff --git a/.changeset/strange-geckos-shake.md b/.changeset/strange-geckos-shake.md new file mode 100644 index 00000000..88490903 --- /dev/null +++ b/.changeset/strange-geckos-shake.md @@ -0,0 +1,5 @@ +--- +'@reactflow/core': patch +--- + +fix(autopan): only update nodes when transform change happen From 607305db6d0cff3b627cf9c13ab13d4f3e1d503f Mon Sep 17 00:00:00 2001 From: Noam Neeman Date: Fri, 5 May 2023 08:12:45 +0300 Subject: [PATCH 03/17] feat(NodeToolbar): add align prop --- packages/node-toolbar/src/NodeToolbar.tsx | 49 +++++++++++++++++++++-- packages/node-toolbar/src/types.ts | 7 ++++ 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/packages/node-toolbar/src/NodeToolbar.tsx b/packages/node-toolbar/src/NodeToolbar.tsx index 428708da..d6394acf 100644 --- a/packages/node-toolbar/src/NodeToolbar.tsx +++ b/packages/node-toolbar/src/NodeToolbar.tsx @@ -14,7 +14,7 @@ import cc from 'classcat'; import { shallow } from 'zustand/shallow'; import NodeToolbarPortal from './NodeToolbarPortal'; -import { NodeToolbarProps } from './types'; +import { Align, NodeToolbarProps } from './types'; const nodeEqualityFn = (a: Node | undefined, b: Node | undefined) => a?.positionAbsolute?.x === b?.positionAbsolute?.x && @@ -34,12 +34,22 @@ const storeSelector = (state: ReactFlowState) => ({ selectedNodesCount: state.getNodes().filter((node) => node.selected).length, }); -function getTransform(nodeRect: Rect, transform: Transform, position: Position, offset: number): string { +function getTransform(nodeRect: Rect, transform: Transform, position: Position, offset: number, align: Align): string { // position === Position.Top let xPos = (nodeRect.x + nodeRect.width / 2) * transform[2] + transform[0]; let yPos = nodeRect.y * transform[2] + transform[1] - offset; let xShift = -50; let yShift = -100; + switch (align) { + case Align.Start: + xPos = nodeRect.x * transform[2] + transform[0]; + xShift = 0; + break; + case Align.End: + xPos = (nodeRect.x + nodeRect.width) * transform[2] + transform[0]; + xShift = -100; + break; + } switch (position) { case Position.Right: @@ -47,16 +57,48 @@ function getTransform(nodeRect: Rect, transform: Transform, position: Position, yPos = (nodeRect.y + nodeRect.height / 2) * transform[2] + transform[1]; xShift = 0; yShift = -50; + + switch (align) { + case Align.Start: + yPos = nodeRect.y * transform[2] + transform[1]; + yShift = 0; + break; + case Align.End: + yPos = (nodeRect.y + nodeRect.height) * transform[2] + transform[1]; + yShift = -100; + break; + } break; case Position.Bottom: yPos = (nodeRect.y + nodeRect.height) * transform[2] + transform[1] + offset; yShift = 0; + switch (align) { + case Align.Start: + xPos = nodeRect.x * transform[2] + transform[0]; + xShift = 0; + break; + case Align.End: + xPos = (nodeRect.x + nodeRect.width) * transform[2] + transform[0]; + xShift = -100; + break; + } break; case Position.Left: xPos = nodeRect.x * transform[2] + transform[0] - offset; yPos = (nodeRect.y + nodeRect.height / 2) * transform[2] + transform[1]; xShift = -100; yShift = -50; + + switch (align) { + case Align.Start: + yPos = nodeRect.y * transform[2] + transform[1]; + yShift = 0; + break; + case Align.End: + yPos = (nodeRect.y + nodeRect.height) * transform[2] + transform[1]; + yShift = -100; + break; + } break; } @@ -71,6 +113,7 @@ function NodeToolbar({ isVisible, position = Position.Top, offset = 10, + align = Align.Center, ...rest }: NodeToolbarProps) { const contextNodeId = useNodeId(); @@ -103,7 +146,7 @@ function NodeToolbar({ const wrapperStyle: CSSProperties = { position: 'absolute', - transform: getTransform(nodeRect, transform, position, offset), + transform: getTransform(nodeRect, transform, position, offset, align), zIndex, ...style, }; diff --git a/packages/node-toolbar/src/types.ts b/packages/node-toolbar/src/types.ts index e2b0d73c..33f82762 100644 --- a/packages/node-toolbar/src/types.ts +++ b/packages/node-toolbar/src/types.ts @@ -6,4 +6,11 @@ export type NodeToolbarProps = HTMLAttributes & { isVisible?: boolean; position?: Position; offset?: number; + align?: Align; }; + +export enum Align { + Center = 'center', + Start = 'start', + End = 'end', +} From 921512eec4b7f319a58b555719a3e9c2a9024a4d Mon Sep 17 00:00:00 2001 From: Noam Neeman Date: Fri, 5 May 2023 11:28:55 +0300 Subject: [PATCH 04/17] more --- .../src/examples/NodeToolbar/CustomNode.tsx | 2 +- .../src/examples/NodeToolbar/index.tsx | 2 +- packages/node-toolbar/src/NodeToolbar.tsx | 57 +++++++------------ packages/node-toolbar/src/types.ts | 6 +- 4 files changed, 25 insertions(+), 42 deletions(-) diff --git a/examples/vite-app/src/examples/NodeToolbar/CustomNode.tsx b/examples/vite-app/src/examples/NodeToolbar/CustomNode.tsx index ca2ac0b7..7d179b7e 100644 --- a/examples/vite-app/src/examples/NodeToolbar/CustomNode.tsx +++ b/examples/vite-app/src/examples/NodeToolbar/CustomNode.tsx @@ -4,7 +4,7 @@ import { Handle, Position, NodeProps, NodeToolbar } from 'reactflow'; const CustomNode: FC = ({ id, data }) => { return ( <> - + diff --git a/examples/vite-app/src/examples/NodeToolbar/index.tsx b/examples/vite-app/src/examples/NodeToolbar/index.tsx index 601d8618..70d8e36e 100644 --- a/examples/vite-app/src/examples/NodeToolbar/index.tsx +++ b/examples/vite-app/src/examples/NodeToolbar/index.tsx @@ -35,7 +35,7 @@ const initialNodes: Node[] = [ { id: '3', type: 'custom', - data: { label: 'toolbar bottom', toolbarPosition: Position.Bottom }, + data: { label: 'toolbar bottom', toolbarPosition: Position.Bottom, toolbarAlign: 'end' }, position: { x: 400, y: 100 }, className: 'react-flow__node-default', }, diff --git a/packages/node-toolbar/src/NodeToolbar.tsx b/packages/node-toolbar/src/NodeToolbar.tsx index d6394acf..86ea993c 100644 --- a/packages/node-toolbar/src/NodeToolbar.tsx +++ b/packages/node-toolbar/src/NodeToolbar.tsx @@ -40,16 +40,6 @@ function getTransform(nodeRect: Rect, transform: Transform, position: Position, let yPos = nodeRect.y * transform[2] + transform[1] - offset; let xShift = -50; let yShift = -100; - switch (align) { - case Align.Start: - xPos = nodeRect.x * transform[2] + transform[0]; - xShift = 0; - break; - case Align.End: - xPos = (nodeRect.x + nodeRect.width) * transform[2] + transform[0]; - xShift = -100; - break; - } switch (position) { case Position.Right: @@ -57,50 +47,47 @@ function getTransform(nodeRect: Rect, transform: Transform, position: Position, yPos = (nodeRect.y + nodeRect.height / 2) * transform[2] + transform[1]; xShift = 0; yShift = -50; - - switch (align) { - case Align.Start: - yPos = nodeRect.y * transform[2] + transform[1]; - yShift = 0; - break; - case Align.End: - yPos = (nodeRect.y + nodeRect.height) * transform[2] + transform[1]; - yShift = -100; - break; - } break; case Position.Bottom: yPos = (nodeRect.y + nodeRect.height) * transform[2] + transform[1] + offset; yShift = 0; - switch (align) { - case Align.Start: - xPos = nodeRect.x * transform[2] + transform[0]; - xShift = 0; - break; - case Align.End: - xPos = (nodeRect.x + nodeRect.width) * transform[2] + transform[0]; - xShift = -100; - break; - } break; case Position.Left: xPos = nodeRect.x * transform[2] + transform[0] - offset; yPos = (nodeRect.y + nodeRect.height / 2) * transform[2] + transform[1]; xShift = -100; yShift = -50; + break; + } + switch (position) { + case Position.Right: + case Position.Left: switch (align) { - case Align.Start: + case 'start': yPos = nodeRect.y * transform[2] + transform[1]; yShift = 0; break; - case Align.End: + case 'end': yPos = (nodeRect.y + nodeRect.height) * transform[2] + transform[1]; yShift = -100; break; } break; - } + case Position.Top: + case Position.Bottom: + switch (align) { + case 'start': + xPos = nodeRect.x * transform[2] + transform[0]; + xShift = 0; + break; + case 'end': + xPos = (nodeRect.x + nodeRect.width) * transform[2] + transform[0]; + xShift = -100; + break; + } + break +} return `translate(${xPos}px, ${yPos}px) translate(${xShift}%, ${yShift}%)`; } @@ -113,7 +100,7 @@ function NodeToolbar({ isVisible, position = Position.Top, offset = 10, - align = Align.Center, + align = 'center', ...rest }: NodeToolbarProps) { const contextNodeId = useNodeId(); diff --git a/packages/node-toolbar/src/types.ts b/packages/node-toolbar/src/types.ts index 33f82762..7ff2087b 100644 --- a/packages/node-toolbar/src/types.ts +++ b/packages/node-toolbar/src/types.ts @@ -9,8 +9,4 @@ export type NodeToolbarProps = HTMLAttributes & { align?: Align; }; -export enum Align { - Center = 'center', - Start = 'start', - End = 'end', -} +export type Align = 'center' | 'start' | 'end'; From c428b906b759dd7e08cc919942e0f8bc9c9c4a3d Mon Sep 17 00:00:00 2001 From: moklick Date: Tue, 9 May 2023 17:08:14 +0200 Subject: [PATCH 05/17] refactor(handles): reduce re-renderings, handles on top of each other #3010 --- .../src/examples/EasyConnect/CustomNode.tsx | 18 +++++++-------- .../src/examples/EasyConnect/style.css | 14 +----------- .../core/src/components/Handle/handler.ts | 20 ++++++++--------- packages/core/src/components/Handle/index.tsx | 2 +- packages/core/src/components/Handle/utils.ts | 22 +++++++++++++++---- 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/examples/vite-app/src/examples/EasyConnect/CustomNode.tsx b/examples/vite-app/src/examples/EasyConnect/CustomNode.tsx index 989df5fa..bd107c93 100644 --- a/examples/vite-app/src/examples/EasyConnect/CustomNode.tsx +++ b/examples/vite-app/src/examples/EasyConnect/CustomNode.tsx @@ -2,8 +2,9 @@ import { Handle, NodeProps, Position, ReactFlowState, useStore } from 'reactflow const connectionNodeIdSelector = (state: ReactFlowState) => state.connectionNodeId; -export default function CustomNode({ id, isConnectable }: NodeProps) { +export default function CustomNode({ id }: NodeProps) { const connectionNodeId = useStore(connectionNodeIdSelector); + const isConnecting = !!connectionNodeId; const isTarget = connectionNodeId && connectionNodeId !== id; const targetHandleStyle = { zIndex: isTarget ? 3 : 1 }; @@ -18,19 +19,16 @@ export default function CustomNode({ id, isConnectable }: NodeProps) { backgroundColor: isTarget ? '#ffcce3' : '#ccd9f6', }} > + {!isConnecting && ( + + )} + - {label} diff --git a/examples/vite-app/src/examples/EasyConnect/style.css b/examples/vite-app/src/examples/EasyConnect/style.css index c2ebc0a2..8e06c4ea 100644 --- a/examples/vite-app/src/examples/EasyConnect/style.css +++ b/examples/vite-app/src/examples/EasyConnect/style.css @@ -28,19 +28,7 @@ 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 { +div.customHandle { width: 100%; height: 100%; background: blue; diff --git a/packages/core/src/components/Handle/handler.ts b/packages/core/src/components/Handle/handler.ts index 9825295b..0b598dec 100644 --- a/packages/core/src/components/Handle/handler.ts +++ b/packages/core/src/components/Handle/handler.ts @@ -51,7 +51,7 @@ export function handlePointerDown({ cancelConnection, } = getState(); let autoPanId = 0; - let prevClosestHandle: ConnectionHandle | null; + let closestHandle: ConnectionHandle | null; const { x, y } = getEventPosition(event); const clickedHandle = doc?.elementFromPoint(x, y); @@ -106,9 +106,9 @@ export function handlePointerDown({ function onPointerMove(event: MouseEvent | TouchEvent) { const { transform } = getState(); - connectionPosition = getEventPosition(event, containerBounds); - prevClosestHandle = getClosestHandle( + connectionPosition = getEventPosition(event, containerBounds); + closestHandle = getClosestHandle( pointToRendererPoint(connectionPosition, transform, false, [1, 1]), connectionRadius, handleLookup @@ -121,7 +121,7 @@ export function handlePointerDown({ const result = isValidHandle( event, - prevClosestHandle, + closestHandle, connectionMode, nodeId, handleId, @@ -136,20 +136,20 @@ export function handlePointerDown({ setState({ connectionPosition: - prevClosestHandle && isValid + closestHandle && isValid ? rendererPointToPoint( { - x: prevClosestHandle.x, - y: prevClosestHandle.y, + x: closestHandle.x, + y: closestHandle.y, }, transform ) : connectionPosition, - connectionStatus: getConnectionStatus(!!prevClosestHandle, isValid), + connectionStatus: getConnectionStatus(!!closestHandle, isValid), connectionEndHandle: result.endHandle, }); - if (!prevClosestHandle && !isValid && !handleDomNode) { + if (!closestHandle && !isValid && !handleDomNode) { return resetRecentHandle(prevActiveHandle); } @@ -164,7 +164,7 @@ export function handlePointerDown({ } function onPointerUp(event: MouseEvent | TouchEvent) { - if ((prevClosestHandle || handleDomNode) && connection && isValid) { + if ((closestHandle || handleDomNode) && connection && isValid) { onConnect?.(connection); } diff --git a/packages/core/src/components/Handle/index.tsx b/packages/core/src/components/Handle/index.tsx index dcd95d7c..ca724285 100644 --- a/packages/core/src/components/Handle/index.tsx +++ b/packages/core/src/components/Handle/index.tsx @@ -62,7 +62,7 @@ const Handle = forwardRef( const store = useStoreApi(); const nodeId = useNodeId(); const { connectOnClick, noPanClassName } = useStore(selector, shallow); - const { connecting, clickConnecting } = useStore(connectingSelector(nodeId, handleId, type)); + const { connecting, clickConnecting } = useStore(connectingSelector(nodeId, handleId, type), shallow); if (!nodeId) { store.getState().onError?.('010', errorMessages['error010']()); diff --git a/packages/core/src/components/Handle/utils.ts b/packages/core/src/components/Handle/utils.ts index b8e8cf6a..353b249a 100644 --- a/packages/core/src/components/Handle/utils.ts +++ b/packages/core/src/components/Handle/utils.ts @@ -41,18 +41,30 @@ export function getClosestHandle( connectionRadius: number, handles: ConnectionHandle[] ): ConnectionHandle | null { - let closestHandle: ConnectionHandle | null = null; + let closestHandles: ConnectionHandle[] = []; let minDistance = Infinity; handles.forEach((handle) => { const distance = Math.sqrt(Math.pow(handle.x - pos.x, 2) + Math.pow(handle.y - pos.y, 2)); - if (distance <= connectionRadius && distance < minDistance) { + if (distance <= connectionRadius) { + if (distance < minDistance) { + closestHandles = [handle]; + } else if (distance === minDistance) { + // when multiple handles are on the same distance we collect all of them + closestHandles.push(handle); + } minDistance = distance; - closestHandle = handle; } }); - return closestHandle; + if (!closestHandles.length) { + return null; + } + + return closestHandles.length === 1 + ? closestHandles[0] + : // if multiple handles are layouted on top of each other we take the one with type = target because it's more likely that the user wants to connect to this one + closestHandles.find((handle) => handle.type === 'target') || closestHandles[0]; } type Result = { @@ -81,6 +93,8 @@ export function isValidHandle( ); const { x, y } = getEventPosition(event); const handleBelow = doc.elementFromPoint(x, y); + // we always want to prioritize the handle below the mouse cursor over the closest distance handle, + // because it could be that the center of another handle is closer to the mouse pointer than the handle below the cursor const handleToCheck = handleBelow?.classList.contains('react-flow__handle') ? handleBelow : handleDomNode; const result: Result = { From cf7a7d3dad1e73215a72a5dc72e21fd50208cdbb Mon Sep 17 00:00:00 2001 From: moklick Date: Tue, 9 May 2023 17:09:28 +0200 Subject: [PATCH 06/17] chore(changeset): add --- .changeset/dirty-tools-switch.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/dirty-tools-switch.md diff --git a/.changeset/dirty-tools-switch.md b/.changeset/dirty-tools-switch.md new file mode 100644 index 00000000..d07b3e1d --- /dev/null +++ b/.changeset/dirty-tools-switch.md @@ -0,0 +1,5 @@ +--- +'@reactflow/core': patch +--- + +handles: handles on top of each other, reduce re-renderings From 70102b701b633760806692f54ef49bedf570f14a Mon Sep 17 00:00:00 2001 From: braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Thu, 20 Apr 2023 19:07:53 +0200 Subject: [PATCH 07/17] feat(core): allow array of ids as updateNodeInternals arg --- packages/core/src/hooks/useUpdateNodeInternals.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/core/src/hooks/useUpdateNodeInternals.ts b/packages/core/src/hooks/useUpdateNodeInternals.ts index 849d76b6..466ad4ce 100644 --- a/packages/core/src/hooks/useUpdateNodeInternals.ts +++ b/packages/core/src/hooks/useUpdateNodeInternals.ts @@ -6,12 +6,16 @@ import type { UpdateNodeInternals } from '../types'; function useUpdateNodeInternals(): UpdateNodeInternals { const store = useStoreApi(); - return useCallback((id: string) => { + return useCallback((id: string | string[]) => { const { domNode, updateNodeDimensions } = store.getState(); const nodeElement = domNode?.querySelector(`.react-flow__node[data-id="${id}"]`) as HTMLDivElement; if (nodeElement) { - requestAnimationFrame(() => updateNodeDimensions([{ id, nodeElement, forceUpdate: true }])); + const updateIds = Array.isArray(id) ? id : [id]; + + updateIds.forEach((id) => { + requestAnimationFrame(() => updateNodeDimensions([{ id, nodeElement, forceUpdate: true }])); + }); } }, []); } From c80d269b85a0054221f4639c328fc36a3befbe70 Mon Sep 17 00:00:00 2001 From: braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Thu, 20 Apr 2023 19:08:42 +0200 Subject: [PATCH 08/17] chore(changeset): add --- .changeset/mighty-seas-hang.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/mighty-seas-hang.md diff --git a/.changeset/mighty-seas-hang.md b/.changeset/mighty-seas-hang.md new file mode 100644 index 00000000..e8384b27 --- /dev/null +++ b/.changeset/mighty-seas-hang.md @@ -0,0 +1,5 @@ +--- +'@reactflow/core': minor +--- + +Add `edgesUpdatable` prop to store state. Allows enabling/disabling edge updating globally. From 80e586fa5e80aa40a317b881578aecb6048ac860 Mon Sep 17 00:00:00 2001 From: braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Tue, 2 May 2023 17:32:44 +0200 Subject: [PATCH 09/17] refactor(core): wrap for-each loop in requestAnimationFrame --- packages/core/src/hooks/useUpdateNodeInternals.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/core/src/hooks/useUpdateNodeInternals.ts b/packages/core/src/hooks/useUpdateNodeInternals.ts index 466ad4ce..6035dc98 100644 --- a/packages/core/src/hooks/useUpdateNodeInternals.ts +++ b/packages/core/src/hooks/useUpdateNodeInternals.ts @@ -13,9 +13,11 @@ function useUpdateNodeInternals(): UpdateNodeInternals { if (nodeElement) { const updateIds = Array.isArray(id) ? id : [id]; - updateIds.forEach((id) => { - requestAnimationFrame(() => updateNodeDimensions([{ id, nodeElement, forceUpdate: true }])); - }); + requestAnimationFrame(() => { + updateIds.forEach((id) => { + updateNodeDimensions([{ id, nodeElement, forceUpdate: true }]); + }); + }) } }, []); } From a72ab2f2dc8c892c6e90b6a6970cfd05c79d4898 Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 10 May 2023 12:32:25 +0200 Subject: [PATCH 10/17] refactor(base-edge): pass id to base edge path --- examples/vite-app/src/examples/Edges/CustomEdge.tsx | 4 ++-- examples/vite-app/src/examples/Edges/CustomEdge2.tsx | 5 ++--- packages/core/src/components/Edges/BaseEdge.tsx | 2 ++ packages/core/src/types/edges.ts | 1 + 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/examples/vite-app/src/examples/Edges/CustomEdge.tsx b/examples/vite-app/src/examples/Edges/CustomEdge.tsx index ec7dfb74..ff700413 100644 --- a/examples/vite-app/src/examples/Edges/CustomEdge.tsx +++ b/examples/vite-app/src/examples/Edges/CustomEdge.tsx @@ -1,5 +1,5 @@ import { FC } from 'react'; -import { EdgeProps, getBezierPath } from 'reactflow'; +import { BaseEdge, EdgeProps, getBezierPath } from 'reactflow'; const CustomEdge: FC = ({ id, @@ -22,7 +22,7 @@ const CustomEdge: FC = ({ return ( <> - + {data.text} diff --git a/examples/vite-app/src/examples/Edges/CustomEdge2.tsx b/examples/vite-app/src/examples/Edges/CustomEdge2.tsx index 0ad41920..b40f12cb 100644 --- a/examples/vite-app/src/examples/Edges/CustomEdge2.tsx +++ b/examples/vite-app/src/examples/Edges/CustomEdge2.tsx @@ -1,5 +1,5 @@ import { FC } from 'react'; -import { EdgeProps, getBezierPath, EdgeText } from 'reactflow'; +import { EdgeProps, getBezierPath, EdgeText, BaseEdge } from 'reactflow'; const CustomEdge: FC = ({ id, @@ -22,7 +22,7 @@ const CustomEdge: FC = ({ return ( <> - + = ({ labelBgBorderRadius={2} onClick={() => console.log(data)} /> - ; ); }; diff --git a/packages/core/src/components/Edges/BaseEdge.tsx b/packages/core/src/components/Edges/BaseEdge.tsx index dc60493c..a9202820 100644 --- a/packages/core/src/components/Edges/BaseEdge.tsx +++ b/packages/core/src/components/Edges/BaseEdge.tsx @@ -3,6 +3,7 @@ import { isNumeric } from '../../utils'; import type { BaseEdgeProps } from '../../types'; const BaseEdge = ({ + id, path, labelX, labelY, @@ -20,6 +21,7 @@ const BaseEdge = ({ return ( <> = Pick< export type BaseEdgeProps = Pick & EdgeLabelOptions & { + id?: string; labelX?: number; labelY?: number; path: string; From 07b975bbee3580249e36a19582213b250f78093c Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 10 May 2023 12:33:12 +0200 Subject: [PATCH 11/17] chore(changeset): add --- .changeset/forty-peas-talk.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/forty-peas-talk.md diff --git a/.changeset/forty-peas-talk.md b/.changeset/forty-peas-talk.md new file mode 100644 index 00000000..ffeccbdf --- /dev/null +++ b/.changeset/forty-peas-talk.md @@ -0,0 +1,5 @@ +--- +'@reactflow/core': patch +--- + +refactor(base-edge): pass id to base edge path From 6a7a18a394a60abf4a8d971bd567b6b4396912dc Mon Sep 17 00:00:00 2001 From: braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Thu, 11 May 2023 20:10:12 +0200 Subject: [PATCH 12/17] chore(core): query node element in for-each loop to get curr el --- .../core/src/hooks/useUpdateNodeInternals.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/core/src/hooks/useUpdateNodeInternals.ts b/packages/core/src/hooks/useUpdateNodeInternals.ts index 6035dc98..9786c65c 100644 --- a/packages/core/src/hooks/useUpdateNodeInternals.ts +++ b/packages/core/src/hooks/useUpdateNodeInternals.ts @@ -8,17 +8,18 @@ function useUpdateNodeInternals(): UpdateNodeInternals { return useCallback((id: string | string[]) => { const { domNode, updateNodeDimensions } = store.getState(); - const nodeElement = domNode?.querySelector(`.react-flow__node[data-id="${id}"]`) as HTMLDivElement; - if (nodeElement) { - const updateIds = Array.isArray(id) ? id : [id]; + const updateIds = Array.isArray(id) ? id : [id]; - requestAnimationFrame(() => { - updateIds.forEach((id) => { - updateNodeDimensions([{ id, nodeElement, forceUpdate: true }]); - }); - }) - } + requestAnimationFrame(() => { + updateIds.forEach((updateId) => { + const nodeElement = domNode?.querySelector(`.react-flow__node[data-id="${updateId}"]`) as HTMLDivElement; + + if (nodeElement) { + updateNodeDimensions([{ id: updateId, nodeElement, forceUpdate: true }]); + } + }); + }); }, []); } From 8386c7af6ce90c46f9c5da81946592978ec50dfc Mon Sep 17 00:00:00 2001 From: moklick Date: Mon, 15 May 2023 10:56:21 +0200 Subject: [PATCH 13/17] refactor(node-toolbar): align prop --- .../src/examples/NodeToolbar/index.tsx | 59 +++++++-------- packages/node-toolbar/src/NodeToolbar.tsx | 72 ++++++++----------- 2 files changed, 52 insertions(+), 79 deletions(-) diff --git a/examples/vite-app/src/examples/NodeToolbar/index.tsx b/examples/vite-app/src/examples/NodeToolbar/index.tsx index 70d8e36e..b4d3d1c5 100644 --- a/examples/vite-app/src/examples/NodeToolbar/index.tsx +++ b/examples/vite-app/src/examples/NodeToolbar/index.tsx @@ -17,49 +17,38 @@ const nodeTypes: NodeTypes = { custom: CustomNode, }; +const positions = ['top', 'right', 'bottom', 'left']; +const alignments = ['start', 'center', 'end']; + const initialNodes: Node[] = [ - { - id: '1', - type: 'custom', - data: { label: 'toolbar top', toolbarPosition: Position.Top }, - position: { x: 0, y: 50 }, - className: 'react-flow__node-default', - }, - { - id: '2', - type: 'custom', - data: { label: 'toolbar right', toolbarPosition: Position.Right }, - position: { x: 300, y: 0 }, - className: 'react-flow__node-default', - }, - { - id: '3', - type: 'custom', - data: { label: 'toolbar bottom', toolbarPosition: Position.Bottom, toolbarAlign: 'end' }, - position: { x: 400, y: 100 }, - className: 'react-flow__node-default', - }, { id: '4', type: 'custom', - data: { label: 'toolbar left', toolbarPosition: Position.Left }, - position: { x: 400, y: 200 }, - className: 'react-flow__node-default', - }, - { - id: '5', - type: 'custom', - data: { label: 'toolbar always open', toolbarPosition: Position.Top, toolbarVisible: true }, - position: { x: 0, y: 200 }, + data: { label: 'toolbar top', toolbarPosition: Position.Top }, + position: { x: 0, y: -200 }, className: 'react-flow__node-default', }, ]; -const initialEdges: Edge[] = [ - { id: 'e1-2', source: '1', target: '2' }, - { id: 'e1-3', source: '1', target: '3' }, - { id: 'e1-4', source: '1', target: '4' }, -]; +positions.forEach((position, posIndex) => { + alignments.forEach((align, alignIndex) => { + const id = `node-${align}-${position}`; + initialNodes.push({ + id, + type: 'custom', + data: { + label: `toolbar ${position} ${align}`, + toolbarPosition: position as Position, + toolbarAlign: align, + toolbarVisible: true, + }, + className: 'react-flow__node-default', + position: { x: posIndex * 300, y: alignIndex * 100 }, + }); + }); +}); + +const initialEdges: Edge[] = []; const defaultEdgeOptions = { zIndex: 0 }; const nodeOrigin: NodeOrigin = [0.5, 0.5]; diff --git a/packages/node-toolbar/src/NodeToolbar.tsx b/packages/node-toolbar/src/NodeToolbar.tsx index 86ea993c..3b02b8bf 100644 --- a/packages/node-toolbar/src/NodeToolbar.tsx +++ b/packages/node-toolbar/src/NodeToolbar.tsx @@ -35,61 +35,45 @@ const storeSelector = (state: ReactFlowState) => ({ }); function getTransform(nodeRect: Rect, transform: Transform, position: Position, offset: number, align: Align): string { + let alignmentOffset = 0.5; + + if (align === 'start') { + alignmentOffset = 0; + } else if (align === 'end') { + alignmentOffset = 1; + } + // position === Position.Top - let xPos = (nodeRect.x + nodeRect.width / 2) * transform[2] + transform[0]; - let yPos = nodeRect.y * transform[2] + transform[1] - offset; - let xShift = -50; - let yShift = -100; + // we set the x any y position of the toolbar based on the nodes position + let pos = [ + (nodeRect.x + nodeRect.width * alignmentOffset) * transform[2] + transform[0], + nodeRect.y * transform[2] + transform[1] - offset, + ]; + // and than shift it based on the alignment. The shift values are in %. + let shift = [-100 * alignmentOffset, -100]; switch (position) { case Position.Right: - xPos = (nodeRect.x + nodeRect.width) * transform[2] + transform[0] + offset; - yPos = (nodeRect.y + nodeRect.height / 2) * transform[2] + transform[1]; - xShift = 0; - yShift = -50; + pos = [ + (nodeRect.x + nodeRect.width) * transform[2] + transform[0] + offset, + (nodeRect.y + nodeRect.height * alignmentOffset) * transform[2] + transform[1], + ]; + shift = [0, -100 * alignmentOffset]; break; case Position.Bottom: - yPos = (nodeRect.y + nodeRect.height) * transform[2] + transform[1] + offset; - yShift = 0; + pos[1] = (nodeRect.y + nodeRect.height) * transform[2] + transform[1] + offset; + shift[1] = 0; break; case Position.Left: - xPos = nodeRect.x * transform[2] + transform[0] - offset; - yPos = (nodeRect.y + nodeRect.height / 2) * transform[2] + transform[1]; - xShift = -100; - yShift = -50; + pos = [ + nodeRect.x * transform[2] + transform[0] - offset, + (nodeRect.y + nodeRect.height * alignmentOffset) * transform[2] + transform[1], + ]; + shift = [-100, -100 * alignmentOffset]; break; } - switch (position) { - case Position.Right: - case Position.Left: - switch (align) { - case 'start': - yPos = nodeRect.y * transform[2] + transform[1]; - yShift = 0; - break; - case 'end': - yPos = (nodeRect.y + nodeRect.height) * transform[2] + transform[1]; - yShift = -100; - break; - } - break; - case Position.Top: - case Position.Bottom: - switch (align) { - case 'start': - xPos = nodeRect.x * transform[2] + transform[0]; - xShift = 0; - break; - case 'end': - xPos = (nodeRect.x + nodeRect.width) * transform[2] + transform[0]; - xShift = -100; - break; - } - break -} - - return `translate(${xPos}px, ${yPos}px) translate(${xShift}%, ${yShift}%)`; + return `translate(${pos[0]}px, ${pos[1]}px) translate(${shift[0]}%, ${shift[1]}%)`; } function NodeToolbar({ From 55e05cf76ae21863691153e76dbd51d1eecd2c60 Mon Sep 17 00:00:00 2001 From: moklick Date: Mon, 15 May 2023 10:58:00 +0200 Subject: [PATCH 14/17] chore(changeset): add --- .changeset/large-seals-reflect.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/large-seals-reflect.md diff --git a/.changeset/large-seals-reflect.md b/.changeset/large-seals-reflect.md new file mode 100644 index 00000000..12a7eff8 --- /dev/null +++ b/.changeset/large-seals-reflect.md @@ -0,0 +1,5 @@ +--- +'@reactflow/node-toolbar': minor +--- + +feat(align): add prop to align bar at start, center or end From 5a9bca1e6229654f7391a0c316995178cfc8b88f Mon Sep 17 00:00:00 2001 From: moklick Date: Mon, 15 May 2023 11:10:39 +0200 Subject: [PATCH 15/17] fix(controls): show correct icon for interactivity button --- packages/controls/src/Controls.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/controls/src/Controls.tsx b/packages/controls/src/Controls.tsx index 73234606..7c529a9e 100644 --- a/packages/controls/src/Controls.tsx +++ b/packages/controls/src/Controls.tsx @@ -1,8 +1,6 @@ -import { memo, useEffect, useState } from 'react'; -import type { FC, PropsWithChildren } from 'react'; +import { memo, useEffect, useState, type FC, type PropsWithChildren } from 'react'; import cc from 'classcat'; -import { useStore, useStoreApi, useReactFlow, Panel } from '@reactflow/core'; -import type { ReactFlowState } from '@reactflow/core'; +import { useStore, useStoreApi, useReactFlow, Panel, type ReactFlowState } from '@reactflow/core'; import PlusIcon from './Icons/Plus'; import MinusIcon from './Icons/Minus'; @@ -13,7 +11,7 @@ import ControlButton from './ControlButton'; import type { ControlProps } from './types'; -const isInteractiveSelector = (s: ReactFlowState) => s.nodesDraggable && s.nodesConnectable && s.elementsSelectable; +const isInteractiveSelector = (s: ReactFlowState) => s.nodesDraggable || s.nodesConnectable || s.elementsSelectable; const Controls: FC> = ({ style, From 46526b4e02b83d74726701e3ba73d0be8cf80787 Mon Sep 17 00:00:00 2001 From: moklick Date: Mon, 15 May 2023 11:11:47 +0200 Subject: [PATCH 16/17] chore(changeset): add --- .changeset/poor-baboons-brake.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/poor-baboons-brake.md diff --git a/.changeset/poor-baboons-brake.md b/.changeset/poor-baboons-brake.md new file mode 100644 index 00000000..ab695a10 --- /dev/null +++ b/.changeset/poor-baboons-brake.md @@ -0,0 +1,5 @@ +--- +'@reactflow/controls': patch +--- + +fix(icons): show correct lock icon From 0d4f7bbfd9764d11a51f2d2698e74a8b3ffa0e5b Mon Sep 17 00:00:00 2001 From: moklick Date: Mon, 15 May 2023 12:03:17 +0200 Subject: [PATCH 17/17] chore(packages): bump --- .changeset/dirty-tools-switch.md | 5 ----- .changeset/forty-peas-talk.md | 5 ----- .changeset/large-seals-reflect.md | 5 ----- .changeset/mighty-seas-hang.md | 5 ----- .changeset/poor-baboons-brake.md | 5 ----- .changeset/strange-geckos-shake.md | 5 ----- packages/background/CHANGELOG.md | 7 +++++++ packages/background/package.json | 2 +- packages/controls/CHANGELOG.md | 9 +++++++++ packages/controls/package.json | 2 +- packages/core/CHANGELOG.md | 12 ++++++++++-- packages/core/package.json | 2 +- packages/minimap/CHANGELOG.md | 7 +++++++ packages/minimap/package.json | 2 +- packages/node-toolbar/CHANGELOG.md | 11 +++++++++++ packages/node-toolbar/package.json | 2 +- packages/reactflow/CHANGELOG.md | 21 ++++++++++++++++++--- packages/reactflow/package.json | 2 +- 18 files changed, 68 insertions(+), 41 deletions(-) delete mode 100644 .changeset/dirty-tools-switch.md delete mode 100644 .changeset/forty-peas-talk.md delete mode 100644 .changeset/large-seals-reflect.md delete mode 100644 .changeset/mighty-seas-hang.md delete mode 100644 .changeset/poor-baboons-brake.md delete mode 100644 .changeset/strange-geckos-shake.md diff --git a/.changeset/dirty-tools-switch.md b/.changeset/dirty-tools-switch.md deleted file mode 100644 index d07b3e1d..00000000 --- a/.changeset/dirty-tools-switch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@reactflow/core': patch ---- - -handles: handles on top of each other, reduce re-renderings diff --git a/.changeset/forty-peas-talk.md b/.changeset/forty-peas-talk.md deleted file mode 100644 index ffeccbdf..00000000 --- a/.changeset/forty-peas-talk.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@reactflow/core': patch ---- - -refactor(base-edge): pass id to base edge path diff --git a/.changeset/large-seals-reflect.md b/.changeset/large-seals-reflect.md deleted file mode 100644 index 12a7eff8..00000000 --- a/.changeset/large-seals-reflect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@reactflow/node-toolbar': minor ---- - -feat(align): add prop to align bar at start, center or end diff --git a/.changeset/mighty-seas-hang.md b/.changeset/mighty-seas-hang.md deleted file mode 100644 index e8384b27..00000000 --- a/.changeset/mighty-seas-hang.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@reactflow/core': minor ---- - -Add `edgesUpdatable` prop to store state. Allows enabling/disabling edge updating globally. diff --git a/.changeset/poor-baboons-brake.md b/.changeset/poor-baboons-brake.md deleted file mode 100644 index ab695a10..00000000 --- a/.changeset/poor-baboons-brake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@reactflow/controls': patch ---- - -fix(icons): show correct lock icon diff --git a/.changeset/strange-geckos-shake.md b/.changeset/strange-geckos-shake.md deleted file mode 100644 index 88490903..00000000 --- a/.changeset/strange-geckos-shake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@reactflow/core': patch ---- - -fix(autopan): only update nodes when transform change happen diff --git a/packages/background/CHANGELOG.md b/packages/background/CHANGELOG.md index 60978e3d..d5b1691f 100644 --- a/packages/background/CHANGELOG.md +++ b/packages/background/CHANGELOG.md @@ -1,5 +1,12 @@ # @reactflow/background +## 11.2.1 + +### Patch Changes + +- Updated dependencies [[`cf7a7d3d`](https://github.com/wbkd/react-flow/commit/cf7a7d3dad1e73215a72a5dc72e21fd50208cdbb), [`07b975bb`](https://github.com/wbkd/react-flow/commit/07b975bbee3580249e36a19582213b250f78093c), [`c80d269b`](https://github.com/wbkd/react-flow/commit/c80d269b85a0054221f4639c328fc36a3befbe70), [`a3fa164c`](https://github.com/wbkd/react-flow/commit/a3fa164c34cc820c79bb031c9fd97b72a3546614)]: + - @reactflow/core@11.7.1 + ## 11.2.0 ### Minor Changes diff --git a/packages/background/package.json b/packages/background/package.json index 6f378c30..3f2bb0a2 100644 --- a/packages/background/package.json +++ b/packages/background/package.json @@ -1,6 +1,6 @@ { "name": "@reactflow/background", - "version": "11.2.0", + "version": "11.2.1", "description": "Background component with different variants for React Flow", "keywords": [ "react", diff --git a/packages/controls/CHANGELOG.md b/packages/controls/CHANGELOG.md index e4815ed6..31a54565 100644 --- a/packages/controls/CHANGELOG.md +++ b/packages/controls/CHANGELOG.md @@ -1,5 +1,14 @@ # @reactflow/controls +## 11.1.12 + +### Patch Changes + +- [#3054](https://github.com/wbkd/react-flow/pull/3054) [`46526b4e`](https://github.com/wbkd/react-flow/commit/46526b4e02b83d74726701e3ba73d0be8cf80787) - fix(icons): show correct lock icon + +- Updated dependencies [[`cf7a7d3d`](https://github.com/wbkd/react-flow/commit/cf7a7d3dad1e73215a72a5dc72e21fd50208cdbb), [`07b975bb`](https://github.com/wbkd/react-flow/commit/07b975bbee3580249e36a19582213b250f78093c), [`c80d269b`](https://github.com/wbkd/react-flow/commit/c80d269b85a0054221f4639c328fc36a3befbe70), [`a3fa164c`](https://github.com/wbkd/react-flow/commit/a3fa164c34cc820c79bb031c9fd97b72a3546614)]: + - @reactflow/core@11.7.1 + ## 11.1.11 ### Patch Changes diff --git a/packages/controls/package.json b/packages/controls/package.json index 777fbd6c..271d2967 100644 --- a/packages/controls/package.json +++ b/packages/controls/package.json @@ -1,6 +1,6 @@ { "name": "@reactflow/controls", - "version": "11.1.11", + "version": "11.1.12", "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 576d20ab..6c1b6932 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,12 +1,21 @@ # @reactflow/core +## 11.7.1 + +### Patch Changes + +- [#3043](https://github.com/wbkd/react-flow/pull/3043) [`cf7a7d3d`](https://github.com/wbkd/react-flow/commit/cf7a7d3dad1e73215a72a5dc72e21fd50208cdbb) - handles: handles on top of each other, reduce re-renderings +- [#3046](https://github.com/wbkd/react-flow/pull/3046) [`07b975bb`](https://github.com/wbkd/react-flow/commit/07b975bbee3580249e36a19582213b250f78093c) - base-edge: pass id to base edge path +- [#3007](https://github.com/wbkd/react-flow/pull/3007) [`c80d269b`](https://github.com/wbkd/react-flow/commit/c80d269b85a0054221f4639c328fc36a3befbe70) Thanks [@bcakmakoglu](https://github.com/bcakmakoglu)! - allow array of ids as updateNodeInternals arg +- [#3029](https://github.com/wbkd/react-flow/pull/3029) [`a3fa164c`](https://github.com/wbkd/react-flow/commit/a3fa164c34cc820c79bb031c9fd97b72a3546614) Thanks [@bcakmakoglu](https://github.com/bcakmakoglu)! - autopan: only update nodes when transform change happen + ## 11.7.0 Most notable updates: - Handles: `isConnectableStart` and `isConnectableEnd` props to configure if you can start or end a connection at a certain handle - Edges: `updatable` option to enable updates for specific edges -- useNodesInitialized: options to configure if hidden nodes should be included (false by default) +- useNodesInitialized: options to configure if hidden nodes should be included (false by default) ### Minor Changes @@ -20,7 +29,6 @@ Most notable updates: - [#2933](https://github.com/wbkd/react-flow/pull/2933) [`fe8cac0a`](https://github.com/wbkd/react-flow/commit/fe8cac0adb359109e0e9eafe8b9261ba354076bb) - prefix error keys with "error" - [#2939](https://github.com/wbkd/react-flow/pull/2939) [`4a4ca171`](https://github.com/wbkd/react-flow/commit/4a4ca171955f5c8d58b23e3ad48406f1a21dc402) - add connection result to store - ## 11.6.1 ### Patch Changes diff --git a/packages/core/package.json b/packages/core/package.json index bc4e0b59..632b2cee 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@reactflow/core", - "version": "11.7.0", + "version": "11.7.1", "description": "Core components and util functions of React Flow.", "keywords": [ "react", diff --git a/packages/minimap/CHANGELOG.md b/packages/minimap/CHANGELOG.md index 3b2f9d44..3a2ade73 100644 --- a/packages/minimap/CHANGELOG.md +++ b/packages/minimap/CHANGELOG.md @@ -1,5 +1,12 @@ # @reactflow/minimap +## 11.5.1 + +### Patch Changes + +- Updated dependencies [[`cf7a7d3d`](https://github.com/wbkd/react-flow/commit/cf7a7d3dad1e73215a72a5dc72e21fd50208cdbb), [`07b975bb`](https://github.com/wbkd/react-flow/commit/07b975bbee3580249e36a19582213b250f78093c), [`c80d269b`](https://github.com/wbkd/react-flow/commit/c80d269b85a0054221f4639c328fc36a3befbe70), [`a3fa164c`](https://github.com/wbkd/react-flow/commit/a3fa164c34cc820c79bb031c9fd97b72a3546614)]: + - @reactflow/core@11.7.1 + ## 11.5.0 ### Minor Changes diff --git a/packages/minimap/package.json b/packages/minimap/package.json index e0766dab..db5861b6 100644 --- a/packages/minimap/package.json +++ b/packages/minimap/package.json @@ -1,6 +1,6 @@ { "name": "@reactflow/minimap", - "version": "11.5.0", + "version": "11.5.1", "description": "Minimap component for React Flow.", "keywords": [ "react", diff --git a/packages/node-toolbar/CHANGELOG.md b/packages/node-toolbar/CHANGELOG.md index e5fce14b..5298148d 100644 --- a/packages/node-toolbar/CHANGELOG.md +++ b/packages/node-toolbar/CHANGELOG.md @@ -1,5 +1,16 @@ # @reactflow/node-toolbar +## 1.2.0 + +### Minor Changes + +- [#3052](https://github.com/wbkd/react-flow/pull/3052) [`55e05cf7`](https://github.com/wbkd/react-flow/commit/55e05cf76ae21863691153e76dbd51d1eecd2c60) Thanks [@Noam3kCH](https://github.com/Noam3kCH)! - feat(align): add prop to align bar at start, center or end + +### Patch Changes + +- Updated dependencies [[`cf7a7d3d`](https://github.com/wbkd/react-flow/commit/cf7a7d3dad1e73215a72a5dc72e21fd50208cdbb), [`07b975bb`](https://github.com/wbkd/react-flow/commit/07b975bbee3580249e36a19582213b250f78093c), [`c80d269b`](https://github.com/wbkd/react-flow/commit/c80d269b85a0054221f4639c328fc36a3befbe70), [`a3fa164c`](https://github.com/wbkd/react-flow/commit/a3fa164c34cc820c79bb031c9fd97b72a3546614)]: + - @reactflow/core@11.7.1 + ## 1.1.11 ### Patch Changes diff --git a/packages/node-toolbar/package.json b/packages/node-toolbar/package.json index 71dad7ca..b0e2d3f7 100644 --- a/packages/node-toolbar/package.json +++ b/packages/node-toolbar/package.json @@ -1,6 +1,6 @@ { "name": "@reactflow/node-toolbar", - "version": "1.1.11", + "version": "1.2.0", "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 f5eebcf3..aa8a801b 100644 --- a/packages/reactflow/CHANGELOG.md +++ b/packages/reactflow/CHANGELOG.md @@ -1,5 +1,22 @@ # reactflow +## 11.7.1 + +### Patch Changes + +- [#3043](https://github.com/wbkd/react-flow/pull/3043) [`cf7a7d3d`](https://github.com/wbkd/react-flow/commit/cf7a7d3dad1e73215a72a5dc72e21fd50208cdbb) - handles: handles on top of each other, reduce re-renderings +- [#3046](https://github.com/wbkd/react-flow/pull/3046) [`07b975bb`](https://github.com/wbkd/react-flow/commit/07b975bbee3580249e36a19582213b250f78093c) - base-edge: pass id to base edge path +- [#3007](https://github.com/wbkd/react-flow/pull/3007) [`c80d269b`](https://github.com/wbkd/react-flow/commit/c80d269b85a0054221f4639c328fc36a3befbe70) Thanks [@bcakmakoglu](https://github.com/bcakmakoglu)! - allow array of ids as updateNodeInternals arg +- [#3029](https://github.com/wbkd/react-flow/pull/3029) [`a3fa164c`](https://github.com/wbkd/react-flow/commit/a3fa164c34cc820c79bb031c9fd97b72a3546614) Thanks [@bcakmakoglu](https://github.com/bcakmakoglu)! - autopan: only update nodes when transform change happen +- [#3052](https://github.com/wbkd/react-flow/pull/3052) [`55e05cf7`](https://github.com/wbkd/react-flow/commit/55e05cf76ae21863691153e76dbd51d1eecd2c60) Thanks [@Noam3kCH](https://github.com/Noam3kCH)! - node-toolbar: add prop to align bar at start, center or end + +- Updated dependencies [[`cf7a7d3d`](https://github.com/wbkd/react-flow/commit/cf7a7d3dad1e73215a72a5dc72e21fd50208cdbb), [`07b975bb`](https://github.com/wbkd/react-flow/commit/07b975bbee3580249e36a19582213b250f78093c), [`55e05cf7`](https://github.com/wbkd/react-flow/commit/55e05cf76ae21863691153e76dbd51d1eecd2c60), [`c80d269b`](https://github.com/wbkd/react-flow/commit/c80d269b85a0054221f4639c328fc36a3befbe70), [`46526b4e`](https://github.com/wbkd/react-flow/commit/46526b4e02b83d74726701e3ba73d0be8cf80787), [`a3fa164c`](https://github.com/wbkd/react-flow/commit/a3fa164c34cc820c79bb031c9fd97b72a3546614)]: + - @reactflow/core@11.7.1 + - @reactflow/node-toolbar@1.2.0 + - @reactflow/controls@11.1.12 + - @reactflow/background@11.2.1 + - @reactflow/minimap@11.5.1 + ## 11.7.0 Most notable updates: @@ -9,7 +26,7 @@ Most notable updates: - Edges: `updatable` option to enable updates for specific edges - MiniMap: `inversePan` and `zoomStep` props - Background: `id` and `offset` props - this enables you to combine different patterns (useful if you want a graph paper like background for example) -- useNodesInitialized: options to configure if hidden nodes should be included (false by default) +- useNodesInitialized: options to configure if hidden nodes should be included (false by default) Big thanks to [@Elringus](https://github.com/Elringus) and [@bcakmakoglu](https://github.com/bcakmakoglu)! @@ -22,14 +39,12 @@ Big thanks to [@Elringus](https://github.com/Elringus) and [@bcakmakoglu](https: - [#2944](https://github.com/wbkd/react-flow/pull/2944) Thanks [@Elringus](https://github.com/Elringus)! - add `inversePan` and `zoomStep` props - [#2941](https://github.com/wbkd/react-flow/pull/2941) Thanks [@Elringus](https://github.com/Elringus)! - background: add `id` and `offset` props - ### Patch Changes - [#2926](https://github.com/wbkd/react-flow/pull/2926) Thanks [@Elringus](https://github.com/Elringus)! - fix non-passive wheel event listener violation - [#2933](https://github.com/wbkd/react-flow/pull/2933) [`fe8cac0a`](https://github.com/wbkd/react-flow/commit/fe8cac0adb359109e0e9eafe8b9261ba354076bb) - prefix error keys with "error" - [#2939](https://github.com/wbkd/react-flow/pull/2939) [`4a4ca171`](https://github.com/wbkd/react-flow/commit/4a4ca171955f5c8d58b23e3ad48406f1a21dc402) - add connection result to store - ### Patch Changes - Updated dependencies [[`098eee3d`](https://github.com/wbkd/react-flow/commit/098eee3d41dabc870777b081796401ff13b5a776), [`fe8cac0a`](https://github.com/wbkd/react-flow/commit/fe8cac0adb359109e0e9eafe8b9261ba354076bb), [`4a4ca171`](https://github.com/wbkd/react-flow/commit/4a4ca171955f5c8d58b23e3ad48406f1a21dc402), [`c1448c2f`](https://github.com/wbkd/react-flow/commit/c1448c2f7415dd3b4b2c54e05404c5ab24e8978d), [`923a54c4`](https://github.com/wbkd/react-flow/commit/923a54c481b90954806202817ba844cfa7203a38), [`4d97a0ed`](https://github.com/wbkd/react-flow/commit/4d97a0ed168ce643fc0c99fa6b47cf1296d66065), [`771c7a5d`](https://github.com/wbkd/react-flow/commit/771c7a5d133ce96e9f7471394c15189e0657ce01), [`c22e1c28`](https://github.com/wbkd/react-flow/commit/c22e1c28c5555a638c2a8e82c3bfc986b3965d36)]: diff --git a/packages/reactflow/package.json b/packages/reactflow/package.json index ad4b8ed7..1cbab90d 100644 --- a/packages/reactflow/package.json +++ b/packages/reactflow/package.json @@ -1,6 +1,6 @@ { "name": "reactflow", - "version": "11.7.0", + "version": "11.7.1", "description": "A highly customizable React library for building node-based editors and interactive flow charts", "keywords": [ "react",