From b7f8749cdfbd01d19a71d560f5c8b4322f11542e Mon Sep 17 00:00:00 2001 From: Aditya Telange <21258296+adityatelange@users.noreply.github.com> Date: Fri, 18 Dec 2020 11:45:10 +0530 Subject: [PATCH] Search: Keyboard Bindings for easier navigation (#138) * set up basic actions on keypress * add actions to perform conditionally * add simple highlight animation * prevent mouseclick to change active element * clear input box on Escape * click on Arrow Right * clear results and focus search-input on esc * refactor --- assets/css/search.css | 8 +++-- assets/js/fastsearch.js | 66 ++++++++++++++++++++++++++++++++++-- layouts/_default/search.html | 2 +- 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/assets/css/search.css b/assets/css/search.css index d788cd22..275cbe10 100644 --- a/assets/css/search.css +++ b/assets/css/search.css @@ -1,4 +1,4 @@ -.searchbox input { +#searchbox input { padding: 4px 10px; width: 100%; color: var(--primary); @@ -7,7 +7,7 @@ border-radius: var(--radius); } -.searchbox input:focus { +#searchbox input:focus { border-color: var(--secondary); } @@ -38,3 +38,7 @@ left: 0px; outline: none; } + +#searchResults .active { + transform: scale(.98); +} diff --git a/assets/js/fastsearch.js b/assets/js/fastsearch.js index e76f9193..152d31c1 100644 --- a/assets/js/fastsearch.js +++ b/assets/js/fastsearch.js @@ -1,4 +1,8 @@ var fuse; // holds our search engine +var resList = document.getElementById('searchResults'); +var sInput = document.getElementById('searchInput'); +var first, last = null +var resultsAvailable = false; // load our search index, only executed onload function loadSearch() { @@ -35,6 +39,15 @@ function loadSearch() { xhr.send(); } + +function itemGen(name, link) { + return `
  • ${name} »
  • ` +} + +function activeToggle() { + document.activeElement.parentElement.classList.toggle("active") +} + // execute search as each character is typed document.getElementById("searchInput").onkeyup = function (e) { // run a search query (for "term") every time a letter is typed @@ -50,11 +63,60 @@ document.getElementById("searchInput").onkeyup = function (e) { } document.getElementById("searchResults").innerHTML = resultSet; + resultsAvailable = true; + first = resList.firstChild; + last = resList.lastChild; } else { + resultsAvailable = false; document.getElementById("searchResults").innerHTML = ''; } } -function itemGen(name, link) { - return `
  • ${name} »
  • ` +// kb bindings +document.onkeydown = function (e) { + let key = e.key; + let ae = document.activeElement; + + if (key === "ArrowDown" && resultsAvailable) { + e.preventDefault(); + if (ae == sInput) { + // if the currently focused element is the search input, focus the of first
  • + activeToggle(); // rm active class + resList.firstChild.lastChild.focus(); + activeToggle(); // add active class + } else if (ae.parentElement == last) { + // if the currently focused element's parent is last, do nothing + } else { + // otherwise select the next search result + activeToggle(); // rm active class + ae.parentElement.nextSibling.lastChild.focus(); + activeToggle(); // add active class + } + } else if (key === "ArrowUp" && resultsAvailable) { + e.preventDefault(); + if (ae == sInput) { + // if the currently focused element is input box, do nothing + } else if (ae.parentElement == first) { + // if the currently focused element is first item, go to input box + activeToggle(); // rm active class + sInput.focus(); + } else { + // otherwise select the previous search result + activeToggle(); // rm active class + ae.parentElement.previousSibling.lastChild.focus(); + activeToggle(); // add active class + } + } else if (key === "ArrowRight" && resultsAvailable) { + ae.click(); // click on active link + } else if (key === "Escape") { + resultsAvailable = false; + document.getElementById("searchResults").innerHTML = sInput.value = ''; // clear inputbox and searchResults + sInput.focus(); // shift focus to input box + } +} + +document.onmousedown = function (e) { + if (e.type === "mousedown") { + e.preventDefault(); // prevent mousedown to change focus + } } diff --git a/layouts/_default/search.html b/layouts/_default/search.html index 44b72c57..2105c298 100644 --- a/layouts/_default/search.html +++ b/layouts/_default/search.html @@ -30,7 +30,7 @@ {{- end}} -