From 37fdf224c07e47312c731b20080533ad7d8d786c Mon Sep 17 00:00:00 2001 From: Italo Date: Tue, 21 Nov 2023 18:20:48 -0300 Subject: [PATCH] fix(SelectMenu): fixes non-strings and nested searchable attributes (#967) Co-authored-by: Benjamin Canac --- .../SelectMenuExampleSearchAttributes.vue | 31 +++++++++++++++++++ docs/content/3.forms/4.select-menu.md | 14 +++++++++ src/runtime/components/forms/SelectMenu.vue | 10 ++++-- 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 docs/components/content/examples/SelectMenuExampleSearchAttributes.vue diff --git a/docs/components/content/examples/SelectMenuExampleSearchAttributes.vue b/docs/components/content/examples/SelectMenuExampleSearchAttributes.vue new file mode 100644 index 00000000..f6b0d7a4 --- /dev/null +++ b/docs/components/content/examples/SelectMenuExampleSearchAttributes.vue @@ -0,0 +1,31 @@ + + + diff --git a/docs/content/3.forms/4.select-menu.md b/docs/content/3.forms/4.select-menu.md index d7bfe951..1ae58d70 100644 --- a/docs/content/3.forms/4.select-menu.md +++ b/docs/content/3.forms/4.select-menu.md @@ -99,6 +99,20 @@ props: --- :: +#### Search Attributes + +Use the `search-attributes` with an array of property names to search on each option object. + +Nested attributes can be accessed using `dot.notation`. When the property value is an array or object, these are cast to string so these can be searched within. + +::component-example +--- +component: 'select-menu-example-search-attributes' +componentProps: + class: 'w-full lg:w-96' +--- +:: + #### Clear on close :u-badge{label="New" class="align-middle ml-2 !rounded-full" variant="subtle"} By default, the search query will be kept after the menu is closed. To clear it on close, set the `clear-search-on-close` prop. diff --git a/src/runtime/components/forms/SelectMenu.vue b/src/runtime/components/forms/SelectMenu.vue index 424dfdb9..06e931e6 100644 --- a/src/runtime/components/forms/SelectMenu.vue +++ b/src/runtime/components/forms/SelectMenu.vue @@ -140,7 +140,7 @@ import UAvatar from '../elements/Avatar.vue' import { useUI } from '../../composables/useUI' import { usePopper } from '../../composables/usePopper' import { useFormGroup } from '../../composables/useFormGroup' -import { mergeConfig } from '../../utils' +import { get, mergeConfig } from '../../utils' import { useInjectButtonGroup } from '../../composables/useButtonGroup' import type { SelectSize, SelectColor, SelectVariant, PopperOptions, Strategy } from '../../types' // @ts-expect-error @@ -422,7 +422,13 @@ export default defineComponent({ return (props.options as any[]).filter((option: any) => { return (props.searchAttributes?.length ? props.searchAttributes : [props.optionAttribute]).some((searchAttribute: any) => { - return ['string', 'number'].includes(typeof option) ? option.toString().search(new RegExp(query.value, 'i')) !== -1 : (option[searchAttribute] && option[searchAttribute].search(new RegExp(query.value, 'i')) !== -1) + if (['string', 'number'].includes(typeof option)) { + return String(option).search(new RegExp(query.value, 'i')) !== -1 + } + + const child = get(option, searchAttribute) + + return child !== null && child !== undefined && String(child).search(new RegExp(query.value, 'i')) !== -1 }) }) })