Files
homelable/frontend/src/utils/viewportCenter.ts
T
Pouzor 2a8c9d618b feat: drop new nodes at centre of visible canvas
New nodes previously landed at a fixed canvas origin, often off-screen,
forcing the user to drag them into view. Add a projector (registered by
CanvasContainer inside ReactFlowProvider) that maps the visible-canvas
centre into flow coordinates, and use it for add-node, group rect, text,
Zigbee/Z-Wave imports, and pending-device approval (single + bulk).

ha-relevant: yes
2026-06-28 00:27:18 +02:00

31 lines
1.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { XYPosition } from '@xyflow/react'
// Projects the centre of the visible canvas into flow-space coordinates.
// Registered by CanvasContainer (inside ReactFlowProvider) so that add-node
// handlers living outside the provider — App handlers, modals — can still drop
// new nodes where the user is actually looking instead of at a fixed canvas
// origin.
type Projector = () => XYPosition
let projector: Projector | null = null
// Used before any canvas is mounted (tests, first render). Matches the old
// hard-coded add position so behaviour degrades gracefully.
const FALLBACK: XYPosition = { x: 300, y: 300 }
export function setViewportCenterProjector(fn: Projector | null): void {
projector = fn
}
// Flow-space coordinate at the centre of the visible canvas.
export function getViewportCenter(): XYPosition {
return projector ? projector() : { ...FALLBACK }
}
// Flow-space top-left position so that a box of `width`×`height` ends up
// centred on screen. With no size it returns the raw centre point.
export function getCenteredPosition(width = 0, height = 0): XYPosition {
const c = getViewportCenter()
return { x: c.x - width / 2, y: c.y - height / 2 }
}