Files
archicratie-edition/src/components/EditionToc.astro
Archicratia 2881fdaf01
All checks were successful
CI / build-and-anchors (push) Successful in 1m42s
SMOKE / smoke (push) Successful in 13s
fix(toc): Essai-thèse links -> /archicrat-ia/* (no /archicratie prefix)
2026-02-20 20:48:31 +01:00

167 lines
3.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
import { getCollection } from "astro:content";
const { currentSlug } = Astro.props;
const entries = (await getCollection("archicratie"))
.filter((e) => e.slug.startsWith("archicrat-ia/"))
.sort((a, b) => (a.data.order ?? 0) - (b.data.order ?? 0));
// ✅ On route lEssai-thèse sur /archicrat-ia/<slug-sans-prefix>/
// (Astro trailingSlash = always → on garde le "/" final)
const strip = (s) => String(s || "").replace(/^archicrat-ia\//, "");
const href = (slug) => `/archicrat-ia/${strip(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>