Add site search powered by Fuse.js

This commit is contained in:
James Panther
2022-01-13 15:56:30 +11:00
parent e9c8a4a049
commit adaa7b757e
29 changed files with 1169 additions and 457 deletions
File diff suppressed because it is too large Load Diff
+8
View File
@@ -14,6 +14,14 @@ body button {
width: 1em;
}
/* Search */
#search-query::-webkit-search-cancel-button,
#search-query::-webkit-search-decoration,
#search-query::-webkit-search-results-button,
#search-query::-webkit-search-results-decoration {
@apply hidden;
}
/* Heading anchors */
.prose .heading-anchor {
@apply absolute top-0 no-underline opacity-0;
+31 -31
View File
@@ -1,37 +1,37 @@
/* Avocado scheme */
:root {
--color-neutral: #fff;
--color-neutral: 255, 255, 255;
/* Stone */
--color-neutral-50: #fafaf9;
--color-neutral-100: #f5f5f4;
--color-neutral-200: #e7e5e4;
--color-neutral-300: #d6d3d1;
--color-neutral-400: #a8a29e;
--color-neutral-500: #78716c;
--color-neutral-600: #57534e;
--color-neutral-700: #44403c;
--color-neutral-800: #292524;
--color-neutral-900: #1c1917;
--color-neutral-50: 250, 250, 249;
--color-neutral-100: 245, 245, 244;
--color-neutral-200: 231, 229, 228;
--color-neutral-300: 214, 211, 209;
--color-neutral-400: 168, 162, 158;
--color-neutral-500: 120, 113, 108;
--color-neutral-600: 87, 83, 78;
--color-neutral-700: 68, 64, 60;
--color-neutral-800: 41, 37, 36;
--color-neutral-900: 28, 25, 23;
/* Lime */
--color-primary-50: #f7fee7;
--color-primary-100: #ecfccb;
--color-primary-200: #d9f99d;
--color-primary-300: #bef264;
--color-primary-400: #a3e635;
--color-primary-500: #84cc16;
--color-primary-600: #65a30d;
--color-primary-700: #4d7c0f;
--color-primary-800: #3f6212;
--color-primary-900: #365314;
--color-primary-50: 247, 254, 231;
--color-primary-100: 236, 252, 203;
--color-primary-200: 217, 249, 157;
--color-primary-300: 190, 242, 100;
--color-primary-400: 163, 230, 53;
--color-primary-500: 132, 204, 22;
--color-primary-600: 101, 163, 13;
--color-primary-700: 77, 124, 15;
--color-primary-800: 63, 98, 18;
--color-primary-900: 54, 83, 20;
/* Emerald */
--color-secondary-50: #ecfdf5;
--color-secondary-100: #d1fae5;
--color-secondary-200: #a7f3d0;
--color-secondary-300: #6ee7b7;
--color-secondary-400: #34d399;
--color-secondary-500: #10b981;
--color-secondary-600: #059669;
--color-secondary-700: #047857;
--color-secondary-800: #065f46;
--color-secondary-900: #064e3b;
--color-secondary-50: 236, 253, 245;
--color-secondary-100: 209, 250, 229;
--color-secondary-200: 167, 243, 208;
--color-secondary-300: 110, 231, 183;
--color-secondary-400: 52, 211, 153;
--color-secondary-500: 16, 185, 129;
--color-secondary-600: 5, 150, 105;
--color-secondary-700: 4, 120, 87;
--color-secondary-800: 6, 95, 70;
--color-secondary-900: 6, 78, 59;
}
+31 -31
View File
@@ -1,37 +1,37 @@
/* Congo scheme */
:root {
--color-neutral: #fff;
--color-neutral: 255, 255, 255;
/* Gray */
--color-neutral-50: #fafafa;
--color-neutral-100: #f4f4f5;
--color-neutral-200: #e4e4e7;
--color-neutral-300: #d4d4d8;
--color-neutral-400: #a1a1aa;
--color-neutral-500: #71717a;
--color-neutral-600: #52525b;
--color-neutral-700: #3f3f46;
--color-neutral-800: #27272a;
--color-neutral-900: #18181b;
--color-neutral-50: 250, 250, 250;
--color-neutral-100: 244, 244, 245;
--color-neutral-200: 228, 228, 231;
--color-neutral-300: 212, 212, 216;
--color-neutral-400: 161, 161, 170;
--color-neutral-500: 113, 113, 122;
--color-neutral-600: 82, 82, 91;
--color-neutral-700: 63, 63, 70;
--color-neutral-800: 39, 39, 42;
--color-neutral-900: 24, 24, 27;
/* Violet */
--color-primary-50: #f5f3ff;
--color-primary-100: #ede9fe;
--color-primary-200: #ddd6fe;
--color-primary-300: #c4b5fd;
--color-primary-400: #a78bfa;
--color-primary-500: #8b5cf6;
--color-primary-600: #7c3aed;
--color-primary-700: #6d28d9;
--color-primary-800: #5b21b6;
--color-primary-900: #4c1d95;
--color-primary-50: 245, 243, 255;
--color-primary-100: 237, 233, 254;
--color-primary-200: 221, 214, 254;
--color-primary-300: 196, 181, 253;
--color-primary-400: 167, 139, 250;
--color-primary-500: 139, 92, 246;
--color-primary-600: 124, 58, 237;
--color-primary-700: 109, 40, 217;
--color-primary-800: 91, 33, 182;
--color-primary-900: 76, 29, 149;
/* Fuchsia */
--color-secondary-50: #fdf4ff;
--color-secondary-100: #fae8ff;
--color-secondary-200: #f5d0fe;
--color-secondary-300: #f0abfc;
--color-secondary-400: #e879f9;
--color-secondary-500: #d946ef;
--color-secondary-600: #c026d3;
--color-secondary-700: #a21caf;
--color-secondary-800: #86198f;
--color-secondary-900: #701a75;
--color-secondary-50: 253, 244, 255;
--color-secondary-100: 250, 232, 255;
--color-secondary-200: 245, 208, 254;
--color-secondary-300: 240, 171, 252;
--color-secondary-400: 232, 121, 249;
--color-secondary-500: 217, 70, 239;
--color-secondary-600: 192, 38, 211;
--color-secondary-700: 162, 28, 175;
--color-secondary-800: 134, 25, 143;
--color-secondary-900: 112, 26, 117;
}
+31 -31
View File
@@ -1,37 +1,37 @@
/* Fire scheme */
:root {
--color-neutral: #fff;
--color-neutral: 255, 255, 255;
/* Stone */
--color-neutral-50: #fafaf9;
--color-neutral-100: #f5f5f4;
--color-neutral-200: #e7e5e4;
--color-neutral-300: #d6d3d1;
--color-neutral-400: #a8a29e;
--color-neutral-500: #78716c;
--color-neutral-600: #57534e;
--color-neutral-700: #44403c;
--color-neutral-800: #292524;
--color-neutral-900: #1c1917;
--color-neutral-50: 250, 250, 249;
--color-neutral-100: 245, 245, 244;
--color-neutral-200: 231, 229, 228;
--color-neutral-300: 214, 211, 209;
--color-neutral-400: 168, 162, 158;
--color-neutral-500: 120, 113, 108;
--color-neutral-600: 87, 83, 78;
--color-neutral-700: 68, 64, 60;
--color-neutral-800: 41, 37, 36;
--color-neutral-900: 28, 25, 23;
/* Orange */
--color-primary-50: #fff7ed;
--color-primary-100: #ffedd5;
--color-primary-200: #fed7aa;
--color-primary-300: #fdba74;
--color-primary-400: #fb923c;
--color-primary-500: #f97316;
--color-primary-600: #ea580c;
--color-primary-700: #c2410c;
--color-primary-800: #9a3412;
--color-primary-900: #7c2d12;
--color-primary-50: 255, 247, 237;
--color-primary-100: 255, 237, 213;
--color-primary-200: 254, 215, 170;
--color-primary-300: 253, 186, 116;
--color-primary-400: 251, 146, 60;
--color-primary-500: 249, 115, 22;
--color-primary-600: 234, 88, 12;
--color-primary-700: 194, 65, 12;
--color-primary-800: 154, 52, 18;
--color-primary-900: 124, 45, 18;
/* Rose */
--color-secondary-50: #fff1f2;
--color-secondary-100: #ffe4e6;
--color-secondary-200: #fecdd3;
--color-secondary-300: #fda4af;
--color-secondary-400: #fb7185;
--color-secondary-500: #f43f5e;
--color-secondary-600: #e11d48;
--color-secondary-700: #be123c;
--color-secondary-800: #9f1239;
--color-secondary-900: #881337;
--color-secondary-50: 255, 241, 242;
--color-secondary-100: 255, 228, 230;
--color-secondary-200: 254, 205, 211;
--color-secondary-300: 253, 164, 175;
--color-secondary-400: 251, 113, 133;
--color-secondary-500: 244, 63, 94;
--color-secondary-600: 225, 29, 72;
--color-secondary-700: 190, 18, 60;
--color-secondary-800: 159, 18, 57;
--color-secondary-900: 136, 19, 55;
}
+31 -31
View File
@@ -1,37 +1,37 @@
/* Ocean scheme */
:root {
--color-neutral: #fff;
--color-neutral: 255, 255, 255;
/* Gray */
--color-neutral-50: #f8fafc;
--color-neutral-100: #f1f5f9;
--color-neutral-200: #e2e8f0;
--color-neutral-300: #cbd5e1;
--color-neutral-400: #94a3b8;
--color-neutral-500: #64748b;
--color-neutral-600: #475569;
--color-neutral-700: #334155;
--color-neutral-800: #1e293b;
--color-neutral-900: #0f172a;
--color-neutral-50: 248, 250, 252;
--color-neutral-100: 241, 245, 249;
--color-neutral-200: 226, 232, 240;
--color-neutral-300: 203, 213, 225;
--color-neutral-400: 148, 163, 184;
--color-neutral-500: 100, 116, 139;
--color-neutral-600: 71, 85, 105;
--color-neutral-700: 51, 65, 85;
--color-neutral-800: 30, 41, 59;
--color-neutral-900: 15, 23, 42;
/* Blue */
--color-primary-50: #eff6ff;
--color-primary-100: #dbeafe;
--color-primary-200: #bfdbfe;
--color-primary-300: #93c5fd;
--color-primary-400: #60a5fa;
--color-primary-500: #3b82f6;
--color-primary-600: #2563eb;
--color-primary-700: #1d4ed8;
--color-primary-800: #1e40af;
--color-primary-900: #1e3a8a;
--color-primary-50: 239, 246, 255;
--color-primary-100: 219, 234, 254;
--color-primary-200: 191, 219, 254;
--color-primary-300: 147, 197, 253;
--color-primary-400: 96, 165, 250;
--color-primary-500: 59, 130, 246;
--color-primary-600: 37, 99, 235;
--color-primary-700: 29, 78, 216;
--color-primary-800: 30, 64, 175;
--color-primary-900: 30, 58, 138;
/* Cyan */
--color-secondary-50: #ecfeff;
--color-secondary-100: #cffafe;
--color-secondary-200: #a5f3fc;
--color-secondary-300: #67e8f9;
--color-secondary-400: #22d3ee;
--color-secondary-500: #06b6d4;
--color-secondary-600: #0891b2;
--color-secondary-700: #0e7490;
--color-secondary-800: #155e75;
--color-secondary-900: #164e63;
--color-secondary-50: 236, 254, 255;
--color-secondary-100: 207, 250, 254;
--color-secondary-200: 165, 243, 252;
--color-secondary-300: 103, 232, 249;
--color-secondary-400: 34, 211, 238;
--color-secondary-500: 6, 182, 212;
--color-secondary-600: 8, 145, 178;
--color-secondary-700: 14, 116, 144;
--color-secondary-800: 21, 94, 117;
--color-secondary-900: 22, 78, 99;
}
+31 -31
View File
@@ -1,37 +1,37 @@
/* Slate scheme */
:root {
--color-neutral: #fff;
--color-neutral: 255, 255, 255;
/* Gray */
--color-neutral-50: #f9fafb;
--color-neutral-100: #f3f4f6;
--color-neutral-200: #e5e7eb;
--color-neutral-300: #d1d5db;
--color-neutral-400: #9ca3af;
--color-neutral-500: #6b7280;
--color-neutral-600: #4b5563;
--color-neutral-700: #374151;
--color-neutral-800: #1f2937;
--color-neutral-900: #111827;
--color-neutral-50: 249, 250, 251;
--color-neutral-100: 243, 244, 246;
--color-neutral-200: 229, 231, 235;
--color-neutral-300: 209, 213, 219;
--color-neutral-400: 156, 163, 175;
--color-neutral-500: 107, 114, 128;
--color-neutral-600: 75, 85, 99;
--color-neutral-700: 55, 65, 81;
--color-neutral-800: 31, 41, 55;
--color-neutral-900: 17, 24, 39;
/* Gray */
--color-primary-50: #f9fafb;
--color-primary-100: #f3f4f6;
--color-primary-200: #e5e7eb;
--color-primary-300: #d1d5db;
--color-primary-400: #9ca3af;
--color-primary-500: #6b7280;
--color-primary-600: #4b5563;
--color-primary-700: #374151;
--color-primary-800: #1f2937;
--color-primary-900: #111827;
--color-primary-50: 249, 250, 251;
--color-primary-100: 243, 244, 246;
--color-primary-200: 229, 231, 235;
--color-primary-300: 209, 213, 219;
--color-primary-400: 156, 163, 175;
--color-primary-500: 107, 114, 128;
--color-primary-600: 75, 85, 99;
--color-primary-700: 55, 65, 81;
--color-primary-800: 31, 41, 55;
--color-primary-900: 17, 24, 39;
/* Gray */
--color-secondary-50: #f9fafb;
--color-secondary-100: #f3f4f6;
--color-secondary-200: #e5e7eb;
--color-secondary-300: #d1d5db;
--color-secondary-400: #9ca3af;
--color-secondary-500: #6b7280;
--color-secondary-600: #4b5563;
--color-secondary-700: #374151;
--color-secondary-800: #1f2937;
--color-secondary-900: #111827;
--color-secondary-50: 249, 250, 251;
--color-secondary-100: 243, 244, 246;
--color-secondary-200: 229, 231, 235;
--color-secondary-300: 209, 213, 219;
--color-secondary-400: 156, 163, 175;
--color-secondary-500: 107, 114, 128;
--color-secondary-600: 75, 85, 99;
--color-secondary-700: 55, 65, 81;
--color-secondary-800: 31, 41, 55;
--color-secondary-900: 17, 24, 39;
}
+1
View File
@@ -0,0 +1 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg>

After

Width:  |  Height:  |  Size: 577 B

+1
View File
@@ -0,0 +1 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="times" class="svg-inline--fa fa-times fa-w-11" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 352 512"><path fill="currentColor" d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"></path></svg>

After

Width:  |  Height:  |  Size: 645 B

+159
View File
@@ -0,0 +1,159 @@
var fuse;
var showButton = document.getElementById("search-button");
var hideButton = document.getElementById("close-search-button");
var wrapper = document.getElementById("search-wrapper");
var modal = document.getElementById("search-modal");
var input = document.getElementById("search-query");
var output = document.getElementById("search-results");
var first = output.firstChild;
var last = output.lastChild;
var searchVisible = false;
var indexed = false;
var hasResults = false;
// Listen for events
showButton.addEventListener("click", displaySearch);
hideButton.addEventListener("click", hideSearch);
wrapper.addEventListener("click", hideSearch);
modal.addEventListener("click", function (event) {
event.stopPropagation();
event.stopImmediatePropagation();
return false;
});
document.addEventListener("keydown", function (event) {
// Forward slash to open search wrapper
if (event.key == "/") {
if (!searchVisible) {
event.preventDefault();
displaySearch();
}
}
// Esc to close search wrapper
if (event.key == "Escape") {
hideSearch();
}
// Down arrow to move down results list
if (event.key == "ArrowDown") {
if (searchVisible && hasResults) {
event.preventDefault();
if (document.activeElement == input) {
first.focus();
} else if (document.activeElement == last) {
last.focus();
} else {
document.activeElement.parentElement.nextSibling.firstElementChild.focus();
}
}
}
// Up arrow to move up results list
if (event.key == "ArrowUp") {
if (searchVisible && hasResults) {
event.preventDefault();
if (document.activeElement == input) {
input.focus();
} else if (document.activeElement == first) {
input.focus();
} else {
document.activeElement.parentElement.previousSibling.firstElementChild.focus();
}
}
}
});
// Update search on each keypress
input.onkeyup = function (event) {
executeQuery(this.value);
};
function displaySearch() {
if (!indexed) {
buildIndex();
}
if (!searchVisible) {
document.body.style.overflow = "hidden";
wrapper.style.visibility = "visible";
input.focus();
searchVisible = true;
}
}
function hideSearch() {
if (searchVisible) {
document.body.style.overflow = "visible";
wrapper.style.visibility = "hidden";
document.activeElement.blur();
searchVisible = false;
}
}
function fetchJSON(path, callback) {
var httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function () {
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200) {
var data = JSON.parse(httpRequest.responseText);
if (callback) callback(data);
}
}
};
httpRequest.open("GET", path);
httpRequest.send();
}
function buildIndex() {
var baseURL = document
.querySelector('script[data-id="fusejs"][data-url]')
.getAttribute("data-url");
fetchJSON(baseURL + "index.json", function (data) {
var options = {
shouldSort: true,
ignoreLocation: true,
threshold: 0.0,
includeMatches: true,
keys: [
{ name: "title", weight: 0.8 },
{ name: "section", weight: 0.2 },
{ name: "summary", weight: 0.6 },
{ name: "content", weight: 0.4 },
],
};
fuse = new Fuse(data, options);
indexed = true;
});
}
function executeQuery(term) {
let results = fuse.search(term);
let resultsHTML = "";
if (results.length > 0) {
results.forEach(function (value, key) {
resultsHTML =
resultsHTML +
`<li class="mb-2">
<a class="flex items-center px-3 py-2 rounded-md appearance-none bg-neutral-100 dark:bg-neutral-700 focus:bg-primary-100 hover:bg-primary-100 dark:hover:bg-primary-900 dark:focus:bg-primary-900 focus:outline-dotted focus:outline-transparent focus:outline-2" href="${value.item.permalink}" tabindex="0">
<div class="grow">
<div class="-mb-1 text-lg font-bold">${value.item.title}</div>
<div class="text-sm text-neutral-500 dark:text-neutral-400">${value.item.section}<span class="px-2 text-primary-500">&middot;</span>${value.item.date}</span></div>
<div class="text-sm italic">${value.item.summary}</div>
</div>
<div class="ml-2 ltr:block rtl:hidden text-neutral-500">&rarr;</div>
<div class="mr-2 ltr:hidden rtl:block text-neutral-500">&larr;</div>
</a>
</li>`;
});
hasResults = true;
} else {
resultsHTML = "";
hasResults = false;
}
output.innerHTML = resultsHTML;
if (results.length > 0) {
first = output.firstChild.firstElementChild;
last = output.lastChild.firstElementChild;
}
}
+9
View File
File diff suppressed because one or more lines are too long