diff --git a/public/docs/css/main.css b/public/docs/css/main.css index c9fb8a2445..f79d2ce55b 100644 --- a/public/docs/css/main.css +++ b/public/docs/css/main.css @@ -1300,6 +1300,19 @@ li.has-children .sub-nav ul li:focus > a { padding-block: var(--gap-menu); } +/* Right-chevron on top-level section links (navigate, not expand). */ +.site-nav + > .site-nav__list + > .site-nav__list-item:not(.has-children) + > a::after { + content: '\f054'; + /* Chevron Right */ + font-family: fa-solid; + float: right; + color: var(--color-menu-marker); + margin-inline-end: 0.5rem; +} + .site-nav details[open] > summary { background-color: var(--bg-color-menu-open); font-weight: bold; diff --git a/src/themes/octopus/components/Navigation.astro b/src/themes/octopus/components/Navigation.astro index 552bc4ee90..1c1cd95fe9 100644 --- a/src/themes/octopus/components/Navigation.astro +++ b/src/themes/octopus/components/Navigation.astro @@ -1,5 +1,6 @@ --- import { Accelerator } from 'astro-accelerator-utils'; +import type { NavPage } from 'astro-accelerator-utils/types/NavPage'; import { Translations, Lang } from '@util/Languages'; import { menu } from '@data/navigation'; import NavigationItem from '@components/NavigationItem.astro'; @@ -9,19 +10,45 @@ const accelerator = new Accelerator(SITE); const stats = new accelerator.statistics('octopus/components/Navigation.astro'); stats.start(); -// Properties type Props = { lang: string; }; const { lang } = Astro.props satisfies Props; -// Language const _ = Lang(lang); -// Logic const currentUrl = new URL(Astro.request.url); const pages = accelerator.navigation.menu(currentUrl, SITE.subfolder, menu); +// Expand the current section in place; collapse every other section to a +// labelled link. +const currentPath = currentUrl.pathname.replace(/\/$/, ''); +function isOnActivePath(page: NavPage): boolean { + const pUrl = (page.url ?? '').replace(/\/$/, ''); + if (!pUrl) return false; + return currentPath === pUrl || currentPath.startsWith(pUrl + '/'); +} +function markActiveBranchOpen(items: NavPage[]): void { + for (const item of items) { + if (item.children && item.children.length > 0 && isOnActivePath(item)) { + item.isOpen = true; + markActiveBranchOpen(item.children); + } + } +} + +for (const top of pages) { + if (top.children && top.children.length > 0) { + if (isOnActivePath(top)) { + top.isOpen = true; + markActiveBranchOpen(top.children); + } else { + if (top.section) top.title = top.section; + top.children = []; + } + } +} + stats.stop(); ---