Add option to highlight current entry

Fixes #2.
This commit is contained in:
Florine W. Dekker 2020-07-20 12:54:32 +02:00
parent 91e77ab3a5
commit 81fff6c7e9
Signed by: FWDekker
GPG Key ID: B1B567AF58D6EE0F
5 changed files with 53 additions and 34 deletions

BIN
package-lock.json generated

Binary file not shown.

View File

@ -1,6 +1,6 @@
{
"name": "@fwdekker/template",
"version": "0.0.17",
"version": "0.0.18",
"description": "The base template for pages on fwdekker.com.",
"author": "Felix W. Dekker (https://fwdekker.com)",
"license": "MIT",
@ -25,8 +25,8 @@
"normalize.css": "^8.0.1"
},
"devDependencies": {
"css-loader": "^3.5.3",
"grunt": "^1.1.0",
"css-loader": "^3.6.0",
"grunt": "^1.2.1",
"grunt-cli": "^1.3.2",
"grunt-contrib-clean": "^2.0.0",
"grunt-contrib-watch": "^1.1.0",
@ -34,6 +34,6 @@
"grunt-webpack": "^3.1.3",
"style-loader": "^1.2.1",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
"webpack-cli": "^3.3.12"
}
}

View File

@ -1,7 +1,10 @@
/* Variables */
:root {
--fwdekker-theme-color: #0033cc;
--fwdekker-theme-color-dark: #00279d;
--fwdekker-theme-color-dark: #0029a3;
--fwdekker-theme-color-very-dark: #001f7a;
--fwdekker-theme-color-light: #003df5;
--fwdekker-theme-color-very-light: #1f57ff;
}

View File

@ -22,27 +22,6 @@
color: white;
}
.nav ul {
margin: 0;
padding: 0;
list-style: none;
}
.nav li {
display: inline-block;
margin: 0;
padding: 0;
position: relative;
background-color: var(--fwdekker-theme-color);
}
.nav li:hover,
.nav li:focus-within {
cursor: pointer;
background-color: var(--fwdekker-theme-color-dark);
}
.nav .logo {
width: calc(1em + var(--padding));
@ -57,6 +36,33 @@
}
.nav ul {
margin: 0;
padding: 0;
list-style: none;
}
.nav ul li {
display: inline-block;
margin: 0;
padding: 0;
position: relative;
background-color: var(--fwdekker-theme-color);
}
.nav ul li:hover,
.nav ul li:focus-within {
cursor: pointer;
background-color: var(--fwdekker-theme-color-very-dark);
}
.nav li.currentPage {
background-color: var(--fwdekker-theme-color-dark);
}
.nav ul li ul {
display: none;
position: absolute;

View File

@ -36,9 +36,10 @@ export const doAfterLoad = function (fun) {
*
* Fetches entries asynchronously from the website's API.
*
* @param [highlightPath] {String} the path to highlight together with its parents
* @returns {HTMLElement} a base navigation element that will eventually be filled with contents
*/
export const nav = function () {
export const nav = function (highlightPath = "") {
const base = h("ul",
h("li", h("a", {href: "https://fwdekker.com/"},
h("div.logo", h("img.logo", {src: "https://fwdekker.com/favicon.png"})),
@ -48,7 +49,7 @@ export const nav = function () {
fetch("https://fwdekker.com/api/nav/")
.then(it => it.json())
.then(json => json.entries.forEach(entry => base.appendChild(unpackEntry(entry))))
.then(json => json.entries.forEach(entry => base.appendChild(unpackEntry(entry, "/", highlightPath))))
.catch(e => {
console.error("Failed to fetch navigation elements", e);
return [];
@ -61,18 +62,27 @@ export const nav = function () {
* Unpacks a navigation entry returned from the navigation API into an HTML element.
*
* @param entry {Object} the entry to unpack
* @param [depth] {Object} the current nesting level
* @param [path] {number} the current path traversed, found by joining the names of the entries with `/`s; always starts
* and ends with a `/`
* @param [highlightPath] {String} the path to highlight together with its parents
* @returns {HTMLElement} the navigation list entry as HTML, described by its children
*/
const unpackEntry = function (entry, depth = 0) {
if (entry.entries.length === 0)
return h("li", h("a", {href: entry.link, innerHTML: entry.name}));
const unpackEntry = function (entry, path = "/", highlightPath = "") {
const shouldHighlight = highlightPath.startsWith(`${path + entry.name}/`);
const arrow = depth === 0 ? "▾" : "▸"
if (entry.entries.length === 0)
return h("li",
h("a", {href: entry.link, innerHTML: entry.name}),
{className: shouldHighlight ? "currentPage" : ""}
);
const depth = path.split("/").length - 2; // -1 because count parts, then another -1 because of leading `/`
const arrow = depth === 0 ? "▾" : "▸";
return h("li",
h("a", {href: entry.link, innerHTML: `${entry.name} ${arrow}`}),
h("ul", entry.entries.map(it => unpackEntry(it, depth + 1)))
h("ul", entry.entries.map(it => unpackEntry(it, `${path + entry.name}/`, highlightPath))),
{className: shouldHighlight ? "currentPage" : ""}
);
};