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 →