UNPKG

melt

Version:

The next generation of Melt UI. Built for Svelte 5.

37 lines (36 loc) 1.44 kB
import { useDebounce } from "runed"; import { extract } from "./extract"; export const letterRegex = /^[a-zA-Z]$/; export function createTypeahead(args) { let value = $state(""); const timeout = $derived(extract(args.timeout, 500)); const debounceClear = useDebounce(() => { value = ""; }, () => timeout); function typeahead(letter) { if (!letterRegex.test(letter)) return; debounceClear(); value += letter.toLowerCase(); const isStartingTypeahead = value.length === 1; const items = args.getItems(); const index = items.findIndex((item) => item.current); const itemsForTypeahead = items .filter((item) => { const searchValue = item.typeahead ?? item.value; return searchValue.toLowerCase().startsWith(value); }) .map((item) => ({ item, index: items.indexOf(item) })); if (!itemsForTypeahead.length) return; // In case you're starting the typeahead, a different element than the first one should be focused. // Otherwise, if the current element matches the typed string, don't change. const next = itemsForTypeahead.find((item) => { if (isStartingTypeahead) return item.index > index; return item.index >= index; }) ?? itemsForTypeahead[0]; return next?.item; } return typeahead; }