Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/rob-balfre/svelte-select
Svelte Select. A select component for Svelte
https://github.com/rob-balfre/svelte-select
autocomplete select svelte sveltejs typeahead
Last synced: 2 days ago
JSON representation
Svelte Select. A select component for Svelte
- Host: GitHub
- URL: https://github.com/rob-balfre/svelte-select
- Owner: rob-balfre
- License: other
- Created: 2018-12-10T23:24:07.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2024-10-20T20:42:55.000Z (about 2 months ago)
- Last Synced: 2024-10-29T15:17:43.167Z (about 1 month ago)
- Topics: autocomplete, select, svelte, sveltejs, typeahead
- Language: JavaScript
- Homepage: https://svelte-select-examples.vercel.app
- Size: 2.06 MB
- Stars: 1,280
- Watchers: 15
- Forks: 182
- Open Issues: 90
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
- my-awesome-list - svelte-select - balfre | 1285 | (JavaScript)
README
Svelte Select
A select/autocomplete/typeahead Svelte component.## Demos
[๐ฅ Examples of every prop, event, slot and more ๐ฅ](https://svelte-select-examples.vercel.app)
[โจ REPL: Simple โจ](https://svelte.dev/repl/c3bbe052fdfc4e87a46ccd9091ee002b)
[๐ REPL: Show me everything ๐บ](https://svelte.dev/repl/3df87e32340e4e9e85bf371becae2af0)
## Installation
```bash
npm install svelte-select
```## Svelte 5
I'm not currently using Svelte 5 in my day job or personal projects so might be a while before I tackle porting / upgrading to Svelte 5. Looking forward to it though, just need to find the time!## Upgrading Svelte Select
See [migration guide](/MIGRATION_GUIDE.md) if upgrading## Rollup and low/no-build setups
List position and floating is powered by `floating-ui`, see their [package-entry-points](https://github.com/floating-ui/floating-ui#package-entry-points) docs if you encounter build errors.
## Props
| Prop | Type | Default | Description |
| ---------------------- | --------- | --------------- | -------------------------------------------------------------- |
| items | `any[]` | `[]` | Array of items available to display / filter |
| value | `any` | `null` | Selected value(s) |
| justValue | `any` | `null` | **READ-ONLY** Selected value(s) excluding container object |
| itemId | `string` | `value` | Override default identifier |
| label | `string` | `label` | Override default label |
| id | `string` | `null` | id attr for input field |
| filterText | `string` | `''` | Text to filter `items` by |
| placeholder | `string` | `Please select` | Placeholder text |
| hideEmptyState | `boolean` | `false` | When no items hide list |
| listOpen | `boolean` | `false` | Open/close list |
| class | `string` | `''` | container classes |
| containerStyles | `string` | `''` | Add inline styles to container |
| clearable | `boolean` | `true` | Enable clearing of value(s) |
| disabled | `boolean` | `false` | Disable select |
| multiple | `boolean` | `false` | Enable multi-select |
| searchable | `boolean` | `true` | If `false` search/filtering is disabled |
| groupHeaderSelectable | `boolean` | `false` | Enable selectable group headers |
| focused | `boolean` | `false` | Controls input focus |
| listAutoWidth | `boolean` | `true` | If `false` will ignore width of select |
| showChevron | `boolean` | `false` | Show chevron |
| inputAttributes | `object` | `{}` | Pass in HTML attributes to Select's input |
| placeholderAlwaysShow | `boolean` | `false` | When `multiple` placeholder text will always show |
| loading | `boolean` | `false` | Shows `loading-icon`. `loadOptions` will override this |
| listOffset | `number` | `5` | `px` space between select and list |
| debounceWait | `number` | `300` | `milliseconds` debounce wait |
| floatingConfig | `object` | `{}` | [Floating UI Config](https://floating-ui.com/) |
| hasError | `boolean` | `false` | If `true` sets error class and styles |
| name | `string` | `null` | Name attribute of hidden input, helpful for form actions |
| required | `boolean` | `false` | If `Select` is within a `` will restrict form submission |
| multiFullItemClearable | `boolean` | `false` | When `multiple` selected items will clear on click |
| closeListOnChange | `boolean` | `true` | After `on:change` list will close |
| clearFilterTextOnBlur | `boolean` | `true` | If `false`, `filterText` value is preserved on:blur |## Named slots
```svelte
```
## Events
| Event Name | Callback | Description |
| ---------- | ----------------- | -------------------------------------------------------------------------- |
| change | { detail } | fires when the user selects an option |
| input | { detail } | fires when the value has been changed |
| focus | { detail } | fires when select > input on:focus |
| blur | { detail } | fires when select > input on:blur |
| clear | { detail } | fires when clear is invoked or item is removed (by user) from multi select |
| loaded | { options } | fires when `loadOptions` resolves |
| error | { type, details } | fires when error is caught |
| filter | { detail } | fires when `listOpen: true` and items are filtered |
| hoverItem | { detail } | fires when hoverItemIndex changes |### Items
`items` can be simple arrays or collections.
```html
import Select from 'svelte-select';
let simple = ['one', 'two', 'three'];
let collection = [
{ value: 1, label: 'one' },
{ value: 2, label: 'two' },
{ value: 3, label: 'three' },
];```
They can also be grouped and include non-selectable items.
```html
import Select from 'svelte-select';
const items = [
{value: 'chocolate', label: 'Chocolate', group: 'Sweet'},
{value: 'pizza', label: 'Pizza', group: 'Savory'},
{value: 'cake', label: 'Cake', group: 'Sweet', selectable: false},
{value: 'chips', label: 'Chips', group: 'Savory'},
{value: 'ice-cream', label: 'Ice Cream', group: 'Sweet'}
];const groupBy = (item) => item.group;
```
You can also use custom collections.
```html
import Select from 'svelte-select';
const itemId = 'id';
const label = 'title';const items = [
{id: 0, title: 'Foo'},
{id: 1, title: 'Bar'},
];```
### Async Items
To load items asynchronously then `loadOptions` is the simplest solution. Supply a function that returns a `Promise` that resolves with a list of items. `loadOptions` has debounce baked in and fires each time `filterText` is updated.
```html
import Select from 'svelte-select';
import { someApiCall } from './services';
async function examplePromise(filterText) {
// Put your async code here...
// For example call an API using filterText as your search params
// When your API responds resolve your Promise
let res = await someApiCall(filterText);
return res;
}```
### Advanced List Positioning / Floating
`svelte-select` uses [floating-ui](https://floating-ui.com/) to control the list floating. See their docs and pass in your config via the `floatingConfig` prop.
```html
import Select from 'svelte-select';
let floatingConfig = {
strategy: 'fixed'
}```
### Exposed methods
These internal functions are exposed to override if needed. Look through the test file (test/src/index.js) for examples.```js
export let itemFilter = (label, filterText, option) => label.toLowerCase().includes(filterText.toLowerCase());
``````js
export let groupBy = undefined;
``````js
export let groupFilter = groups => groups;
``````js
export let createGroupHeaderItem = groupValue => {
return {
value: groupValue,
label: groupValue
};
};
``````js
export function handleClear() {
value = undefined;
listOpen = false;
dispatch("clear", value);
handleFocus();
}
``````js
export let loadOptions = undefined; // if used must return a Promise that updates 'items'
/* Return an object with { cancelled: true } to keep the loading state as active. */
``````js
export const getFilteredItems = () => {
return filteredItems;
};
``````js
export let debounce = (fn, wait = 1) => {
clearTimeout(timeout);
timeout = setTimeout(fn, wait);
};
```Override core functionality at your own risk! See ([get-items.js](/src/lib/get-items.js) & [filter.js](/src/lib/filter.js))
```js
// core replaceable methods...
```## A11y (Accessibility)
Override these methods to change the `aria-context` and `aria-selection` text.
```js
export let ariaValues = (values) => {
return `Option ${values}, selected.`;
}export let ariaListOpen = (label, count) => {
return `You are currently focused on option ${label}. There are ${count} results available.`;
}export let ariaFocused = () => {
return `Select is focused, type to refine list, press down to open the menu.`;
}
```## CSS custom properties (variables)
You can style a component by overriding [the available CSS custom properties](/docs/theming_variables.md).
```html
import Select from 'svelte-select';
```
You can also use the `inputStyles` prop to write in any override styles needed for the input.
```html
import Select from 'svelte-select';
const items = ['One', 'Two', 'Three'];
```
### ๐งช Experimental: Replace styles (Tailwind, Bootstrap, Bulma etc)
If you'd like to supply your own styles use: `import Select from 'svelte-select/no-styles/Select.svelte'`. Then somewhere in your code or build pipeline add your own. There is a tailwind stylesheet via `import 'svelte-select/tailwind.css'`. It uses `@extend` so PostCSS is required.## License
[LIL](LICENSE)