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

hey.js

v1.1.5

Published

hey.js is a simple dependency-free modal written in JavaScript.

Readme

:wave: hey.js

hey.js is a simple dependency-free modal written in JavaScript.

Why should I use hey.js

  • Accessible (TODO).
  • Lightweight.
  • Flexible - works with inline content, dynamic content or AJAX'd content (TODO).
  • No jQuery dependency.
  • Great default styles that gracefully take care of scrollbar shifting and overflow issues.

Go on...

There are loads of great modals out there, such as Modaal.

However most don't address the little UI annoyances that plague modals, such as the 'scrollbar shift' when applying overflow: hidden to body.

Browser Support

Supports all recent versions of major browsers out of the box (IE10 and up). IE9 support requires a classList polyfill.

Installation

Install hey via NPM/Yarn:

// Yarn
yarn add hey.js
// NPM
npm install --save hey.js

You can include hey via a module bundler, such as Webpack:

// JS
import hey from 'hey.js';

Or just include the script directly:

<!-- HTML -->
<script src="myPath/js/heyModal.min.js"></script>

You'll also need to include the base stylesheet, and optionally a theme. You can import them as part of your build process:

// SASS
@import '../../node_modules/hey.js/dist/css/hey.css';
@import '../../node_modules/hey.js/dist/css/hey-minimal.css';

Or include them directly:

<!-- HTML -->
<link rel="stylesheet" href="myPath/css/hey.css">
<link rel="stylesheet" href="myPath/css/hey-minimal.css">

How to use

All below methods require manual initialization by passing in the trigger (link/button), like so:

heyModal(document.querySelector('.modal-trigger'))

If you have multiple modals with the same class you'll need to loop over and initialize each:

var myModals = document.querySelectorAll('.js-modal-trigger');

for (var i = 0; i < myModals.length; i++) {
    heyModal(myModals[i]);
}

Inline

hey.js generates the markup it needs to create accessible modals, without you having to worry about copying and pasting markup.

As long as you use the appropriate data attributes, hey.js will dynamically create a modal with your in-page content, then remove the old version from the DOM.

You can include an 'inline' modal on the page like so:

<!-- This is the 'link' that will open the modal -->
<a class="great-modal-trigger" data-hey=".great-modal">Modal link</a>

<!-- This is the modal itself -->
<div class="great-modal" style="display: none;">
    <h3 data-hey-title>Modal title</h3>
    <div data-hey-body>This is a modal and the contents</div>
    <div data-hey-footer></div>
</div>

Then initialise it like so:

const myModal = heyModal(document.querySelector('.great-modal-trigger'));

Confirm prompt

You may want to use hey.js as a confirm prompt for a link - for instance, clicking on link that performs a dangerous action:

<a href="/delete-post">Delete</a>

You can do this by creating an inline modal and using the data-hey attribute:

<!-- The modal trigger -->
<a
    data-hey="#great-modal"
    href="/delete"
    class="modal-trigger button"
>
    Delete post
</a>

<!-- The modal target -->
<div id="great-modal" style="display: none;">
    <h3 data-hey-title>Delete post</h3>
    <div data-hey-body>
        <p>This is a modal and the contents</p>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis metus est, eu aliquet arcu
            interdum eu. Mauris in tortor semper, pulvinar nunc et, tincidunt lectus. Donec erat ex, ultricies sit</p>
            
        <!-- Manually include a confirm link in the body --> 
        <a href="/delete">Delete</a>
        
        <!-- Include a close button by adding the 'data-hey-close' attribute -->
        <button data-hey-close>Cancel</button>
    </div>
</div>

However, hey.js also provides a simpler alternative. You can omit the modal target altogether, and have hey.js generate it:

<!-- The modal trigger, no need to provide a target -->
<a
    data-hey-confirm
    data-hey-title="Confirm"
    data-hey-body="Are you sure?"
    href="/delete"
    class="modal-trigger button"
>
    Delete post
</a>

Simply add the data-hey-confirm attribute along with data-hey-title and data-hey-body. The confirm link will automatically be the target link.

This works well when there are a lot of links on the page that would need modals, and where it is impractical to produce the markup manually. The downside is that this approach is less flexible - there is no way to include HTML in the body of the modal.

Modal link attributes:

If you're using an inline modal, only the data-hey attribute is required.

If you're generating a confirm modal, the data-hey-title, data-hey-body and data-hey-confirm attributes are all required.

| Attribute | Description | |--------------------|-----------------------------------------------------------------| | data-hey | The class/id of the modal target (optional). | | data-hey-title | The title of the modal (optional). | | data-hey-body | The main content of the modal (optional). | | data-hey-confirm | Generates confirm yes/no actions based on a link (optional). |

Modal attributes

| Attribute | Description | |-----------------|---------------------------------------------------------------------| | data-hey-title | The title of the modal, appearing in the header. | | data-hey-body | The main content/body of the modal. | | data-hey-close | If this element is clicked it will close the modal (optional). |

Methods

Your hey.js modal has several methods once initialised (like so):

const myModal = heyModal(document.querySelector('.great-modal-trigger'));

Open

Opens the modal manually:

myModal.open();

Close

Closes the modal manually:

myModal.close();

Destroy (TODO)

Removes the modal and cleans up:

myModal.destroy();

Events

hey.js fires two custom events (heyOpen and heyClose) on the main modal element.

You can either add an event listener to the generated wrapper, e.g.:

myModal.comp.wrapper.addEventListener('heyOpen', () => {
    console.log('open!');
});

Or you can use the included .on helper method, which defaults to the wrapper:

myModal.on('heyOpen', () => {
    console.log('opening!');
});

Theming

The essential 'base' styles are in hey.css. These should be included first and overridden as necessary.

It's worth noting that the modal close event, which is responsible for firing events and mitigating shifting scrollbars, happens when the transition is finished on the .modal element. This means if the dialog has a separate transition, it should finish before the main modal's transition ends. If this isn't the case, the dialog will animate during (or after the scrollbar change), which will cause an unnecessary shift.