Merge branch 'main' into feat/zindexmode

This commit is contained in:
Moritz Klack
2025-12-02 13:41:50 +01:00
committed by GitHub
21 changed files with 125 additions and 37 deletions

View File

@@ -1,5 +1,16 @@
# @xyflow/react
## 12.9.3
### Patch Changes
- [#5621](https://github.com/xyflow/xyflow/pull/5621) [`c1304dba7`](https://github.com/xyflow/xyflow/commit/c1304dba7a20bb8d74c7aceb23cd80b56e4c0482) Thanks [@moklick](https://github.com/moklick)! - Set `paneClickDistance` default value to `1`.
- [#5578](https://github.com/xyflow/xyflow/pull/5578) [`00bcb9f5f`](https://github.com/xyflow/xyflow/commit/00bcb9f5f45f49814b9ac19b3f55cfe069ee3773) Thanks [@peterkogo](https://github.com/peterkogo)! - Pass current pointer position to connection
- Updated dependencies [[`00bcb9f5f`](https://github.com/xyflow/xyflow/commit/00bcb9f5f45f49814b9ac19b3f55cfe069ee3773)]:
- @xyflow/system@0.0.73
## 12.9.2
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@xyflow/react",
"version": "12.9.2",
"version": "12.9.3",
"description": "React Flow - A highly customizable React library for building node-based editors and interactive flow charts.",
"keywords": [
"react",

View File

@@ -1,4 +1,5 @@
import { memo, type ReactNode } from 'react';
import { shallow } from 'zustand/shallow';
import { useStore } from '../../hooks/useStore';
import { useGlobalKeyHandler } from '../../hooks/useGlobalKeyHandler';
@@ -72,7 +73,7 @@ function FlowRendererComponent<NodeType extends Node = Node>({
onViewportChange,
isControlledViewport,
}: FlowRendererProps<NodeType>) {
const { nodesSelectionActive, userSelectionActive } = useStore(selector);
const { nodesSelectionActive, userSelectionActive } = useStore(selector, shallow);
const selectionKeyPressed = useKeyPress(selectionKeyCode, { target: win });
const panActivationKeyPressed = useKeyPress(panActivationKeyCode, { target: win });

View File

@@ -104,7 +104,7 @@ function ReactFlow<NodeType extends Node = Node, EdgeType extends Edge = Edge>(
onPaneMouseLeave,
onPaneScroll,
onPaneContextMenu,
paneClickDistance = 0,
paneClickDistance = 1,
nodeClickDistance = 0,
children,
onReconnect,

View File

@@ -14,7 +14,9 @@ import {
NodeOrigin,
CoordinateExtent,
fitViewport,
ZIndexMode,
getHandlePosition,
Position,
ZIndexMode
} from '@xyflow/system';
import { applyEdgeChanges, applyNodeChanges, createSelectionChange, getSelectionChanges } from '../utils/changes';
@@ -191,7 +193,7 @@ const createStore = ({
updateNodePositions: (nodeDragItems, dragging = false) => {
const parentExpandChildren: ParentExpandChild[] = [];
const changes = [];
const { nodeLookup, triggerNodeChanges } = get();
const { nodeLookup, triggerNodeChanges, connection, updateConnection } = get();
for (const [id, dragItem] of nodeDragItems) {
// we are using the nodelookup to be sure to use the current expandParent and parentId value
@@ -210,6 +212,11 @@ const createStore = ({
dragging,
};
if (node && connection.inProgress && connection.fromNode.id === node.id) {
const updatedFrom = getHandlePosition(node, connection.fromHandle, Position.Left, true);
updateConnection({ ...connection, from: updatedFrom });
}
if (expandParent && node.parentId) {
parentExpandChildren.push({
id,

View File

@@ -125,9 +125,9 @@ function applyChange(change: any, element: any): any {
case 'dimensions': {
if (typeof change.dimensions !== 'undefined') {
element.measured ??= {};
element.measured.width = change.dimensions.width;
element.measured.height = change.dimensions.height;
element.measured = {
...change.dimensions,
};
if (change.setAttributes) {
if (change.setAttributes === true || change.setAttributes === 'width') {

View File

@@ -1,5 +1,18 @@
# @xyflow/svelte
## 1.4.2
### Patch Changes
- [#5603](https://github.com/xyflow/xyflow/pull/5603) [`17a175791`](https://github.com/xyflow/xyflow/commit/17a175791b2420b32d55a8fcbbb35649862b85cf) Thanks [@peterkogo](https://github.com/peterkogo)! - Fix onPaneClick always firing when moving the viewport
- [#5615](https://github.com/xyflow/xyflow/pull/5615) [`8b35c77eb`](https://github.com/xyflow/xyflow/commit/8b35c77ebe5a4f6cba33c597d94eba1ead64fdfc) Thanks [@peterkogo](https://github.com/peterkogo)! - Fix wrong positions when resizing nodes with a non-default node-origin
- [#5578](https://github.com/xyflow/xyflow/pull/5578) [`00bcb9f5f`](https://github.com/xyflow/xyflow/commit/00bcb9f5f45f49814b9ac19b3f55cfe069ee3773) Thanks [@peterkogo](https://github.com/peterkogo)! - Pass current pointer position to connection
- Updated dependencies [[`00bcb9f5f`](https://github.com/xyflow/xyflow/commit/00bcb9f5f45f49814b9ac19b3f55cfe069ee3773)]:
- @xyflow/system@0.0.73
## 1.4.1
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@xyflow/svelte",
"version": "1.4.1",
"version": "1.4.2",
"description": "Svelte Flow - A highly customizable Svelte library for building node-based editors, workflow systems, diagrams and more.",
"keywords": [
"svelte",

View File

@@ -15,7 +15,9 @@ import {
updateAbsolutePositions,
snapPosition,
calculateNodePosition,
type SetCenterOptions
type SetCenterOptions,
getHandlePosition,
Position
} from '@xyflow/system';
import type { EdgeTypes, NodeTypes, Node, Edge, FitViewOptions } from '$lib/types';
@@ -51,6 +53,15 @@ export function createStore<NodeType extends Node = Node, EdgeType extends Edge
const updateNodePositions: UpdateNodePositions = (nodeDragItems, dragging = false) => {
store.nodes = store.nodes.map((node) => {
if (store.connection.inProgress && store.connection.fromNode.id === node.id) {
const internalNode = store.nodeLookup.get(node.id);
if (internalNode) {
store.connection = {
...store.connection,
from: getHandlePosition(internalNode, store.connection.fromHandle, Position.Left, true)
};
}
}
const dragItem = nodeDragItems.get(node.id);
return dragItem ? { ...node, position: dragItem.position, dragging } : node;
});

View File

@@ -1,5 +1,11 @@
# @xyflow/system
## 0.0.73
### Patch Changes
- [#5578](https://github.com/xyflow/xyflow/pull/5578) [`00bcb9f5f`](https://github.com/xyflow/xyflow/commit/00bcb9f5f45f49814b9ac19b3f55cfe069ee3773) Thanks [@peterkogo](https://github.com/peterkogo)! - Pass current pointer position to connection
## 0.0.72
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@xyflow/system",
"version": "0.0.72",
"version": "0.0.73",
"description": "xyflow core system that powers React Flow and Svelte Flow.",
"keywords": [
"node-based UI",

View File

@@ -101,7 +101,19 @@ export function isEdgeVisible({ sourceNode, targetNode, width, height, transform
return getOverlappingArea(viewRect, boxToRect(edgeBox)) > 0;
}
const getEdgeId = ({ source, sourceHandle, target, targetHandle }: Connection | EdgeBase): string =>
/**
* Type for a custom edge ID generator function.
* @public
*/
export type GetEdgeId = (params: Connection | EdgeBase) => string;
/**
* The default edge ID generator function. Generates an ID based on the source, target, and handles.
* @public
* @param params - The connection or edge to generate an ID for.
* @returns The generated edge ID.
*/
export const getEdgeId = ({ source, sourceHandle, target, targetHandle }: Connection | EdgeBase): string =>
`xy-edge__${source}${sourceHandle || ''}-${target}${targetHandle || ''}`;
const connectionExists = (edge: EdgeBase, edges: EdgeBase[]) => {
@@ -114,11 +126,19 @@ const connectionExists = (edge: EdgeBase, edges: EdgeBase[]) => {
);
};
export type AddEdgeOptions = {
/**
* Custom function to generate edge IDs. If not provided, the default `getEdgeId` function is used.
*/
getEdgeId?: GetEdgeId;
};
/**
* This util is a convenience function to add a new Edge to an array of edges. It also performs some validation to make sure you don't add an invalid edge or duplicate an existing one.
* @public
* @param edgeParams - Either an `Edge` or a `Connection` you want to add.
* @param edges - The array of all current edges.
* @param options - Optional configuration object.
* @returns A new array of edges with the new edge added.
*
* @remarks If an edge with the same `target` and `source` already exists (and the same
@@ -128,7 +148,8 @@ const connectionExists = (edge: EdgeBase, edges: EdgeBase[]) => {
*/
export const addEdge = <EdgeType extends EdgeBase>(
edgeParams: EdgeType | Connection,
edges: EdgeType[]
edges: EdgeType[],
options: AddEdgeOptions = {}
): EdgeType[] => {
if (!edgeParams.source || !edgeParams.target) {
devWarn('006', errorMessages['error006']());
@@ -136,13 +157,15 @@ export const addEdge = <EdgeType extends EdgeBase>(
return edges;
}
const edgeIdGenerator = options.getEdgeId || getEdgeId;
let edge: EdgeType;
if (isEdgeBase(edgeParams)) {
edge = { ...edgeParams };
} else {
edge = {
...edgeParams,
id: getEdgeId(edgeParams),
id: edgeIdGenerator(edgeParams),
} as EdgeType;
}
@@ -167,6 +190,10 @@ export type ReconnectEdgeOptions = {
* @default true
*/
shouldReplaceId?: boolean;
/**
* Custom function to generate edge IDs. If not provided, the default `getEdgeId` function is used.
*/
getEdgeId?: GetEdgeId;
};
/**
@@ -207,10 +234,12 @@ export const reconnectEdge = <EdgeType extends EdgeBase>(
return edges;
}
const edgeIdGenerator = options.getEdgeId || getEdgeId;
// Remove old edge and create the new edge with parameters of old edge.
const edge = {
...rest,
id: options.shouldReplaceId ? getEdgeId(newConnection) : oldEdgeId,
id: options.shouldReplaceId ? edgeIdGenerator(newConnection) : oldEdgeId,
source: newConnection.source,
target: newConnection.target,
sourceHandle: newConnection.sourceHandle,

View File

@@ -93,8 +93,8 @@ function onPointerDown(
position: fromHandleInternal.position,
};
const fromNodeInternal = nodeLookup.get(nodeId)!;
const from = getHandlePosition(fromNodeInternal, fromHandle, Position.Left, true);
const fromInternalNode = nodeLookup.get(nodeId)!;
const from = getHandlePosition(fromInternalNode, fromHandle, Position.Left, true);
let previousConnection: ConnectionInProgress = {
inProgress: true,
@@ -103,7 +103,7 @@ function onPointerDown(
from,
fromHandle,
fromPosition: fromHandle.position,
fromNode: fromNodeInternal,
fromNode: fromInternalNode,
to: position,
toHandle: null,
@@ -172,9 +172,14 @@ function onPointerDown(
connection = result.connection;
isValid = isConnectionValid(!!closestHandle, result.isValid);
const fromInternalNode = nodeLookup.get(nodeId);
const from = fromInternalNode
? getHandlePosition(fromInternalNode, fromHandle, Position.Left, true)
: previousConnection.from;
const newConnection: ConnectionInProgress = {
// from stays the same
...previousConnection,
from,
isValid,
to:
result.toHandle && isValid