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 🙏

© 2025 – Pkg Stats / Ryan Hefner

roving-tabindex

v0.3.3

Published

A simple HTML web component that implements the roving tabindex pattern for building accessible menus and grids.

Readme

Roving tabindex

A simple HTML web component that implements the roving tabindex pattern for building accessible menus and grids.

Wrap it around some markup and give it a selector to determine which elements become navigable!

<script type="module" src="https://esm.sh/roving-tabindex"></script>
<roving-tabindex selector="button">
  <ul>
    <li><button>One</button></li>
    <li><button>Two</button></li>
    <li><button>Three</button></li>
  </ul>
</roving-tabindex>

<roving-tabindex> works especially well as progressive enhancement on menus that are already keyboard navigable with the tab key. It also works well in JavaScript framework apps, letting you easily create keyboard navigable toolbars and menus without managing state or focus yourself. Because it's a web component, it works with every JavaScript framework.

Quick start

The easiest way to get started with <roving-tabindex> is by adding a <script> tag that imports it from a CDN:

<script type="module" src="https://unpkg.com/roving-tabindex/roving-tabindex.js"></script>

It defines its custom element on import using the tag name roving-tabindex, so you can use it in your HTML with no further code!

Read on for more in-depth installation instructions.

Installation

<roving-tabindex> is a dependency-free library.

npm

You can install <roving-tabindex> from npm:

npm install roving-tabindex

Then just import it within your app:

import "roving-tabindex";

CDN

You can also import it from a CDN without installing anything:

<script type="module" src="https://unpkg.com/roving-tabindex/roving-tabindex.js"></script>

Vendoring

Finally, you can "vendor" it by downloading roving-tabindex.js and copying it into your codebase.

<import RovingTabindex from "./roving-tabindex.js";>

This might not be the most popular installation method, but it's my favorite. It's the reason that <roving-tabindex> is a single plain JavaScript file with no dependencies: it will work in any frontend web project, with any framework and any build system (or none at all)!

Usage

To use <roving-tabindex>, just wrap it around the elements for which you want arrow key navigation. Use the selector attribute to determine which descendant elements should be included.

<roving-tabindex selector="button, a">
  <ul class="menu" role="toolbar" aria-label="toolbar-example">
    <li><button>One</button></li>
    <li><button>Two</button></li>
    <li><button>Three</button></li>
    <li><a href="#">Link</a></li>
  </ul>
</roving-tabindex>

Make sure you set WAI-ARIA-related properties as appropriate. For example, the previous demo implements keyboard navigation described in the toolbar pattern, but <roving-tabindex> doesn't manage the role and aria-label attributes for you.

By default, the left/up and right/down arrow keys move forward and backward in the list, respectively, but you can set the direction attribute to "horizontal" or "vertical" to use only the corresponding set of arrow keys:

<roving-tabindex selector="button, a" direction="horizontal">
  <ul class="menu" role="toolbar" aria-label="toolbar-example">
    <li><button>One</button></li>
    <li><button>Two</button></li>
    <li><button>Three</button></li>
    <li><a href="#">Link</a></li>
  </ul>
</roving-tabindex>

<roving-tabindex> can also be used to navigate in two dimensions by setting the direction attribute to "grid" and setting the columns attribute to the number of columns.

<roving-tabindex selector="button" direction="grid" columns="3">
  <!-- row 1 -->
  <button>a1</button>
  <button>b1</button>
  <button>c1</button>

  <!-- row 2 -->
  <button>a2</button>
  <button>b2</button>
  <button>c2</button>

  <!-- row 3 -->
  <button>a3</button>
  <button>b3</button>
  <button>c3</button>
</roving-tabindex>

By default, <roving-tabindex> will stop navigating once you reach the end of the list (or, in a grid, the end of the row or column). Setting the loop attribute causes it to wrap around to the other end.

Changing the tag name

By default, <roving-tabindex> registers itself as that tag name upon import. That means as soon as you import it, you can start using it on the page with no additional setup required:

<script type="module" src="https://unpkg.com/roving-tabindex/roving-tabindex.js"></script>

<roving-tabindex selector="button">
  <!-- ... -->
</roving-tabindex>

If you'd rather use a different tag name, you can import it with the query string parameter ?define=tag-name, where tag-name is whatever tag name you'd like. (Note that custom element tag names must include a hyphen.)

<script type="module" src="https://unpkg.com/roving-tabindex/roving-tabindex.js?define=tag-name"></script>

If you'd prefer to control the registration yourself, you can import it with the query string parameter ?nodefine and use the static method define:

<script type="module">
  import RovingTabindex from "https://unpkg.com/roving-tabindex/roving-tabindex.js?nodefine";

  RovingTabindex.define("tag-name");
</script>

This will all work no matter what method you use to install <roving-tabindex>.