From 839683b4e1f90595a0b87f9fa1ce03210859f2a5 Mon Sep 17 00:00:00 2001 From: Ben Busby Date: Mon, 1 Aug 2022 13:01:12 -0600 Subject: [PATCH] Allow result navigation w/ Tab and Shift+Tab Closes #457 --- app/static/js/keyboard.js | 98 ++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 42 deletions(-) diff --git a/app/static/js/keyboard.js b/app/static/js/keyboard.js index 7fd05ef..14df9d5 100644 --- a/app/static/js/keyboard.js +++ b/app/static/js/keyboard.js @@ -1,44 +1,58 @@ (function () { - let searchBar, results; - const keymap = { - ArrowUp: goUp, - ArrowDown: goDown, - k: goUp, - j: goDown, - '/': focusSearch, - }; - let activeIdx = -1; - - document.addEventListener('DOMContentLoaded', () => { - searchBar = document.querySelector('#search-bar'); - results = document.querySelectorAll('#main>div>div>div>a'); - }); - - document.addEventListener('keydown', (e) => { - if (e.target.tagName === 'INPUT') return true; - if (typeof keymap[e.key] === 'function') { - e.preventDefault(); - keymap[e.key](); - } - }); - - function goUp () { - if (activeIdx > 0) focusResult(activeIdx - 1); - else focusSearch(); - } - - function goDown () { - if (activeIdx < results.length - 1) focusResult(activeIdx + 1); - } - - function focusResult (idx) { - activeIdx = idx; - results[activeIdx].scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'nearest' }); - results[activeIdx].focus(); - } - - function focusSearch () { - activeIdx = -1; - searchBar.focus(); - } + let searchBar, results; + let shift = false; + const keymap = { + ArrowUp: goUp, + ArrowDown: goDown, + ShiftTab: goUp, + Tab: goDown, + k: goUp, + j: goDown, + '/': focusSearch, + }; + let activeIdx = -1; + + document.addEventListener('DOMContentLoaded', () => { + searchBar = document.querySelector('#search-bar'); + results = document.querySelectorAll('#main>div>div>div>a'); + }); + + document.addEventListener('keydown', (e) => { + if (e.key === 'Shift') { + shift = true; + } + + if (e.target.tagName === 'INPUT') return true; + if (typeof keymap[e.key] === 'function') { + e.preventDefault(); + + keymap[`${shift && e.key == 'Tab' ? 'Shift' : ''}${e.key}`](); + } + }); + + document.addEventListener('keyup', (e) => { + if (e.key === 'Shift') { + shift = false; + } + }); + + function goUp () { + if (activeIdx > 0) focusResult(activeIdx - 1); + else focusSearch(); + } + + function goDown () { + if (activeIdx < results.length - 1) focusResult(activeIdx + 1); + } + + function focusResult (idx) { + activeIdx = idx; + results[activeIdx].scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'nearest' }); + results[activeIdx].focus(); + } + + function focusSearch () { + activeIdx = -1; + searchBar.focus(); + } }());