/react-untabbable

An extremely simple utility to make a container and its children untabbable but still focusable, which is a great aid in accessibility.

Primary LanguageJavaScriptMIT LicenseMIT

npm

react-untabbable

An extremely simple utility to make a container and all its children untabbable, but still focusable. This can be useful in achieving a better accessibility for you components, like a menu with nested panels or the dreaded carousel where you probably want some of the items to be untabbable.

How does it work?

It quite simply applies the value -1 to the tabbable elements inside a container, restoring afterwards when needed.

  • First it obtains all the tabbable elements within a container using the package tabbable
  • A description of each element is saved with information of the tabindex
  • All elements have their tabindex set to -1
  • When needed, the previous value for the tabindex is restored to the respective elements

How to use

You can either use the hook or the component itself, pick what better suits your needs. Both have the same API.

Component

import { Untabbable } from 'react-untabbable';

const options = { disabled: false, includeContainer: true };

<Untabbable { ...options } >
    <div tabIndex="0" className="container">
        <h1>All elements, including the container, are untabbable!</h1>
        <button>Try to focus me with your keyboard!</button>
        <button>You can still focus me though!</button>
    </div>
</Untabbable>

Hook

import React, { useRef } from 'react';
import { useUntabbable } from 'react-untabbable';

const MyComponent = () => {
    const containerRef = useRef();

    const options = { disabled: false, includeContainer: true };

    useUntabbable(containerRef, options);

    return (
        <div ref={ containerRef } tabIndex="0" className="container">
            <h1>All elements, including the container, are untabbable!</h1>
            <button>Try to focus me with your keyboard!</button>
            <button>You can still focus me though!</button>
        </div>
    )
};