diff --git a/src/design-system/composites/CommandPalette/CommandPalette.module.css b/src/design-system/composites/CommandPalette/CommandPalette.module.css index 256cc7f..4a57919 100644 --- a/src/design-system/composites/CommandPalette/CommandPalette.module.css +++ b/src/design-system/composites/CommandPalette/CommandPalette.module.css @@ -277,6 +277,23 @@ overflow-y: auto; } +/* Match context snippet */ +.matchContext { + font-size: 11px; + color: var(--text-faint); + font-family: var(--font-mono); + margin-top: 3px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.matchContext em { + font-style: normal; + color: var(--amber); + font-weight: 600; +} + /* Match highlight */ .mark { background: none; diff --git a/src/design-system/composites/CommandPalette/CommandPalette.tsx b/src/design-system/composites/CommandPalette/CommandPalette.tsx index 69921a3..9f4f9f5 100644 --- a/src/design-system/composites/CommandPalette/CommandPalette.tsx +++ b/src/design-system/composites/CommandPalette/CommandPalette.tsx @@ -92,14 +92,10 @@ export function CommandPalette({ open, onClose, onSelect, data, onOpen, onQueryC } }, [open]) - // Filter results - const filtered = useMemo(() => { + // Stage 1: apply text query + scope filters (used for counts) + const queryFiltered = useMemo(() => { let results = data - if (activeCategory !== 'all') { - results = results.filter((r) => r.category === activeCategory) - } - if (query.trim()) { const q = query.toLowerCase() results = results.filter( @@ -107,7 +103,6 @@ export function CommandPalette({ open, onClose, onSelect, data, onOpen, onQueryC ) } - // Apply scope filters for (const sf of scopeFilters) { results = results.filter((r) => r.category === sf.field || r.title.toLowerCase().includes(sf.value.toLowerCase()), @@ -115,7 +110,13 @@ export function CommandPalette({ open, onClose, onSelect, data, onOpen, onQueryC } return results - }, [data, query, activeCategory, scopeFilters]) + }, [data, query, scopeFilters]) + + // Stage 2: apply category filter (used for display) + const filtered = useMemo(() => { + if (activeCategory === 'all') return queryFiltered + return queryFiltered.filter((r) => r.category === activeCategory) + }, [queryFiltered, activeCategory]) // Group results by category const grouped = useMemo(() => { @@ -130,14 +131,14 @@ export function CommandPalette({ open, onClose, onSelect, data, onOpen, onQueryC // Flatten for keyboard nav const flatResults = useMemo(() => filtered, [filtered]) - // Counts per category + // Counts per category (from query-filtered, before category filter) const categoryCounts = useMemo(() => { - const counts: Record = { all: data.length } - for (const r of data) { + const counts: Record = { all: queryFiltered.length } + for (const r of queryFiltered) { counts[r.category] = (counts[r.category] ?? 0) + 1 } return counts - }, [data]) + }, [queryFiltered]) function handleKeyDown(e: React.KeyboardEvent) { switch (e.key) { @@ -303,6 +304,12 @@ export function CommandPalette({ open, onClose, onSelect, data, onOpen, onQueryC
{highlightText(result.meta, query)}
+ {result.matchContext && ( +
+ )}
{result.expandedContent && (