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

@moderntribe/a11y-dialog

v5.3.0

Published

A tiny script to make dialog windows accessible to assistive technology users.

Downloads

29

Readme

MT A11y Dialog

mt-a11y-dialog is a lightweight yet flexible script to create accessible dialog windows. Forked from edenspiekermann

✔︎ No dependencies
✔︎ Closing dialog on overlay click and ESC
✔︎ Toggling aria-* attributes
✔︎ Trapping and restoring focus
✔︎ Firing events
✔︎ DOM and JS APIs
✔︎ Fast and tiny

Installation

npm install mt-a11y-dialog --save

Or you could also copy/paste the script in your project directly, but you will be disconnected from this repository, making it hard for your to get updates.

Usage

You will find a concrete demo in the example folder of this repository, but basically here is the gist:

Required Markup

All you require is a trigger, most likely a button since we want to be accessible, and then a script of type "text/template" which contains the contents of the dialog. Your trigger will need a "data-content" attribute which contains the string that the script tag has as its "data-js" attribute.

<button data-js="trigger-newsletter-signup" data-content="newsletter-signup-content">Open the dialog window</button>
<script data-js="newsletter-signup-content" type="text/template">
	HTML CONTENT
</script>

Styling layer

You will have to implement some styles for the dialog to “work” (visually speaking). The script itself does not take care of any styling whatsoever, not even the display property. It basically mostly toggles the aria-hidden attribute on the dialog itself and its counterpart containers. You can use this to show and hide the dialog:

.dialog[aria-hidden='true'] {
  display: none;
}

The example directory here has a styled modal you can use in your code for inspiration. You also have control over all the css classes used in the dialog as is explained further on.

Show/Hide Effects

To keep this library very light, we only provide a few low level utilities for animations, but with a bit of css you can do whatever you like.

50 milliseconds after the aria-hidden attribute is set to false on the root node a class of a11y-dialog--open is added.

This class is then removed on close, and if the effect type is set to css the aria-hidden attribute is set to true only after the effectSpeed time in milliseconds has passed, allowing whatever css animations you want to apply to run. You just have to synchronize your css animation timings you use with the effect speed.

The fade effect is handled for you in javascript and requires no css.

JavaScript instantiation

// Instantiate a new A11yDialog module
const dialog = new A11yDialog({ trigger: '.some-selector or an element node' });

Here are all the options you can pass to the dialog on init, and the defaults that the system uses:

appendTarget: '', // the dialog will be inserted after the button, you could supply a selector string here to override
bodyLock: true, // lock the body while dialog open?
closeButtonAriaLabel: 'Close this dialog window', // aria label for close button
closeButtonClasses: 'a11y-dialog__close-button', // classes for close button
contentClasses: 'a11y-dialog__content', // dialog content classes
effect: 'none', // none, fade, css
effectSpeed: 300, // effect speed in milliseconds
effectEasing: 'ease-in-out', // a css easing string
overlayClasses: 'a11y-dialog__overlay', // overlay classes
overlayClickCloses: true, // clicking overlay closes dialog
trigger: null, // the trigger for the dialog, can be selector string or element node
wrapperClasses: 'a11y-dialog', // the wrapper class for the dialog

JS API

Regarding the JS API, it simply consists of show() and hide() methods on the dialog instance.

// Show the dialog
dialog.show();

// Hide the dialog
dialog.hide();

For advanced usages, there are create() and destroy() methods. These are responsible for attaching click event listeners to dialog openers and closers. Note that the create() method is automatically called on instantiation so there is no need to call it again directly.

// Unbind click listeners from dialog openers and closers and remove all bound
// custom event listeners registered with `.on()`
dialog.destroy();

// Bind click listeners to dialog openers and closers
dialog.create();

Events

When shown, hidden and destroyed, the instance will emit certain events. It is possible to subscribe to these with the on() method which will receive the dialog DOM element and the event object (if any).

The event object can be used to know which trigger (opener / closer) has been used in case of a show or hide event.

dialog.on('render', function (dialogEl, event) {
  // The dialog is not rendered until the first time its called for by the trigger
  // Instantiate any js that needs to run on the dialog content here, like a slider init
});

dialog.on('show', function (dialogEl, event) {
  // Do something when dialog gets shown
  // Note: opener is `event.currentTarget`
});

dialog.on('hide', function (dialogEl, event) {
  // Do something when dialog gets hidden
  // Note: closer is `event.currentTarget`
});

dialog.on('destroy', function (dialogEl) {
  // Do something when dialog gets destroyed
});

dialog.on('create', function (dialogEl) {
  // Do something when dialog gets created
  // Note: because the initial `create()` call is made from the constructor, it
  // is not possible to react to this particular one (as registering will be
  // done after instantiation)
});

You can unregister these handlers with the off() method.

dialog.on('show', doSomething);
// …
dialog.off('show', doSomething);

Disclaimer & credits

This repository is a fork from edenspiekermann & faction23