feat(stammbaum): recentre on a node via centreOnId prop (#692)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { untrack } from 'svelte';
|
||||
import { SvelteMap, SvelteSet } from 'svelte/reactivity';
|
||||
import type { components } from '$lib/generated/api';
|
||||
import {
|
||||
@@ -8,7 +9,12 @@ import {
|
||||
ROW_GAP,
|
||||
type Layout
|
||||
} from '$lib/person/genealogy/layout/buildLayout';
|
||||
import { type PanZoomState, clampZoom, ZOOM_STEP_KB } from '$lib/person/genealogy/panZoom';
|
||||
import {
|
||||
type PanZoomState,
|
||||
clampZoom,
|
||||
recentreOn,
|
||||
ZOOM_STEP_KB
|
||||
} from '$lib/person/genealogy/panZoom';
|
||||
import { panZoomGestures } from '$lib/person/genealogy/panZoomGestures';
|
||||
|
||||
type PersonNodeDTO = components['schemas']['PersonNodeDTO'];
|
||||
@@ -21,6 +27,8 @@ interface Props {
|
||||
panZoom: PanZoomState;
|
||||
/** Emitted when the keyboard, a gesture, or a recentre changes the view. */
|
||||
onPanZoom?: (state: PanZoomState) => void;
|
||||
/** When set to a node id, the canvas recentres on that node (US-PAN-005). */
|
||||
centreOnId?: string | null;
|
||||
onSelect: (id: string) => void;
|
||||
/**
|
||||
* Force-show or force-hide the generation gutter. When undefined, falls
|
||||
@@ -37,6 +45,7 @@ let {
|
||||
selectedId,
|
||||
panZoom,
|
||||
onPanZoom = () => {},
|
||||
centreOnId = null,
|
||||
onSelect,
|
||||
showGutter
|
||||
}: Props = $props();
|
||||
@@ -130,6 +139,18 @@ function nodeCenter(id: string): { x: number; y: number } | null {
|
||||
return { x: p.x + NODE_W / 2, y: p.y + NODE_H / 2 };
|
||||
}
|
||||
|
||||
// Recentre when the parent sets centreOnId (US-PAN-005). Only centreOnId is a
|
||||
// tracked dependency — the current view is read untracked so a normal pan does
|
||||
// not retrigger a recentre.
|
||||
$effect(() => {
|
||||
const id = centreOnId;
|
||||
if (!id) return;
|
||||
untrack(() => {
|
||||
const c = nodeCenter(id);
|
||||
if (c) onPanZoom(recentreOn(c, baseCentre, panZoom, true));
|
||||
});
|
||||
});
|
||||
|
||||
let focusedId = $state<string | null>(null);
|
||||
|
||||
function handleNodeKey(event: KeyboardEvent, id: string) {
|
||||
|
||||
Reference in New Issue
Block a user