Searchbar
Form
Component
Navigation
Search input with autocomplete dropdown, keyboard navigation, and global shortcut support.
Default
Basic searchbar with items and selection callback
+f
Press ⌘F to focus
Sizes
Available size variants
Small
+f
Medium (default)
+f
Large
+f
Minimal Variant
Simpler dropdown without icon wrappers
Minimal variant for filter bars and simpler use cases
Without Shortcut
Hide the keyboard shortcut hint
Search Dialog (Default)
Popup search with icon wrappers and category colors
Default variant shows colored icon wrappers based on category
Search Dialog (Minimal)
Simpler popup without icon wrappers
Minimal variant for simpler use cases
With Search Callback
Get notified on every keystroke
+f
Searchbar Props
Searchbar (inline) component API reference
| Prop | Type | Default | Description |
|---|---|---|---|
items | SearchItem[] | [] | Array of items to search through |
onSelect | (item: SearchItem) => void | — | Callback when an item is selected |
onSearch | (query: string) => void | — | Callback when search query changes |
placeholder | string | "Search..." | Placeholder text |
variant | "default" | "minimal" | "default" | Visual style: default shows icon wrappers, minimal is simpler |
showShortcut | boolean | true | Show keyboard shortcut hint (also enables shortcut listener) |
shortcutKeys | string[] | ["cmd", "f"] | Custom keyboard shortcut display |
size | "sm" | "md" | "lg" | "md" | Input size variant |
maxResults | number | 5 | Maximum results to display |
className | string | — | Additional CSS classes |
SearchDialog Props
SearchDialog (popup) component API reference
| Prop | Type | Default | Description |
|---|---|---|---|
items | SearchItem[] | [] | Array of items to search through |
onSelect | (item: SearchItem) => void | — | Callback when an item is selected |
onSearch | (query: string) => void | — | Callback when search query changes |
placeholder | string | "Search..." | Placeholder text |
variant | "default" | "minimal" | "default" | Visual style: default shows icon wrappers, minimal is simpler |
showShortcut | boolean | true | Show keyboard shortcut hint (also enables shortcut listener) |
shortcutKeys | string[] | ["cmd", "f"] | Custom keyboard shortcut display |
maxResults | number | 10 | Maximum results to display |
groupByCategory | boolean | true | Group results by category |
trigger | React.ReactNode | — | Custom trigger element (default: button) |
emptyMessage | string | "No results found" | Empty state message |
className | string | — | Additional CSS classes for trigger button |
SearchItem Type
Structure of search items
interface SearchItem {
/** Unique identifier */
id: string
/** Display title */
title: string
/** Optional category/subtitle */
category?: string
/** Additional search keywords */
keywords?: string[]
/** Custom callback when selected */
onSelect?: () => void
/** Optional icon (lucide-react icon component) */
icon?: React.ComponentType<{ className?: string }>
/** Optional color for icon wrapper (used in default variant) */
color?: 'slate' | 'indigo' | 'teal' | 'emerald' | 'amber' | 'rose' | 'purple' | 'blue'
}Usage
Import and implementation examples
import { Searchbar, SearchDialog, type SearchItem } from '@/components/ui/searchbar'
import { FileText, Users, FolderKanban } from 'lucide-react'
// Define items (icons/colors are auto-assigned based on category)
const items: SearchItem[] = [
{ id: '1', title: 'Dashboard', category: 'Pages' },
{ id: '2', title: 'Settings', category: 'Pages' },
{ id: '3', title: 'John Doe', category: 'Team', keywords: ['developer'] },
]
// Items with custom icons and colors
const customItems: SearchItem[] = [
{ id: '1', title: 'Q4 Report', category: 'Documents', icon: FileText, color: 'teal' },
{ id: '2', title: 'Sarah Johnson', category: 'Team', icon: Users, color: 'indigo' },
{ id: '3', title: 'Website Redesign', category: 'Projects', icon: FolderKanban, color: 'purple' },
]
// ===== SEARCHBAR (Inline) =====
// Default variant with icon wrappers
<Searchbar
items={items}
onSelect={(item) => console.log('Selected:', item)}
placeholder="Search..."
/>
// Minimal variant (no icon wrappers)
<Searchbar
items={items}
onSelect={handleSelect}
variant="minimal"
showShortcut={false}
placeholder="Filter tasks..."
/>
// ===== SEARCH DIALOG (Popup) =====
// Default variant with icon wrappers (based on category)
<SearchDialog
items={items}
onSelect={(item) => router.push(item.id)}
placeholder="Search everything..."
/>
// Minimal variant (simpler, no icon wrappers)
<SearchDialog
items={items}
variant="minimal"
onSelect={handleSelect}
placeholder="Quick search..."
/>
// With custom icons and colors
<SearchDialog
items={customItems}
onSelect={handleSelect}
groupByCategory
placeholder="Search..."
/>
// With custom trigger
<SearchDialog
items={items}
onSelect={handleSelect}
trigger={<Button variant="inverse">Open Search</Button>}
/>Features
Built-in functionality
- Global shortcut: ⌘F / Ctrl+F focuses the searchbar from anywhere
- Keyboard navigation: Arrow keys to navigate, Enter to select, Escape to close
- Fuzzy search: Searches title, category, and custom keywords
- Size variants: Small, medium, and large sizes for different contexts
- Autocomplete dropdown: Shows matching results with smooth animations
- Click outside to close: Dropdown closes when clicking outside
- Dark mode: Full dark mode support
Accessibility
Accessibility considerations
ARIA Attributes
Native input element with proper focus managementResults announced via list semanticsKeyboard Navigation
| Key | Action |
|---|---|
| ⌘F / Ctrl+F | Focus searchbar |
| Arrow Up/Down | Navigate results |
| Enter | Select highlighted result |
| Escape | Close dropdown and blur |
Notes
- Focus ring visible when input is focused
- Selected result visually highlighted
- Shortcut hint hidden when typing to reduce clutter