Sidebar nav: full garden tree on every page

- buildNavTree: every non-draft page nested by vault folder; folders link
  to their (real or synthetic) index page and take its title when set
- NavTree component: recursive details/summary tree, no JS — folders on
  the current path render open, current page gets aria-current styling
- layout: sticky left sidebar >=72rem, flows after the footer as a site
  index on narrow screens

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wes
2026-07-15 14:54:04 -04:00
co-authored by Claude Opus 4.8
parent 04c9aa2fb2
commit 13b23ace3d
3 changed files with 202 additions and 16 deletions
+38
View File
@@ -0,0 +1,38 @@
---
interface Props {
nodes: any[];
currentPath: string;
}
const { nodes, currentPath } = Astro.props;
// build-time pathnames may carry .html / index.html suffixes — normalize
const norm = decodeURIComponent(currentPath)
.replace(/index\.html$/, '')
.replace(/\.html$/, '');
const here = (u: string) => norm === u || norm === u.replace(/\/$/, '');
const under = (u: string) => norm.startsWith(u);
---
<ul class="nav-tree">
{
nodes.map((n) =>
n.children ? (
<li>
<details open={under(n.url)}>
<summary>
<a href={n.url} aria-current={here(n.url) ? 'page' : undefined}>
{n.name}
</a>
</summary>
<Astro.self nodes={n.children} currentPath={currentPath} />
</details>
</li>
) : (
<li>
<a href={n.url} aria-current={here(n.url) ? 'page' : undefined}>
{n.name}
</a>
</li>
),
)
}
</ul>