From 22da0df68e50637c0797088dd18d7e9b1fee175f Mon Sep 17 00:00:00 2001 From: John Robb Date: Tue, 2 May 2023 10:39:06 +0200 Subject: [PATCH 01/19] chore(contributing): update * Update CONTRIBUTING.md * Update bug_report.yml --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- CONTRIBUTING.md | 39 ++++++++++++++++++--------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 88667189..842f28e8 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -6,7 +6,7 @@ body: value: | Thank you for reporting an issue :pray:. - **Please only file issues for v10. Will will no longer fix issues for v9.** + **Please only file issues for v11. Will will no longer fix issues for v10.** This issue tracker is for reporting bugs found in react-flow (https://github.com/wbkd/react-flow) If you have a question about how to achieve something and are struggling, please post a question diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 862e3e10..beb24d6c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,26 +1,39 @@ -# React Flow Contribution Guidelines +# Contributing to React Flow -Thanks for your interest in contributing to React Flow 🙌 -Every form of contribution is appreciated. From issue reports to pull requests and documentation 👌 -Please check out the [existing issues](https://github.com/wbkd/react-flow/issues) and [discussions](https://github.com/wbkd/react-flow/discussions) before you open a new one. +Hello there! So glad you want to help out with React Flow 🤗 You’re the best. Here’s a guide for how you can contribute to the project. -#### 🐛 Bug Reports +# Our Contributing Philosophy -For reporting bugs, please create a [new issue](https://github.com/wbkd/react-flow/issues/new/choose). +The direction of React Flow and which new features are added, and which are left out, is decided by the core team (sometimes referred to as a “cathedral” style of development). The core team is paid to do this work ([see how here](https://reactflow.dev/blog/asking-for-money-for-open-source/)). With this model we ensure that the people doing the most work on the library are paid for their time and effort, and that we prevent the library from bloating. -#### ☝️ General Usage +That being said, React Flow is only interesting because of the people who make things with it, share their work, and discuss it. Some of the most important and undervalued work in open source is from non-code contributions, and that is where we can use the most help from you. -When you have questions about the general usage of React Flow you can use the [Q & A section](https://github.com/wbkd/react-flow/discussions/categories/q-a) or the [Discord channel](https://discord.gg/Bqt6xrs). +# How can I help? -#### ✨ Feature Requests +The things we need the most help for the library and its community are: -If you are missing a certain feature, please use the [New Features](https://github.com/wbkd/react-flow/discussions/categories/new-features) discussion section. +**🐛 Bug reports:** We simply can’t catch them all. Check [existing issues](https://github.com/wbkd/react-flow/issues/new/choose) and discussion first, then [create a new issue](https://github.com/wbkd/react-flow/issues/new/choose) to tell us what’s up. -#### 📝 Docs +**💬 Answering questions** in our [Discord Server](https://discord.gg/Bqt6xrs) and [Github discussions](https://github.com/wbkd/react-flow/discussions). -The docs have its own [react-flow-docs repo](https://github.com/wbkd/react-flow-docs). Please open an issue or pull request there if you are missing something. +🎬 **Create tutorials** for React Flow. Send them to us and we’ll happily share them! -#### 💫 Pull Requests +**✏️ Edit our [Docs](https://reactflow.dev/docs/introduction/)**: Make changes in the [react-flow-docs repo](https://github.com/wbkd/react-flow-docs), or click the "edit this page” button that lives on every doc site. + +All interactions should be done with care following our [Code of Conduct](https://github.com/wbkd/react-flow/blob/main/CODE_OF_CONDUCT.md). + +## Enhancements + +If you have an idea or suggestion for an enhancement to the React Flow library, please use the [New Features](https://github.com/wbkd/react-flow/discussions/categories/new-features) discussion section. If you want to build it yourself, **please reach out to us before you dive into a new pull request.** The direction of React Flow and which new features are added are discussed in our Discord Server and in [this Github discussions section](https://github.com/wbkd/react-flow/discussions/categories/new-features), and in the end they are decided by the core team. + +Talking to us first about the enhancement you want to build will be the most likely way to get your pull request into the library (see Our Contributing Philosophy above). We would hate to see you write code you’re proud of, just to learn that we’ve already been working on the same thing, or that we feel doesn’t fit into the core library. + +### Contact us + +To ask about a possible enhancement, email us at info@reactflow.dev + + +### 💫 Pull Requests If you want to contribute improvements or new features we are happy to review your PR :) Please use a meaningful commit message and add a little description of your changes. From 85993cfbf87ec6732c555da9af65f2ce58097ede Mon Sep 17 00:00:00 2001 From: moklick Date: Wed, 3 May 2023 11:41:07 +0200 Subject: [PATCH 02/19] 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 03/19] 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 04/19] 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 05/19] 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 06/19] 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 07/19] 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 08/19] 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 09/19] 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 10/19] 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 11/19] 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 12/19] 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 13/19] 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 fcb58c3c15c22822cdb9304cc95c8b68fc2e8806 Mon Sep 17 00:00:00 2001 From: Connie <105062735+conniepaula@users.noreply.github.com> Date: Thu, 11 May 2023 18:08:13 -0300 Subject: [PATCH 14/19] Update link to cypress examples Link to cypress examples was taking users to a 404 page due to a missing 'vite-app' folder in the path. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 50673003..6962878c 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ Run `pnpm build` once and then you can use `pnpm dev` for local development. ## Testing -Testing is done with cypress. You can find the tests in the [`examples/cypress`](/examples/cypress/) folder. In order to run the tests do: +Testing is done with cypress. You can find the tests in the [`examples/vite-app/cypress`](/examples/vite-app/cypress/) folder. In order to run the tests do: ```sh pnpm test From 8386c7af6ce90c46f9c5da81946592978ec50dfc Mon Sep 17 00:00:00 2001 From: moklick Date: Mon, 15 May 2023 10:56:21 +0200 Subject: [PATCH 15/19] 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 16/19] 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 17/19] 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 18/19] 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 19/19] 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",