Add site search powered by Fuse.js

pull/100/head
James Panther 2022-01-13 15:56:30 +11:00
parent e9c8a4a049
commit adaa7b757e
No known key found for this signature in database
GPG Key ID: D36F789E45745D17
29 changed files with 1169 additions and 457 deletions

View File

@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Multilingual support
- Right-to-left (RTL) language support
- Site search powered by Fuse.js
- Automatic Markdown image resizing and srcset generation
- Performance and Accessibility improvements to achieve perfect Lighthouse scores
- Author `headline` parameter

File diff suppressed because it is too large Load Diff

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;

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;
}

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;
}

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;
}

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;
}

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;
}

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

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
assets/js/search.js 100644
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
assets/lib/fuse/fuse.min.js vendored 100644

File diff suppressed because one or more lines are too long

View File

@ -9,3 +9,6 @@ enableEmoji = true
enableRobotsTXT = true
summaryLength = 0
[outputs]
home = ["HTML", "RSS", "JSON"]

View File

@ -6,6 +6,7 @@
# https://jpanther.github.io/congo/docs/configuration/#theme-parameters
colorScheme = "congo"
enableSearch = false
# darkMode = "auto"
# darkToggle = false
# logo = "img/logo.jpg"

View File

@ -9,3 +9,6 @@ enableEmoji = true
enableRobotsTXT = true
summaryLength = 0
[outputs]
home = ["HTML", "RSS", "JSON"]

View File

@ -6,6 +6,7 @@
# https://jpanther.github.io/congo/docs/configuration/#theme-parameters
colorScheme = "congo"
enableSearch = true
# darkMode = "auto"
# darkToggle = false
# logo = "img/logo.jpg"

View File

@ -30,6 +30,11 @@ list:
externalurl_title: "Link zu einer externen Seite"
no_articles: "Es gibt hier noch keine Beiträge."
# search:
# open_button_title: "Search (/)"
# close_button_title: "Close (Esc)"
# input_placeholder: "Search"
sharing:
email: "Per E-Mail teilen"
facebook: "Auf Facebook teilen"

View File

@ -30,6 +30,11 @@ list:
externalurl_title: "Link to external site"
no_articles: "There's no articles to list here yet."
search:
open_button_title: "Search (/)"
close_button_title: "Close (Esc)"
input_placeholder: "Search"
sharing:
email: "Send via email"
facebook: "Share on Facebook"

View File

@ -30,6 +30,11 @@ list:
externalurl_title: "Link a página externa"
no_articles: "Aún no hay artículos para listar aquí."
# search:
# open_button_title: "Search (/)"
# close_button_title: "Close (Esc)"
# input_placeholder: "Search"
sharing:
email: "Enviar vía email"
facebook: "Compartir en Facebook"

View File

@ -30,6 +30,11 @@ list:
externalurl_title: "Lien d'article externe."
no_articles: "Il n'y a pas encore d'articles ici."
# search:
# open_button_title: "Search (/)"
# close_button_title: "Close (Esc)"
# input_placeholder: "Search"
sharing:
email: "Envoyer par email"
facebook: "Poster sur Facebook"

View File

@ -30,6 +30,11 @@ list:
externalurl_title: "Link para site externo"
no_articles: "Não tem artigos para lista aqui ainda."
# search:
# open_button_title: "Search (/)"
# close_button_title: "Close (Esc)"
# input_placeholder: "Search"
sharing:
email: "Enviar por email"
facebook: "Compartilhar pelo Facebook"

View File

@ -29,6 +29,11 @@ list:
externalurl_title: "链接到外部网站"
no_articles: "这里还没有任何文章可以列出。"
# search:
# open_button_title: "Search (/)"
# close_button_title: "Close (Esc)"
# input_placeholder: "Search"
sharing:
email: "通过电子邮件发送"
facebook: "分享到 Facebook"

View File

@ -17,14 +17,17 @@
<div class="absolute flex self-center">
<a
class="px-3 py-1 text-sm -translate-y-8 rounded-b-lg bg-primary-200 dark:bg-neutral-600 focus:translate-y-0"
href="#maincontent"
href="#main-content"
><span class="font-bold ltr:pr-2 rtl:pl-2 text-primary-600 dark:text-primary-400"
>&darr;</span
>{{ i18n "header.skip_to_main" }}</a
>
</div>
{{- partial "header.html" . -}}
<main id="maincontent" class="grow">{{- block "main" . }}{{- end }}</main>
<main id="main-content" class="grow">{{- block "main" . }}{{- end }}</main>
{{ if .Site.Params.enableSearch | default false }}
{{- partial "search.html" . -}}
{{ end }}
{{- partial "footer.html" . -}}
</body>
</html>

View File

@ -0,0 +1,6 @@
{{- $.Scratch.Add "index" slice -}}
{{- range .Site.RegularPages -}}
{{ $section := .Site.GetPage "section" .Section }}
{{- $.Scratch.Add "index" (dict "date" (.Date | time.Format (.Site.Language.Params.dateFormat | default ":date_long")) "title" .Title "section" $section.Title "summary" .Summary "content" (.Plain | safeJS) "permalink" .Permalink) -}}
{{- end -}}
{{- $.Scratch.Get "index" | jsonify -}}

View File

@ -42,6 +42,19 @@
>
</li>
{{ end }}
{{ if .Site.Params.enableSearch | default false }}
<li
class="ltr:text-right rtl:text-left ltr:sm:mr-7 ltr:sm:last:mr-0 rtl:sm:ml-7 rtl:sm:last:ml-0"
>
<button
id="search-button"
class="text-base hover:text-neutral-600 dark:hover:text-neutral-300"
title="{{ i18n "search.open_button_title" }}"
>
{{ partial "icon.html" "search" }}
</button>
</li>
{{ end }}
</ul>
</nav>
{{ end }}

View File

@ -0,0 +1,52 @@
{{ $fuseLib := resources.Get "lib/fuse/fuse.min.js" }}
{{ $fuseConfig := resources.Get "js/search.js" }}
{{ $fuseConfig := $fuseConfig | resources.Minify }}
{{ $fuseJS := slice $fuseLib $fuseConfig | resources.Concat "js/fuse.bundle.js" | resources.Fingerprint "sha512" -}}
<script defer type="text/javascript" src="{{ $fuseJS.RelPermalink }}" integrity="{{ $fuseJS.Data.Integrity }}" data-id="fusejs" data-url="{{ .Site.BaseURL }}"></script>
<div
id="search-wrapper"
class="fixed inset-0 z-50 flex flex-col p-4 sm:p-6 md:p-[10vh] lg:p-[12vh] w-screen h-screen cursor-default bg-neutral-500/50 backdrop-blur-sm dark:bg-neutral-900/50 invisible"
>
<div
id="search-modal"
class="flex flex-col w-full max-w-3xl min-h-0 mx-auto border rounded-md shadow-lg border-neutral-200 top-20 bg-neutral dark:bg-neutral-800 dark:border-neutral-700"
>
<header class="relative z-10 flex items-center justify-between flex-none px-2">
<form class="flex items-center flex-auto min-w-0">
<div class="flex items-center justify-center w-8 h-8 text-neutral-400">
{{ partial "icon.html" "search" }}
</div>
<input
type="search"
id="search-query"
class="flex flex-auto h-12 mx-1 bg-transparent appearance-none focus:outline-dotted focus:outline-transparent focus:outline-2"
placeholder="{{ i18n "search.input_placeholder" }}"
tabindex="0"
/>
</form>
<button
id="close-search-button"
class="flex items-center justify-center w-8 h-8 text-neutral-600"
title="{{ i18n "search.close_button_title" }}"
>
{{ partial "icon.html" "times" }}
</button>
</header>
<section class="flex-auto px-2 overflow-auto">
<ul id="search-results">
<!-- <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> -->
</ul>
</section>
</div>
</div>

18
package-lock.json generated
View File

@ -12,12 +12,13 @@
"devDependencies": {
"@tailwindcss/typography": "^0.5.0",
"chart.js": "^3.7.0",
"fuse.js": "^6.5.3",
"katex": "^0.15.1",
"mermaid": "^8.13.8",
"prettier": "^2.3.2",
"prettier-plugin-go-template": "^0.0.11",
"rimraf": "^3.0.2",
"tailwindcss": "^3.0.12",
"tailwindcss": "^3.0.13",
"vendor-copy": "^3.0.1"
}
},
@ -1411,6 +1412,15 @@
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
"node_modules/fuse.js": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.5.3.tgz",
"integrity": "sha512-sA5etGE7yD/pOqivZRBvUBd/NaL2sjAu6QuSaFoe1H2BrJSkH/T/UXAJ8CdXdw7DvY3Hs8CXKYkDWX7RiP5KOg==",
"dev": true,
"engines": {
"node": ">=10"
}
},
"node_modules/glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
@ -3400,6 +3410,12 @@
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
"fuse.js": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.5.3.tgz",
"integrity": "sha512-sA5etGE7yD/pOqivZRBvUBd/NaL2sjAu6QuSaFoe1H2BrJSkH/T/UXAJ8CdXdw7DvY3Hs8CXKYkDWX7RiP5KOg==",
"dev": true
},
"glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",

View File

@ -31,6 +31,7 @@
"devDependencies": {
"@tailwindcss/typography": "^0.5.0",
"chart.js": "^3.7.0",
"fuse.js": "^6.5.3",
"katex": "^0.15.1",
"mermaid": "^8.13.8",
"prettier": "^2.3.2",
@ -64,6 +65,10 @@
{
"from": "node_modules/katex/dist/fonts/",
"to": "assets/lib/katex/fonts/"
},
{
"from": "node_modules/fuse.js/dist/fuse.min.js",
"to": "assets/lib/fuse/fuse.min.js"
}
]
}

View File

@ -1,5 +1,14 @@
const colors = require("tailwindcss/colors");
function varWithOpacity(variable) {
return ({ opacityValue }) => {
if (opacityValue === undefined) {
return `rgb(var(${variable}))`;
}
return `rgba(var(${variable}), ${opacityValue})`;
};
}
module.exports = {
content: [
"./layouts/**/*.html",
@ -9,47 +18,47 @@ module.exports = {
],
darkMode: "class",
theme: {
colors: {
transparent: "transparent",
neutral: {
DEFAULT: "var(--color-neutral)",
50: "var(--color-neutral-50)",
100: "var(--color-neutral-100)",
200: "var(--color-neutral-200)",
300: "var(--color-neutral-300)",
400: "var(--color-neutral-400)",
500: "var(--color-neutral-500)",
600: "var(--color-neutral-600)",
700: "var(--color-neutral-700)",
800: "var(--color-neutral-800)",
900: "var(--color-neutral-900)",
},
primary: {
50: "var(--color-primary-50)",
100: "var(--color-primary-100)",
200: "var(--color-primary-200)",
300: "var(--color-primary-300)",
400: "var(--color-primary-400)",
500: "var(--color-primary-500)",
600: "var(--color-primary-600)",
700: "var(--color-primary-700)",
800: "var(--color-primary-800)",
900: "var(--color-primary-900)",
},
secondary: {
50: "var(--color-secondary-50)",
100: "var(--color-secondary-100)",
200: "var(--color-secondary-200)",
300: "var(--color-secondary-300)",
400: "var(--color-secondary-400)",
500: "var(--color-secondary-500)",
600: "var(--color-secondary-600)",
700: "var(--color-secondary-700)",
800: "var(--color-secondary-800)",
900: "var(--color-secondary-900)",
},
},
extend: {
colors: {
transparent: "transparent",
neutral: {
DEFAULT: varWithOpacity("--color-neutral"),
50: varWithOpacity("--color-neutral-50"),
100: varWithOpacity("--color-neutral-100"),
200: varWithOpacity("--color-neutral-200"),
300: varWithOpacity("--color-neutral-300"),
400: varWithOpacity("--color-neutral-400"),
500: varWithOpacity("--color-neutral-500"),
600: varWithOpacity("--color-neutral-600"),
700: varWithOpacity("--color-neutral-700"),
800: varWithOpacity("--color-neutral-800"),
900: varWithOpacity("--color-neutral-900"),
},
primary: {
50: varWithOpacity("--color-primary-50"),
100: varWithOpacity("--color-primary-100"),
200: varWithOpacity("--color-primary-200"),
300: varWithOpacity("--color-primary-300"),
400: varWithOpacity("--color-primary-400"),
500: varWithOpacity("--color-primary-500"),
600: varWithOpacity("--color-primary-600"),
700: varWithOpacity("--color-primary-700"),
800: varWithOpacity("--color-primary-800"),
900: varWithOpacity("--color-primary-900"),
},
secondary: {
50: varWithOpacity("--color-secondary-50"),
100: varWithOpacity("--color-secondary-100"),
200: varWithOpacity("--color-secondary-200"),
300: varWithOpacity("--color-secondary-300"),
400: varWithOpacity("--color-secondary-400"),
500: varWithOpacity("--color-secondary-500"),
600: varWithOpacity("--color-secondary-600"),
700: varWithOpacity("--color-secondary-700"),
800: varWithOpacity("--color-secondary-800"),
900: varWithOpacity("--color-secondary-900"),
},
},
typography: (theme) => ({
DEFAULT: {
css: [