Skip to content

Select — JavaScript

The markup and CSS classes are on the HTML & CSS page. This page covers wiring it up.

Initialize

ts
import { Select } from '@popovandrii/ui-elements'
import '@popovandrii/ui-elements/style.css'

const select = new Select()

Cleanup

Select adds a document-level outside-click listener, so tear it down with dispose() (not just destroy()) to remove that global listener too.

Events

ts
document.addEventListener('ui-select-change', (e) => {
  const { id, value } = (e as CustomEvent).detail // the option's data-value
})

Programmatic API

ts
const el = document.querySelector('.UIselect')!

select.setValue(el, 'banana')                   // choose by value, emits + flashes
select.setValue(el, 'banana', { silent: true }) // no event
select.scan()                                   // (re)bind newly added markup
select.dispose()                                // unbind everything incl. global listener

Usage with Vue

Note the cleanup: Select uses dispose() (not destroy()) to also remove its document-level outside-click listener.

vue
<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue'
import { Select } from '@popovandrii/ui-elements'
import '@popovandrii/ui-elements/style.css'

const root = ref<HTMLElement>()
let select: Select | null = null

function onChange(e: Event) {
  const { id, value } = (e as CustomEvent).detail // option's data-value
  console.log(id, value)
}

onMounted(() => {
  select = new Select({}, false, { root: root.value! })
  root.value!.addEventListener('ui-select-change', onChange)
})
onUnmounted(() => {
  root.value?.removeEventListener('ui-select-change', onChange)
  select?.dispose() // ← removes the global outside-click listener too
})
</script>

<template>
  <div ref="root">
    <div class="UIselect primary" tabindex="0" role="listbox">
      <span class="UIselect-selected">Pick a fruit</span>
      <input type="hidden" name="fruit" />
      <ul class="UIselect-options" hidden>
        <li class="UIselect-options__items" role="presentation">
          <ul role="group">
            <li role="option" data-value="apple">Apple</li>
            <li role="option" data-value="banana">Banana</li>
          </ul>
        </li>
      </ul>
    </div>
  </div>
</template>

The shared patterns (observe, a composable, dynamic lists) are in the full Usage with Vue guide.