feat(stammbaum): serialise pan/zoom state to URL params (#692)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-29 16:26:07 +02:00
parent a7d0e96613
commit 369a0213e5
2 changed files with 21 additions and 0 deletions

View File

@@ -2,6 +2,7 @@ import { describe, it, expect } from 'vitest';
import { import {
clampZoom, clampZoom,
parsePanZoomParams, parsePanZoomParams,
serializePanZoomParams,
DEFAULT_VIEW, DEFAULT_VIEW,
DEFAULT_ZOOM, DEFAULT_ZOOM,
MIN_ZOOM, MIN_ZOOM,
@@ -59,3 +60,18 @@ describe('parsePanZoomParams', () => {
expect(parsePanZoomParams({ z: '-3' }).z).toBe(MIN_ZOOM); expect(parsePanZoomParams({ z: '-3' }).z).toBe(MIN_ZOOM);
}); });
}); });
describe('serializePanZoomParams', () => {
it('produces string cx/cy/z keys', () => {
expect(serializePanZoomParams({ x: 120, y: -40, z: 1.5 })).toEqual({
cx: '120',
cy: '-40',
z: '1.5'
});
});
it('round-trips through parsePanZoomParams', () => {
const state = { x: 87.5, y: -12.25, z: 2.4 };
expect(parsePanZoomParams(serializePanZoomParams(state))).toEqual(state);
});
});

View File

@@ -56,3 +56,8 @@ export function parsePanZoomParams(raw: {
z: clampZoom(finiteOr(raw.z, DEFAULT_ZOOM)) z: clampZoom(finiteOr(raw.z, DEFAULT_ZOOM))
}; };
} }
/** Serialise a view state into URL query params (the inverse of {@link parsePanZoomParams}). */
export function serializePanZoomParams(state: PanZoomState): { cx: string; cy: string; z: string } {
return { cx: String(state.x), cy: String(state.y), z: String(state.z) };
}