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

droppy-menu

v2.2.1

Published

Pure JavaScript multi-level dropdown menu.

Readme

Droppy

Droppy is a pure JavaScript multi-level dropdown menu. It shows and hides elements using your custom animations. Styling the menu via custom CSS is up to you.

Quick Start

Start using Droppy in three steps.

  1. Add Droppy to your page.
<script defer type="module" src="https://cdn.jsdelivr.net/npm/[email protected]/src/droppy.js"></script>
  1. Mark your menu with the data-menu attribute.
<nav data-menu>
  <ul class="menu">
    <li>
      <a href="#">First level - Link #1</a>
      <ul class="dropdown">
        <li><a href="#">Second level - Link #1</a></li>
      </ul>
    </li>
  </ul>
</nav>
  1. Style your brand-new dropdown menu.
li > .dropdown {
  display: none;
}

That's it! You're all set to start using Droppy.

Install via NPM

You can install Droppy via NPM by adding the package to your project.

npm install --save droppy-menu

Init via Droppy class

Create a new Droppy instance by specifying the trigger and dropdown elements. Done!

import Droppy from '@/droppy-menu/src/droppy.js';

const trigger = document.querySelector('li > a');
const dropdown = document.querySelector('li > ul');

const droppy = new Droppy(trigger, dropdown, {
    // Options...
});

A Droppy instance represents a single node of your dropdown menu. This is useful if you want to use Droppy for a modal or a single dropdown.

Init via HTML attribute

You can initialize Droppy in HTML using the generator's attributes. Check the section related to generators.

Options

You can customize Droppy using the options object.

/** @type {DroppyOptions} Default values */
const droppyOptions = {
  animationIn: '', // A CSS class with animation.
  animationOut: '', // A CSS class with animation.
  display: 'block', // E.g. block, inline, flex, grid, etc.
  triggerActiveClass: 'active', // Adds the class to the trigger.
  preventDefault: false, // If the trigger is <a> element, prevent default action.
}

Methods

Public methods of Droppy instances. They are self-explanatory.

const droppy = new Droppy(trigger, dropdown);

droppy.show(); // Shows current dropdown.
droppy.hide(); // Hides current dropdown.
droppy.toggle(); // Shows/hides current dropdown.

DroppyContext class

Each Droppy instance is added to a DroppyContext. If you don't specify a context when creating an instance, it will be added to the globalContext. You can access the globalContext by importing it into your script.

import { globalContext } from '@/droppy-menu/src/droppy.js';

You can also define a custom context for a specific Droppy instance by specifying it in the constructor:

import Droppy, { DroppyContext } from '@/droppy-menu/src/droppy.js';

const customContext = new DroppyContext();

new Droppy(trigger, drop, options, customContext);

The DroppyContext is used to group multiple Droppy instances together.

Generators

Droppy provides functions that help you create specific behaviors. For example, menuGenerator allows you to create a dropdown menu, while tabsGenerator enables a tabbed interface. Each generator function has its own options, which are always a superset of DroppyOptions.

The menuGenerator function

Define your menu structure using the wrapper, trigger, and drop options along with a root element. The generator will search for each wrapper and then select the trigger and drop elements inside it. If clickAwayToClose option is true, clicking outside the drop will close it.

import { menuGenerator } from '/@/droppy-menu/src/droppy.js';

const options = {
    wrapper: 'li',
    trigger: 'a',
    drop: 'ul',
    clickAwayToClose: true,
    ...droppyOptions,
}

const nav = document.querySelector('nav');

/** @type {DroppyContext} */
const context = menuGenerator(nav, options);

As shown in the Quick Start section, you can initialize Droppy in HTML using the data-menu attribute. Options can be set in its value.

<nav data-menu='{
    "wrapper": "li", 
    "trigger": "a", 
    "drop": "ul", 
    "animationIn": "fade-in", 
    "animationOut": "fade-out"
 }'>
   ...
</nav>

The tabsGenerator function

Within the root element, the generator will look for the data-target attribute. Each data-target value must be a valid CSS selector. E.g. data-target="#tab-1". The generator will ignore any missing or invalid selectors.

import { tabsGenerator } from '/@/droppy-menu/src/droppy.js';

const options = { ...droppyOptions };

const root = document.querySelector('.tabs');

/** @type {DroppyContext} */
const context = tabsGenerator(root, options);

You can initialize tabs in HTML using the data-tabs attribute. Options can be set in its value.

<div data-tabs='{ "animationIn":"fade-in" }'>
    <button data-target="#tab-1">Tab 1</button>
    <button data-target="#tab-2">Tab 2</button>
    <button data-target="#tab-3">Tab 3</button>
    
    <div id="tab-1">
        <!-- Content... -->
    </div>

    <div id="tab-2">
        <!-- Content... -->
    </div>

    <div id="tab-2">
        <!-- Content... -->
    </div>
</div>

The modalGenerator function

The modalGenerator function is used to create a modal dialog. It will look for the modal and backdrop CSS selector in the options.

import { modalGenerator } from '@/droppy-menu/src/droppy.js';

const options = {
    modal: #modal',
    backdrop: '#backdrop',
    ...droppyOptions,
}

const trigger = document.querySelector('button[data-modal]');

/** @type {DroppyContext} */
const context = modalGenerator(trigger, options);

You can initialize tabs in HTML using the data-modal attribute. Options can be set in its value.

<div>
    <button data-modal='{ "modal":"#modal", "backdrop":"#backdrop" }'>Open modal</button>
    
    <div id="modal">
        <p>Modal content...</p>
    </div>

    <div id="backdrop" class="backdrop"></div>
</div>