feat: add sticky sidebar navigation to learning hub articles

This commit is contained in:
Aaron Powell
2026-02-11 13:54:36 +11:00
parent 6bb024224b
commit 867650fb77
2 changed files with 143 additions and 3 deletions

View File

@@ -1594,6 +1594,84 @@ a:hover {
color: var(--color-warning);
}
/* Learning Hub - Sidebar Layout */
.learning-hub-layout {
display: grid;
grid-template-columns: 240px 1fr;
gap: 48px;
align-items: start;
}
.learning-hub-sidebar {
position: sticky;
top: 24px;
max-height: calc(100vh - 48px);
overflow-y: auto;
}
.sidebar-section {
margin-bottom: 24px;
}
.sidebar-section h3 {
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--color-text-muted);
margin-bottom: 8px;
padding: 0 12px;
}
.sidebar-nav-list {
list-style: none;
padding: 0;
margin: 0;
}
.sidebar-nav-list li {
margin: 0;
}
.sidebar-nav-list a {
display: block;
padding: 6px 12px;
font-size: 13px;
line-height: 1.4;
color: var(--color-text-muted);
text-decoration: none;
border-radius: 6px;
border-left: 2px solid transparent;
transition: color 0.15s, background-color 0.15s, border-color 0.15s;
}
.sidebar-nav-list a:hover {
color: var(--color-text);
background-color: var(--color-glass);
}
.sidebar-nav-list a.active {
color: var(--color-text-emphasis);
background-color: var(--color-glass);
border-left-color: var(--color-accent);
font-weight: 600;
}
@media (max-width: 900px) {
.learning-hub-layout {
grid-template-columns: 1fr;
gap: 0;
}
.learning-hub-sidebar {
position: static;
max-height: none;
border-bottom: 1px solid var(--color-border);
padding-bottom: 20px;
margin-bottom: 32px;
}
}
/* Learning Hub - Article Styles */
.breadcrumb {
margin-bottom: 16px;

View File

@@ -1,5 +1,6 @@
---
import BaseLayout from './BaseLayout.astro';
import { getCollection } from 'astro:content';
interface Props {
title: string;
@@ -11,6 +12,31 @@ interface Props {
const { title, description, estimatedReadingTime, lastUpdated, tags } = Astro.props;
const base = import.meta.env.BASE_URL;
const articles = await getCollection('learning-hub');
const fundamentalsOrder = [
'what-are-agents-prompts-instructions',
'understanding-copilot-context',
'copilot-configuration-basics',
'defining-custom-instructions',
'creating-effective-prompts',
'before-after-customization-examples',
];
const referenceOrder = [
'github-copilot-terminology-glossary',
];
const fundamentals = articles
.filter((a) => fundamentalsOrder.includes(a.id))
.sort((a, b) => fundamentalsOrder.indexOf(a.id) - fundamentalsOrder.indexOf(b.id));
const reference = articles
.filter((a) => referenceOrder.includes(a.id))
.sort((a, b) => referenceOrder.indexOf(a.id) - referenceOrder.indexOf(b.id));
const currentSlug = Astro.url.pathname.replace(/\/$/, '').split('/').pop();
---
<BaseLayout title={title} description={description} activeNav="learning-hub">
@@ -38,9 +64,45 @@ const base = import.meta.env.BASE_URL;
<div class="page-content">
<div class="container">
<article class="article-content">
<slot />
</article>
<div class="learning-hub-layout">
<nav class="learning-hub-sidebar" aria-label="Learning Hub articles">
<div class="sidebar-section">
<h3>Fundamentals</h3>
<ol class="sidebar-nav-list">
{fundamentals.map((article) => (
<li>
<a
href={`${base}learning-hub/${article.id}/`}
class={currentSlug === article.id ? 'active' : ''}
aria-current={currentSlug === article.id ? 'page' : undefined}
>
{article.data.title}
</a>
</li>
))}
</ol>
</div>
<div class="sidebar-section">
<h3>Reference</h3>
<ul class="sidebar-nav-list">
{reference.map((article) => (
<li>
<a
href={`${base}learning-hub/${article.id}/`}
class={currentSlug === article.id ? 'active' : ''}
aria-current={currentSlug === article.id ? 'page' : undefined}
>
{article.data.title}
</a>
</li>
))}
</ul>
</div>
</nav>
<article class="article-content">
<slot />
</article>
</div>
</div>
</div>
</main>