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 🙏

© 2024 – Pkg Stats / Ryan Hefner

search-buddy

v1.8.2

Published

Your search-buddy who will get you to the right URL. Ultra small and flexible and no dependency required. It offers a built-in filtering algorithm for client side processing.

Downloads

46

Readme

search-buddy is an open‑source ultra lightweight javascript plugin (* <1kb). It can help you create instant search and/or facilitate navigation between pages. It was written in pure JS without any dependencies, those make it ultra lightweight. * ~0.2kb after gzip.

It is especially useful in projects that are stuck in complex navigation structures (e.g. admin panel). It will surely make your users' everyday things more enjoyable.

Features

  • key shortcut (e.g. doubleShiftLeft, ControlLeft+Slash, doubleEscape and so on)
  • arrow navigation
  • cache mechanism (sessionStorage)
  • built-in search algorithm, you just pass the items to be searched
  • dynamic mode - you can pass an array of items or an async function where you can call your API to fetch items.
  • responsive design
  • and more, please check Live demo!

Installation

npm i search-buddy

Usage

import { SearchBuddy } from 'search-buddy';

let searchBuddy = SearchBuddy({
    items: [
        { title: "Settings", path: "/settings", icon: "🛠️" },
        { title: "Users", path: "/users", icon: "👥️" }
    ],
    keyShortcut: "doubleShiftLeft",
});

// optionally: you can also bind click events to searchBuddy.show
document.querySelector("#search-btn").addEventListener("click", searchBuddy.show);

You also need to load styles, you can import styles in scss

@import 'search-buddy';

or via javascript (you may need a css loader)

import 'search-buddy/dist/esm/index.css'

Installation via CDN (jsDelivr)

This script contains all javascript and css styles, there is no need to load any additional file.

<script src="https://cdn.jsdelivr.net/npm/search-buddy@latest/dist/standalone.min.js"></script>
<script>
  let searchBuddy = SearchBuddy({
    items: [
      { title: "Settings", path: "/settings", icon: "🛠️" },
      { title: "Users", path: "/users", icon: "👥️" }
    ],
    keyShortcut: "doubleShiftLeft",
  });
</script>

Configuration

Options with default values

SearchBuddy({
  /**
   * The URL the user will be redirected to if there are no results
   * and the user clicks Enter. The search value will be appended to this URL.
   * 
   * @example: "/search?query="
   */
  fallbackSearchUrl: null,

  /**
   * It can be an array or an async function. 
   * 
   * @example [ {title: "Page", path: "/page", } ]
   * or
   * @example async () => {
            return new Promise((resolve, reject) => {
                // call your API
            })
        }
   */
  items: [],
  /**
   * Key shortcut used to activate search-buddy.
   * There is a naming convention. If you want to listen for a double click,
   * then use "double[keyCode]" where [keyCode] is the code of the key.
   * In case you want to use two key press event,
   * use the key code separated by a plus sign.
   *
   * Key codes: https://w3c.github.io/uievents/#dom-keyboardevent-code
   *
   * @example "doubleShiftLeft"
   * @example "doubleEscape"
   * @example "ControlLeft+Slash"
   */
  keyShortcut: null,
  /**
   * The maximum number of items rendered in search box.
   */
  maxResults: 25,
  /**
   * The placeholder for search input.
   */
  placeholder: "Start typing...",
  /**
   * Flag to enable saving results to sessionStorage.
   * It is especially useful when loading items via API.
   */
  stateSave: false,
  /**
   * The time threshold (ms) for double clicks.
   * It is used only if keyShortcut is passed.
   */
  threshold: 1000,
  /**
   * Show/hide emojis.
   */
  withIcons: true,
})

Instance

Whenever you run SearchBuddy(options) the new instance will be created. The instance contains some public attributes and methods. You should avoid creating multiple instances, the idea is to have one instance per entire app.

Usually there is no need to manually interact with the instance, but if you want to use it anyway then here you have a little docs:

// Let's create an instance
const searchBuddy = SearchBuddy(options);

/**
 * Reference to DOM element
 */
searchBuddy.container

/**
 * Manually opens a container
 */
searchBuddy.show()

/**
 * Manually hides a container
 */
searchBuddy.hide()

/**
 * Manually destroys DOM elements and removes all event listeners 
 */
searchBuddy.destroy()

Digging Deeper

fetch items with async

As you know, it may happen that you have much more URLs, then the recommended solution is to pass an async function for items parameter and enable the session storage cache.

Instead of passing array you can simply pass an async function, this function will be resolved by search-buddy. This function MUST return just an array of items.

SearchBuddy({
    items: async () => { /* ... */ },
    stateSave: true, // <-- enable cache with sessionStorage
    keyShortcut: "doubleShiftLeft",
});

async example

SearchBuddy({
    keyShortcut: "doubleShiftLeft",
    stateSave: true,
    items: async () => {
        const getData = () => {
            return fetch('/api/search-buddy-items.json')
                .then(response => response.json())
                .then(data => data);
        };
        return new Promise((resolve, reject) => {
            resolve(getData());
        });
    },
});

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

License

MIT