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 - Multilingual support
- Right-to-left (RTL) language support - Right-to-left (RTL) language support
- Site search powered by Fuse.js
- Automatic Markdown image resizing and srcset generation - Automatic Markdown image resizing and srcset generation
- Performance and Accessibility improvements to achieve perfect Lighthouse scores - Performance and Accessibility improvements to achieve perfect Lighthouse scores
- Author `headline` parameter - Author `headline` parameter

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,14 @@ body button {
width: 1em; 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 */ /* Heading anchors */
.prose .heading-anchor { .prose .heading-anchor {
@apply absolute top-0 no-underline opacity-0; @apply absolute top-0 no-underline opacity-0;

View File

@ -1,37 +1,37 @@
/* Avocado scheme */ /* Avocado scheme */
:root { :root {
--color-neutral: #fff; --color-neutral: 255, 255, 255;
/* Stone */ /* Stone */
--color-neutral-50: #fafaf9; --color-neutral-50: 250, 250, 249;
--color-neutral-100: #f5f5f4; --color-neutral-100: 245, 245, 244;
--color-neutral-200: #e7e5e4; --color-neutral-200: 231, 229, 228;
--color-neutral-300: #d6d3d1; --color-neutral-300: 214, 211, 209;
--color-neutral-400: #a8a29e; --color-neutral-400: 168, 162, 158;
--color-neutral-500: #78716c; --color-neutral-500: 120, 113, 108;
--color-neutral-600: #57534e; --color-neutral-600: 87, 83, 78;
--color-neutral-700: #44403c; --color-neutral-700: 68, 64, 60;
--color-neutral-800: #292524; --color-neutral-800: 41, 37, 36;
--color-neutral-900: #1c1917; --color-neutral-900: 28, 25, 23;
/* Lime */ /* Lime */
--color-primary-50: #f7fee7; --color-primary-50: 247, 254, 231;
--color-primary-100: #ecfccb; --color-primary-100: 236, 252, 203;
--color-primary-200: #d9f99d; --color-primary-200: 217, 249, 157;
--color-primary-300: #bef264; --color-primary-300: 190, 242, 100;
--color-primary-400: #a3e635; --color-primary-400: 163, 230, 53;
--color-primary-500: #84cc16; --color-primary-500: 132, 204, 22;
--color-primary-600: #65a30d; --color-primary-600: 101, 163, 13;
--color-primary-700: #4d7c0f; --color-primary-700: 77, 124, 15;
--color-primary-800: #3f6212; --color-primary-800: 63, 98, 18;
--color-primary-900: #365314; --color-primary-900: 54, 83, 20;
/* Emerald */ /* Emerald */
--color-secondary-50: #ecfdf5; --color-secondary-50: 236, 253, 245;
--color-secondary-100: #d1fae5; --color-secondary-100: 209, 250, 229;
--color-secondary-200: #a7f3d0; --color-secondary-200: 167, 243, 208;
--color-secondary-300: #6ee7b7; --color-secondary-300: 110, 231, 183;
--color-secondary-400: #34d399; --color-secondary-400: 52, 211, 153;
--color-secondary-500: #10b981; --color-secondary-500: 16, 185, 129;
--color-secondary-600: #059669; --color-secondary-600: 5, 150, 105;
--color-secondary-700: #047857; --color-secondary-700: 4, 120, 87;
--color-secondary-800: #065f46; --color-secondary-800: 6, 95, 70;
--color-secondary-900: #064e3b; --color-secondary-900: 6, 78, 59;
} }

View File

@ -1,37 +1,37 @@
/* Congo scheme */ /* Congo scheme */
:root { :root {
--color-neutral: #fff; --color-neutral: 255, 255, 255;
/* Gray */ /* Gray */
--color-neutral-50: #fafafa; --color-neutral-50: 250, 250, 250;
--color-neutral-100: #f4f4f5; --color-neutral-100: 244, 244, 245;
--color-neutral-200: #e4e4e7; --color-neutral-200: 228, 228, 231;
--color-neutral-300: #d4d4d8; --color-neutral-300: 212, 212, 216;
--color-neutral-400: #a1a1aa; --color-neutral-400: 161, 161, 170;
--color-neutral-500: #71717a; --color-neutral-500: 113, 113, 122;
--color-neutral-600: #52525b; --color-neutral-600: 82, 82, 91;
--color-neutral-700: #3f3f46; --color-neutral-700: 63, 63, 70;
--color-neutral-800: #27272a; --color-neutral-800: 39, 39, 42;
--color-neutral-900: #18181b; --color-neutral-900: 24, 24, 27;
/* Violet */ /* Violet */
--color-primary-50: #f5f3ff; --color-primary-50: 245, 243, 255;
--color-primary-100: #ede9fe; --color-primary-100: 237, 233, 254;
--color-primary-200: #ddd6fe; --color-primary-200: 221, 214, 254;
--color-primary-300: #c4b5fd; --color-primary-300: 196, 181, 253;
--color-primary-400: #a78bfa; --color-primary-400: 167, 139, 250;
--color-primary-500: #8b5cf6; --color-primary-500: 139, 92, 246;
--color-primary-600: #7c3aed; --color-primary-600: 124, 58, 237;
--color-primary-700: #6d28d9; --color-primary-700: 109, 40, 217;
--color-primary-800: #5b21b6; --color-primary-800: 91, 33, 182;
--color-primary-900: #4c1d95; --color-primary-900: 76, 29, 149;
/* Fuchsia */ /* Fuchsia */
--color-secondary-50: #fdf4ff; --color-secondary-50: 253, 244, 255;
--color-secondary-100: #fae8ff; --color-secondary-100: 250, 232, 255;
--color-secondary-200: #f5d0fe; --color-secondary-200: 245, 208, 254;
--color-secondary-300: #f0abfc; --color-secondary-300: 240, 171, 252;
--color-secondary-400: #e879f9; --color-secondary-400: 232, 121, 249;
--color-secondary-500: #d946ef; --color-secondary-500: 217, 70, 239;
--color-secondary-600: #c026d3; --color-secondary-600: 192, 38, 211;
--color-secondary-700: #a21caf; --color-secondary-700: 162, 28, 175;
--color-secondary-800: #86198f; --color-secondary-800: 134, 25, 143;
--color-secondary-900: #701a75; --color-secondary-900: 112, 26, 117;
} }

View File

@ -1,37 +1,37 @@
/* Fire scheme */ /* Fire scheme */
:root { :root {
--color-neutral: #fff; --color-neutral: 255, 255, 255;
/* Stone */ /* Stone */
--color-neutral-50: #fafaf9; --color-neutral-50: 250, 250, 249;
--color-neutral-100: #f5f5f4; --color-neutral-100: 245, 245, 244;
--color-neutral-200: #e7e5e4; --color-neutral-200: 231, 229, 228;
--color-neutral-300: #d6d3d1; --color-neutral-300: 214, 211, 209;
--color-neutral-400: #a8a29e; --color-neutral-400: 168, 162, 158;
--color-neutral-500: #78716c; --color-neutral-500: 120, 113, 108;
--color-neutral-600: #57534e; --color-neutral-600: 87, 83, 78;
--color-neutral-700: #44403c; --color-neutral-700: 68, 64, 60;
--color-neutral-800: #292524; --color-neutral-800: 41, 37, 36;
--color-neutral-900: #1c1917; --color-neutral-900: 28, 25, 23;
/* Orange */ /* Orange */
--color-primary-50: #fff7ed; --color-primary-50: 255, 247, 237;
--color-primary-100: #ffedd5; --color-primary-100: 255, 237, 213;
--color-primary-200: #fed7aa; --color-primary-200: 254, 215, 170;
--color-primary-300: #fdba74; --color-primary-300: 253, 186, 116;
--color-primary-400: #fb923c; --color-primary-400: 251, 146, 60;
--color-primary-500: #f97316; --color-primary-500: 249, 115, 22;
--color-primary-600: #ea580c; --color-primary-600: 234, 88, 12;
--color-primary-700: #c2410c; --color-primary-700: 194, 65, 12;
--color-primary-800: #9a3412; --color-primary-800: 154, 52, 18;
--color-primary-900: #7c2d12; --color-primary-900: 124, 45, 18;
/* Rose */ /* Rose */
--color-secondary-50: #fff1f2; --color-secondary-50: 255, 241, 242;
--color-secondary-100: #ffe4e6; --color-secondary-100: 255, 228, 230;
--color-secondary-200: #fecdd3; --color-secondary-200: 254, 205, 211;
--color-secondary-300: #fda4af; --color-secondary-300: 253, 164, 175;
--color-secondary-400: #fb7185; --color-secondary-400: 251, 113, 133;
--color-secondary-500: #f43f5e; --color-secondary-500: 244, 63, 94;
--color-secondary-600: #e11d48; --color-secondary-600: 225, 29, 72;
--color-secondary-700: #be123c; --color-secondary-700: 190, 18, 60;
--color-secondary-800: #9f1239; --color-secondary-800: 159, 18, 57;
--color-secondary-900: #881337; --color-secondary-900: 136, 19, 55;
} }

View File

@ -1,37 +1,37 @@
/* Ocean scheme */ /* Ocean scheme */
:root { :root {
--color-neutral: #fff; --color-neutral: 255, 255, 255;
/* Gray */ /* Gray */
--color-neutral-50: #f8fafc; --color-neutral-50: 248, 250, 252;
--color-neutral-100: #f1f5f9; --color-neutral-100: 241, 245, 249;
--color-neutral-200: #e2e8f0; --color-neutral-200: 226, 232, 240;
--color-neutral-300: #cbd5e1; --color-neutral-300: 203, 213, 225;
--color-neutral-400: #94a3b8; --color-neutral-400: 148, 163, 184;
--color-neutral-500: #64748b; --color-neutral-500: 100, 116, 139;
--color-neutral-600: #475569; --color-neutral-600: 71, 85, 105;
--color-neutral-700: #334155; --color-neutral-700: 51, 65, 85;
--color-neutral-800: #1e293b; --color-neutral-800: 30, 41, 59;
--color-neutral-900: #0f172a; --color-neutral-900: 15, 23, 42;
/* Blue */ /* Blue */
--color-primary-50: #eff6ff; --color-primary-50: 239, 246, 255;
--color-primary-100: #dbeafe; --color-primary-100: 219, 234, 254;
--color-primary-200: #bfdbfe; --color-primary-200: 191, 219, 254;
--color-primary-300: #93c5fd; --color-primary-300: 147, 197, 253;
--color-primary-400: #60a5fa; --color-primary-400: 96, 165, 250;
--color-primary-500: #3b82f6; --color-primary-500: 59, 130, 246;
--color-primary-600: #2563eb; --color-primary-600: 37, 99, 235;
--color-primary-700: #1d4ed8; --color-primary-700: 29, 78, 216;
--color-primary-800: #1e40af; --color-primary-800: 30, 64, 175;
--color-primary-900: #1e3a8a; --color-primary-900: 30, 58, 138;
/* Cyan */ /* Cyan */
--color-secondary-50: #ecfeff; --color-secondary-50: 236, 254, 255;
--color-secondary-100: #cffafe; --color-secondary-100: 207, 250, 254;
--color-secondary-200: #a5f3fc; --color-secondary-200: 165, 243, 252;
--color-secondary-300: #67e8f9; --color-secondary-300: 103, 232, 249;
--color-secondary-400: #22d3ee; --color-secondary-400: 34, 211, 238;
--color-secondary-500: #06b6d4; --color-secondary-500: 6, 182, 212;
--color-secondary-600: #0891b2; --color-secondary-600: 8, 145, 178;
--color-secondary-700: #0e7490; --color-secondary-700: 14, 116, 144;
--color-secondary-800: #155e75; --color-secondary-800: 21, 94, 117;
--color-secondary-900: #164e63; --color-secondary-900: 22, 78, 99;
} }

View File

@ -1,37 +1,37 @@
/* Slate scheme */ /* Slate scheme */
:root { :root {
--color-neutral: #fff; --color-neutral: 255, 255, 255;
/* Gray */ /* Gray */
--color-neutral-50: #f9fafb; --color-neutral-50: 249, 250, 251;
--color-neutral-100: #f3f4f6; --color-neutral-100: 243, 244, 246;
--color-neutral-200: #e5e7eb; --color-neutral-200: 229, 231, 235;
--color-neutral-300: #d1d5db; --color-neutral-300: 209, 213, 219;
--color-neutral-400: #9ca3af; --color-neutral-400: 156, 163, 175;
--color-neutral-500: #6b7280; --color-neutral-500: 107, 114, 128;
--color-neutral-600: #4b5563; --color-neutral-600: 75, 85, 99;
--color-neutral-700: #374151; --color-neutral-700: 55, 65, 81;
--color-neutral-800: #1f2937; --color-neutral-800: 31, 41, 55;
--color-neutral-900: #111827; --color-neutral-900: 17, 24, 39;
/* Gray */ /* Gray */
--color-primary-50: #f9fafb; --color-primary-50: 249, 250, 251;
--color-primary-100: #f3f4f6; --color-primary-100: 243, 244, 246;
--color-primary-200: #e5e7eb; --color-primary-200: 229, 231, 235;
--color-primary-300: #d1d5db; --color-primary-300: 209, 213, 219;
--color-primary-400: #9ca3af; --color-primary-400: 156, 163, 175;
--color-primary-500: #6b7280; --color-primary-500: 107, 114, 128;
--color-primary-600: #4b5563; --color-primary-600: 75, 85, 99;
--color-primary-700: #374151; --color-primary-700: 55, 65, 81;
--color-primary-800: #1f2937; --color-primary-800: 31, 41, 55;
--color-primary-900: #111827; --color-primary-900: 17, 24, 39;
/* Gray */ /* Gray */
--color-secondary-50: #f9fafb; --color-secondary-50: 249, 250, 251;
--color-secondary-100: #f3f4f6; --color-secondary-100: 243, 244, 246;
--color-secondary-200: #e5e7eb; --color-secondary-200: 229, 231, 235;
--color-secondary-300: #d1d5db; --color-secondary-300: 209, 213, 219;
--color-secondary-400: #9ca3af; --color-secondary-400: 156, 163, 175;
--color-secondary-500: #6b7280; --color-secondary-500: 107, 114, 128;
--color-secondary-600: #4b5563; --color-secondary-600: 75, 85, 99;
--color-secondary-700: #374151; --color-secondary-700: 55, 65, 81;
--color-secondary-800: #1f2937; --color-secondary-800: 31, 41, 55;
--color-secondary-900: #111827; --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 enableRobotsTXT = true
summaryLength = 0 summaryLength = 0
[outputs]
home = ["HTML", "RSS", "JSON"]

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -30,6 +30,11 @@ list:
externalurl_title: "Link a página externa" externalurl_title: "Link a página externa"
no_articles: "Aún no hay artículos para listar aquí." 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: sharing:
email: "Enviar vía email" email: "Enviar vía email"
facebook: "Compartir en Facebook" facebook: "Compartir en Facebook"

View File

@ -30,6 +30,11 @@ list:
externalurl_title: "Lien d'article externe." externalurl_title: "Lien d'article externe."
no_articles: "Il n'y a pas encore d'articles ici." 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: sharing:
email: "Envoyer par email" email: "Envoyer par email"
facebook: "Poster sur Facebook" facebook: "Poster sur Facebook"

View File

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

View File

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

View File

@ -17,14 +17,17 @@
<div class="absolute flex self-center"> <div class="absolute flex self-center">
<a <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" 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" ><span class="font-bold ltr:pr-2 rtl:pl-2 text-primary-600 dark:text-primary-400"
>&darr;</span >&darr;</span
>{{ i18n "header.skip_to_main" }}</a >{{ i18n "header.skip_to_main" }}</a
> >
</div> </div>
{{- partial "header.html" . -}} {{- 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" . -}} {{- partial "footer.html" . -}}
</body> </body>
</html> </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> </li>
{{ end }} {{ 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> </ul>
</nav> </nav>
{{ end }} {{ 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": { "devDependencies": {
"@tailwindcss/typography": "^0.5.0", "@tailwindcss/typography": "^0.5.0",
"chart.js": "^3.7.0", "chart.js": "^3.7.0",
"fuse.js": "^6.5.3",
"katex": "^0.15.1", "katex": "^0.15.1",
"mermaid": "^8.13.8", "mermaid": "^8.13.8",
"prettier": "^2.3.2", "prettier": "^2.3.2",
"prettier-plugin-go-template": "^0.0.11", "prettier-plugin-go-template": "^0.0.11",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"tailwindcss": "^3.0.12", "tailwindcss": "^3.0.13",
"vendor-copy": "^3.0.1" "vendor-copy": "^3.0.1"
} }
}, },
@ -1411,6 +1412,15 @@
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true "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": { "node_modules/glob": {
"version": "7.2.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
@ -3400,6 +3410,12 @@
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true "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": { "glob": {
"version": "7.2.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",

View File

@ -31,6 +31,7 @@
"devDependencies": { "devDependencies": {
"@tailwindcss/typography": "^0.5.0", "@tailwindcss/typography": "^0.5.0",
"chart.js": "^3.7.0", "chart.js": "^3.7.0",
"fuse.js": "^6.5.3",
"katex": "^0.15.1", "katex": "^0.15.1",
"mermaid": "^8.13.8", "mermaid": "^8.13.8",
"prettier": "^2.3.2", "prettier": "^2.3.2",
@ -64,6 +65,10 @@
{ {
"from": "node_modules/katex/dist/fonts/", "from": "node_modules/katex/dist/fonts/",
"to": "assets/lib/katex/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"); const colors = require("tailwindcss/colors");
function varWithOpacity(variable) {
return ({ opacityValue }) => {
if (opacityValue === undefined) {
return `rgb(var(${variable}))`;
}
return `rgba(var(${variable}), ${opacityValue})`;
};
}
module.exports = { module.exports = {
content: [ content: [
"./layouts/**/*.html", "./layouts/**/*.html",
@ -9,47 +18,47 @@ module.exports = {
], ],
darkMode: "class", darkMode: "class",
theme: { 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: { 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) => ({ typography: (theme) => ({
DEFAULT: { DEFAULT: {
css: [ css: [