fix(person-typeahead): add resetKey prop to clear term on navigation reset
When the user types in the sender/receiver typeahead without selecting a person and then clicks ×-reset (navigating back to /documents), the manually-typed term was not cleared because initialName stayed '' between navigations — the existing $effect tracking initialName never fired. Adding `resetKey` (incremented by the page on every navigation) forces the effect to re-run via `void resetKey`, clearing searchTerm=initialName even when initialName is unchanged. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,7 @@ interface Props {
|
||||
restrictToCorrespondentsOf?: string;
|
||||
excludePersonId?: string;
|
||||
badge?: 'additive' | 'replace';
|
||||
resetKey?: number;
|
||||
onchange?: (value: string) => void;
|
||||
onfocused?: () => void;
|
||||
}
|
||||
@@ -39,6 +40,7 @@ let {
|
||||
restrictToCorrespondentsOf,
|
||||
excludePersonId,
|
||||
badge,
|
||||
resetKey = 0,
|
||||
onchange,
|
||||
onfocused
|
||||
}: Props = $props();
|
||||
@@ -48,8 +50,11 @@ let {
|
||||
// eslint-disable-next-line svelte/prefer-writable-derived
|
||||
let searchTerm = $state(initialName);
|
||||
|
||||
// Sync display text when the selected person changes externally (e.g. swap, navigation).
|
||||
// Sync display text when initialName changes OR when resetKey increments (navigation reset).
|
||||
// resetKey is incremented by the page on every SvelteKit navigation so that a manually-typed
|
||||
// term that was never committed (no person selected) gets cleared even if initialName stays ''.
|
||||
$effect(() => {
|
||||
void resetKey;
|
||||
searchTerm = initialName;
|
||||
});
|
||||
|
||||
|
||||
@@ -270,6 +270,30 @@ describe('PersonTypeahead – correspondent mode', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// ─── resetKey ─────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('PersonTypeahead – resetKey', () => {
|
||||
it('clears a manually-typed term when resetKey changes even if initialName stays empty', async () => {
|
||||
mockFetchWithPersons([]);
|
||||
const { rerender } = render(PersonTypeahead, {
|
||||
name: 'senderId',
|
||||
label: 'Absender',
|
||||
initialName: '',
|
||||
resetKey: 0
|
||||
});
|
||||
const input = page.getByPlaceholder('Namen tippen...');
|
||||
|
||||
// User types something without selecting a person
|
||||
await input.fill('Max');
|
||||
await waitForDebounce();
|
||||
await expect.element(input).toHaveValue('Max');
|
||||
|
||||
// Navigation resets: initialName stays '', but resetKey increments
|
||||
await rerender({ name: 'senderId', label: 'Absender', initialName: '', resetKey: 1 });
|
||||
await expect.element(input).toHaveValue('');
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Click outside ────────────────────────────────────────────────────────────
|
||||
|
||||
describe('PersonTypeahead – click outside', () => {
|
||||
|
||||
Reference in New Issue
Block a user