feat(CommandPalette): handle filter attribute in groups (#871)

This commit is contained in:
Benjamin Canac
2023-10-26 11:59:55 +02:00
committed by GitHub
parent 68f024f742
commit 8ba2a791e4
5 changed files with 70 additions and 17 deletions

View File

@@ -1,19 +1,17 @@
<script setup>
const groups = computed(() => {
return [{
key: 'users',
label: q => q && `Users matching “${q}”...`,
search: async (q) => {
if (!q) {
return []
}
const users = await $fetch('https://jsonplaceholder.typicode.com/users', { params: { q } })
return users.map(user => ({ id: user.id, label: user.name, suffix: user.email }))
const groups = [{
key: 'users',
label: q => q && `Users matching “${q}”...`,
search: async (q) => {
if (!q) {
return []
}
}].filter(Boolean)
})
const users = await $fetch('https://jsonplaceholder.typicode.com/users', { params: { q } })
return users.map(user => ({ id: user.id, label: user.name, suffix: user.email }))
}
}]
</script>
<template>

View File

@@ -0,0 +1,30 @@
<script setup>
const people = [
{ id: 1, label: 'Wade Cooper', child: true },
{ id: 2, label: 'Arlene Mccoy' },
{ id: 3, label: 'Devon Webb', child: true },
{ id: 4, label: 'Tom Cook' },
{ id: 5, label: 'Tanya Fox', child: true },
{ id: 6, label: 'Hellen Schmidt' },
{ id: 7, label: 'Caroline Schultz', child: true },
{ id: 8, label: 'Mason Heaney' },
{ id: 9, label: 'Claudie Smitham', child: true },
{ id: 10, label: 'Emil Schaefer' }
]
const groups = [{
key: 'users',
commands: people,
filter: (q, commands) => {
if (!q) {
return commands?.filter(command => !command.child)
}
return commands
}
}]
</script>
<template>
<UCommandPalette :groups="groups" :autoselect="false" />
</template>

View File

@@ -183,6 +183,19 @@ componentProps:
The `loading` state will automatically be enabled when a `search` function is loading. You can disable this behavior by setting the `loading-icon` prop to `null` or globally in `ui.commandPalette.default.loadingIcon`.
::
## Filter search
You can also pass a function to the `filter` property of a group to filter displayed commands after the search happened. The function will receive the query as its first argument, the array of commands as second argument and should return an array of commands.
::component-example
---
padding: false
component: 'command-palette-example-filter'
componentProps:
class: 'h-[274px]'
---
::
## Slots
### `<group>-icon`

View File

@@ -237,7 +237,8 @@ export default defineComponent({
}
for (const key in groupedCommands) {
const group = props.groups.find(group => group.key === key)
const commands = groupedCommands[key].slice(0, options.value.resultLimit).map((result) => {
let commands = groupedCommands[key].map((result) => {
const { item, ...data } = result
return {
@@ -246,12 +247,22 @@ export default defineComponent({
} as Command
})
groups.push({ ...group, commands })
if (group.filter && typeof group.filter === 'function') {
commands = group.filter(query.value, commands)
}
groups.push({ ...group, commands: commands.slice(0, options.value.resultLimit) })
}
for (const group of props.groups) {
if (group.search && searchResults.value[group.key]?.length) {
groups.push({ ...group, commands: (searchResults.value[group.key] || []).slice(0, options.value.resultLimit) })
let commands = (searchResults.value[group.key] || [])
if (group.filter && typeof group.filter === 'function') {
commands = group.filter(query.value, commands)
}
groups.push({ ...group, commands: commands.slice(0, options.value.resultLimit) })
}
}

View File

@@ -23,5 +23,6 @@ export interface Group {
inactive?: string
commands?: Command[]
search?: Function
filter?: Function
[key: string]: any
}