UIAdvancedSelect
UIAdvancedSelect
An enhanced select component that provides advanced features like search, virtual scrolling, remote data loading, and custom rendering.
<template> <UIAdvancedSelect v-model:value="selectedValue" :options="options" :multiple="true" :virtualScroll="true" :remote="false" :searchPlaceholder="$t('search.placeholder')" :triggerPlaceholder="$t('select.placeholder')" :maxTagCount="3" :popoverWidth="400" @onChange="handleChange" @onSearch="handleSearch" @onScroll="handleScroll" > <template #action-top> <UIButton size="small" @click="handleAddNew"> {{ $t('button.addNew') }} </UIButton> </template>
<template #option="{ option }"> <div class="flex items-center gap-2"> <UIAvatar :src="option.avatar" size="small" :randomColor="true" /> <span>{{ option.label }}</span> </div> </template> </UIAdvancedSelect></template>
<script setup lang="ts">interface SelectOption { value: string | number label: string avatar?: string disabled?: boolean [key: string]: any}
const selectedValue = ref<string[]>([])const options = ref<SelectOption[]>([ { value: '1', label: 'Option 1', avatar: 'avatar1.jpg' }, { value: '2', label: 'Option 2', avatar: 'avatar2.jpg' }, { value: '3', label: 'Option 3', avatar: 'avatar3.jpg', disabled: true }])
const handleChange = (value: string | string[]) => { console.log('Selection changed:', value)}
const handleSearch = (searchText: string) => { // Handle search input console.log('Search text:', searchText)}
const handleScroll = (event: Event) => { // Handle virtual scroll console.log('Scrolled')}
const handleAddNew = () => { // Handle adding new option console.log('Add new clicked')}</script>Props
value(string | number | Array): Selected value(s)options(Array): Options to select from multiple(boolean): Enable multiple selectionvirtualScroll(boolean): Enable virtual scrolling for large datasetsremote(boolean): Enable remote data fetchingdisabled(boolean): Disable the selectloading(boolean): Show loading statesearchPlaceholder(string): Search input placeholdertriggerPlaceholder(string): Trigger button placeholdermaxTagCount(number | ‘responsive’): Maximum number of tags to showtrigger(‘hover’ | ‘click’ | ‘focus’ | ‘manual’): Trigger modeselectType(‘tags’ | ‘default’): Select typerandomColor(boolean): Use random colors for avatarssortSelectedValues(boolean): Sort selected valuesplacement(string): Dropdown placementpopoverWidth(number | ‘trigger’): Popover widthhandleNewOptionRemote(boolean): Handle new tag creation remotely
Events
update:value: Emitted when selection changesonChange: Emitted when selection changes with new valueonSearch: Emitted when search input changesonScroll: Emitted on scroll (for virtual scrolling)onClose: Emitted when dropdown closesonChangeSrc: Emitted when source changesonNewTag: Emitted when new tag is created
Slots
action-top: Custom content above the options listaction-bottom: Custom content below the options listoption: Custom option renderingselected: Custom selected value renderingempty: Custom empty state content
Usage Examples
- Basic Usage:
<template> <UIAdvancedSelect v-model:value="value" :options="options" placeholder="Select an option" /></template>- Multiple Selection with Virtual Scroll:
<template> <UIAdvancedSelect v-model:value="selectedValues" :options="largeOptionsList" :multiple="true" :virtualScroll="true" :maxTagCount="3" /></template>- Remote Data Loading:
<template> <UIAdvancedSelect v-model:value="value" :options="remoteOptions" :remote="true" :loading="loading" @onSearch="handleRemoteSearch" /></template>
<script setup>const loading = ref(false)const remoteOptions = ref([])
const handleRemoteSearch = async (searchText: string) => { loading.value = true try { const response = await fetchOptions(searchText) remoteOptions.value = response.data } finally { loading.value = false }}</script>- Custom Option Rendering:
<template> <UIAdvancedSelect v-model:value="value" :options="options"> <template #option="{ option }"> <div class="flex items-center gap-2"> <img :src="option.icon" class="w-4 h-4" /> <span>{{ option.label }}</span> <span class="text-gray-400 text-sm">{{ option.description }}</span> </div> </template> </UIAdvancedSelect></template>Best Practices
-
Performance Optimization:
- Use
virtualScrollfor large datasets (>100 items) - Enable
remotefor server-side filtering - Implement debounced search for remote data
- Use
maxTagCountfor multiple selection
- Use
-
User Experience:
- Provide clear placeholder text
- Show loading states during data fetch
- Include helpful empty states
- Use appropriate dropdown width
-
Accessibility:
- Include proper ARIA labels
- Support keyboard navigation
- Provide clear focus indicators
- Use descriptive option text
-
Responsive Design:
- Consider mobile-friendly sizes
- Use responsive tag count
- Handle long option text
- Adjust dropdown placement
-
Translation:
- Use translation keys for placeholders
- Translate empty states
- Include localized search text
- Support RTL languages