From 4f77447ab5c6192f1743668e137cf6efe4b551b5 Mon Sep 17 00:00:00 2001
From: Alessandro
Date: Tue, 14 Oct 2025 10:22:30 +0200
Subject: [PATCH 01/10] Fix svelte minimap if all nodes are hidden
---
packages/svelte/src/lib/plugins/Minimap/Minimap.svelte | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte b/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte
index 33209dcb..04bb982a 100644
--- a/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte
+++ b/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte
@@ -60,8 +60,11 @@
width: store.width / store.viewport.zoom,
height: store.height / store.viewport.zoom
});
+
+ const hasVisibleNodes = $derived(store.nodeLookup.size > 0 && store.nodes.some((n) => !n.hidden));
+
let boundingRect = $derived(
- store.nodeLookup.size > 0
+ hasVisibleNodes
? getBoundsOfRects(
getInternalNodesBounds(store.nodeLookup, { filter: (n) => !n.hidden }),
viewBB
From a67f2992b1c5cbeaca5f5d79d623390f4fbc1057 Mon Sep 17 00:00:00 2001
From: Alessandro
Date: Tue, 14 Oct 2025 11:33:10 +0200
Subject: [PATCH 02/10] Update getInternalNodesBounds and examples
---
.../src/examples/CustomMiniMapNode/index.tsx | 29 ++++++++------
.../src/components/Header/Header.svelte | 1 +
.../examples/custom-minimap/+page.svelte | 39 +++++++++++--------
.../src/lib/plugins/Minimap/Minimap.svelte | 19 +++++----
packages/system/src/utils/graph.ts | 9 ++++-
5 files changed, 60 insertions(+), 37 deletions(-)
diff --git a/examples/react/src/examples/CustomMiniMapNode/index.tsx b/examples/react/src/examples/CustomMiniMapNode/index.tsx
index 21b1d073..1bb0f39b 100644
--- a/examples/react/src/examples/CustomMiniMapNode/index.tsx
+++ b/examples/react/src/examples/CustomMiniMapNode/index.tsx
@@ -1,4 +1,4 @@
-import { MouseEvent, CSSProperties, useCallback } from 'react';
+import { MouseEvent, CSSProperties, useCallback, useState } from 'react';
import {
ReactFlow,
@@ -14,19 +14,13 @@ import {
ReactFlowInstance,
useEdgesState,
useNodesState,
+ Panel,
} from '@xyflow/react';
const onInit = (reactFlowInstance: ReactFlowInstance) => console.log('flow loaded:', reactFlowInstance);
const onNodeClick = (_: MouseEvent, node: Node) => console.log('click', node);
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
-const buttonStyle: CSSProperties = {
- position: 'absolute',
- left: 10,
- top: 10,
- zIndex: 4,
-};
-
const CustomMiniMapNode = ({ x, y, width, height }: MiniMapNodeProps) => {
return ;
};
@@ -34,6 +28,7 @@ const CustomMiniMapNode = ({ x, y, width, height }: MiniMapNodeProps) => {
const CustomMiniMapNodeFlow = () => {
const [nodes, setNodes, onNodesChange] = useNodesState([]);
const [edges, setEdges, onEdgesChange] = useEdgesState([]);
+ const [hideAllNodes, setHideAllNodes] = useState(false);
const onConnect = useCallback((params: Connection | Edge) => setEdges((els) => addEdge(params, els)), [setEdges]);
const addRandomNode = () => {
@@ -45,10 +40,17 @@ const CustomMiniMapNodeFlow = () => {
x: Math.random() * window.innerWidth,
y: Math.random() * window.innerHeight,
},
+ hidden: hideAllNodes,
};
setNodes((nds) => nds.concat(newNode));
};
+ const toggleHideAllNodes = () => {
+ setHideAllNodes(!hideAllNodes);
+ setNodes((nds) => nds.map((n) => ({ ...n, hidden: hideAllNodes })));
+ setEdges((eds) => eds.map((e) => ({ ...e, hidden: hideAllNodes })));
+ };
+
return (
{
-
+
+
+
+
);
};
diff --git a/examples/svelte/src/components/Header/Header.svelte b/examples/svelte/src/components/Header/Header.svelte
index 0ebe84e9..c03eef13 100644
--- a/examples/svelte/src/components/Header/Header.svelte
+++ b/examples/svelte/src/components/Header/Header.svelte
@@ -17,6 +17,7 @@
'handle-connect',
'interaction',
'intersections',
+ 'minimap-bug',
'node-toolbar',
'node-resizer',
'overview',
diff --git a/examples/svelte/src/routes/examples/custom-minimap/+page.svelte b/examples/svelte/src/routes/examples/custom-minimap/+page.svelte
index 1e9c96ca..0a0c734c 100644
--- a/examples/svelte/src/routes/examples/custom-minimap/+page.svelte
+++ b/examples/svelte/src/routes/examples/custom-minimap/+page.svelte
@@ -4,15 +4,17 @@
Background,
Controls,
MiniMap,
+ Panel,
type Node,
- type Edge,
+ type Edge
} from '@xyflow/svelte';
-
+
import '@xyflow/svelte/dist/style.css';
import CustomMiniMapNode from './CustomMiniMapNode.svelte';
let nodes = $state.raw([]);
let edges = $state.raw([]);
+ let hideAllNodes = $state(false);
function addRandomNode() {
const nodeId = (nodes.length + 1).toString();
@@ -21,28 +23,33 @@
data: { label: `Node: ${nodeId}` },
position: {
x: Math.random() * (typeof window !== 'undefined' ? window.innerWidth : 800),
- y: Math.random() * (typeof window !== 'undefined' ? window.innerHeight : 600),
+ y: Math.random() * (typeof window !== 'undefined' ? window.innerHeight : 600)
},
- type: 'default'
+ type: 'default',
+ hidden: hideAllNodes
};
nodes = [...nodes, newNode];
}
+
+ function toggleHideAllNodes() {
+ hideAllNodes = !hideAllNodes;
+ nodes = nodes.map((node) => ({
+ ...node,
+ hidden: hideAllNodes
+ }));
+ }
-
+
-
+
+
+
+
+
diff --git a/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte b/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte
index 04bb982a..6748dc47 100644
--- a/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte
+++ b/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte
@@ -61,16 +61,19 @@
height: store.height / store.viewport.zoom
});
- const hasVisibleNodes = $derived(store.nodeLookup.size > 0 && store.nodes.some((n) => !n.hidden));
+ // let boundingRect = $derived(
+ // store.nodeLookup.size > 0 && store.nodes.some((n) => !n.hidden)
+ // ? getBoundsOfRects(
+ // getInternalNodesBounds(store.nodeLookup, { filter: (n) => !n.hidden }),
+ // viewBB
+ // )
+ // : viewBB
+ // );
let boundingRect = $derived(
- hasVisibleNodes
- ? getBoundsOfRects(
- getInternalNodesBounds(store.nodeLookup, { filter: (n) => !n.hidden }),
- viewBB
- )
- : viewBB
+ getBoundsOfRects(getInternalNodesBounds(store.nodeLookup, { filter: (n) => !n.hidden }), viewBB)
);
+
let scaledWidth = $derived(boundingRect.width / width);
let scaledHeight = $derived(boundingRect.height / height);
let viewScale = $derived(Math.max(scaledWidth, scaledHeight));
@@ -124,7 +127,7 @@
{#each store.nodes as userNode (userNode.id)}
{@const node = store.nodeLookup.get(userNode.id)}
- {#if node && nodeHasDimensions(node)}
+ {#if node && nodeHasDimensions(node) && !node.hidden}
{@const nodeDimesions = getNodeDimensions(node)}
,
params: GetInternalNodesBoundsParams = {}
): Rect => {
+ const emptyRect = { x: 0, y: 0, width: 0, height: 0 };
+
if (nodeLookup.size === 0) {
- return { x: 0, y: 0, width: 0, height: 0 };
+ return emptyRect;
}
let box = { x: Infinity, y: Infinity, x2: -Infinity, y2: -Infinity };
+ let hasVisibleNodes = false;
+
nodeLookup.forEach((node) => {
if (params.filter === undefined || params.filter(node)) {
+ hasVisibleNodes = true;
const nodeBox = nodeToBox(node as InternalNodeBase);
box = getBoundsOfBoxes(box, nodeBox);
}
});
- return boxToRect(box);
+ return hasVisibleNodes ? boxToRect(box) : emptyRect;
};
export const getNodesInside = (
From 8be0307688d29d1f4ba52b7b7f9e5bd2cadbb24d Mon Sep 17 00:00:00 2001
From: Alessandro
Date: Tue, 14 Oct 2025 12:09:39 +0200
Subject: [PATCH 03/10] remove comments
---
packages/svelte/src/lib/plugins/Minimap/Minimap.svelte | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte b/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte
index 6748dc47..90c6abb4 100644
--- a/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte
+++ b/packages/svelte/src/lib/plugins/Minimap/Minimap.svelte
@@ -61,15 +61,6 @@
height: store.height / store.viewport.zoom
});
- // let boundingRect = $derived(
- // store.nodeLookup.size > 0 && store.nodes.some((n) => !n.hidden)
- // ? getBoundsOfRects(
- // getInternalNodesBounds(store.nodeLookup, { filter: (n) => !n.hidden }),
- // viewBB
- // )
- // : viewBB
- // );
-
let boundingRect = $derived(
getBoundsOfRects(getInternalNodesBounds(store.nodeLookup, { filter: (n) => !n.hidden }), viewBB)
);
From 34c9b7491495688733aa87828359be16f61def51 Mon Sep 17 00:00:00 2001
From: Alessandro Cheli <17289614+0x0f0f0f@users.noreply.github.com>
Date: Tue, 14 Oct 2025 12:09:53 +0200
Subject: [PATCH 04/10] Update
examples/react/src/examples/CustomMiniMapNode/index.tsx
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
examples/react/src/examples/CustomMiniMapNode/index.tsx | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/examples/react/src/examples/CustomMiniMapNode/index.tsx b/examples/react/src/examples/CustomMiniMapNode/index.tsx
index 1bb0f39b..5766d109 100644
--- a/examples/react/src/examples/CustomMiniMapNode/index.tsx
+++ b/examples/react/src/examples/CustomMiniMapNode/index.tsx
@@ -46,9 +46,12 @@ const CustomMiniMapNodeFlow = () => {
};
const toggleHideAllNodes = () => {
- setHideAllNodes(!hideAllNodes);
- setNodes((nds) => nds.map((n) => ({ ...n, hidden: hideAllNodes })));
- setEdges((eds) => eds.map((e) => ({ ...e, hidden: hideAllNodes })));
+ setHideAllNodes(prev => {
+ const next = !prev;
+ setNodes(nds => nds.map(n => ({ ...n, hidden: next })));
+ setEdges(eds => eds.map(e => ({ ...e, hidden: next })));
+ return next;
+ });
};
return (
From 0fbc99e5293ccb7411135aa8bb732b523d137892 Mon Sep 17 00:00:00 2001
From: Alessandro
Date: Tue, 14 Oct 2025 12:46:47 +0200
Subject: [PATCH 05/10] remove example
---
examples/svelte/src/components/Header/Header.svelte | 1 -
1 file changed, 1 deletion(-)
diff --git a/examples/svelte/src/components/Header/Header.svelte b/examples/svelte/src/components/Header/Header.svelte
index c03eef13..0ebe84e9 100644
--- a/examples/svelte/src/components/Header/Header.svelte
+++ b/examples/svelte/src/components/Header/Header.svelte
@@ -17,7 +17,6 @@
'handle-connect',
'interaction',
'intersections',
- 'minimap-bug',
'node-toolbar',
'node-resizer',
'overview',
From 8a9ee2d836776da42b867c6ba90d302fbbc79b37 Mon Sep 17 00:00:00 2001
From: Alessandro
Date: Tue, 14 Oct 2025 13:20:10 +0200
Subject: [PATCH 06/10] Add changeset
---
.changeset/giant-foxes-roll.md | 6 ++++++
1 file changed, 6 insertions(+)
create mode 100644 .changeset/giant-foxes-roll.md
diff --git a/.changeset/giant-foxes-roll.md b/.changeset/giant-foxes-roll.md
new file mode 100644
index 00000000..2cc1b82a
--- /dev/null
+++ b/.changeset/giant-foxes-roll.md
@@ -0,0 +1,6 @@
+---
+'@xyflow/svelte': patch
+'@xyflow/system': patch
+---
+
+Fix Minimap if all nodes are hidden in a flow and refactor getInternalNodesBounds
From 3057dcd8cbef80fbf8b89f8408afdbbe087aede3 Mon Sep 17 00:00:00 2001
From: Alessandro
Date: Tue, 14 Oct 2025 13:20:38 +0200
Subject: [PATCH 07/10] simplify getInternalNodesBounds
---
packages/system/src/utils/graph.ts | 13 ++-----------
1 file changed, 2 insertions(+), 11 deletions(-)
diff --git a/packages/system/src/utils/graph.ts b/packages/system/src/utils/graph.ts
index 1b7d27d1..ab68ae72 100644
--- a/packages/system/src/utils/graph.ts
+++ b/packages/system/src/utils/graph.ts
@@ -241,25 +241,16 @@ export const getInternalNodesBounds = ,
params: GetInternalNodesBoundsParams = {}
): Rect => {
- const emptyRect = { x: 0, y: 0, width: 0, height: 0 };
-
- if (nodeLookup.size === 0) {
- return emptyRect;
- }
-
- let box = { x: Infinity, y: Infinity, x2: -Infinity, y2: -Infinity };
-
- let hasVisibleNodes = false;
+ let box = { x: 0, y: 0, x2: 0, y2: 0 };
nodeLookup.forEach((node) => {
if (params.filter === undefined || params.filter(node)) {
- hasVisibleNodes = true;
const nodeBox = nodeToBox(node as InternalNodeBase);
box = getBoundsOfBoxes(box, nodeBox);
}
});
- return hasVisibleNodes ? boxToRect(box) : emptyRect;
+ return boxToRect(box);
};
export const getNodesInside = (
From 43e06954161d275bdf905c7dac07a66eef8180e6 Mon Sep 17 00:00:00 2001
From: Alessandro
Date: Tue, 14 Oct 2025 13:33:58 +0200
Subject: [PATCH 08/10] restore version with infinity
---
packages/system/src/utils/graph.ts | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/packages/system/src/utils/graph.ts b/packages/system/src/utils/graph.ts
index ab68ae72..1b7d27d1 100644
--- a/packages/system/src/utils/graph.ts
+++ b/packages/system/src/utils/graph.ts
@@ -241,16 +241,25 @@ export const getInternalNodesBounds = ,
params: GetInternalNodesBoundsParams = {}
): Rect => {
- let box = { x: 0, y: 0, x2: 0, y2: 0 };
+ const emptyRect = { x: 0, y: 0, width: 0, height: 0 };
+
+ if (nodeLookup.size === 0) {
+ return emptyRect;
+ }
+
+ let box = { x: Infinity, y: Infinity, x2: -Infinity, y2: -Infinity };
+
+ let hasVisibleNodes = false;
nodeLookup.forEach((node) => {
if (params.filter === undefined || params.filter(node)) {
+ hasVisibleNodes = true;
const nodeBox = nodeToBox(node as InternalNodeBase);
box = getBoundsOfBoxes(box, nodeBox);
}
});
- return boxToRect(box);
+ return hasVisibleNodes ? boxToRect(box) : emptyRect;
};
export const getNodesInside = (
From b5287b8808acf0f81288d27a553d8fbe5c8c4d79 Mon Sep 17 00:00:00 2001
From: moklick
Date: Tue, 14 Oct 2025 16:00:01 +0200
Subject: [PATCH 09/10] chore(getInternalNodesBounds): cleanup
---
packages/system/src/utils/graph.ts | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/packages/system/src/utils/graph.ts b/packages/system/src/utils/graph.ts
index 1b7d27d1..df32a165 100644
--- a/packages/system/src/utils/graph.ts
+++ b/packages/system/src/utils/graph.ts
@@ -241,25 +241,17 @@ export const getInternalNodesBounds = ,
params: GetInternalNodesBoundsParams = {}
): Rect => {
- const emptyRect = { x: 0, y: 0, width: 0, height: 0 };
-
- if (nodeLookup.size === 0) {
- return emptyRect;
- }
-
let box = { x: Infinity, y: Infinity, x2: -Infinity, y2: -Infinity };
-
let hasVisibleNodes = false;
nodeLookup.forEach((node) => {
if (params.filter === undefined || params.filter(node)) {
+ box = getBoundsOfBoxes(box, nodeToBox(node as InternalNodeBase));
hasVisibleNodes = true;
- const nodeBox = nodeToBox(node as InternalNodeBase);
- box = getBoundsOfBoxes(box, nodeBox);
}
});
- return hasVisibleNodes ? boxToRect(box) : emptyRect;
+ return hasVisibleNodes ? boxToRect(box) : { x: 0, y: 0, width: 0, height: 0 };
};
export const getNodesInside = (
From 15831900dec006043e8459ac25c44ae0762bb87a Mon Sep 17 00:00:00 2001
From: Moritz Klack
Date: Tue, 14 Oct 2025 16:05:31 +0200
Subject: [PATCH 10/10] Do not crash minimap if all nodes are hidden
Refactor getInternalNodesBounds for improved stability.
---
.changeset/giant-foxes-roll.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.changeset/giant-foxes-roll.md b/.changeset/giant-foxes-roll.md
index 2cc1b82a..14d73c64 100644
--- a/.changeset/giant-foxes-roll.md
+++ b/.changeset/giant-foxes-roll.md
@@ -3,4 +3,4 @@
'@xyflow/system': patch
---
-Fix Minimap if all nodes are hidden in a flow and refactor getInternalNodesBounds
+Do not crash minimap if all nodes are hidden