fix(SelectMenu): fixes non-strings and nested searchable attributes (#967)

Co-authored-by: Benjamin Canac <canacb1@gmail.com>
This commit is contained in:
Italo
2023-11-21 18:20:48 -03:00
committed by GitHub
parent 73d0fa7273
commit 37fdf224c0
3 changed files with 53 additions and 2 deletions

View File

@@ -0,0 +1,31 @@
<script setup>
const options = [
{ id: 1, name: 'Wade Cooper', favoriteColors: ['red', 'yellow'] },
{ id: 2, name: 'Arlene Mccoy', favoriteColors: ['blue', 'yellow'] },
{ id: 3, name: 'Devon Webb', favoriteColors: ['green', 'blue'] },
{ id: 4, name: 'Tom Cook', favoriteColors: ['blue', 'red'] },
{ id: 5, name: 'Tanya Fox', favoriteColors: ['green', 'red'] },
{ id: 5, name: 'Hellen Schmidt', favoriteColors: ['green', 'yellow'] }
]
const selected = ref(options[1])
</script>
<template>
<USelectMenu
v-model="selected"
:options="options"
class="w-full lg:w-96"
placeholder="Select an user"
searchable
searchable-placeholder="Search by name or favorite colors"
option-attribute="name"
by="id"
:search-attributes="['name', 'favoriteColors']"
>
<template #option="{ option: person }">
<span v-for="color in person.favoriteColors" :key="color.id" class="h-2 w-2 rounded-full" :class="`bg-${color}-500 dark:bg-${color}-400`" />
<span class="truncate">{{ person.name }}</span>
</template>
</USelectMenu>
</template>

View File

@@ -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.

View File

@@ -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
})
})
})