Svelte Typeahead

A themeable typeahead/combobox for Svelte 5 - single or multiple selection, free-text entries, async search. No Tailwind or stylesheet required by consumers.

  • Svelte 5
  • TypeScript
  • Zero Tailwind dependency
  • Themeable

Overview

SvelteTypeahead renders a text input that opens a floating menu below it, filtered as the user types - no full-screen modal, no scroll-lock. All state and logic lives in a plain Typeahead class backed by Svelte stores, so the component itself stays a thin view over that state.

Installation

yarn add @whizzes/svelte-typeahead

Usage

<script lang="ts">
  import { SvelteTypeahead } from '@whizzes/svelte-typeahead';

  let selected = $state([]);
</script>

<SvelteTypeahead
  id="skills"
  options={['Rust', 'TypeScript', 'Svelte', 'Go']}
  bind:selected
/>

Props

PropTypeDefaultDescription
idstring-Required. Derives the input, listbox and option element ids.
optionsTypeaheadOption[][]The full candidate list - a string, or an object read via labelKey.
selectedTypeaheadOption[][]The current selection. Bindable with bind:selected.
multiplebooleanfalseAllow more than one selection, rendered as removable tokens.
labelKeystring | (option) => string'label'Field (or accessor) read off an object option for display/filtering.
filterBy(option, text) => booleancase/diacritic matchCustom filter predicate, replacing the default one.
allowNewbooleanfalseLets the user select their typed text as a new, synthetic option.
onSearch(query: string) => void-When set, filtering is delegated to the consumer (async mode).
onchange(selected: TypeaheadOption[]) => void-Fires on selection/removal/clear caused by user interaction.
themePartial<TypeaheadTheme>DEFAULT_TYPEAHEAD_THEMEOverrides any subset of the visual theme - see Theming below.

See the full prop list in the README for every option (id, valueKey, disabled, clearButton, isLoading, minLength, newSelectionPrefix, emptyLabel, searchText, searchDelay, name, class).

Theming

Every visual aspect is a CSS custom property, set via the theme prop - only pass the fields you want to override:

<SvelteTypeahead theme={{ accentColor: '#059669', activeBackground: '#059669' }} />
FieldDefault
textColor#111827
mutedTextColor#6b7280
placeholderColor#9ca3af
borderColor#d1d5db
borderRadius0.375rem
accentColor#4f46e5
activeBackground#4f46e5
activeTextColor#ffffff
inputBackground#ffffff
menuBackground#ffffff
menuShadow0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1)
tokenBackground#eef2ff
tokenTextColor#4338ca
tokenBorderColor#c7d2fe
highlightBackground#fef08a
fontFamilysans-serif
fontSize1rem

Playground

Tweak the props below and watch the live instance update.

Picked: []

Examples

Single selection

Picked: -

Multiple selection

Picked: -

Object options (labelKey/valueKey)

Picked: -

allowNew (free text)

Picked: -

Async search (onSearch)

Filters asyncResults on a 400ms debounce.

Disabled

A pre-filled, non-interactive instance.