parent
91e77ab3a5
commit
81fff6c7e9
Binary file not shown.
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@fwdekker/template",
|
"name": "@fwdekker/template",
|
||||||
"version": "0.0.17",
|
"version": "0.0.18",
|
||||||
"description": "The base template for pages on fwdekker.com.",
|
"description": "The base template for pages on fwdekker.com.",
|
||||||
"author": "Felix W. Dekker (https://fwdekker.com)",
|
"author": "Felix W. Dekker (https://fwdekker.com)",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
@ -25,8 +25,8 @@
|
||||||
"normalize.css": "^8.0.1"
|
"normalize.css": "^8.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"css-loader": "^3.5.3",
|
"css-loader": "^3.6.0",
|
||||||
"grunt": "^1.1.0",
|
"grunt": "^1.2.1",
|
||||||
"grunt-cli": "^1.3.2",
|
"grunt-cli": "^1.3.2",
|
||||||
"grunt-contrib-clean": "^2.0.0",
|
"grunt-contrib-clean": "^2.0.0",
|
||||||
"grunt-contrib-watch": "^1.1.0",
|
"grunt-contrib-watch": "^1.1.0",
|
||||||
|
@ -34,6 +34,6 @@
|
||||||
"grunt-webpack": "^3.1.3",
|
"grunt-webpack": "^3.1.3",
|
||||||
"style-loader": "^1.2.1",
|
"style-loader": "^1.2.1",
|
||||||
"webpack": "^4.43.0",
|
"webpack": "^4.43.0",
|
||||||
"webpack-cli": "^3.3.11"
|
"webpack-cli": "^3.3.12"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
/* Variables */
|
/* Variables */
|
||||||
:root {
|
:root {
|
||||||
--fwdekker-theme-color: #0033cc;
|
--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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,27 +22,6 @@
|
||||||
color: white;
|
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 {
|
.nav .logo {
|
||||||
width: calc(1em + var(--padding));
|
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 {
|
.nav ul li ul {
|
||||||
display: none;
|
display: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
@ -36,9 +36,10 @@ export const doAfterLoad = function (fun) {
|
||||||
*
|
*
|
||||||
* Fetches entries asynchronously from the website's API.
|
* 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
|
* @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",
|
const base = h("ul",
|
||||||
h("li", h("a", {href: "https://fwdekker.com/"},
|
h("li", h("a", {href: "https://fwdekker.com/"},
|
||||||
h("div.logo", h("img.logo", {src: "https://fwdekker.com/favicon.png"})),
|
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/")
|
fetch("https://fwdekker.com/api/nav/")
|
||||||
.then(it => it.json())
|
.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 => {
|
.catch(e => {
|
||||||
console.error("Failed to fetch navigation elements", e);
|
console.error("Failed to fetch navigation elements", e);
|
||||||
return [];
|
return [];
|
||||||
|
@ -61,18 +62,27 @@ export const nav = function () {
|
||||||
* Unpacks a navigation entry returned from the navigation API into an HTML element.
|
* Unpacks a navigation entry returned from the navigation API into an HTML element.
|
||||||
*
|
*
|
||||||
* @param entry {Object} the entry to unpack
|
* @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
|
* @returns {HTMLElement} the navigation list entry as HTML, described by its children
|
||||||
*/
|
*/
|
||||||
const unpackEntry = function (entry, depth = 0) {
|
const unpackEntry = function (entry, path = "/", highlightPath = "") {
|
||||||
if (entry.entries.length === 0)
|
const shouldHighlight = highlightPath.startsWith(`${path + entry.name}/`);
|
||||||
return h("li", h("a", {href: entry.link, innerHTML: 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",
|
return h("li",
|
||||||
h("a", {href: entry.link, innerHTML: `${entry.name} ${arrow}`}),
|
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" : ""}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue