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

PropTypeDefaultDescription
itemsSearchItem[][]Array of items to search through
onSelect(item: SearchItem) => voidCallback when an item is selected
onSearch(query: string) => voidCallback when search query changes
placeholderstring"Search..."Placeholder text
variant"default" | "minimal""default"Visual style: default shows icon wrappers, minimal is simpler
showShortcutbooleantrueShow keyboard shortcut hint (also enables shortcut listener)
shortcutKeysstring[]["cmd", "f"]Custom keyboard shortcut display
size"sm" | "md" | "lg""md"Input size variant
maxResultsnumber5Maximum results to display
classNamestringAdditional CSS classes

SearchDialog Props

SearchDialog (popup) component API reference

PropTypeDefaultDescription
itemsSearchItem[][]Array of items to search through
onSelect(item: SearchItem) => voidCallback when an item is selected
onSearch(query: string) => voidCallback when search query changes
placeholderstring"Search..."Placeholder text
variant"default" | "minimal""default"Visual style: default shows icon wrappers, minimal is simpler
showShortcutbooleantrueShow keyboard shortcut hint (also enables shortcut listener)
shortcutKeysstring[]["cmd", "f"]Custom keyboard shortcut display
maxResultsnumber10Maximum results to display
groupByCategorybooleantrueGroup results by category
triggerReact.ReactNodeCustom trigger element (default: button)
emptyMessagestring"No results found"Empty state message
classNamestringAdditional 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 semantics

Keyboard Navigation

KeyAction
⌘F / Ctrl+FFocus searchbar
Arrow Up/DownNavigate results
EnterSelect highlighted result
EscapeClose dropdown and blur

Notes

  • Focus ring visible when input is focused
  • Selected result visually highlighted
  • Shortcut hint hidden when typing to reduce clutter

Related Components