npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sehaj23/react-spotlight-search

v1.0.2

Published

A React component that provides Spotlight-like search functionality for modules and links

Readme

🔍 Spotlight Search

npm version License: MIT TypeScript

A beautiful, fast, and customizable Spotlight-like search component for React applications.

🎬 Demo

Spotlight Search Demo

✨ Features

  • 🔍 Fuzzy Search: Intelligent search with typo tolerance using Fuse.js
  • 🏷️ Tag Support: Search by alternative names and hidden tags
  • Recently Used: Smart caching of recently selected items (up to 6)
  • ⌨️ Keyboard Navigation: Full keyboard support with arrow keys and shortcuts
  • 🎨 Modern Design: Beautiful Spotlight-inspired UI with smooth animations
  • 🌙 Theme Support: Light, dark, and auto themes
  • 📱 Responsive: Works perfectly on all screen sizes
  • 🎯 Custom Handlers: Per-item click functions for flexible behavior
  • 🚀 TypeScript: Full TypeScript support with comprehensive types
  • 🔧 Customizable: Easy styling with CSS custom properties
  • Performant: Optimized for large datasets with smart filtering

🚀 Quick Start

Installation

npm install @sehaj23/react-spotlight-search

Peer Dependencies (install if not already in your project):

npm install react react-dom @mui/material @mui/icons-material @emotion/react @emotion/styled

Basic Usage

import React, { useState } from 'react';
import { Spotlight, SpotlightItem } from '@sehaj23/react-spotlight-search';

const items: SpotlightItem[] = [
  {
    id: '1',
    name: 'Dashboard',
    url: '/dashboard',
    tags: ['home', 'main', 'overview']
  },
  {
    id: '2',
    name: 'User Settings',
    url: '/settings',
    tags: ['profile', 'preferences', 'config'],
    onClick: (item) => {
      // Custom click handler for this item
      console.log('Opening settings with custom logic');
    }
  },
  {
    id: '3',
    name: 'Analytics',
    url: '/analytics',
    tags: ['stats', 'metrics', 'data']
  }
];

function App() {
  const [isOpen, setIsOpen] = useState(false);

  const handleSelect = (item: SpotlightItem) => {
    // Global handler for items without custom onClick
    window.location.href = item.url;
    setIsOpen(false);
  };

  // Open spotlight with keyboard shortcut
  React.useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
        e.preventDefault();
        setIsOpen(true);
      }
    };

    document.addEventListener('keydown', handleKeyDown);
    return () => document.removeEventListener('keydown', handleKeyDown);
  }, []);

  return (
    <>
      <button onClick={() => setIsOpen(true)}>
        Open Search (⌘K)
      </button>
      
      <Spotlight
        items={items}
        onSelect={handleSelect}
        isOpen={isOpen}
        onClose={() => setIsOpen(false)}
        placeholder="Search anything..."
        showInitialResults={false}
        theme="auto"
      />
    </>
  );
}

📖 API Reference

SpotlightItem

interface SpotlightItem {
  id: string;                               // Unique identifier
  name: string;                             // Display name
  url: string;                              // URL or path
  tags: string[];                           // Alternative search terms
  icon?: string;                            // Optional icon URL
  onClick?: (item: SpotlightItem) => void; // Custom click handler
}

SpotlightProps

interface SpotlightProps {
  items: SpotlightItem[];                   // Array of searchable items
  onSelect: (item: SpotlightItem) => void; // Global selection handler
  placeholder?: string;                     // Search input placeholder (default: "Search...")
  maxResults?: number;                      // Maximum results to show (default: 8)
  showRecent?: boolean;                     // Show recently used items (default: true)
  showInitialResults?: boolean;             // Show results before typing (default: true)
  className?: string;                       // Additional CSS class
  isOpen?: boolean;                         // Control visibility (default: true)
  onClose?: () => void;                     // Close callback
  customStyles?: string;                    // Path to custom CSS file or CSS string
  theme?: 'light' | 'dark' | 'auto';      // Theme selection (default: 'auto')
}

⌨️ Keyboard Shortcuts

| Key | Action | |-----|--------| | / | Navigate between results | | Enter | Select highlighted item | | Tab / | Accept autocomplete suggestion | | Escape | Close spotlight | | ⌘K / Ctrl+K | Open spotlight (implement in your app) |

🎨 Customization

Themes

The component supports three theme modes:

<Spotlight theme="light" />   // Force light theme
<Spotlight theme="dark" />    // Force dark theme  
<Spotlight theme="auto" />    // Follow system preference (default)

Custom Styling

Method 1: CSS File

<Spotlight customStyles="/path/to/custom-styles.css" />

Method 2: Inline CSS

<Spotlight 
  customStyles={`
    .spotlight-container {
      border-radius: 20px;
      box-shadow: 0 25px 50px rgba(0, 0, 0, 0.5);
    }
    .spotlight-item.selected {
      background: rgba(255, 0, 0, 0.1);
    }
  `}
/>

Method 3: CSS Custom Properties

:root {
  --spotlight-bg: rgba(255, 255, 255, 0.98);
  --spotlight-text: #000000;
  --spotlight-border: rgba(0, 0, 0, 0.1);
  --spotlight-accent: #007AFF;
}

Smart Icons

The component automatically selects appropriate Material-UI icons based on item names and tags:

  • Dashboard → Dashboard icon
  • Settings → Settings icon
  • Analytics → Analytics icon
  • Team/Users → Group icon
  • Projects → Assignment icon
  • Messages → Message icon
  • Calendar → Event icon
  • Files → Folder icon
  • Default → Article icon

🔧 Advanced Usage

Custom Click Handlers

Provide different behaviors for different items:

const items: SpotlightItem[] = [
  {
    id: 'external',
    name: 'Google',
    url: 'https://google.com',
    tags: ['search', 'external'],
    onClick: (item) => {
      window.open(item.url, '_blank'); // Open in new tab
    }
  },
  {
    id: 'api',
    name: 'Refresh Data',
    url: '/api/refresh',
    tags: ['action', 'reload'],
    onClick: async (item) => {
      const response = await fetch(item.url, { method: 'POST' });
      if (response.ok) {
        alert('Data refreshed successfully!');
      }
    }
  },
  {
    id: 'modal',
    name: 'Open Modal',
    url: '/modal',
    tags: ['dialog', 'popup'],
    onClick: (item) => {
      setModalOpen(true);
      setModalContent(item.name);
    }
  }
];

Complex Search Data

const complexItems: SpotlightItem[] = [
  {
    id: 'user-john',
    name: 'John Doe',
    url: '/users/john',
    tags: ['user', 'employee', 'developer', '[email protected]'],
    icon: '/avatars/john.jpg'
  },
  {
    id: 'project-alpha',
    name: 'Project Alpha',
    url: '/projects/alpha',
    tags: ['project', 'development', 'frontend', 'react', 'typescript'],
    onClick: (item) => {
      // Track project access
      analytics.track('project_accessed', { projectId: item.id });
      window.location.href = item.url;
    }
  }
];

Integration with React Router

import { useNavigate } from 'react-router-dom';

function AppWithRouter() {
  const navigate = useNavigate();

  const handleSelect = (item: SpotlightItem) => {
    navigate(item.url);
    setIsOpen(false);
  };

  return (
    <Spotlight
      items={items}
      onSelect={handleSelect}
      // ... other props
    />
  );
}

🎯 Examples

E-commerce Store

const storeItems = [
  { id: '1', name: 'iPhone 15 Pro', url: '/products/iphone-15-pro', tags: ['phone', 'apple', 'mobile'] },
  { id: '2', name: 'MacBook Air', url: '/products/macbook-air', tags: ['laptop', 'apple', 'computer'] },
  { id: '3', name: 'Orders', url: '/orders', tags: ['purchase', 'history', 'shopping'] },
  { id: '4', name: 'Account Settings', url: '/account', tags: ['profile', 'user', 'preferences'] }
];

Documentation Site

const docsItems = [
  { id: '1', name: 'Getting Started', url: '/docs/getting-started', tags: ['intro', 'setup', 'installation'] },
  { id: '2', name: 'API Reference', url: '/docs/api', tags: ['reference', 'methods', 'functions'] },
  { id: '3', name: 'Examples', url: '/docs/examples', tags: ['samples', 'code', 'snippets'] },
  { id: '4', name: 'FAQ', url: '/docs/faq', tags: ['questions', 'help', 'support'] }
];

Admin Dashboard

const adminItems = [
  { id: '1', name: 'User Management', url: '/admin/users', tags: ['users', 'accounts', 'management'] },
  { id: '2', name: 'System Logs', url: '/admin/logs', tags: ['logs', 'debugging', 'monitoring'] },
  { id: '3', name: 'Analytics', url: '/admin/analytics', tags: ['stats', 'metrics', 'reports'] }
];

🛠️ Development

Build from Source

git clone https://github.com/sehaj23/react-spotlight.git
cd react-spotlight
npm install
npm run build

Run Demo

npm run dev
# Open demo.html in your browser

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Development Setup

  1. Fork the repository
  2. Clone your fork: git clone https://github.com/yourusername/react-spotlight.git
  3. Install dependencies: npm install
  4. Make your changes
  5. Test your changes: npm run build
  6. Submit a pull request

📄 License

MIT © Sehaj Chawla

🙏 Acknowledgments

  • Inspired by macOS Spotlight search
  • Built with Fuse.js for fuzzy searching
  • Uses Material-UI for icons and components
  • TypeScript support for better developer experience

Star ⭐ this repository if you find it helpful!