A flexible search component with 5 different search patterns. Choose the variant that best fits your use case: live instant search, command palette (⌘K), scoped search with filters, contextual suggestions, or federated multi-source search.
Preview
Interactive demo showcasing all 5 search variants.
Installation
Usage
import {
SearchPanel,
SearchPanelResults,
SearchPanelSuggestions,
SearchPanelFederated,
SearchPanelCommands,
} from "@/components/ui/search-panel"
export default function MySearch() {
const [results, setResults] = useState([])
return (
<SearchPanel
variant="instant"
placeholder="Search components..."
onQueryChange={(query) => {
// Fetch results based on query
setResults(searchData(query))
}}
>
<SearchPanelResults
results={results}
onSelect={(result) => console.log(result)}
/>
</SearchPanel>
)
}Variants
1. Instant Search
Results appear as you type with configurable debounce. Best for quick lookups and autocomplete.
<SearchPanel variant="instant" debounce={150}>
<SearchPanelResults results={results} />
</SearchPanel>2. Command Palette
Modal search triggered by ⌘K (Ctrl+K). Supports both search and commands with > prefix.
<SearchPanel variant="command" placeholder="Search or type > for commands">
<SearchPanelCommands
commands={[
{ id: "theme", title: "Toggle theme", action: () => toggleTheme() },
{ id: "settings", title: "Open settings", shortcut: "⌘," },
]}
results={results}
/>
</SearchPanel>3. Scoped Search
Search with tabs/filters to narrow down results by category.
<SearchPanel
variant="scoped"
scopes={[
{ id: "all", label: "All" },
{ id: "docs", label: "Docs" },
{ id: "code", label: "Code" },
]}
defaultScope="all"
>
<SearchPanelResults results={filteredResults} />
</SearchPanel>4. Contextual Suggestions
Shows recent searches, trending items, and personalized suggestions before typing.
<SearchPanel variant="contextual">
<SearchPanelSuggestions
recent={[{ id: "1", title: "carousel" }]}
trending={[{ id: "2", title: "button" }]}
suggested={[{ id: "3", title: "Based on your history..." }]}
/>
<SearchPanelResults results={results} />
</SearchPanel>5. Federated Search
Search across multiple sources simultaneously with grouped results.
<SearchPanel variant="federated">
<SearchPanelFederated
sources={[
{ id: "components", name: "Components", results: [...] },
{ id: "docs", name: "Documentation", results: [...] },
{ id: "github", name: "GitHub Issues", results: [...] },
]}
onSelect={(result, source) => console.log(result, source)}
/>
</SearchPanel>Props
SearchPanel
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "instant" | "command" | "scoped" | "contextual" | "federated" | "instant" | Search pattern variant |
| size | "sm" | "md" | "lg" | "xl" | "full" | "md" | Panel width |
| placeholder | string | "Search..." | Input placeholder text |
| debounce | number | 150 | Debounce delay in ms (instant variant) |
| scopes | { id: string; label: string }[] | - | Available scopes (scoped variant) |
| onQueryChange | (query: string) => void | - | Callback when search query changes |
SearchPanelResults
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| results | SearchResult[] | [] | Array of search results |
| loading | boolean | false | Show loading state |
| emptyMessage | string | "No results found" | Message when no results |
| onSelect | (result: SearchResult) => void | - | Callback when result is selected |
SearchResult Type
interface SearchResult {
id: string
title: string
description?: string
category?: string
icon?: React.ReactNode
href?: string
keywords?: string[]
}Features
- 5 Search Patterns — instant, command palette, scoped, contextual, federated
- Keyboard Navigation — ⌘K shortcut for command palette, arrow keys for results
- Debounced Input — configurable delay for instant search
- Multi-Source — search across multiple data sources simultaneously
- Contextual — shows recent, trending, and personalized suggestions
- Accessible — proper ARIA attributes and keyboard support