Skip to content

Overview

The SelectInput component is implemented using the Svelecte library. It offers extensive configuration options, making it versatile and suitable for multiple use cases. The component can handle multiple selections, accommodate objects as values, and provide creatable options, giving users a highly flexible input experience.

The component handles it validations and errors the parent Form component.

Implementation

Below is how the SelectInput component is implemented.

svelte
<script>
  import { getContext, onMount } from "svelte"
  import { fade } from "svelte/transition"
  import { key } from "./form"
  import Svelecte from "svelecte"
  import { uniqueId } from "lodash"
  import { isArray } from "lodash"

  export let name
  export let label = name
  export let noLabel = false
  export let required = false
  export let readonly = false
  export let placeholder = ""
  export let options = []
  export let valueAsObject = false
  export let creatable = false
  export const updateSelection = onUpdateSelection

  let id = uniqueId(name)
  let el

  const { touched, errors, data } = getContext(key)

  let value = $data[name]
  let ready = false

  $: hasError = $touched[name] && $errors[name]?.length
  $: error = $errors[name]?.join(", ")

  // reset the value and make it stick
  $: if (el && options.length && !ready) {
    if (isArray(value)) {
      el.setSelection([])
      setTimeout(() => el.setSelection([...value], true), 0)
    }
    ready = true
  }

  function onUpdateSelection(selection) {
    $data[name] = selection
  }

</script>


<div class="form-control">
  <label class="label flex" class:hidden={noLabel} for={id}>
    <span class="label-text">
      {label}
      {#if required}
        <span class="text-red-600" in:fade out:fade>*</span>
      {/if}
    </span>
  </label>
  <Svelecte bind:this={el} bind:value={$data[name]} {name} options={options} {required} {creatable} {valueAsObject} {placeholder} inputId={id} on:change {...$$restProps}/>

  {#if hasError}
    <label class="label" for={id} in:fade out:fade>
      <span class="label-text-alt text-red-900">{error}</span>
    </label>
  {/if}
</div>

Released under the MIT License.