chore(CommandPalette): support by prop and highlight

This commit is contained in:
Benjamin Canac
2022-10-09 13:31:11 +02:00
parent f0e482cf01
commit d29377f614
3 changed files with 43 additions and 3 deletions

View File

@@ -185,7 +185,23 @@
</div>
<UCard body-class="">
<UCommandPalette v-model="form.persons" multiple :groups="[{ key: 'persons', commands: people, customQuery, options: { fuseOptions: { useExtendedSearch: true, keys: ['name', 'static'] } } }]" command-attribute="name" />
<UCommandPalette
v-model="form.persons"
multiple
:groups="[{
key: 'persons',
commands: people,
customQuery,
options: {
fuseOptions: {
includeMatches: true,
useExtendedSearch: true,
keys: ['name']
}
}
}]"
command-attribute="name"
/>
</UCard>
</div>

View File

@@ -1,6 +1,7 @@
<template>
<Combobox
ref="comboboxRef"
:by="by"
:model-value="modelValue"
:multiple="multiple"
:nullable="nullable"
@@ -56,6 +57,10 @@ const props = defineProps({
type: [String, Number, Object, Array],
default: null
},
by: {
type: String,
default: 'id'
},
multiple: {
type: Boolean,
default: false
@@ -152,9 +157,18 @@ const fuse = props.groups.reduce((acc, group) => {
}, {})
const groups = computed(() => props.groups.map((group) => {
const commands = fuse[group.key].results.value.map((result) => {
const { item, ...data } = result
return {
...item,
...data
}
})
return {
...group,
commands: fuse[group.key].results.value.map(result => group.commands.find(command => command.id === result.item.id)).filter(Boolean).slice(0, group.options?.resultLimit || options.value.resultLimit)
commands: commands.slice(0, group.options?.resultLimit || options.value.resultLimit)
}
}).filter(group => group.commands.length))

View File

@@ -26,7 +26,8 @@
<div class="flex items-center gap-1.5 min-w-0" :class="{ 'opacity-50': command.disabled }">
<slot :name="`${group.key}-command`" :group="group" :command="command">
<span v-if="command.prefix" class="u-text-gray-400">{{ command.prefix }}</span>
<span class="truncate" :class="{ 'flex-none': command.suffix }">{{ command[commandAttribute] }}</span>
<span v-if="command.matches?.length" class="truncate" :class="{ 'flex-none': command.suffix }" v-html="highlight(command.matches[0])" />
<span v-else class="truncate" :class="{ 'flex-none': command.suffix }">{{ command[commandAttribute] }}</span>
<span v-if="command.suffix" class="u-text-gray-400 truncate">{{ command.suffix }}</span>
</slot>
</div>
@@ -69,6 +70,15 @@ defineProps({
required: true
}
})
function highlight ({ indices, value }, i = 1) {
const pair = indices[indices.length - i]
if (!pair) {
return value
}
return `${highlight({ indices, value: value.substring(0, pair[0]) }, i + 1)}<mark>${value.substring(pair[0], pair[1] + 1)}</mark>${value.substring(pair[1] + 1)}`
}
</script>
<script lang="ts">