Components / Forms

Combobox

An editable, typo-tolerant input that filters a listbox and stores the selected option value.

Preview

Install

Run in your project
Package manager
npx @getweini/cli@latest add combobox

Use cases

Large country list

Filter options by visible labels and alternate keywords.

Search and select

Control query text separately from the committed option value.

Usage example

Vue
<script setup lang="ts">
import { ref } from 'vue'
import Combobox from './components/ui/combobox/Combobox.vue'

const country = ref<string>()
const countries = [
  { label: 'Luxembourg', value: 'LU', keywords: ['Grand Duchy'] },
  { label: 'Belgium', value: 'BE' },
  { label: 'France', value: 'FR' },
]
const messages = {
  listboxLabel: 'Countries',
  empty: 'No matches',
  clearSelection: 'Clear country',
}
</script>

<template>
  <label for="country">Country</label>
  <Combobox
    id="country"
    v-model="country"
    :options="countries"
    :messages="messages"
    name="country"
    clearable
  />
</template>

More examples

Country with aliases

Keywords help people find a value using another common name.

Country with aliases
<script setup lang="ts">
import { ref } from 'vue'
import Combobox from './components/ui/combobox/Combobox.vue'
const country = ref<string>()
const options = [
  { label: 'Luxembourg', value: 'LU', keywords: ['Grand Duchy'] },
  { label: 'Belgium', value: 'BE' },
]
const messages = { listboxLabel: 'Countries', empty: 'No countries match', clearSelection: 'Clear country' }
</script>
<template>
  <label for="country">Country</label>
  <Combobox id="country" v-model="country" :options="options" :messages="messages" name="country" clearable />
</template>

Strict project lookup

Use substring matching when near matches would be misleading.

Strict project lookup
<script setup lang="ts">
import { ref } from 'vue'
import Combobox from './components/ui/combobox/Combobox.vue'
const project = ref<string>()
const query = ref('')
const options = [{ label: 'Atlas', value: 'atlas' }, { label: 'Atelier', value: 'atelier' }]
const messages = { listboxLabel: 'Projects', empty: 'No projects match', clearSelection: 'Clear project' }
</script>
<template>
  <label for="project">Project</label>
  <Combobox id="project" v-model="project" v-model:query="query" :options="options" :messages="messages" :typo-tolerant="false" />
</template>

Key API

The most useful props, models, slots, events, and methods for this component.

Key API for Combobox
NameTypeDefault or requirement
v-modelT | undefinedundefined
v-model:querystring''
options{ label; value; disabled?; keywords? }[]required
messages{ listboxLabel; empty; clearSelection }required
id / placeholder / name / formstringundefined
sizesm | md | lgmd
disabled / readonly / required / invalid / clearablebooleanfalse
autocompletenone | listlist
typoTolerantbooleantrue
by / serializefunctions for object valuesObject.is / String

Search matches full-text terms across labels and keywords, tolerates common typing mistakes by default, and can be made strict with typoTolerant=false. Arrow keys move the active option without committing, Enter selects, and Escape restores the selected label.

Implementation notes

  • The model stores the option value, while v-model:query stores editable text.
  • Arrow navigation highlights an option; Enter commits it and Escape restores the selected label.

Accessibility and localization

  • Provide a field label and localize listbox, empty-state, and clear-action messages.
Weini UIDesign system · Vue component library · Free and public