Skip to content

Commit

Permalink
Merge pull request #28 from paganotoni/feature-keyboard-movements
Browse files Browse the repository at this point in the history
feature: adding keyboard movements funcionality
  • Loading branch information
paganotoni authored Jun 8, 2024
2 parents a6de499 + 42bc1b0 commit ad07aa7
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 38 deletions.
5 changes: 5 additions & 0 deletions internal/assets/doco.css
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,8 @@ nav.documents h3 {
.medium-zoom-image--opened {
z-index: 999;
}

#search-results li.selected,
#search-quick-actions li.selected {
@apply bg-blue-100;
}
106 changes: 76 additions & 30 deletions internal/assets/doco.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
String.prototype.interpolate = function (params) {
const names = Object.keys(params);
const vals = Object.values(params);
return new Function(...names, `return \`${this}\`;`)(...vals);
};

document.addEventListener("DOMContentLoaded", () => {
// Add highligthing to the code blocks
hljs.highlightAll();
Expand Down Expand Up @@ -29,6 +35,65 @@ document.addEventListener("DOMContentLoaded", () => {
.getElementById("search-input")
.addEventListener("keyup", (e) => search(e.target.value));

document.addEventListener("keydown", () => {
let paletteVisible = document
.getElementById("search-palette")
.classList.contains("hidden");

if (paletteVisible) {
return;
}

let selector = "#search-results li.selected";
let quickLinksVisisble = document
.querySelector("#search-quick-actions")
.classList.contains("hidden");

if (!quickLinksVisisble) {
selector = "#search-quick-actions li.selected";
}

// get the current selected element
let selected = document.querySelector(selector);
if (selected == null) {
return;
}

// on arrow down move the selected element down
if (event.keyCode == 40) {
let next = selected.nextElementSibling;
if (next == null) {
return;
}

selected.classList.remove("selected");
next.classList.add("selected");
next.scrollIntoView(false);
}

// on arrow up move the selected element up
if (event.keyCode == 38) {
let prev = selected.previousElementSibling;
if (prev == null) {
return;
}

selected.classList.remove("selected");
prev.classList.add("selected");
prev.scrollIntoView(false);
}

// on enter navigate to the selected element
if (event.keyCode == 13) {
let selected = document.querySelector("#search-results li.selected a");
if (selected == null) {
return;
}

window.location = selected.href;
}
});

// Loading the index when the page it loaded so the search just uses it.
fetch("/index.json")
.then((response) => response.json())
Expand Down Expand Up @@ -85,6 +150,7 @@ function hideSearch() {
}

let tm = null;
let lastQuery = "";
function search(searchQuery) {
if (searchQuery.length == 0) {
document.getElementById("search-no-results").classList.add("hidden");
Expand All @@ -94,6 +160,12 @@ function search(searchQuery) {
return;
}

if (searchQuery == lastQuery) {
return;
}

lastQuery = searchQuery;

if (tm != null) {
clearTimeout(tm);
}
Expand All @@ -118,48 +190,22 @@ function search(searchQuery) {
}

function populateResults(result) {
let template = document.getElementById("search-result-template").innerHTML;
var template = document.getElementById("search-result-template").innerHTML;
document.getElementById("search-results").innerHTML = "";

result.forEach((value, index) => {
if (value.item.title == null) {
return;
}

var output = render(template, {
const output = template.interpolate({
key: index,
title: value.item.title,
link: value.item.link,
// selecting the first one
selected: index == 0 ? "selected" : "",
});

document.getElementById("search-results").innerHTML += output;
});
}

function render(templateString, data) {
var conditionalMatches, conditionalPattern, copy;
conditionalPattern = /\$\{\s*isset ([a-zA-Z]*) \s*\}(.*)\$\{\s*end\s*}/g;
//since loop below depends on re.lastIndex, we use a copy to capture any manipulations whilst inside the loop
copy = templateString;
while (
(conditionalMatches = conditionalPattern.exec(templateString)) !== null
) {
if (data[conditionalMatches[1]]) {
//valid key, remove conditionals, leave contents.
copy = copy.replace(conditionalMatches[0], conditionalMatches[2]);
} else {
//not valid, remove entire section
copy = copy.replace(conditionalMatches[0], "");
}
}

templateString = copy;
//now any conditionals removed we can do simple substitution
var key, find, re;
for (key in data) {
find = "\\$\\{\\s*" + key + "\\s*\\}";
re = new RegExp(find, "g");
templateString = templateString.replace(re, data[key]);
}
return templateString;
}
16 changes: 8 additions & 8 deletions internal/page.html
Original file line number Diff line number Diff line change
Expand Up @@ -176,19 +176,19 @@ <h1 id="welcome" class="font-bold text-4xl mb-2">{{.Title}}</h1>
<div class="z-[100] mx-auto max-w-2xl transform divide-y divide-gray-100 overflow-hidden rounded-xl bg-white shadow-2xl ring-1 ring-black ring-opacity-5 transition-all">
<div class="relative">
<span class="material-symbols-outlined pointer-events-none absolute top-3.5 left-4 h-5 w-5 text-gray-400 ">search</span>
<input id="search-input" type="text" class="block w-full py-3 pl-12 pr-4 text-lg text-gray-900 placeholder-gray-500 bg-gray-50 focus:outline-0 focus:border-transparent rounded-xl" placeholder="Search..." aria-label="Search" />
<input id="search-input" type="text" class="block w-full py-3 pl-12 pr-4 text-lg text-gray-900 placeholder-gray-500 bg-gray-50 focus-visible:outline-none focus-visible:ring-offset-0 focus-visible:ring-0 focus:border-transparent rounded-xl" placeholder="Search..." aria-label="Search" />
<button id="close-search" class="bg-gray-200 h-8 w-8 text-xs text-gray-600 rounded-md inline-block absolute right-2 top-2">esc</button>
</div>

<ul id="search-quick-actions" class="max-h-80 scroll-py-2 divide-y divide-gray-100 overflow-y-auto">
<li class="p-2">
<h2 class="sr-only">Quick Actions</h2>
<ul class="text-sm text-gray-700">
{{- range .Config.QuickLinks }}
<li class="group cursor-default select-none items-center rounded-md px-3 py-2">
<a href="{{.Link}}" class="flex flex-row items-center group hover:text-blue-500">
<span class="material-symbols-outlined">{{.Icon}}</span>
<span class="ml-3 flex-auto truncate">{{.Text}}</span>
<ul sclass="text-sm text-gray-700">
{{- range $index, $el := .Config.QuickLinks }}
<li class="{{- if eq $index 0 }} selected {{end}} group cursor-default select-none items-center rounded-md px-3 py-2">
<a href="{{$el.Link}}" class="flex flex-row items-center group hover:text-blue-500">
<span class="material-symbols-outlined">{{$el.Icon}}</span>
<span class="ml-3 flex-auto truncate">{{$el.Text}}</span>
<span class="material-symbols-outlined">arrow_forward</span>
</a>
</li>
Expand All @@ -207,7 +207,7 @@ <h2 class="sr-only">Quick Actions</h2>

<!-- Search Result Template -->
<template id="search-result-template" >
<li class="text-gray-700 group cursor-default select-none items-center rounded-md px-3 py-2 hover:text-blue-500">
<li class="${selected} text-gray-700 group cursor-default select-none items-center rounded-md px-3 py-2 hover:text-blue-500">
<a class="flex items-center" href="/${link}">
<svg class="h-6 w-6 flex-none" fill="none" stroke="currentColor" viewbox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"></path></svg>
<span class="ml-3 flex-grow flex-auto truncate">${title}</span>
Expand Down

0 comments on commit ad07aa7

Please sign in to comment.