feat(search): add onTextInput callback to TagInput for live tag filter
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,9 +6,10 @@ import { clickOutside } from '$lib/actions/clickOutside';
|
|||||||
interface Props {
|
interface Props {
|
||||||
tags?: string[];
|
tags?: string[];
|
||||||
allowCreation?: boolean;
|
allowCreation?: boolean;
|
||||||
|
onTextInput?: (text: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { tags = $bindable([]), allowCreation = true }: Props = $props();
|
let { tags = $bindable([]), allowCreation = true, onTextInput }: Props = $props();
|
||||||
|
|
||||||
let inputVal = $state('');
|
let inputVal = $state('');
|
||||||
let suggestions: string[] = $state([]);
|
let suggestions: string[] = $state([]);
|
||||||
@@ -101,7 +102,7 @@ function handleKeydown(e: KeyboardEvent) {
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
bind:value={inputVal}
|
bind:value={inputVal}
|
||||||
oninput={() => fetchSuggestions(inputVal)}
|
oninput={() => { fetchSuggestions(inputVal); onTextInput?.(inputVal); }}
|
||||||
onkeydown={handleKeydown}
|
onkeydown={handleKeydown}
|
||||||
onfocus={() => fetchSuggestions(inputVal)}
|
onfocus={() => fetchSuggestions(inputVal)}
|
||||||
placeholder={tags.length === 0
|
placeholder={tags.length === 0
|
||||||
|
|||||||
@@ -208,3 +208,24 @@ describe('TagInput – autocomplete', () => {
|
|||||||
await expect.element(page.getByRole('option', { name: 'Familie' })).not.toBeInTheDocument();
|
await expect.element(page.getByRole('option', { name: 'Familie' })).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ─── onTextInput callback ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
describe('TagInput – onTextInput callback', () => {
|
||||||
|
it('calls onTextInput with the current value on every input event', async () => {
|
||||||
|
mockFetchEmpty();
|
||||||
|
const onTextInput = vi.fn();
|
||||||
|
render(TagInput, { tags: [], allowCreation: false, onTextInput });
|
||||||
|
const input = page.getByRole('textbox');
|
||||||
|
await input.fill('fa');
|
||||||
|
await expect.poll(() => onTextInput.mock.calls.length).toBeGreaterThan(0);
|
||||||
|
expect(onTextInput).toHaveBeenCalledWith('fa');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not throw when onTextInput is not provided', async () => {
|
||||||
|
mockFetchEmpty();
|
||||||
|
render(TagInput, { tags: [], allowCreation: false });
|
||||||
|
const input = page.getByRole('textbox');
|
||||||
|
await expect(input.fill('fa')).resolves.not.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user