New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

react-roving-tabindex

Package Overview
Dependencies
Maintainers
1
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-roving-tabindex

React implementation of a roving tabindex, now with grid support

  • 2.0.0-alpha.2
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
19K
decreased by-23.71%
Maintainers
1
Weekly downloads
 
Created
Source

react-roving-tabindex

React Hooks implementation of a roving tabindex. See the storybook here to try it out.

bundlephobia NPM JavaScript Style Guide CircleCI

Background

The roving tabindex is an accessibility pattern for a grouped set of inputs. It assists people who are using their keyboard to navigate your Web site. All inputs in a group get treated as a single tab stop, which speeds up keyboard navigation. The last focused input in a group is also remembered, so that it can receive focus again when the user tabs back to the group.

When in the group, the left and right (or up and down) arrow keys move between the inputs. The Home and End keys (Fn+LeftArrow and Fn+RightArrow on macOS) move to the group's first and last inputs respectively.

More information about the roving tabindex pattern is available here and here.

Implementation Considerations

There are two main architectural choices to be made:

  • Whether dynamic enabling and unenabling of the inputs in the group should be supported.
  • How the inputs in a group are identified, including if they need to be direct children of the group container.

This package opts to support dynamic enabling and unenabling. It also allows inputs to be nested as necessary within subcomponents and wrapper elements. It uses React Context to communicate between the managing group component and the nested inputs.

This package does not support nesting one roving tabindex group inside another. I believe that this complicates keyboard navigation too much.

Requirements

This package has been written using the React Hooks API, so it is only usable with React version 16.8 onwards.

Installation

npm install --save react-roving-tabindex

This package includes TypeScript typings.

If you need to support IE 11 then you need to also install a polyfill for Array.prototype.findIndex. One option is the polyfill on the MDN website.

Usage

There is a storybook for this package here.

import React from "react";
import {
  RovingTabIndexProvider,
  useRovingTabIndex,
  useFocusEffect
} from "react-roving-tabindex";

type Props = {
  disabled?: boolean;
  children: React.ReactNode;
};

const ToolbarButton = ({ disabled = false, children }: Props) => {
  // The ref of the input to be controlled.
  const ref = React.useRef<HTMLButtonElement>(null);

  // handleKeyDown and handleClick are stable for the lifetime of the component:
  const [tabIndex, focused, handleKeyDown, handleClick] = useRovingTabIndex(
    ref, // Don't change the value of this ref.
    disabled // But change this as you like throughout the lifetime of the component.
  );

  // Use some mechanism to set focus on the button if it gets focus.
  // In this case I use the included useFocusEffect hook:
  useFocusEffect(focused, ref);

  return (
    <button
      ref={ref}
      tabIndex={tabIndex} // tabIndex must be applied here.
      disabled={disabled}
      onKeyDown={handleKeyDown}
      onClick={handleClick}
    >
      {children}
    </button>
  );
};

const App = () => (
  // Wrap each group in a RovingTabIndexProvider.
  <RovingTabIndexProvider>
    {/*
      it's fine for the roving tabindex components to be nested
      in other DOM elements or React components.
    */}
    <ToolbarButton>First Button</ToolbarButton>
    <ToolbarButton>Second Button</ToolbarButton>
  </RovingTabIndexProvider>
);

Custom ID

You can optionally pass a custom ID to the useRovingTabIndex hook as the third argument:

const [tabIndex, focused, handleKeyDown, handleClick] = useRovingTabIndex(
  ref,
  disabled,
  "custom-id-1" // A custom ID.
);

This is useful if you need to support server-side rendering. The value initially passed will be used for the lifetime of the containing component. You cannot dynamically change this ID.

Navigation

By default the left and right arrow keys are used to move between inputs. You can change this using the direction prop on the provider:

<RovingTabIndexProvider direction="horizontal|vertical|both" />

The vertical option requires the up and down arrows for navigation. The both option is a mix of the other two options.

Upgrading

From version 1

This package no longer includes a ponyfill for Array.prototype.findIndex. If you need to support IE 11 then you now need to install a polyfill for that method. One option is the polyfill on the MDN website.

License

MIT © stevejay

Development

If you have build errors when building Storybook locally, you are likely using Node v13. Please use either Node v14+ or Node v12.

Issues

  • The @types/styled-components package is currently downgraded to v4.1.8 because of this issue. This only affects the Storybook build.

Keywords

FAQs

Package last updated on 21 Oct 2020

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc