Skip to content

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 selection
  • virtualScroll (boolean): Enable virtual scrolling for large datasets
  • remote (boolean): Enable remote data fetching
  • disabled (boolean): Disable the select
  • loading (boolean): Show loading state
  • searchPlaceholder (string): Search input placeholder
  • triggerPlaceholder (string): Trigger button placeholder
  • maxTagCount (number | ‘responsive’): Maximum number of tags to show
  • trigger (‘hover’ | ‘click’ | ‘focus’ | ‘manual’): Trigger mode
  • selectType (‘tags’ | ‘default’): Select type
  • randomColor (boolean): Use random colors for avatars
  • sortSelectedValues (boolean): Sort selected values
  • placement (string): Dropdown placement
  • popoverWidth (number | ‘trigger’): Popover width
  • handleNewOptionRemote (boolean): Handle new tag creation remotely

Events

  • update:value: Emitted when selection changes
  • onChange: Emitted when selection changes with new value
  • onSearch: Emitted when search input changes
  • onScroll: Emitted on scroll (for virtual scrolling)
  • onClose: Emitted when dropdown closes
  • onChangeSrc: Emitted when source changes
  • onNewTag: Emitted when new tag is created

Slots

  • action-top: Custom content above the options list
  • action-bottom: Custom content below the options list
  • option: Custom option rendering
  • selected: Custom selected value rendering
  • empty: Custom empty state content

Usage Examples

  1. Basic Usage:
<template>
<UIAdvancedSelect
v-model:value="value"
:options="options"
placeholder="Select an option"
/>
</template>
  1. Multiple Selection with Virtual Scroll:
<template>
<UIAdvancedSelect
v-model:value="selectedValues"
:options="largeOptionsList"
:multiple="true"
:virtualScroll="true"
:maxTagCount="3"
/>
</template>
  1. 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>
  1. 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

  1. Performance Optimization:

    • Use virtualScroll for large datasets (>100 items)
    • Enable remote for server-side filtering
    • Implement debounced search for remote data
    • Use maxTagCount for multiple selection
  2. User Experience:

    • Provide clear placeholder text
    • Show loading states during data fetch
    • Include helpful empty states
    • Use appropriate dropdown width
  3. Accessibility:

    • Include proper ARIA labels
    • Support keyboard navigation
    • Provide clear focus indicators
    • Use descriptive option text
  4. Responsive Design:

    • Consider mobile-friendly sizes
    • Use responsive tag count
    • Handle long option text
    • Adjust dropdown placement
  5. Translation:

    • Use translation keys for placeholders
    • Translate empty states
    • Include localized search text
    • Support RTL languages