Skip to content

VfSmartSelect

Advanced searchable select component with filtering, keyboard navigation, grouping, and async data loading.

Import

typescript
import { VfSmartSelect } from '@zyno-io/vue-foundation';

Basic Usage

vue
<VfSmartSelect v-model="selectedUser" :options="users" :label-field="'name'" :value-field="'id'" placeholder="Select a user..." null-title="None" />

Props

PropTypeDescription
modelValueV | nullSelected value (v-model)
optionsT[]Static options array
loadOptions(search: string | null) => Promise<T[]>Async option loader
preloadbooleanLoad options immediately on mount
remoteSearchbooleanReload options on each search (debounced 250ms)
keyFieldkeyof TField used as unique key
keyExtractor(option: T) => string | symbolCustom key extraction
valueFieldkeyof TField used as the emitted value
valueExtractor(option: T) => VCustom value extraction
labelFieldkeyof TField displayed as option text
formatter(option: T) => stringCustom display formatter
selectionFormatter(option: T) => stringCustom formatter for the selected value in the input
subtitleFormatter(option: T) => stringFormat subtitle text below option
classForOption(option: T) => stringCSS class per option
groupFieldkeyof TField to group options by
groupFormatter(option: T) => stringCustom group label formatter
searchFields(keyof T)[]Fields to search (defaults to title + subtitle)
prependOptionsT[]Options prepended to the list
appendOptionsT[]Options appended to the list
onCreateItem(text: string) => voidEnable "Create ..." option when no match
showCreateTextOnNewItembooleanShow "Create <text>..." label (default: true)
nullTitlestringText for the null/deselect option
noResultsTextstringText when search has no matches
placeholderstringInput placeholder text
loadingTextstringPlaceholder while loading
disabledbooleanDisable the select
requiredbooleanHTML required attribute
namestringHTML name attribute
autoNextbooleanFocus next input after selection
debugbooleanKeep options open on blur (development aid)

Events

EventDescription
update:modelValueEmitted when the selected value changes
optionsLoadedEmitted after async options finish loading

Slots

vue
<VfSmartSelect v-model="value" :options="items">
    <!-- Custom option rendering -->
    <template #option="{ option }">
        <div class="custom-option">
            <img :src="option.ref.avatar" />
            <span>{{ option.title }}</span>
        </div>
    </template>

    <!-- Custom group header -->
    <template #group="{ group }">
        <strong>{{ group }}</strong>
    </template>

    <!-- Custom no-results message -->
    <template #no-results>
        No matches. Try a different search.
    </template>
</VfSmartSelect>

Exposed Methods

typescript
const selectRef = ref();
selectRef.value.addRemoteOption(newOption); // Add option to remote options list

Features

  • Search text highlighting via mark.js
  • Keyboard navigation (Arrow keys, Page Up/Down, Home/End, Enter, Escape)
  • Option list teleported to body for proper z-index stacking
  • Automatic scroll management for highlighted options

Demos

Basic (label-field + value-field)

Grouped with null-title (deselect)

Full object value (no value-field)

When value-field is omitted, the entire option object is emitted as the model value.

Custom formatter + value-extractor

Use formatter and value-extractor functions instead of field names for full control.

Preselected value

Delayed options (loading state)

When options is initially undefined, the select shows loading-text until options are provided.

Async loadOptions

Use load-options for async data fetching. With preload, options load on mount. Without it, they load on first open.

Create item

Pass on-create-item to allow creating new options when no search match is found.

Disabled