diff --git a/package.json b/package.json index 0f914d0..a535362 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@fwdekker/template", - "version": "3.3.4", + "version": "3.3.5", "description": "The base template for pages on fwdekker.com.", "author": "Florine W. Dekker", "license": "MIT", diff --git a/src/main/css/snippets/nav.css b/src/main/css/snippets/nav.css index b86a940..3d59e44 100644 --- a/src/main/css/snippets/nav.css +++ b/src/main/css/snippets/nav.css @@ -29,6 +29,10 @@ nav.fwd-nav li > :first-child { margin: 0; } +nav.fwd-nav a { + cursor: pointer; +} + nav.fwd-nav ul ul { display: none; @@ -113,7 +117,7 @@ nav.fwd-nav #logo::before { } /* Hamburger */ -nav.fwd-nav #nav-hamburger-label { +nav.fwd-nav #fwd-nav-hamburger-label { height: fit-content; margin: 0; padding: calc(var(--nav-element-spacing-horizontal) + var(--nav-link-spacing-vertical)); @@ -121,18 +125,18 @@ nav.fwd-nav #nav-hamburger-label { color: var(--primary-inverse); } -nav.fwd-nav #nav-hamburger-label:where(:active, :focus-within, :hover) { +nav.fwd-nav #fwd-nav-hamburger-label:where(:active, :focus-within, :hover) { background-color: var(--primary-focus-dark); } @media (min-width: 576px) { - nav.fwd-nav #nav-hamburger-label { + nav.fwd-nav #fwd-nav-hamburger-label { display: none; } } @media (max-width: 576px) { - nav.fwd-nav #nav-hamburger-checkbox:not(:checked) ~ ul li:not(:first-child) { + nav.fwd-nav #fwd-nav-hamburger-checkbox:not(:checked) ~ ul li:not(:first-child) { display: none; } } diff --git a/src/main/js/Template.ts b/src/main/js/Template.ts index a92d6d5..d28bc84 100644 --- a/src/main/js/Template.ts +++ b/src/main/js/Template.ts @@ -81,8 +81,12 @@ export function getMetaProperty(name: string): string | null | undefined { * @returns a base navigation element that will eventually be filled with contents */ function nav(highlightPath?: string, cb?: (json: any) => void): HTMLElement { - const base = stringToHtml(``); + const nav = stringToHtml(``); + const checkbox = stringToHtml(``); + nav.appendChild(checkbox); + + const base = stringToHtml(``); fetch("https://fwdekker.com/api/nav/") .then(it => it.json()) .then(json => { @@ -94,11 +98,11 @@ function nav(highlightPath?: string, cb?: (json: any) => void): HTMLElement { ); }) .catch(error => console.error("Failed to fetch navigation elements", error)); - - const nav = stringToHtml(``); - nav.appendChild(stringToHtml(``)); nav.appendChild(base); - nav.appendChild(stringToHtml(``)); + + const label = stringToHtml(``); + nav.appendChild(label); + return nav; } @@ -106,34 +110,40 @@ function nav(highlightPath?: string, cb?: (json: any) => void): HTMLElement { * Unpacks a navigation entry returned from the navigation API into an HTML element. * * @param entry the entry to unpack - * @param path the current path traversed, found by joining the names of the entries with `/`s; always starts and ends - * with a `/` + * @param parentPath the current path traversed, found by joining the names of the entries with `/`s; always starts and + * ends with a `/` * @param highlightPath the path to highlight together with its parents, or `undefined` if no path should be highlighted * @returns the navigation list entry as HTML, described by its children */ -function unpackEntry(entry: any, path: string = "/", highlightPath?: string): string { - const classList = []; - if (highlightPath?.startsWith(`${path + entry.name}/`) ?? false) classList.push("current-page"); - if (entry.border) classList.push("border-above"); - const classString = classList.length !== 0 ? `class="${classList.join(" ")}"` : ""; +function unpackEntry(entry: any, parentPath: string = "/", highlightPath?: string): string { + const path = `${parentPath + entry.name}/`; - const externalLinkString = !(/^https:\/\/.*fwdekker.com/i.test(entry.link)) && entry.link !== "#" - ? `target="_blank"` - : ""; + const classList = []; + if (highlightPath?.startsWith(path) ?? false) classList.push("current-page"); + if (entry.border) classList.push("border-above"); + const classString = classList.length === 0 ? "" : `class="${classList.join(" ")}"`; + + let hrefString; + if (entry.link == null) { + hrefString = ""; + } else { + hrefString = `href="${entry.link}"`; + if (entry.link !== "#" && !/^https:\/\/.*fwdekker.com/i.test(entry.link)) + hrefString += ` target="_blank"`; + } if (entry.entries.length === 0) - return "" + - `
  • ` + - `${entry.name}` + - `
  • `; + return `
  • ${entry.name}
  • `; - const depth = path.split("/").length - 2; // -1 because count parts, then another -1 because of leading `/` + const depth = parentPath.split("/").length - 2; // -1 because count parts, then another -1 because of leading `/` const arrow = depth === 0 ? "▾" : "▸"; return "" + `
  • ` + - `${entry.name} ${arrow}` + - `` + + /**/`${entry.name} ${arrow}` + + /**/`` + `
  • `; }