JSFiddle - React, Tailwind, and code Playground

by sliekens

HTML

<script src="https://use.fontawesome.com/f24612cca2.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<table>
  <tr>
    <th class="selector"> <span class="fa fa-check-square-o"></span> </th>
    <th>First</th>
    <th>Second</th>
    <th>Third</th>
  </tr>
  <tr tabindex="0">
    <td class="selector">
      <span class="fa fa-square-o no-focus"></span>
      <span class="fa fa-check-square-o focus"></span>
    </td>
    <td tabindex="0">1</td>
    <td tabindex="0">2</td>
    <td tabindex="0">3</td>
  </tr>
  <tr tabindex="0">
    <td class="selector">
      <span class="fa fa-square-o no-focus"></span>
      <span class="fa fa-check-square-o focus"></span>
    </td>
    <td tabindex="0">4</td>
    <td tabindex="0">5</td>
    <td tabindex="0">6</td>
  </tr>
</table>

CSS

table {
    table-layout: fixed;
    width: 100%;
    border: 1px solid black;
  }
  
  th,
  td {
    border: 1px solid black;
  }
  
  .selector {
    width: 20px;
  }
  
  tbody:focus,
  tr:focus,
  td:focus {
    outline: none;
    background-color: #337ab7;
  }
  
  tr:not(:focus) > .selector .focus {
    display: none;
  }
  
  tr:focus > .selector .no-focus {
    display: none;
  }

JavaScript

function getSequentialFocusNavigationOrder(nodeList) {
  var els = Array.prototype.slice.call(nodeList);
  els = els.filter(e => e.tabIndex !== -1);
  els = els.filter(e => !e.disabled);
  els = els.sort(function(left, right) {
    if (left.tabIndex === 0) {
      if (right.tabIndex === 0) {
        return 0;
      }
      return 1;
    }
    if (left.tabIndex === right.tabIndex) {
      return 0;
    }
    if (left.tabIndex > right.tabIndex) {
      return 1;
    }
    return -1;
  });
  return els;
}

var table = document.querySelector('table');
$(table).on('keydown', ':focus', function(e) {
  var tableElements = table.querySelectorAll('tr,th,td');
  switch (e.which) {
    case 37:
      var els = getSequentialFocusNavigationOrder(tableElements);
      var current = els.indexOf(this);
      if (current !== 0) {
        els[current - 1].focus();
      }
      break;
    case 39:
      var els = getSequentialFocusNavigationOrder(tableElements);
      var current = els.indexOf(this);
      if (current < els.length) {
        els[current + 1].focus();
      }
      break;
    default:
      console.log(e.which);
      break;
  }
});