167 lines
3.9 KiB
Plaintext
167 lines
3.9 KiB
Plaintext
---
|
||
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 l’Essai-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>
|