BaseCombobox

A field you type into to narrow a list, then choose from it.

Import it from rei-kit: import { BaseCombobox } from 'rei-kit'

Open BaseCombobox in the live documentation, where every prop below is a control you can change, in four materials and ten palettes.

Usage

<script setup lang="ts">
import { ref } from 'vue'
import { BaseCombobox } from 'rei-kit'

const country = ref('')
const countries = [
  { value: 'tr', label: 'Türkiye' },
  { value: 'jp', label: 'Japan' },
  { value: 'de', label: 'Germany' },
]

/* More than one answer: the chosen ones become chips in the field. */
const recipients = ref<string[]>(['tr'])

/* A list that lives on a server. `@search` is the typed text, debounced by
   the component; `filter="none"` stops it narrowing what the server already
   narrowed. */
const results = ref<{ value: string; label: string }[]>([])
const loading = ref(false)

async function search(query: string) {
  if (query === '') {
    results.value = []
    return
  }

  loading.value = true
  const response = await fetch(`/api/cities?q=${encodeURIComponent(query)}`)
  results.value = await response.json()
  loading.value = false
}
</script>

<template>
  <BaseCombobox
    v-model="country"
    label="Country"
    :options="countries"
    placeholder="Start typing"
    empty-label="No country matches"
  />

  <BaseCombobox
    v-model="recipients"
    mode="multiple"
    label="Recipients"
    :options="countries"
    :remove-label="(name) => `Remove ${name}`"
    placeholder="Add someone"
    empty-label="Nobody matches"
  />

  <BaseCombobox
    label="City"
    :options="results"
    :loading="loading"
    loading-label="Searching…"
    filter="none"
    placeholder="Type at least two letters"
    empty-label="No city matches"
    @search="search"
  />
</template>

Props

Props
PropTypeRequired or defaultWhat it is for
modelValueValueundefinedThe chosen value, or values in `multiple` mode, with `v-model`.
labelstringyes
optionsreadonly ComboboxOption<V>[]yes
placeholderstring''
hintstring''
errorstring''
disabledbooleanfalse
emptyLabelstringyesShown when nothing matches. Already translated.
modeM'single' as M`multiple` keeps the chosen ones as chips in the field.
removeLabel((label: string) => string)undefinedNames a chip's remove button. Without it, chips carry no button.
loadingbooleanfalseMarks the list busy while an answer is on its way.
loadingLabelstring''Read while `loading`. Already translated.
filter'local' | 'none''local'`none` when the server has already narrowed the list.
debouncenumber200How long typing settles before `search`, in milliseconds.
virtualizeAfternumber150Past this many options, only the rows near the viewport are rendered.
rowHeightnumber36A row's height in pixels; the virtual window is measured in these.

About rei-kit

rei-kit is an accessible Vue 3 and Tailwind CSS 4 component library: 106 components, themed by role rather than by colour on three independent axes — ten WCAG-checked palettes, four materials and light or dark, each switched with one attribute. Typed, tested, SSR-safe, no runtime dependencies, MIT.

pnpm add rei-kit · npm · GitHub