feat(stammbaum): bottom-right zoom + fit-to-screen control cluster (#692)

Move zoom controls out of the page header into a docked bottom-right cluster
inside the canvas (one-handed phone reach, Leonie) and add a fit-to-screen
button (data-testid=fit-to-screen). Add the 5 new i18n keys to de/en/es.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-29 16:52:32 +02:00
parent ffc14dd2ff
commit 7a6c2e877f
5 changed files with 59 additions and 21 deletions

View File

@@ -3,6 +3,7 @@ import { m } from '$lib/paraglide/messages.js';
import { page } from '$app/state';
import StammbaumTree from '$lib/person/genealogy/StammbaumTree.svelte';
import StammbaumSidePanel from '$lib/person/genealogy/StammbaumSidePanel.svelte';
import StammbaumControls from '$lib/person/genealogy/StammbaumControls.svelte';
import {
type PanZoomState,
DEFAULT_VIEW,
@@ -36,6 +37,9 @@ function zoomIn() {
function zoomOut() {
view = { ...view, z: clampZoom(view.z - ZOOM_STEP_KB) };
}
function fitToScreen() {
view = DEFAULT_VIEW;
}
</script>
<!-- 4.25rem = 4rem navbar (h-16) + 0.25rem accent strip (h-1).
@@ -46,26 +50,6 @@ function zoomOut() {
class="flex shrink-0 items-center justify-between border-b border-line bg-surface px-6 py-4"
>
<h1 class="font-serif text-2xl text-ink">{m.nav_stammbaum()}</h1>
{#if data.nodes.length > 0}
<div class="flex items-center gap-2">
<button
type="button"
onclick={zoomOut}
aria-label={m.stammbaum_zoom_out()}
class="inline-flex h-11 w-11 items-center justify-center rounded-sm border border-line bg-surface text-ink-2 transition hover:bg-muted focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:outline-none"
>
</button>
<button
type="button"
onclick={zoomIn}
aria-label={m.stammbaum_zoom_in()}
class="inline-flex h-11 w-11 items-center justify-center rounded-sm border border-line bg-surface text-ink-2 transition hover:bg-muted focus-visible:ring-2 focus-visible:ring-focus-ring focus-visible:outline-none"
>
+
</button>
</div>
{/if}
</header>
{#if data.nodes.length === 0}
@@ -98,7 +82,7 @@ function zoomOut() {
</div>
{:else}
<div class="flex flex-1 overflow-hidden">
<div class="flex-1 overflow-hidden bg-muted/20">
<div class="relative flex-1 overflow-hidden bg-muted/20">
<StammbaumTree
nodes={data.nodes}
edges={data.edges}
@@ -107,6 +91,7 @@ function zoomOut() {
onPanZoom={(v) => (view = v)}
onSelect={(id) => (selectedId = id)}
/>
<StammbaumControls onZoomIn={zoomIn} onZoomOut={zoomOut} onFit={fitToScreen} />
</div>
{#if selectedNode}
<!-- Desktop: side panel on the right -->