Fix v-select search & selection of groups (#14154)

* fix search not matching parent items

* make group selectable in v-select

* fix wrong prop name

* set selected group to active for highlighted style

* Fix typings

Co-authored-by: ian <licitdev@gmail.com>
This commit is contained in:
Azri Kahar
2022-06-29 03:06:18 +08:00
committed by GitHub
parent d98432899e
commit ad7d39203f
4 changed files with 63 additions and 6 deletions

View File

@@ -1,5 +1,11 @@
<template>
<v-list-group :clickable="item.selectable" :open="item.children?.length === 1" :value="item.value">
<v-list-group
:active="isActive"
:clickable="groupSelectable || item.selectable"
:open="item.children?.length === 1"
:value="item.value"
@click="onGroupClick(item)"
>
<template #activator>
<v-list-item-icon v-if="multiple === false && allowOther === false && item.icon">
<v-icon :name="item.icon" />
@@ -24,6 +30,7 @@
:model-value="modelValue"
:multiple="multiple"
:allow-other="allowOther"
:group-selectable="groupSelectable"
@update:model-value="$emit('update:modelValue', $event)"
/>
<select-list-item
@@ -39,7 +46,7 @@
</template>
<script lang="ts">
import { defineComponent, PropType } from 'vue';
import { computed, defineComponent, PropType } from 'vue';
import { Option } from './types';
import SelectListItem from './select-list-item.vue';
@@ -63,7 +70,31 @@ export default defineComponent({
type: Boolean,
required: true,
},
groupSelectable: {
type: Boolean,
default: false,
},
},
emits: ['update:modelValue'],
setup(props, { emit }) {
const isActive = computed(() => {
if (props.multiple) {
if (!Array.isArray(props.modelValue) || !props.item.value) {
return false;
}
return props.modelValue.includes(props.item.value);
} else {
return props.modelValue === props.item.value;
}
});
return { isActive, onGroupClick };
function onGroupClick(item: Option) {
if (!props.groupSelectable) return;
emit('update:modelValue', item.value);
}
},
});
</script>

View File

@@ -3,7 +3,7 @@
<v-list-item
v-else
:active="multiple ? (modelValue || []).includes(item.value) : modelValue === item.value"
:active="isActive"
:disabled="item.disabled"
clickable
:value="item.value"
@@ -27,7 +27,7 @@
</template>
<script lang="ts">
import { defineComponent, PropType } from 'vue';
import { computed, defineComponent, PropType } from 'vue';
import { Option } from './types';
export default defineComponent({
@@ -51,5 +51,20 @@ export default defineComponent({
},
},
emits: ['update:modelValue'],
setup(props) {
const isActive = computed(() => {
if (props.multiple) {
if (!Array.isArray(props.modelValue) || !props.item.value) {
return false;
}
return props.modelValue.includes(props.item.value);
} else {
return props.modelValue === props.item.value;
}
});
return {
isActive,
};
},
});
</script>

View File

@@ -65,6 +65,7 @@
:model-value="modelValue"
:multiple="multiple"
:allow-other="allowOther"
:group-selectable="groupSelectable"
@update:model-value="$emit('update:modelValue', $event)"
/>
<select-list-item
@@ -178,6 +179,10 @@ export default defineComponent({
type: Boolean,
default: false,
},
groupSelectable: {
type: Boolean,
default: false,
},
mandatory: {
type: Boolean,
default: true,
@@ -292,8 +297,13 @@ export default defineComponent({
const searchValue = internalSearch.value.toLowerCase();
return item?.children
? item.children.some((item: Record<string, any>) => filterItem(item))
: item.text?.toLowerCase().includes(searchValue) || item.value?.toLowerCase().includes(searchValue);
? isMatchingCurrentItem(item, searchValue) ||
item.children.some((item: Record<string, any>) => filterItem(item))
: isMatchingCurrentItem(item, searchValue);
function isMatchingCurrentItem(item: Record<string, any>, searchValue: string): boolean {
return item.text?.toLowerCase().includes(searchValue) || item.value?.toLowerCase().includes(searchValue);
}
};
const items = internalSearch.value ? props.items.filter(filterItem).map(parseItem) : props.items.map(parseItem);

View File

@@ -24,6 +24,7 @@
:model-value="value"
:placeholder="t('select')"
allow-other
group-selectable
@update:model-value="emitValue($event)"
/>
<template v-else-if="is === 'interface-datetime'">