Roving Tabindex - javascript helper to create accessible widgets

Demos

Radio Group

Implemented using WAI Guidelines.

Preview

My favourite color:
Red
Green
Blue

HTML

<div role="radiogroup" aria-labelledby="label_1">
    <strong id="label_1">My favourite color:</strong>
    <div id="radio-group-widget">
        <div role="radio" aria-checked="false" tabindex="0">Red</div>
        <div role="radio" aria-checked="false" tabindex="-1">Green</div>
        <div role="radio" aria-checked="false" tabindex="-1">Blue</div>
    </div>
</div>

Javascript

const radiogroup = document.getElementById('radio-group-widget');

new RovingTabindex(radiogroup);

radiogroup.addEventListener('movefocus', (event) => {
    event.detail.to.click()
});

radiogroup.addEventListener('keydown', (event) => {
    if (event.target.matches('[role="radio"]') && event.key === " ") {
        event.preventDefault(); //do not scroll down
        event.target.click();
    }
});

radiogroup.addEventListener('click', (event) => {
   if (event.target.matches('[role="radio"][tabindex="-1"]')) {
       let from = radiogroup.querySelector('[tabindex="0"]');
       let to = event.target;

       //uncheck previously checked item
       from.setAttribute('tabindex', '-1');
       from.setAttribute('aria-checked', 'false');

       //check new item
       to.setAttribute('tabindex', '0');
       to.setAttribute('aria-checked', 'true');
       to.focus();
   }
});
Radio group widget implementation in HTML and javascript.

Toolbar

Implemented using WAI Guidelines.

Preview

HTML

<div id="toolbar-widget" role="toolbar" aria-label="Demo toolbar" aria-controls="square">
    <div class="wrapper">
        <button tabindex="0">1</button>
        <button tabindex="-1">2</button>
        <button tabindex="-1">3</button>
    </div>
    <button tabindex="-1">4</button>
    <button tabindex="-1">5</button>
</div>
<div id="square"></div>

Javascript

const toolbar = document.getElementById('toolbar-widget');

new RovingTabindex(toolbar, {
    next: ['ArrowRight'],
    previous: ['ArrowLeft'],
    childrenSelector: 'button'
});

const manageFocus = (from,to) => {
    from.setAttribute('tabindex', '-1');
    to.setAttribute('tabindex', '0');
    to.focus();
};

toolbar.addEventListener('movefocus', (event) => {
    manageFocus(event.detail.from, event.detail.to)
});

toolbar.addEventListener('click', (event) => {
    if (event.target.matches('[tabindex="-1"]')) {
        let from = toolbar.querySelector('[tabindex="0"]');
        let to = event.target;

        manageFocus(from, to);
    }
});
Toolbar widget implementation in HTML and javascript.

Getting started

  1. Setup your HTML: a parent and children with appropriate tabindex.

    <div id="demo">
        <button tabindex="0">Button 1</button>
        <button tabindex="-1">Button 2</button>
        <button tabindex="-1">Button 3</button>
    </div>
  2. Add rovingtabindex.js before your closing body tag.

    <script src="rovingtabindex.js"></script>
  3. Initialize RovingTabindex.

    new RovingTabindex('#demo');

Settings

Methods

Events

Get it now

You will find all the code on Github.