Rendering

Svelecte provides many ways how to customize rendering. Whole concept of rendering was rewritten in v4.0 to provide more possibilities as many (some) users requested. Hopefully you will have enough tools to make it work as you need.

In general rendering customization can be split into 2 groups:

Render functions

Render functions (aka renderers) are simple functions which return string, which is then rendered through {@html} tag. This is very easily customizable and more importantly available also outside svelte. Another advantage is, that highlighting is handled automatically. Of course highlighting can be disabled if needed.

Render function have following signature:

/**
 * @param {object} item
 * @param {boolean} [selectionSection] - if true, option is rendered in control, otherwise in dropdown
 * @param {string} [inputValue] - search value, if you want to handle highlighting yourself
 * @returns {string}
 */
function renderer() {}
/**
 * @param {object} item
 * @param {boolean} [selectionSection] - if true, option is rendered in control, otherwise in dropdown
 * @param {string} [inputValue] - search value, if you want to handle highlighting yourself
 * @returns {string}
 */
function renderer() {}

You can define renderers globally or per-component basis. To differenciate whether item is selected you can use internal $selected property.

Note: When using custom renderers with inputValue being used, it’s up to you correctly escape HTML tags

<script>
  import Svelecte, { addRenderer } from 'svelecte';

  function colorRenderer(item, _isSelection, _inputValue) {
    return _isSelection
      ? `<div style="width:16px; height: 16px; background-color: ${item.hex};"></div>${item.text}`
      : `${item.text} (#${item.hex})`
  }

  addRenderer('color', colorRenderer);
</script>

<Svelecte renderer="color" />

<Svelecte renderer={colorRenderer} />
<script>
  import Svelecte, { addRenderer } from 'svelecte';

  function colorRenderer(item, _isSelection, _inputValue) {
    return _isSelection
      ? `<div style="width:16px; height: 16px; background-color: ${item.hex};"></div>${item.text}`
      : `${item.text} (#${item.hex})`
  }

  addRenderer('color', colorRenderer);
</script>

<Svelecte renderer="color" />

<Svelecte renderer={colorRenderer} />

Result:

Using renderer globally:

Using renderer locally:

Slots

Svelecte provide multiple slots as you can see below. On the left you can see default slot implementation, on the right you can see slot placeholders.

3 selected
Icon
Collapsed selection

Slot summary:

<slot name="icon" />
<slot name="collapsedSelection" let:selectedOptions let:i18n />
<slot name="selection" let:selectedOptions let:bindItem />
<slot name="clear-icon" let:selectedOptions let:inputValue />
<slot name="dropdown-toggle" let:isOpen />
<slot name="list-header" />
<slot name="option" let:item />
<slot name="create-row" let:isCreating let:inputValue let:i18n  />
<slot name="icon" />
<slot name="collapsedSelection" let:selectedOptions let:i18n />
<slot name="selection" let:selectedOptions let:bindItem />
<slot name="clear-icon" let:selectedOptions let:inputValue />
<slot name="dropdown-toggle" let:isOpen />
<slot name="list-header" />
<slot name="option" let:item />
<slot name="create-row" let:isCreating let:inputValue let:i18n  />

Slots in more details:

• selection

<slot name="selection" let:selectedOptions let:bindItem/>

<!-- example implementation -->
<slot name="selection" let:selectedOptions let:bindItem>
  {#each selectedOptions as opt (opt.id)}
    <div>
      {item.text}
      <button data-action="deselect" use:bindItem={opt}>&times;</button>
    </div>
  {/each}
</slot>
<slot name="selection" let:selectedOptions let:bindItem/>

<!-- example implementation -->
<slot name="selection" let:selectedOptions let:bindItem>
  {#each selectedOptions as opt (opt.id)}
    <div>
      {item.text}
      <button data-action="deselect" use:bindItem={opt}>&times;</button>
    </div>
  {/each}
</slot>

Where:

  • selectedOptions is array of selected options as objects
  • bindItem is action which can be used to bind selected option option to the element with attribute data-action="deselect". This attribute indicates, that when given option should be removed from selection.

• collapsedSelection

collapsedSelection is paired with collapseSelection prop:

  • collapseSelection=false: only selection slot is visible (default)
  • collapseSelection='blur': selection slot is show only when component is focused
  • collapseSelection='always': selection slot is never show
<slot name="collapsedSelection" let:selectedOptions let:i18n/>

<!-- default implementation -->
<slot name="collapsedSelection" let:selectedOptions let:i18n>
  {i18n.collapsedSelection(selectedOptions.length)}
</slot>
<slot name="collapsedSelection" let:selectedOptions let:i18n/>

<!-- default implementation -->
<slot name="collapsedSelection" let:selectedOptions let:i18n>
  {i18n.collapsedSelection(selectedOptions.length)}
</slot>

Where:

  • selectedOptions is array of selected options as objects
  • i18n default or customized i18n object

• clear-icon

clear-icon slot is coupled with clearable prop.

<slot name="clear-icon" let:selectedOptions let:inputValue />
<slot name="clear-icon" let:selectedOptions let:inputValue />

Where:

  • selectedOptions is array of selected options as objects
  • inputValue search query

• drodpdown-toggle

<slot name="dropdown-toggle" let:isOpen />
<slot name="dropdown-toggle" let:isOpen />

• list-header

<!-- empty slot with no props -->
<slot name="list-header" />
<!-- empty slot with no props -->
<slot name="list-header" />

Originally added to address issue #151, but can be used for anything. If you want to display selected options here as in mentioned issue, check Migration guide.

• option

<slot name="option" let:item />
<slot name="option" let:item />

Where:

  • item is current option in dropdown. To duplicate highlighting functionality you need to use function highlightSearch exported from the library.

• create-row

create-row slot with creatable prop (and you enter to enter some input).

<slot name="create-row" let:isCreating let:inputValue let:i18n />
<slot name="create-row" let:isCreating let:inputValue let:i18n />

Where:

  • isCreating is true when executing async createHandler.
  • inputValue entered value
  • i18n default or customized i18n object

Made with Svelte ❤ by Martin Skocik.

You can support me through GitHub.