feat: integrate centered flow node positioning in canvas components

- Added useCenteredFlowNodePosition hook to improve node placement in the CanvasCommandPalette and CanvasToolbar.
- Updated node creation logic to utilize centered positioning, enhancing the visual layout and user experience during node interactions.
- Refactored offset calculations to stagger node positions based on the current node count, ensuring a more organized canvas layout.
This commit is contained in:
Matthias
2026-03-27 23:56:06 +01:00
parent 83c0073d51
commit 5dd5dcf55b
3 changed files with 52 additions and 4 deletions

View File

@@ -0,0 +1,44 @@
"use client";
import { useCallback } from "react";
import { useReactFlow } from "@xyflow/react";
const SNAP = 16;
function snapToGrid(x: number, y: number): { x: number; y: number } {
return {
x: Math.round(x / SNAP) * SNAP,
y: Math.round(y / SNAP) * SNAP,
};
}
/**
* Top-left flow position for a node centered in the visible React Flow pane
* (viewport), with optional stagger and 16px grid snap to match the canvas.
*/
export function useCenteredFlowNodePosition() {
const { screenToFlowPosition } = useReactFlow();
return useCallback(
(width: number, height: number, stagger: number) => {
const pane = document.querySelector(".react-flow__pane");
const rect =
pane?.getBoundingClientRect() ??
document.querySelector(".react-flow")?.getBoundingClientRect();
if (!rect || rect.width === 0 || rect.height === 0) {
return snapToGrid(100 + stagger, 100 + stagger);
}
const center = screenToFlowPosition({
x: rect.left + rect.width / 2,
y: rect.top + rect.height / 2,
});
const x = center.x - width / 2 + stagger;
const y = center.y - height / 2 + stagger;
return snapToGrid(x, y);
},
[screenToFlowPosition],
);
}