diff --git a/.changeset/stale-bananas-argue.md b/.changeset/stale-bananas-argue.md new file mode 100644 index 00000000..c5c30810 --- /dev/null +++ b/.changeset/stale-bananas-argue.md @@ -0,0 +1,6 @@ +--- +'@xyflow/react': patch +'@xyflow/system': patch +--- + +use correct index when using setNodes for inserting diff --git a/packages/react/src/utils/changes.ts b/packages/react/src/utils/changes.ts index df215340..6de98e3a 100644 --- a/packages/react/src/utils/changes.ts +++ b/packages/react/src/utils/changes.ts @@ -19,10 +19,11 @@ function applyChanges(changes: any[], elements: any[]): any[] { // By storing a map of changes for each element, we can a quick lookup as we // iterate over the elements array! const changesMap = new Map(); + const addItemChanges: any[] = []; for (const change of changes) { if (change.type === 'add') { - updatedElements.push(change.item); + addItemChanges.push(change); continue; } else if (change.type === 'remove' || change.type === 'replace') { // For a 'remove' change we can safely ignore any other changes queued for @@ -73,6 +74,18 @@ function applyChanges(changes: any[], elements: any[]): any[] { updatedElements.push(updatedElement); } + // we need to wait for all changes to be applied before adding new items + // to be able to add them at the correct index + if (addItemChanges.length) { + addItemChanges.forEach((change) => { + if (change.index !== undefined) { + updatedElements.splice(change.index, 0, { ...change.item }); + } else { + updatedElements.push({ ...change.item }); + } + }); + } + return updatedElements; } @@ -237,7 +250,7 @@ export function getElementsDiffChanges({ const changes: any[] = []; const itemsLookup = new Map(items.map((item) => [item.id, item])); - for (const item of items) { + for (const [index, item] of items.entries()) { const lookupItem = lookup.get(item.id); const storeItem = lookupItem?.internals?.userNode ?? lookupItem; @@ -246,7 +259,7 @@ export function getElementsDiffChanges({ } if (storeItem === undefined) { - changes.push({ item: item, type: 'add' }); + changes.push({ item: item, type: 'add', index }); } } diff --git a/packages/system/src/types/changes.ts b/packages/system/src/types/changes.ts index 5db0b6de..9b232733 100644 --- a/packages/system/src/types/changes.ts +++ b/packages/system/src/types/changes.ts @@ -32,6 +32,7 @@ export type NodeRemoveChange = { export type NodeAddChange = { item: NodeType; type: 'add'; + index?: number; }; export type NodeReplaceChange = { @@ -57,6 +58,7 @@ export type EdgeRemoveChange = NodeRemoveChange; export type EdgeAddChange = { item: EdgeType; type: 'add'; + index?: number; }; export type EdgeReplaceChange = {