fix(date-input): re-derive display when value prop changes externally
`display` was initialised once and never updated, so the text box would show a stale German date after the parent reset `value` (e.g. × reset button or timeline drag). A guarded `$effect` re-derives `display` from `value` whenever the two are out of sync while preserving mid-typing partial dates (germanToIso returns '' for incomplete input, which matches value='' during typing → no spurious re-derive). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { untrack } from 'svelte';
|
||||||
import { isoToGerman, handleGermanDateInput, germanToIso } from '$lib/shared/utils/date';
|
import { isoToGerman, handleGermanDateInput, germanToIso } from '$lib/shared/utils/date';
|
||||||
import { m } from '$lib/paraglide/messages.js';
|
import { m } from '$lib/paraglide/messages.js';
|
||||||
|
|
||||||
@@ -24,6 +25,16 @@ let {
|
|||||||
|
|
||||||
let display = $state(isoToGerman(value ?? ''));
|
let display = $state(isoToGerman(value ?? ''));
|
||||||
|
|
||||||
|
// Re-derive display when value changes externally (e.g. timeline drag, reset nav).
|
||||||
|
// Guard prevents overwriting while the user is mid-typing a partial date:
|
||||||
|
// germanToIso returns '' for partial input, matching value '' → no re-derive.
|
||||||
|
$effect(() => {
|
||||||
|
const externalIso = value ?? '';
|
||||||
|
if (germanToIso(untrack(() => display)) !== externalIso) {
|
||||||
|
display = isoToGerman(externalIso);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// ─── Validation helper ────────────────────────────────────────────────────
|
// ─── Validation helper ────────────────────────────────────────────────────
|
||||||
function isCalendarValid(iso: string): boolean {
|
function isCalendarValid(iso: string): boolean {
|
||||||
if (!iso) return false;
|
if (!iso) return false;
|
||||||
|
|||||||
@@ -183,6 +183,26 @@ describe('DateInput – clearing the date', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ─── External value changes ───────────────────────────────────────────────────
|
||||||
|
|
||||||
|
describe('DateInput – external value changes', () => {
|
||||||
|
it('clears display when value prop is reset to empty externally', async () => {
|
||||||
|
const { rerender } = render(DateInput, { value: '1920-01-01' });
|
||||||
|
const input = page.getByRole('textbox');
|
||||||
|
await expect.element(input).toHaveValue('01.01.1920');
|
||||||
|
await rerender({ value: '' });
|
||||||
|
await expect.element(input).toHaveValue('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('updates display when value prop changes to a new date externally', async () => {
|
||||||
|
const { rerender } = render(DateInput, { value: '1920-01-01' });
|
||||||
|
const input = page.getByRole('textbox');
|
||||||
|
await expect.element(input).toHaveValue('01.01.1920');
|
||||||
|
await rerender({ value: '1945-05-08' });
|
||||||
|
await expect.element(input).toHaveValue('08.05.1945');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// ─── Hidden input ─────────────────────────────────────────────────────────────
|
// ─── Hidden input ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
describe('DateInput – hidden input for form submission', () => {
|
describe('DateInput – hidden input for form submission', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user