Skip to main contentSkip to navigation

Desktop Spotlight

A macOS Spotlight-style search dialog with keyboard navigation and category grouping

Component desktop-spotlight-demo not found in registry.

Installation

Run the following command:

npx @hanzo/ui@latest add desktop

Usage

import { Spotlight, SpotlightItem } from "@hanzo/ui/desktop"

const items: SpotlightItem[] = [
  {
    id: "settings",
    title: "Settings",
    category: "Applications",
    icon: <Settings />,
  },
  {
    id: "documents",
    title: "Documents",
    category: "Folders",
    icon: <Folder />,
  },
  { id: "music", title: "Music", category: "Applications", icon: <Music /> },
]

export function SpotlightDemo() {
  const [isOpen, setIsOpen] = useState(false)

  return (
    <>
      <button onClick={() => setIsOpen(true)}>Open Spotlight</button>

      <Spotlight
        isOpen={isOpen}
        onClose={() => setIsOpen(false)}
        items={items}
        onSelect={(item) => {
          console.log("Selected:", item)
          setIsOpen(false)
        }}
      />
    </>
  )
}

Props

Spotlight

PropTypeDefaultDescription
isOpenboolean-Controls visibility of the spotlight dialog
onClose() => void-Callback when spotlight is closed
itemsSpotlightItem[]-Array of searchable items
onSelect(item: SpotlightItem) => void-Callback when an item is selected
placeholderstring'Search...'Search input placeholder text

SpotlightItem

PropertyTypeDescription
idstringUnique identifier for the item
titlestringDisplay title
subtitlestringOptional subtitle/description text
iconReactNodeOptional icon to display
categorystringCategory for grouping
keywordsstring[]Optional search keywords
action() => voidOptional action callback

Features

  • Fuzzy Search: Real-time filtering as you type
  • Category Grouping: Items organized by category headers
  • Keyboard Navigation: Arrow keys to navigate, Enter to select, Escape to close
  • Focus Management: Auto-focus on open, proper focus trap
  • Smooth Animations: Fade and scale transitions

Examples

Application Launcher

import {
  Spotlight,
  SpotlightItem,
  useKeyboardShortcuts,
} from "@hanzo/ui/desktop"
import {
  Calendar,
  Chrome,
  Folder,
  Mail,
  Music,
  Settings,
  Terminal,
} from "lucide-react"

const apps: SpotlightItem[] = [
  {
    id: "terminal",
    label: "Terminal",
    category: "Applications",
    icon: <Terminal className="h-5 w-5" />,
  },
  {
    id: "safari",
    label: "Safari",
    category: "Applications",
    icon: <Chrome className="h-5 w-5" />,
  },
  {
    id: "mail",
    label: "Mail",
    category: "Applications",
    icon: <Mail className="h-5 w-5" />,
  },
  {
    id: "calendar",
    label: "Calendar",
    category: "Applications",
    icon: <Calendar className="h-5 w-5" />,
  },
  {
    id: "music",
    label: "Music",
    category: "Applications",
    icon: <Music className="h-5 w-5" />,
  },
  {
    id: "settings",
    label: "System Preferences",
    category: "Applications",
    icon: <Settings className="h-5 w-5" />,
  },
  {
    id: "documents",
    label: "Documents",
    category: "Folders",
    icon: <Folder className="h-5 w-5" />,
  },
  {
    id: "downloads",
    label: "Downloads",
    category: "Folders",
    icon: <Folder className="h-5 w-5" />,
  },
]

export function AppLauncher() {
  const [isOpen, setIsOpen] = useState(false)

  // ⌘+Space to open (like macOS)
  useKeyboardShortcuts([
    { key: " ", meta: true, action: () => setIsOpen(true) },
  ])

  return (
    <Spotlight
      isOpen={isOpen}
      onClose={() => setIsOpen(false)}
      items={apps}
      placeholder="Search applications..."
      onSelect={(item) => {
        console.log("Launch:", item.label)
        setIsOpen(false)
      }}
    />
  )
}

Command Palette

import { Spotlight, SpotlightItem } from "@hanzo/ui/desktop"
import { Clipboard, Copy, Redo, Save, Scissors, Undo } from "lucide-react"

const commands: SpotlightItem[] = [
  {
    id: "save",
    label: "Save",
    category: "File",
    icon: <Save />,
    shortcut: "⌘S",
  },
  {
    id: "copy",
    label: "Copy",
    category: "Edit",
    icon: <Copy />,
    shortcut: "⌘C",
  },
  {
    id: "cut",
    label: "Cut",
    category: "Edit",
    icon: <Scissors />,
    shortcut: "⌘X",
  },
  {
    id: "paste",
    label: "Paste",
    category: "Edit",
    icon: <Clipboard />,
    shortcut: "⌘V",
  },
  {
    id: "undo",
    label: "Undo",
    category: "Edit",
    icon: <Undo />,
    shortcut: "⌘Z",
  },
  {
    id: "redo",
    label: "Redo",
    category: "Edit",
    icon: <Redo />,
    shortcut: "⌘⇧Z",
  },
]

export function CommandPalette() {
  const [isOpen, setIsOpen] = useState(false)

  return (
    <Spotlight
      isOpen={isOpen}
      onClose={() => setIsOpen(false)}
      items={commands}
      placeholder="Type a command..."
      onSelect={(item) => {
        console.log("Execute:", item.id)
        setIsOpen(false)
      }}
    />
  )
}

Keyboard Shortcuts

ShortcutAction
/ Navigate between items
EnterSelect highlighted item
EscapeClose spotlight
⌘K / ⌘SpaceOpen spotlight (when configured)