0}
aria-expanded={showResults}
id="{id}-typeahead"
>
= 0 &&
!hideDropdown &&
results.length > 0
? `${id}-result-${selectedIndex}`
: null}
bind:value
on:type
on:input
on:change
on:focus
on:focus={() => {
open();
if (showDropdownOnFocus || showAllResultsOnFocus) {
showResults = true;
isFocused = true;
}
}}
on:clear
on:clear={open}
on:blur={(e) => {
// Check if focus is moving to an element within the combobox
const relatedTarget = e.relatedTarget;
if (relatedTarget && comboboxRef?.contains(relatedTarget)) {
return;
}
// Close immediately for keyboard navigation (Tab, Shift+Tab)
close();
}}
on:keydown
on:keydown={(e) => {
if (results.length === 0) return;
switch (e.key) {
case "Enter":
select();
break;
case "ArrowDown":
e.preventDefault();
change(1);
break;
case "ArrowUp":
e.preventDefault();
change(-1);
break;
case "Escape":
e.preventDefault();
value = "";
searchRef?.focus();
close();
break;
}
}}
/>
{#if showResults}
{#each results as result, index}
- {
if (result.disabled) return;
e.preventDefault(); // Prevent input from losing focus
selectedIndex = index;
select();
}}
on:mouseenter={() => {
if (result.disabled) return;
selectedIndex = index;
}}
>
{@html result.string}
{/each}
{/if}
{#if $$slots["no-results"] && !hideDropdown && value.length > 0 && results.length === 0}
{/if}
================================================
FILE: src/Typeahead.svelte.d.ts
================================================
import type { SvelteComponentTyped } from "svelte";
import type { SearchProps } from "svelte-search/src/Search.svelte";
export interface TypeaheadProps