Initial Release
This commit is contained in:
15
assets/css/paginator.css
Normal file
15
assets/css/paginator.css
Normal file
@ -0,0 +1,15 @@
|
||||
.pagination {
|
||||
@apply inline-flex border rounded px-1 dark:border-gray-600;
|
||||
}
|
||||
.page-item {
|
||||
@apply mx-0.5 my-1 cursor-pointer rounded hover:bg-gray-800 hover:text-white dark:hover:bg-gray-500 dark:hover:text-white;
|
||||
}
|
||||
a.page-link {
|
||||
@apply px-3 py-1 block;
|
||||
}
|
||||
.page-item.active {
|
||||
@apply bg-gray-800 text-white dark:bg-gray-300 dark:text-gray-900;
|
||||
}
|
||||
.page-item.disabled {
|
||||
@apply text-gray-400 hover:bg-transparent hover:text-gray-400 cursor-not-allowed;
|
||||
}
|
13
assets/css/postcss.config.js
Normal file
13
assets/css/postcss.config.js
Normal file
@ -0,0 +1,13 @@
|
||||
const themeDir = __dirname + "/../../";
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
require("postcss-import")({
|
||||
path: [themeDir],
|
||||
}),
|
||||
require("tailwindcss")(themeDir + "assets/css/tailwind.config.js"),
|
||||
require("autoprefixer")({
|
||||
path: [themeDir],
|
||||
}),
|
||||
],
|
||||
};
|
55
assets/css/site.css
Normal file
55
assets/css/site.css
Normal file
@ -0,0 +1,55 @@
|
||||
/* Custom Styles */
|
||||
body {
|
||||
font-family: "Inter", sans-serif;
|
||||
}
|
||||
|
||||
/* Fonts */
|
||||
|
||||
/* inter-300 - latin */
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: url("/fonts/inter-v3-latin-300.eot"); /* IE9 Compat Modes */
|
||||
src: local(""),
|
||||
url("/fonts/inter-v3-latin-300.eot?#iefix") format("embedded-opentype"),
|
||||
/* IE6-IE8 */ url("/fonts/inter-v3-latin-300.woff2") format("woff2"),
|
||||
/* Super Modern Browsers */ url("/fonts/inter-v3-latin-300.woff")
|
||||
format("woff"),
|
||||
/* Modern Browsers */ url("/fonts/inter-v3-latin-300.ttf")
|
||||
format("truetype"),
|
||||
/* Safari, Android, iOS */ url("/fonts/inter-v3-latin-300.svg#Inter")
|
||||
format("svg"); /* Legacy iOS */
|
||||
}
|
||||
/* inter-500 - latin */
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url("/fonts/inter-v3-latin-500.eot"); /* IE9 Compat Modes */
|
||||
src: local(""),
|
||||
url("/fonts/inter-v3-latin-500.eot?#iefix") format("embedded-opentype"),
|
||||
/* IE6-IE8 */ url("/fonts/inter-v3-latin-500.woff2") format("woff2"),
|
||||
/* Super Modern Browsers */ url("/fonts/inter-v3-latin-500.woff")
|
||||
format("woff"),
|
||||
/* Modern Browsers */ url("/fonts/inter-v3-latin-500.ttf")
|
||||
format("truetype"),
|
||||
/* Safari, Android, iOS */ url("/fonts/inter-v3-latin-500.svg#Inter")
|
||||
format("svg"); /* Legacy iOS */
|
||||
}
|
||||
/* inter-700 - latin */
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: url("/fonts/inter-v3-latin-700.eot"); /* IE9 Compat Modes */
|
||||
src: local(""),
|
||||
url("/fonts/inter-v3-latin-700.eot?#iefix") format("embedded-opentype"),
|
||||
/* IE6-IE8 */ url("/fonts/inter-v3-latin-700.woff2") format("woff2"),
|
||||
/* Super Modern Browsers */ url("/fonts/inter-v3-latin-700.woff")
|
||||
format("woff"),
|
||||
/* Modern Browsers */ url("/fonts/inter-v3-latin-700.ttf")
|
||||
format("truetype"),
|
||||
/* Safari, Android, iOS */ url("/fonts/inter-v3-latin-700.svg#Inter")
|
||||
format("svg"); /* Legacy iOS */
|
||||
}
|
55
assets/css/styles.css
Normal file
55
assets/css/styles.css
Normal file
@ -0,0 +1,55 @@
|
||||
/* Tailwind base - put variables under: tailwind.config.js */
|
||||
@import "node_modules/tailwindcss/base";
|
||||
/* Tailwind component classes registered by plugins*/
|
||||
@import "node_modules/tailwindcss/components";
|
||||
/* Site Specific */
|
||||
@import "assets/css/site";
|
||||
/* Paginator */
|
||||
@import "assets/css/paginator";
|
||||
/* Tailwind's utility classes - generated based on config file */
|
||||
@import "node_modules/tailwindcss/utilities";
|
||||
|
||||
@layer components {
|
||||
details.toc[open] summary ~ * {
|
||||
animation: slideUp 0.25s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes slideUp {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
details.toc[open] summary svg {
|
||||
@apply transform duration-200 rotate-180 ease-in-out;
|
||||
}
|
||||
|
||||
details.toc > ul {
|
||||
@apply ml-4;
|
||||
}
|
||||
|
||||
details.toc ul {
|
||||
@apply list-none;
|
||||
margin-top: 0.125rem /* 2px */ !important;
|
||||
margin-bottom: 0.125rem /* 2px */ !important;
|
||||
}
|
||||
details.toc ul li {
|
||||
margin-top: 0.125rem /* 2px */ !important;
|
||||
margin-bottom: 0.125rem /* 2px */ !important;
|
||||
}
|
||||
details.toc ul li:before {
|
||||
@apply rounded-none bg-gray-400;
|
||||
}
|
||||
details.toc ul li a {
|
||||
@apply no-underline text-gray-700 dark:text-gray-200 text-base;
|
||||
}
|
||||
|
||||
a:empty {
|
||||
display: none;
|
||||
}
|
||||
}
|
110
assets/css/tailwind.config.js
Normal file
110
assets/css/tailwind.config.js
Normal file
@ -0,0 +1,110 @@
|
||||
const themeDir = __dirname + "/../../";
|
||||
|
||||
module.exports = {
|
||||
purge: {
|
||||
enabled: process.env.HUGO_ENVIRONMENT === "production",
|
||||
content: [
|
||||
themeDir + "layouts/**/*.html",
|
||||
themeDir + "content/**/*.html",
|
||||
"layouts/**/*.html",
|
||||
"config.toml",
|
||||
"content/**/*.html",
|
||||
"assets/js/search.js",
|
||||
"exampleSite/layouts/**/*.html",
|
||||
"exampleSite/config.toml",
|
||||
"exampleSite/content/**/*.html",
|
||||
],
|
||||
},
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
typography: (theme) => ({
|
||||
DEFAULT: {
|
||||
css: [
|
||||
{
|
||||
'code::before': {
|
||||
content: '""',
|
||||
},
|
||||
'code::after': {
|
||||
content: '""',
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
dark: {
|
||||
css: [
|
||||
{
|
||||
color: theme("colors.gray.400"),
|
||||
'[class~="lead"]': {
|
||||
color: theme("colors.gray.300"),
|
||||
},
|
||||
a: {
|
||||
color: theme("colors.white"),
|
||||
},
|
||||
strong: {
|
||||
color: theme("colors.white"),
|
||||
},
|
||||
"ol > li::before": {
|
||||
color: theme("colors.gray.400"),
|
||||
},
|
||||
"ul > li::before": {
|
||||
backgroundColor: theme("colors.gray.600"),
|
||||
},
|
||||
hr: {
|
||||
borderColor: theme("colors.gray.200"),
|
||||
},
|
||||
blockquote: {
|
||||
color: theme("colors.gray.200"),
|
||||
borderLeftColor: theme("colors.gray.600"),
|
||||
},
|
||||
h1: {
|
||||
color: theme("colors.white"),
|
||||
},
|
||||
h2: {
|
||||
color: theme("colors.white"),
|
||||
},
|
||||
h3: {
|
||||
color: theme("colors.white"),
|
||||
},
|
||||
h4: {
|
||||
color: theme("colors.white"),
|
||||
},
|
||||
"figure figcaption": {
|
||||
color: theme("colors.gray.400"),
|
||||
},
|
||||
code: {
|
||||
color: theme("colors.white"),
|
||||
},
|
||||
"a code": {
|
||||
color: theme("colors.white"),
|
||||
},
|
||||
'code::before': {
|
||||
content: '""',
|
||||
},
|
||||
'code::after': {
|
||||
content: '""',
|
||||
},
|
||||
pre: {
|
||||
color: theme("colors.gray.200"),
|
||||
backgroundColor: theme("colors.gray.800"),
|
||||
},
|
||||
thead: {
|
||||
color: theme("colors.white"),
|
||||
borderBottomColor: theme("colors.gray.400"),
|
||||
},
|
||||
"tbody tr": {
|
||||
borderBottomColor: theme("colors.gray.600"),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
variants: {
|
||||
extend: {
|
||||
typography: ["dark"],
|
||||
},
|
||||
},
|
||||
plugins: [require("@tailwindcss/typography")],
|
||||
};
|
9
assets/js/fuse.min.js
vendored
Normal file
9
assets/js/fuse.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
174
assets/js/search.js
Normal file
174
assets/js/search.js
Normal file
@ -0,0 +1,174 @@
|
||||
// Credits to search implementation: https://gist.github.com/cmod/5410eae147e4318164258742dd053993
|
||||
|
||||
var fuse; // holds our search engine
|
||||
var searchVisible = false;
|
||||
var firstRun = true; // allow us to delay loading json data unless search activated
|
||||
var list = document.querySelector('.search-list'); // targets the <ul>
|
||||
var first = list.firstChild; // first child of search list
|
||||
var last = list.lastChild; // last child of search list
|
||||
var maininput = document.querySelector('.search-ui input'); // input box for search
|
||||
var searchResultsHeading = document.querySelector('.search-results'); // input box for search
|
||||
var noResults = document.querySelector('.no-results'); // input box for search
|
||||
var resultsAvailable = false; // Did we get any search results?
|
||||
|
||||
// ==========================================
|
||||
// The main keyboard event listener running the show
|
||||
//
|
||||
document.querySelector('.open-search').addEventListener('click', openSearch);
|
||||
document.querySelector('.close-search').addEventListener('click', closeSearch);
|
||||
|
||||
function closeSearch() {
|
||||
document.querySelector('.search-ui').classList.add("hidden");
|
||||
document.activeElement.blur(); // remove focus from search box
|
||||
searchVisible = false; // search not visible
|
||||
searchResultsHeading.classList.add('hidden');
|
||||
}
|
||||
|
||||
function openSearch() {
|
||||
// Load json search index if first time invoking search
|
||||
// Means we don't load json unless searches are going to happen; keep user payload small unless needed
|
||||
if (firstRun) {
|
||||
loadSearch(); // loads our json data and builds fuse.js search index
|
||||
firstRun = false; // let's never do this again
|
||||
}
|
||||
|
||||
//Close the mobile menu when search is click.
|
||||
mobileMenu.classList.toggle('hidden');
|
||||
|
||||
// Toggle visibility of search box
|
||||
if (!searchVisible) {
|
||||
document.querySelector('.search-ui').classList.remove("hidden");
|
||||
document.querySelector('.search-ui input').focus(); // put focus in input box so you can just start typing
|
||||
searchVisible = true; // search visible
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', function (event) {
|
||||
|
||||
if (event.metaKey && event.which === 191) {
|
||||
openSearch()
|
||||
}
|
||||
|
||||
// Allow ESC (27) to close search box
|
||||
if (event.keyCode == 27) {
|
||||
if (searchVisible) {
|
||||
document.querySelector('.search-ui').classList.add("hidden");
|
||||
document.activeElement.blur();
|
||||
searchVisible = false;
|
||||
searchResultsHeading.classList.add('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
// DOWN (40) arrow
|
||||
if (event.keyCode == 40) {
|
||||
if (searchVisible && resultsAvailable) {
|
||||
console.log("down");
|
||||
event.preventDefault(); // stop window from scrolling
|
||||
if (document.activeElement == maininput) { first.focus(); } // if the currently focused element is the main input --> focus the first <li>
|
||||
else if (document.activeElement == last) { last.focus(); } // if we're at the bottom, stay there
|
||||
else { document.activeElement.parentElement.nextSibling.firstElementChild.focus(); } // otherwise select the next search result
|
||||
}
|
||||
}
|
||||
|
||||
// UP (38) arrow
|
||||
if (event.keyCode == 38) {
|
||||
if (searchVisible && resultsAvailable) {
|
||||
event.preventDefault(); // stop window from scrolling
|
||||
if (document.activeElement == maininput) { maininput.focus(); } // If we're in the input box, do nothing
|
||||
else if (document.activeElement == first) { maininput.focus(); } // If we're at the first item, go to input box
|
||||
else { document.activeElement.parentElement.previousSibling.firstElementChild.focus(); } // Otherwise, select the search result above the current active one
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
// ==========================================
|
||||
// execute search as each character is typed
|
||||
//
|
||||
document.querySelector('.search-ui input').onkeyup = function (e) {
|
||||
executeSearch(this.value);
|
||||
}
|
||||
|
||||
|
||||
// ==========================================
|
||||
// fetch some json without jquery
|
||||
//
|
||||
function fetchJSONFile(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();
|
||||
}
|
||||
|
||||
|
||||
// ==========================================
|
||||
// load our search index, only executed once
|
||||
// on first call of search box (CMD-/)
|
||||
//
|
||||
function loadSearch() {
|
||||
const lang = document.querySelector('head > meta[name="lang"]')?.getAttribute?.('content')
|
||||
fetchJSONFile(`${lang ? "/" + lang : ""}/index.json`, function (data) {
|
||||
|
||||
var options = { // fuse.js options; check fuse.js website for details
|
||||
shouldSort: true,
|
||||
location: 0,
|
||||
distance: 100,
|
||||
threshold: 0.4,
|
||||
minMatchCharLength: 2,
|
||||
keys: [
|
||||
'title',
|
||||
'permalink',
|
||||
'contents'
|
||||
]
|
||||
};
|
||||
fuse = new Fuse(data, options); // build the index from the json file
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// ==========================================
|
||||
// using the index we loaded on CMD-/, run
|
||||
// a search query (for "term") every time a letter is typed
|
||||
// in the search box
|
||||
//
|
||||
function executeSearch(term) {
|
||||
let results = fuse.search(term); // the actual query being run using fuse.js
|
||||
let searchitems = ''; // our results bucket
|
||||
|
||||
if (results.length === 0) { // no results based on what was typed into the input box
|
||||
resultsAvailable = false;
|
||||
searchitems = '';
|
||||
if (term !== "") {
|
||||
noResults.classList.remove('hidden')
|
||||
} else {
|
||||
noResults.classList.add('hidden')
|
||||
}
|
||||
} else { // build our html
|
||||
noResults.classList.add('hidden')
|
||||
if (term !== "") {
|
||||
searchResultsHeading.classList.remove('hidden');
|
||||
}
|
||||
|
||||
for (let item in results.slice(0, 5)) { // only show first 5 results
|
||||
const title = '<div class="text-2xl mb-2 font-bold">' + results[item].item.title + '</div>';
|
||||
const date = results[item].item.date ? '<div><em class="px-4">' + new Date(results[item].item.date).toUTCString().substring(0, 16) + '</em></div>' : '';
|
||||
const contents = '<div class="prose px-4">' + results[item].item.contents + '</div>';
|
||||
|
||||
searchitems = searchitems + '<li><a class="block mb-2 px-4 py-2 rounded pb-2 border-b border-gray-200 dark:border-gray-600 focus:bg-gray-100 dark:focus:bg-gray-700 focus:outline-none" href="' + results[item].item.permalink + '" tabindex="0">' + title + '</a>' + date + contents + '</li>';
|
||||
}
|
||||
resultsAvailable = true;
|
||||
}
|
||||
|
||||
list.innerHTML = searchitems;
|
||||
if (results.length > 0) {
|
||||
first = list.firstChild.firstElementChild; // first result container — used for checking against keyboard up/down location
|
||||
last = list.lastChild.firstElementChild; // last result container — used for checking against keyboard up/down location
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user