Files
archicratie-edition/src/components/EditionToc.astro
Archicratia 9cb0d5e416
All checks were successful
CI / build-and-anchors (push) Successful in 38s
CI / build-and-anchors (pull_request) Successful in 37s
SMOKE / smoke (push) Successful in 5s
content: wire archicrat-ia as first-class collection (routes + toc + schema)
2026-03-03 15:02:50 +01:00

163 lines
3.7 KiB
Plaintext

---
import { getCollection } from "astro:content";
const { currentSlug } = Astro.props;
// ✅ Après migration : TOC = collection "archicrat-ia"
const entries = (await getCollection("archicrat-ia"))
.sort((a, b) => (a.data.order ?? 0) - (b.data.order ?? 0));
const href = (slug) => `/archicrat-ia/${slug}/`;
---
<nav class="toc-global" aria-label="Table des matières — ArchiCraT-IA">
<div class="toc-global__head">
<div class="toc-global__title">Table des matières</div>
</div>
<ol class="toc-global__list">
{entries.map((e) => {
const active = e.slug === currentSlug;
return (
<li class={`toc-item ${active ? "is-active" : ""}`}>
<a class="toc-link" href={href(e.slug)} aria-current={active ? "page" : undefined}>
<span class="toc-link__row">
{active ? (
<span class="toc-active-indicator" aria-hidden="true">👉</span>
) : (
<span class="toc-active-spacer" aria-hidden="true"></span>
)}
<span class="toc-link__title">{e.data.title}</span>
{active && (
<span class="toc-badge" aria-label="Chapitre en cours">
En cours
</span>
)}
</span>
{active && <span class="toc-underline" aria-hidden="true"></span>}
</a>
</li>
);
})}
</ol>
</nav>
<style>
.toc-global{
border: 1px solid rgba(127,127,127,0.22);
border-radius: 16px;
padding: 12px;
background: rgba(127,127,127,0.06);
}
.toc-global__head{
margin-bottom: 10px;
padding-bottom: 10px;
border-bottom: 1px dashed rgba(127,127,127,0.25);
}
.toc-global__title{
font-size: 13px;
font-weight: 800;
letter-spacing: .2px;
opacity: .88;
}
.toc-global__list{
list-style: none;
margin: 0;
padding: 0;
}
.toc-global__list li::marker{ content: ""; }
.toc-item{ margin: 6px 0; }
.toc-link{
display: block;
text-decoration: none;
border-radius: 14px;
padding: 8px 10px;
transition: transform 120ms ease, background 120ms ease;
}
.toc-link:hover{
background: rgba(127,127,127,0.10);
text-decoration: none;
transform: translateY(-1px);
}
.toc-link__row{
display: grid;
grid-template-columns: auto 1fr auto;
gap: 10px;
align-items: center;
}
.toc-active-indicator{
font-size: 14px;
line-height: 1;
}
.toc-active-spacer{
width: 14px;
}
.toc-link__title{
font-size: 13px;
line-height: 1.25;
max-width: 100%;
}
.toc-badge{
font-size: 11px;
font-weight: 800;
letter-spacing: .2px;
padding: 3px 8px;
border-radius: 999px;
border: 1px solid rgba(127,127,127,0.30);
background: rgba(127,127,127,0.10);
opacity: .92;
white-space: nowrap;
}
.toc-item.is-active .toc-link{
background: rgba(127,127,127,0.12);
}
.toc-item.is-active .toc-link__title{
font-weight: 800;
}
.toc-underline{
display: block;
margin-top: 8px;
height: 1px;
width: 100%;
background: rgba(127,127,127,0.35);
border-radius: 999px;
}
.toc-global__list{
max-height: 44vh;
overflow: auto;
padding-right: 8px;
scrollbar-gutter: stable;
}
@media (prefers-color-scheme: dark){
.toc-global{ background: rgba(255,255,255,0.04); }
.toc-link:hover{ background: rgba(255,255,255,0.06); }
.toc-item.is-active .toc-link{ background: rgba(255,255,255,0.06); }
.toc-badge{ background: rgba(255,255,255,0.06); }
}
</style>
<script is:inline>
(() => {
const active = document.querySelector(".toc-global .toc-item.is-active");
if (active) active.scrollIntoView({ block: "nearest" });
})();
</script>