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.
# Yarn
yarn add -D svelte-typeahead
# npm
npm i -D svelte-typeahead
# pnpm
pnpm i -D svelte-typeahead
To use this component with SvelteKit or vite-powered set-ups, instruct vite
to optimize the "fuzzy"
dependency.
// svelte.config.js
const config = {
kit: {
vite: {
optimizeDeps: {
include: ["fuzzy"],
},
},
},
};
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;
}
Pass an array of objects to the data
prop. Use the extractor
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} />
Prop name | Value | Description |
---|---|---|
value | string (default: "" ) |
Input search value |
data | TItem[] (default: [] ) |
Items to search |
extract | (TItem) => any |
Target an item key if data is an object array |
disable | (TItem) => boolean |
Pass in a function to disable items. They can be displayed in the results but will not be selectable. |
filter | (TItem) => boolean |
Pass in a function to filter items. They will be hidden and are not displayed in the results. |
autoselect | boolean (default: true ) |
Automatically select the first (top) result |
inputAfterSelect | "update" or "clear" or "keep" (default: "update" ) |
Set to "clear" to clear the value after selecting a result. Set to "keep" to keep the search field unchanged after a selection. |
results | FuzzyResult[] (default: [] ) |
Raw fuzzy results from the fuzzy module |
focusAfterSelect | boolean (default: false ) |
Set to true to re-focus the input after selecting a result. |
showDropdownOnFocus | boolean (default: false ) |
Set to true to only show results when the input is focused. |
limit | number (default: Infinity ) |
Specify the maximum number of results to display. |
...$$restProps |
(forwarded to svelte-search ) |
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
Svelte version 3.31 or greater is required to use this component with TypeScript.
TypeScript definitions are located in the types folder.