Skip to content

ComboBox API Reference

Complete API documentation for the ComboBox component.

Props

Core Functionality

PropTypeDefaultDescription
itemsArray[]Array of items to display in the dropdown
modelValueString/Number/Array/ObjectnullThe selected value(s). Use with v-model
multipleBooleanfalseEnable multiple selection mode

Item Configuration

PropTypeDefaultDescription
itemTextString'text'Property name to use for item display text
itemValueString'value'Property name to use for item value
itemDisabledString'disabled'Property name to check if item is disabled

Filtering & Sorting

PropTypeDefaultDescription
filterFunctionFunctionnullCustom filter function (item, searchText) => Boolean
selectedOnTopBooleanfalseShow selected items at the top of the list
PropTypeDefaultDescription
placementString'bottom'Menu placement: 'top', 'bottom'
offsetArray[0, 0.125]Offset from trigger [x, y] in rem
menuWidthString/NumbernullCustom menu width (px or string with units)
matchTriggerWidthBooleantrueMatch menu width to trigger width

Input Configuration

PropTypeDefaultDescription
placeholderString''Input placeholder text
disabledBooleanfalseDisable the combobox
loadingBooleanfalseShow loading state
clearableBooleanfalseShow clear button when there's a selection
readonlyBooleanfalseMake input readonly (menu won't open)

Events

EventPayloadDescription
update:modelValuevalueEmitted when selection changes. Use with v-model
changevalueEmitted when selection changes (same as update:modelValue)
selectitem, valueEmitted when an item is selected from the dropdown
removeitem, valueEmitted when an item is removed (multiple mode)
searchsearchTextEmitted when search text changes
createitem, valueEmitted when a custom item is created by typing

Event Examples

vue
<template>
  <OComboBox
    v-model="selected"
    :items="items"
    @select="handleSelect"
    @create="handleCreate"
    @search="handleSearch"
  />
</template>

<script setup>
const handleSelect = (item, value) => {
  console.log('Selected item:', item);
  console.log('Selected value:', value);
};

const handleCreate = (item, value) => {
  console.log('Created custom item:', item);
  console.log('Custom value:', value);
  // You can save custom items to your backend here
};

const handleSearch = (searchText) => {
  console.log('Searching for:', searchText);
  // Perform async search if needed
};
</script>

Slots

SlotPropsDescription
no-data-Custom content to display when no items are available

Slot Examples

vue
<template>
  <OComboBox v-model="selected" :items="items">
    <template #no-data>
      <div class="custom-empty">
        <p>No options found</p>
        <button @click="loadMore">Load More</button>
      </div>
    </template>
  </OComboBox>
</template>

Methods

Methods exposed via template ref:

MethodParametersReturnsDescription
focus()-voidFocus the input field
blur()-voidBlur the input field
openMenu()-voidOpen the dropdown menu
closeMenu()-voidClose the dropdown menu
search(value)StringvoidSet the search text programmatically

Method Examples

vue
<template>
  <div>
    <OComboBox ref="comboboxRef" v-model="selected" :items="items" />
    <button @click="focusComboBox">Focus</button>
    <button @click="openMenu">Open Menu</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const comboboxRef = ref(null);

const focusComboBox = () => {
  comboboxRef.value.focus();
};

const openMenu = () => {
  comboboxRef.value.openMenu();
};
</script>

TypeScript Types

typescript
interface ComboBoxItem {
  text: string;
  value: any;
  disabled?: boolean;
  [key: string]: any;
}

type ComboBoxValue = string | number | Array<string | number> | object | null;

type FilterFunction = (item: ComboBoxItem, searchText: string) => boolean;

type Placement = 'top' | 'bottom';

Usage Patterns

Single Selection with Custom Values

vue
<template>
  <OComboBox
    v-model="country"
    :items="countries"
    placeholder="Select or type a country..."
  />
</template>

<script setup>
import { ref } from 'vue';

const country = ref(null);
const countries = ref([
  { text: 'United States', value: 'us' },
  { text: 'United Kingdom', value: 'uk' },
  { text: 'Canada', value: 'ca' },
]);
</script>

Multiple Selection (Tags)

vue
<template>
  <OComboBox
    v-model="tags"
    :items="suggestions"
    :multiple="true"
    placeholder="Type tags and press Enter..."
    @create="handleCreateTag"
  />
</template>

<script setup>
import { ref } from 'vue';

const tags = ref([]);
const suggestions = ref([
  { text: 'Vue', value: 'vue' },
  { text: 'React', value: 'react' },
  { text: 'Angular', value: 'angular' },
]);

const handleCreateTag = (item, value) => {
  console.log('New tag created:', value);
  // Optionally save to backend
};
</script>

With Custom Filter

vue
<template>
  <OComboBox
    v-model="selected"
    :items="products"
    :filter-function="customFilter"
    placeholder="Search products..."
  />
</template>

<script setup>
import { ref } from 'vue';

const selected = ref(null);
const products = ref([
  { text: 'Laptop', value: 'laptop', category: 'electronics' },
  { text: 'Phone', value: 'phone', category: 'electronics' },
  { text: 'Desk', value: 'desk', category: 'furniture' },
]);

const customFilter = (item, searchText) => {
  const text = item.text.toLowerCase();
  const category = item.category.toLowerCase();
  const search = searchText.toLowerCase();
  
  return text.includes(search) || category.includes(search);
};
</script>

Email Input Example

vue
<template>
  <OComboBox
    v-model="emails"
    :items="emailSuggestions"
    :multiple="true"
    placeholder="Enter email addresses..."
    @create="validateEmail"
  />
</template>

<script setup>
import { ref } from 'vue';

const emails = ref([]);
const emailSuggestions = ref([
  { text: 'john@example.com', value: 'john@example.com' },
  { text: 'jane@example.com', value: 'jane@example.com' },
]);

const validateEmail = (item, value) => {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  if (!emailRegex.test(value)) {
    alert('Invalid email address');
    // Remove invalid email
    emails.value = emails.value.filter(e => e !== value);
  }
};
</script>

Keyboard Shortcuts

KeyAction
EnterCreate custom entry from typed text
BackspaceRemove last selected item (multiple, empty input)
Shift/Ctrl/Cmd + BackspaceRemove all selected items (multiple mode)
EscapeClose the dropdown menu
Click outsideClose menu and commit typed text (single mode)

Styling

The component uses scoped styles with the following main classes:

  • .combobox - Root container
  • .trigger-container - Input trigger area
  • .combobox-input - The input field
  • .combobox-dropdown - Dropdown menu container
  • .select-option - Individual option item
  • .option-checkbox - Checkbox for multiple selection
  • .clear-button - Clear selection button
  • .select-arrow - Dropdown arrow icon

Custom Styling Example

vue
<style>
.combobox {
  /* Custom styles */
}

.combobox .trigger-container {
  border-radius: 8px;
  border-color: #3b82f6;
}

.combobox .combobox-input {
  font-size: 1.125rem;
}
</style>

Best Practices

  1. Use for flexible input: Use ComboBox when users need both predefined options and custom entries
  2. Provide suggestions: Always provide relevant suggestions in the items prop
  3. Handle create event: Listen to the create event to validate or save custom entries
  4. Single vs Multiple: Use single mode for single-value fields, multiple mode for tags/lists
  5. Validation: Implement validation in the create event handler for custom entries
  6. Clearable: Enable clearable for better UX when values can be optional
  7. Loading state: Use the loading prop during async operations
  8. Accessible placeholders: Provide clear placeholder text that describes what users can do

Accessibility

The component follows accessibility best practices:

  • Keyboard navigation support
  • Focus management
  • ARIA attributes for screen readers
  • Clear visual states (focus, hover, disabled)
  • Semantic HTML structure

Performance Tips

  1. Large datasets: For very large item lists, consider implementing virtual scrolling
  2. Async search: Use the search event to implement server-side filtering
  3. Debouncing: Debounce the search event for async operations
  4. Custom filter: Use custom filter functions for complex filtering logic

View Demo →

View Implementation →