Accessible, fuzzy search typeahead component.
This component uses the lightweight fuzzy library for client-side, fuzzy search and follows WAI-ARIA guidelines.
Try it in the Svelte REPL.
# npm
npm i svelte-typeahead
# pnpm
pnpm i svelte-typeahead
# Yarn
yarn add svelte-typeahead
# Bun
bun add svelte-typeaheadPass an array of objects to the data prop. Use the extract prop to specify the value to search on.
<script>
  import Typeahead from "svelte-typeahead";
  const data = [
    { state: "California" },
    { state: "North Carolina" },
    { state: "North Dakota" },
    { state: "South Carolina" },
    { state: "South Dakota" },
    { state: "Michigan" },
    { state: "Tennessee" },
    { state: "Nevada" },
    { state: "New Hampshire" },
    { state: "New Jersey" },
  ];
  const extract = (item) => item.state;
</script>
<Typeahead {data} {extract} />$$restProps are forwarded to svelte-search.
Use the label prop to specify a custom label.
<Typeahead label="U.S. States" {data} {extract} />Hidden label
Set hideLabel to true to visually hide the label.
It's recommended that you set the label – even if hidden – for accessibility.
<Typeahead label="U.S. States" hideLabel {data} {extract} />This component uses the fuzzy library to highlight matching characters with the mark element.
Use the default slot to render custom results.
<Typeahead {data} {extract} let:result let:index>
  <strong>{@html result.string}</strong>
  {index}
</Typeahead>Use the "no-results" slot to render a message if the search value does not yield results.
<Typeahead value="abcd" {data} {extract} let:value>
  <svelte:fragment slot="no-results">
    No results found for "{value}"
  </svelte:fragment>
</Typeahead>Use the limit prop to specify the maximum number of results to display. The default is Infinity.
<Typeahead limit={2} {data} {extract} />Disable items using the disable filter. Disabled items are not selectable or navigable by keyboard.
In the following example, items with a state value containing "Carolina" are disabled.
<Typeahead
  {data}
  value="ca"
  extract={(item) => item.state}
  disable={(item) => /Carolina/.test(item.state)}
/>Set focusAfterSelect to true to re-focus the search input after selecting a result.
<Typeahead focusAfterSelect {data} {extract} />By default, the dropdown will be shown if the value has results.
Set showDropdownOnFocus to true to only show the dropdown when the search input is focused.
<Typeahead value="ca" showDropdownOnFocus {data} {extract} />By default, no results are shown if an empty input (i.e., value="") is focused.
Set showAllResultsOnFocus to true for all results to be shown when an empty input is focused.
<Typeahead showAllResultsOnFocus {data} {extract} />Note: this component is minimally styled by design. You can target the component using the [data-svelte-typeahead] selector.
:global([data-svelte-typeahead]) {
  margin: 1rem;
}| Name | Type | Default value | Description | 
|---|---|---|---|
| value | string | "" | Input search value. | 
| data | TItem[] | [] | Items to search. | 
| extract | (TItem) => any | (item) => item | Target the value if TItemis an object. | 
| disable | (TItem) => boolean | (item) => false | Disabled items are shown in results but are not selectable. | 
| filter | (TItem) => boolean | (item) => false | Filtered out items will not be displayed in the results. | 
| autoselect | boolean | true | Whether to automatically select the first result. | 
| inputAfterSelect | "update" | "clear" | "keep" | "update" | Set to "clear"to clear thevalueafter selecting a result. Set to"keep"to keep the search field unchanged after a selection. | 
| results | FuzzyResult[] | [] | Raw fuzzy results from the fuzzy module | 
| focusAfterSelect | boolean | false | Set to trueto re-focus the input after selecting a result. | 
| showDropdownOnFocus | boolean | false | Set to trueto only show results when the input is focused. | 
| showAllResultsOnFocus | boolean | false | Set to truefor all results to be shown when an empty input is focused. | 
| limit | number | Infinity | Specify the maximum number of results to display. | 
| ...$$restProps | (forwarded to svelte-search) | N/A | All other props are forwarded to the input element. | 
- on:select: dispatched when selecting a result
- on:clear: dispatched when clearing the input field
<script>
  import Typeahead from "svelte-typeahead";
  let e = [];
</script>
<Typeahead
  {data}
  {extract}
  on:select={({ detail }) => (e = [...e, { event: "select", detail }])}
  on:clear={() => (e = [...e, { event: "clear" }])}
/>
<pre>{JSON.stringify(e, null, 2)}</pre>The following events are forwarded to the svelte-search component.
- on:type
- on:input
- on:change
- on:focus
- on:clear
- on:blur
- on:keydown