diff --git a/src/design-system/composites/CommandPalette/CommandPalette.tsx b/src/design-system/composites/CommandPalette/CommandPalette.tsx index 5cdb0d1..43a2d57 100644 --- a/src/design-system/composites/CommandPalette/CommandPalette.tsx +++ b/src/design-system/composites/CommandPalette/CommandPalette.tsx @@ -19,8 +19,7 @@ interface CommandPaletteProps { onSubmit?: (query: string) => void } -const CATEGORY_LABELS: Record = { - all: 'All', +const KNOWN_CATEGORY_LABELS: Record = { application: 'Applications', exchange: 'Exchanges', attribute: 'Attributes', @@ -28,8 +27,8 @@ const CATEGORY_LABELS: Record = { agent: 'Agents', } -const ALL_CATEGORIES: Array = [ - 'all', +/** Preferred display order for known categories */ +const KNOWN_CATEGORY_ORDER: string[] = [ 'application', 'exchange', 'attribute', @@ -37,6 +36,13 @@ const ALL_CATEGORIES: Array = [ 'agent', ] +function categoryLabel(cat: string): string { + if (cat === 'all') return 'All' + if (KNOWN_CATEGORY_LABELS[cat]) return KNOWN_CATEGORY_LABELS[cat] + // Title-case unknown categories: "my-thing" → "My Thing", "foo_bar" → "Foo Bar" + return cat.replace(/[-_]/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase()) +} + function highlightText(text: string, query: string, matchRanges?: [number, number][]): ReactNode { if (!query && (!matchRanges || matchRanges.length === 0)) return text @@ -69,7 +75,7 @@ function highlightText(text: string, query: string, matchRanges?: [number, numbe export function CommandPalette({ open, onClose, onSelect, data, onOpen, onQueryChange, onSubmit }: CommandPaletteProps) { const [query, setQuery] = useState('') - const [activeCategory, setActiveCategory] = useState('all') + const [activeCategory, setActiveCategory] = useState('all') const [scopeFilters, setScopeFilters] = useState([]) const [focusedIdx, setFocusedIdx] = useState(0) const [expandedId, setExpandedId] = useState(null) @@ -128,7 +134,7 @@ export function CommandPalette({ open, onClose, onSelect, data, onOpen, onQueryC // Group results by category const grouped = useMemo(() => { - const map = new Map() + const map = new Map() for (const r of filtered) { if (!map.has(r.category)) map.set(r.category, []) map.get(r.category)!.push(r) @@ -148,6 +154,19 @@ export function CommandPalette({ open, onClose, onSelect, data, onOpen, onQueryC return counts }, [queryFiltered]) + // Build tab list dynamically: 'all' + known categories (in order) + any unknown categories found in data + const visibleCategories = useMemo(() => { + const dataCategories = new Set(data.map((r) => r.category)) + const tabs: string[] = ['all'] + for (const cat of KNOWN_CATEGORY_ORDER) { + if (dataCategories.has(cat)) tabs.push(cat) + } + for (const cat of dataCategories) { + if (!tabs.includes(cat)) tabs.push(cat) + } + return tabs + }, [data]) + function handleKeyDown(e: React.KeyboardEvent) { switch (e.key) { case 'Escape': @@ -246,7 +265,7 @@ export function CommandPalette({ open, onClose, onSelect, data, onOpen, onQueryC {/* Category tabs */}
- {ALL_CATEGORIES.map((cat) => ( + {visibleCategories.map((cat) => (