mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-14 20:19:34 +01:00
fix(SelectMenu): fixes non-strings and nested searchable attributes (#967)
Co-authored-by: Benjamin Canac <canacb1@gmail.com>
This commit is contained in:
@@ -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>
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user