diff --git a/docs/components/content/examples/InputMenuExampleSearchAsync.vue b/docs/components/content/examples/InputMenuExampleSearchAsync.vue new file mode 100644 index 00000000..b09984e9 --- /dev/null +++ b/docs/components/content/examples/InputMenuExampleSearchAsync.vue @@ -0,0 +1,26 @@ + + + diff --git a/docs/content/3.forms/2.input-menu.md b/docs/content/3.forms/2.input-menu.md index 026cdf20..08d07013 100644 --- a/docs/content/3.forms/2.input-menu.md +++ b/docs/content/3.forms/2.input-menu.md @@ -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. diff --git a/src/runtime/components/forms/InputMenu.vue b/src/runtime/components/forms/InputMenu.vue index 5401a686..28ae1a25 100644 --- a/src/runtime/components/forms/InputMenu.vue +++ b/src/runtime/components/forms/InputMenu.vue @@ -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[])>, + default: undefined + }, searchAttributes: { type: Array, default: null }, + debounce: { + type: Number, + default: 200 + }, popper: { type: Object as PropType, 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 }