feat(stammbaum): centre-on-person control in the panel title row (#692)

Add an onCentre control to StammbaumSidePanel (title row, both desktop aside
and mobile sheet). The page drives a one-shot centreOnId so StammbaumTree
recentres the canvas on the focal node (US-PAN-005). Also tighten the panel
spec's deathYear fixture to a valid type.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-29 17:10:49 +02:00
parent 1e5a45a027
commit 1dffb430ac
4 changed files with 76 additions and 21 deletions

View File

@@ -14,10 +14,12 @@ type InferredRelationshipWithPersonDTO = components['schemas']['InferredRelation
interface Props {
node: PersonNodeDTO;
onClose: () => void;
/** When provided, a "centre on this person" control appears in the title row (US-PAN-005). */
onCentre?: () => void;
canWrite?: boolean;
}
let { node, onClose, canWrite = false }: Props = $props();
let { node, onClose, onCentre, canWrite = false }: Props = $props();
let directRels = $state<RelationshipDTO[]>([]);
let derivedRels = $state<InferredRelationshipWithPersonDTO[]>([]);
@@ -95,23 +97,45 @@ const topDerived = $derived(
</p>
{/if}
</div>
<button
type="button"
onclick={onClose}
aria-label={m.comp_dismiss()}
class="shrink-0 rounded-sm p-1 text-ink-3 transition hover:bg-muted hover:text-ink focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:outline-none"
>
<svg
class="h-4 w-4"
viewBox="0 0 16 16"
fill="none"
stroke="currentColor"
stroke-width="2"
aria-hidden="true"
<div class="flex shrink-0 items-center gap-1">
{#if onCentre}
<button
type="button"
onclick={onCentre}
aria-label={m.stammbaum_centre_on_person()}
class="rounded-sm p-1 text-ink-3 transition hover:bg-muted hover:text-ink focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:outline-none"
>
<svg
class="h-4 w-4"
viewBox="0 0 16 16"
fill="none"
stroke="currentColor"
stroke-width="1.5"
aria-hidden="true"
>
<circle cx="8" cy="8" r="2" />
<path stroke-linecap="round" d="M8 1v2M8 13v2M1 8h2M13 8h2" />
</svg>
</button>
{/if}
<button
type="button"
onclick={onClose}
aria-label={m.comp_dismiss()}
class="rounded-sm p-1 text-ink-3 transition hover:bg-muted hover:text-ink focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:outline-none"
>
<path stroke-linecap="round" d="M3 3l10 10M13 3L3 13" />
</svg>
</button>
<svg
class="h-4 w-4"
viewBox="0 0 16 16"
fill="none"
stroke="currentColor"
stroke-width="2"
aria-hidden="true"
>
<path stroke-linecap="round" d="M3 3l10 10M13 3L3 13" />
</svg>
</button>
</div>
</div>
{#if error}