From 20476f4b9a95817598fb2e2ae5cb383b0d1411e2 Mon Sep 17 00:00:00 2001 From: Benjamin Canac Date: Fri, 7 Jun 2024 16:01:30 +0200 Subject: [PATCH] feat(CommandPalette): improve theme and performance --- playground/pages/command-palette.vue | 1 - src/runtime/components/CommandPalette.vue | 33 +++++++++++++---------- src/runtime/utils/fuse.ts | 6 ++--- src/theme/command-palette.ts | 4 +-- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/playground/pages/command-palette.vue b/playground/pages/command-palette.vue index 97d838e7..06e00a90 100644 --- a/playground/pages/command-palette.vue +++ b/playground/pages/command-palette.vue @@ -102,7 +102,6 @@ defineShortcuts({ :groups="groups" :fuse="{ fuseOptions: { - threshold: 0.1, includeMatches: true } }" diff --git a/src/runtime/components/CommandPalette.vue b/src/runtime/components/CommandPalette.vue index c1bfea80..85ee4950 100644 --- a/src/runtime/components/CommandPalette.vue +++ b/src/runtime/components/CommandPalette.vue @@ -99,6 +99,7 @@ const ui = computed(() => tv({ extend: commandPalette, slots: props.ui })()) const fuse = computed(() => defu({}, props.fuse, { fuseOptions: { ignoreLocation: true, + threshold: 0.1, keys: ['label', 'suffix'] }, resultLimit: 12, @@ -112,13 +113,7 @@ const items = computed(() => props.groups?.filter((group) => { } return true -}).flatMap((group) => { - let items = group.items || [] - if (group.filter) { - items = group.filter(searchTerm.value, items) - } - return items?.map(item => ({ ...item, group: group.id })) || [] -}) || []) +}).flatMap(group => group.items?.map(item => ({ ...item, group: group.id })) || []) || []) const { results: fuseResults } = useFuse(searchTerm, items, fuse) @@ -127,7 +122,7 @@ const groups = computed(() => { return [] } - const groups: Record['matches'] })[]> = fuseResults.value.reduce((acc, result) => { + const groupsById: Record['matches'] })[]> = fuseResults.value.reduce((acc, result) => { const { item, matches } = result if (!item.group) { return acc @@ -139,12 +134,22 @@ const groups = computed(() => { return acc }, {}) - return Object.entries(groups).map(([id, items]) => { + return Object.entries(groupsById).map(([id, items]) => { const group = props.groups?.find(group => group.id === id) + if (group?.filter && typeof group.filter === 'function') { + items = group.filter(searchTerm.value, items) + } + return { ...group, - items: items.slice(0, fuse.value.resultLimit) + items: items.slice(0, fuse.value.resultLimit).map((item) => { + return { + ...item, + labelHtml: highlight(item, searchTerm.value, 'label'), + suffixHtml: highlight(item, searchTerm.value, undefined, ['label']) + } + }) } }) }) @@ -180,7 +185,7 @@ const groups = computed(() => { - + @@ -197,7 +202,7 @@ const groups = computed(() => { { {{ item.prefix }} - + - + diff --git a/src/runtime/utils/fuse.ts b/src/runtime/utils/fuse.ts index eabf1440..d6ca245a 100644 --- a/src/runtime/utils/fuse.ts +++ b/src/runtime/utils/fuse.ts @@ -54,9 +54,9 @@ export function highlight(item: T & { matches?: FuseResult['matches'] }, s content += value.substring(nextUnhighlightedRegionStartingIndex) - const endIndex = content.indexOf('') - if (endIndex > 50) { - content = truncateHTMLFromStart(content, 45) + const markIndex = content.indexOf('') + if (markIndex !== -1) { + content = truncateHTMLFromStart(content, content.length - markIndex) } return content diff --git a/src/theme/command-palette.ts b/src/theme/command-palette.ts index 4e0b627e..fb5bcd35 100644 --- a/src/theme/command-palette.ts +++ b/src/theme/command-palette.ts @@ -19,8 +19,8 @@ export default (options: Required) => ({ itemTrailingHighlightedIcon: 'shrink-0 size-5 text-gray-400 dark:text-gray-500 hidden group-data-highlighted:inline-flex', itemTrailingKbds: 'hidden lg:inline-flex items-center shrink-0 gap-0.5', itemLabel: 'truncate space-x-1', - itemLabelBase: '[&>mark]:text-[initial] [&>mark]:bg-[initial]', - itemLabelPrefix: 'text-gray-400 dark:text-gray-500', + itemLabelBase: 'text-gray-900 dark:text-white [&>mark]:bg-primary-500 dark:[&>mark]:bg-primary-400 [&>mark]:text-white dark:[&>mark]:text-gray-900', + itemLabelPrefix: 'text-gray-700 dark:text-gray-200', itemLabelSuffix: 'text-gray-400 dark:text-gray-500 [&>mark]:bg-primary-500 dark:[&>mark]:bg-primary-400 [&>mark]:text-white dark:[&>mark]:text-gray-900' } })