/svelecte

Selectize-like component written in Svelte, also usable as custom-element 💪⚡

Primary LanguageSvelteMIT LicenseMIT

Svelecte NPM version

svelecte

Flexible autocomplete/select component written in Svelte. Massively inspired by Selectize.js. Also usable as custom element (CE). Usable in forms, behaves very similar to standard <select> element.

See the latest changes on the Releases page.

📃 Features

  • searchable
  • multiselect with limit of max selected items
  • allow simple array or complex objects as items
  • custom item renderer (formatter)
  • allow creating new items (and possibly edit them)
  • remote data fetch
  • virtual list support
  • i18n support
  • SSR support
  • lazy dropdown rendering
  • usable as custom element
  • stylable
  • reordable multi selection with addition of svelte-dnd-action (example)
  • usable with svelte-use-form (example)

🔧 Installation

npm install svelecte --save

Minimalistic example

<script>
import Svelecte from 'svelecte';

const list = [{ id: 1, name: 'Item 1' }, { id: 2, name: 'Item 2'}, ...];
let myValue = null;
</script>

<Svelecte options={list} bind:value={myValue}></Svelecte>
💭 Note about value and readSelection property
Since v3.0 inner logic behind these properties has changed. Now `value` property reflects inner selection. By default it returns `valueField` property (if not defined, Svelecte tries to guess which property is representing value). This also means that if you want to set new value, you need to assign to it correct value. Let's take the example above:
myValue = 2;

This would select item with id property 2.

Sometimes you want to work strictly with objects, like myValue = {id: 2, name: 'Item 2'}. You can set property valueAsObject which tells Svelecte to handle value property as object or array of object (if multiple is also set).

Property readSelection always returns selected object or object array no matter if valueAsObject is set or not.


👀 Examples

👉 Examples with more detailed documentation can be found at https://mskocik.github.io/svelecte/.

🛠 Configuration & API

Exposed properties:

Property Type Default Description
name string null create internal <select> element which you can use validatorAction on. Without name defined, no <select> is created
options array [] Data array
valueAsObject bool false Switch whether Svelecte should expects from and return to bind:value objects or primitive value (usually string, number)
valueField string null Property to be used as value (if not specified, will be selected automatically)
labelField string null Property shown in dropdown (if not specified, will be selected automatically)
groupLabelField string label Property to be used as optgroup label
groupItemsField string options Property holding optgroup option list
disabledField string $disabled Property to check, whether given options should be disabled and unselectable
required bool false make sense only when name is defined
placeholder string Select Input placeholder
searchable bool true Allow search among items by typing
disabled bool false Disable component
renderer string|function null dropdown and selection renderer function. More info in item rendering section
controlItem Component Item Item component when item is selected. See Custom Items section for more details.
dropdownItem Component Item Item component in dropdown. See Custom Items section for more details.
highlightFirstItem bool true Automatically highlight the first item in the list when the dropdown opens
selectOnTab bool string null
resetOnBlur bool true Control if input value should be cleared on blur
resetOnSelect bool true Control if input value should be cleared on item selection. Note: applicable only with multiple
clearable bool false Display ✖ icon to clear whole selection
multiple bool false allow multiselection. Will be set automatically to true, if name property ends with [], like tags[]
closeAfterSelect bool false closes dropdown after selection. Setting this to true is useful for multiple select only. For single select dropdown is always closed no matter the value this property has
max number 0 Maximum allowed items selected, applicable only for multiselect
collapseSelection bool false collapse selection when multiple and not focused
alwaysCollapsed bool false keep collapsed selection even when focused. Selected options are shown in dropdown on the top
inputId string null allow targeting input using a html label.
creatable bool false Allow creating new item(s)
creatablePrefix string * Prefix marking new item
allowEditing bool false When pressing Backspace switch to edit mode instead of removing newly created item. NOTE intended to be used with creatable property
keepCreated bool true Switch whether to add newly created option to option list or not
delimiter string , split inserted text when pasting to create multiple items
createFilter function null Function, that transform input string to custom value. It can serve as a filter, if value is valid or not. If you want to dismiss entered value, function should return '' (empty string). By default all input string is trimmed and all multiple spaces are removed. Function notation:
createFilter(inputValue: string, dropdownOptions: array): string
createTransform function null Custom function transforming input string to option object. Default returns object with valueField and labelField properties, where labelField's value is input string prefixed with creatablePrefix property. Function notation:
createTransform(inputValue: string, creatablePrefix: string, valueField: string, labelField: string): object
fetch string|function null Check "remote datasource" section for more details
fetchMode string auto When set to init options are fetched only when mounted, when searching it search in downloaded dataset
fetchCallback function null optional fetch callback
fetchResetOnBlur bool true reset previous search results on empty input, related to resetOnBlur
fetchDebounceTime number 500 Change default debounce time for fetch request
minQuery number 1 Minimal amount of characters required to perform remote request. Usable with fetch property
lazyDropdown bool true render dropdown after first focus, not by default
virtualList bool false Whether use virtual list for dropdown items (useful for large datasets)
vlHeight number null Height of virtual list dropdown (if not specified, computed automatically)
vlItemSize number null Height of one row (if not specified, computed automatically)
searchField string|array null Specify item property that will be used to search by (if not specified all props except value prop will be used)
sortField string null Specify sort property. If not specified, labelField will be used
disableSifter bool false Disable Sifter filtering & sorting. Can be useful in combination with fetch, when further filtering or sorting may be undesired
disableHighlight bool false Disable highlighting of input value in results. Can be useful with a renderer function that includes additional text or does its own highlighting
class string svelecte-control default css class
style string null inline style
hasAnchor bool null internal: when passing also existing select (for CE)
i18n object null I18n object overriding default settings
dndzone function empty Pass dndzone from svelte-dnd-action, if you want to support selection reordering. See the example REPL
validatorAction array null Bind validator action for inner <select> element. Designed to be used with svelte-use-form. See the example REPL. For this to work, name property MUST be defined

Custom items

If renderer property is not enough for you or you prefer Component syntax to HTML strings, you can use your own Components. Keep in mind that default Item component handles highlighting when searching, but the rest of features like styling should be inherited if you use proper css classes (the same as Item component)..

To make it easier to use your own Components, there are available actions, highlighting function and close button icon for you to use.

The simplest example can be found in this REPL.


Emitted events:

Event arguments description
fetch options newly fetched remote options
change selection selected objects. If anchor property is defined, change event is called also on it
createoption option newly created option object
blur - blur event
invalidValue invalidValue triggered when passed value is out of provided options items. Internal (and bound, if any) value is set to null or [] if multiple
enterKey underlying keyDown event triggered when natively it would cause form submit (dropdown is closed). This gives you ability to prevent it by calling event.detail.preventDefault()

Public API:

Name type arguments description
focus function - focus input
getSelection function bool return selection, if true is passed, only values are returns, whole objects otherwise
setSelection function array set selection programmatically
config property - context property: global common config for all instances, you can override most properties here and also some additional, mainly i18n
addFormatter function - context function: with signature (name, formatFn) you can add additional item renderers (formatters)

I18n

This is default value of i18n property:

// config.i18n defaults:
{
  i18n: {
    empty: 'No options',
    nomatch: 'No matching options',    
    max: num => `Maximum items ${num} selected`,
    fetchBefore: 'Type to start searching',
    fetchQuery: (minQuery, inputLength) => `Type ${minQuery > 1 && minQuery > inputLength 
      ? `at least ${minQuery - inputLength} characters `
      : '' }to start searching`,
    fetchEmpty: 'No data related to your search',
    collapsedSelection: count => `${count} selected`,
    createRowLabel: value => `Create '${value}'`
  },
  collapseSelectionFn: function(selectionCount, selection) {
    return settings.i18n.collapsedSelection(selectionCount);
  }
}

You can override whole object or only items you are interested in. You can override it globally or on component level:

// global override
import Svelecte, { config } from 'svelecte';

config.i18n = {
    empty: '🚫',
    nomatch: '✋',
    max: num => '🙄',
    fetchBefore: '💻',
    fetchQuery: (minQuery, inputLength) => '🧮',
    fetchEmpty: '🚮',
    collapsedSelection: () => '🗃',
    createRowLabel: value => `📝 ${value}`
}

// local override (component-level)
const myI18n = {
    empty: `Empty list, can't you see?`
}

<Svelecte i18n={myI18n}></Svelecte>

Customizable Slots

There are different slots within the component that allow to insert custom code and icons.

Control.svelte (bubbled up to the Svelecte component)

  • icon This allows to insert custom code like e.g. an icon at the start/left of the Control.svelte
  • control-end This allows to insert custom code at the end/right of the Control.svelte. It is positioned AFTER the indicator icons.

🙏 Thanks to

License

MIT License