mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-14 20:19:34 +01:00
chore(InputMenu): handle async search with search prop
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
<script setup>
|
||||
const loading = ref(false)
|
||||
const selected = ref()
|
||||
|
||||
async function search (q) {
|
||||
loading.value = true
|
||||
|
||||
const users = await $fetch('https://jsonplaceholder.typicode.com/users', { params: { q } })
|
||||
|
||||
loading.value = false
|
||||
|
||||
return users
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UInputMenu
|
||||
v-model="selected"
|
||||
:search="search"
|
||||
:loading="loading"
|
||||
placeholder="Search for a user..."
|
||||
option-attribute="name"
|
||||
trailing
|
||||
by="id"
|
||||
/>
|
||||
</template>
|
||||
@@ -126,6 +126,20 @@ componentProps:
|
||||
---
|
||||
::
|
||||
|
||||
### Async search
|
||||
|
||||
Pass a function to the `search` prop to customize the search behavior and filter options according to your needs. The function will receive the query as its first argument and should return an array.
|
||||
|
||||
Use the `debounce` prop to adjust the delay of the function.
|
||||
|
||||
::component-example
|
||||
---
|
||||
component: 'input-menu-example-search-async'
|
||||
componentProps:
|
||||
class: 'w-full lg:w-48'
|
||||
---
|
||||
::
|
||||
|
||||
## Popper
|
||||
|
||||
Use the `popper` prop to customize the popper instance.
|
||||
|
||||
@@ -99,7 +99,7 @@ import {
|
||||
ComboboxOption as HComboboxOption,
|
||||
ComboboxInput as HComboboxInput
|
||||
} from '@headlessui/vue'
|
||||
import { computedAsync } from '@vueuse/core'
|
||||
import { computedAsync, useDebounceFn } from '@vueuse/core'
|
||||
import { defu } from 'defu'
|
||||
import { twMerge, twJoin } from 'tailwind-merge'
|
||||
import UIcon from '../elements/Icon.vue'
|
||||
@@ -234,10 +234,18 @@ export default defineComponent({
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
search: {
|
||||
type: Function as PropType<((query: string) => Promise<any[]> | any[])>,
|
||||
default: undefined
|
||||
},
|
||||
searchAttributes: {
|
||||
type: Array,
|
||||
default: null
|
||||
},
|
||||
debounce: {
|
||||
type: Number,
|
||||
default: 200
|
||||
},
|
||||
popper: {
|
||||
type: Object as PropType<PopperOptions>,
|
||||
default: () => ({})
|
||||
@@ -358,7 +366,13 @@ export default defineComponent({
|
||||
)
|
||||
})
|
||||
|
||||
const debouncedSearch = props.search && typeof props.search === 'function' ? useDebounceFn(props.search, props.debounce) : undefined
|
||||
|
||||
const filteredOptions = computedAsync(async () => {
|
||||
if (debouncedSearch) {
|
||||
return await debouncedSearch(query.value)
|
||||
}
|
||||
|
||||
if (query.value === '') {
|
||||
return props.options
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user