feat(ui): harmoniser navigation pages d’entrée et recherche
All checks were successful
SMOKE / smoke (push) Successful in 6s
CI / build-and-anchors (push) Successful in 44s
CI / build-and-anchors (pull_request) Successful in 36s

This commit is contained in:
2026-04-25 01:31:14 +02:00
parent 8605b7198f
commit 64e56e8abc
10 changed files with 835 additions and 254 deletions

View File

@@ -28,6 +28,7 @@ const tocId = `toc-global-${collection}-${String(basePath).replace(/[^\w-]+/g, "
<nav
class="toc-global"
data-mobile-default="closed"
aria-label={label}
data-toc-global
data-toc-key={`global:${collection}:${basePath}`}
@@ -35,14 +36,14 @@ const tocId = `toc-global-${collection}-${String(basePath).replace(/[^\w-]+/g, "
<button
class="toc-global__head toc-global__toggle"
type="button"
aria-expanded="true"
aria-expanded="false"
aria-controls={tocId}
>
<span class="toc-global__title">{label}</span>
<span class="toc-global__chevron" aria-hidden="true">▾</span>
</button>
<div class="toc-global__body-clip" id={tocId}>
<div class="toc-global__body-clip" id={tocId} hidden>
<div class="toc-global__body">
<ol class="toc-global__list">
{entries.map((e) => {
@@ -291,6 +292,10 @@ const tocId = `toc-global-${collection}-${String(basePath).replace(/[^\w-]+/g, "
max-height: min(42vh, 360px);
padding-right: 4px;
}
.toc-global__body-clip[hidden]{
display: none !important;
}
}
@media (prefers-color-scheme: dark){
@@ -332,9 +337,16 @@ const tocId = `toc-global-${collection}-${String(basePath).replace(/[^\w-]+/g, "
const setOpen = (open, { persist = true } = {}) => {
const isMobile = mq.matches;
nav.classList.toggle("is-collapsed", isMobile && !open);
toggle.setAttribute("aria-expanded", open ? "true" : "false");
if (persist && isMobile) write(open);
const effectiveOpen = isMobile ? open : true;
nav.classList.toggle("is-collapsed", isMobile && !effectiveOpen);
toggle.setAttribute("aria-expanded", effectiveOpen ? "true" : "false");
if (bodyClip) {
bodyClip.hidden = isMobile && !effectiveOpen;
}
if (persist && isMobile) write(effectiveOpen);
};
const initState = () => {

View File

@@ -7,18 +7,18 @@ const tocId = `toc-local-${Math.random().toString(36).slice(2, 9)}`;
---
{items.length > 0 && (
<nav class="toc-local" aria-label="Dans ce chapitre" data-toc-local>
<nav class="toc-local" aria-label="Dans ce chapitre" data-toc-local data-mobile-default="closed">
<button
class="toc-local__head toc-local__toggle"
type="button"
aria-expanded="true"
aria-expanded="false"
aria-controls={tocId}
>
<span class="toc-local__title">Dans ce chapitre</span>
<span class="toc-local__chevron" aria-hidden="true">▾</span>
</button>
<div class="toc-local__body-clip" id={tocId}>
<div class="toc-local__body-clip" id={tocId} hidden>
<div class="toc-local__body">
<ol class="toc-local__list">
{items.map((h) => (
@@ -69,12 +69,18 @@ const tocId = `toc-local-${Math.random().toString(36).slice(2, 9)}`;
const setOpen = (open, { persist = true, emit = true } = {}) => {
const isMobile = mq.matches;
toc.classList.toggle("is-collapsed", isMobile && !open);
toggle.setAttribute("aria-expanded", open ? "true" : "false");
const effectiveOpen = isMobile ? open : true;
if (persist && isMobile) writeState(open);
toc.classList.toggle("is-collapsed", isMobile && !effectiveOpen);
toggle.setAttribute("aria-expanded", effectiveOpen ? "true" : "false");
if (emit && open && isMobile) {
if (bodyClip) {
bodyClip.hidden = isMobile && !effectiveOpen;
}
if (persist && isMobile) writeState(effectiveOpen);
if (emit && effectiveOpen && isMobile) {
window.dispatchEvent(new CustomEvent("archicratie:tocLocalOpen"));
}
};
@@ -85,7 +91,7 @@ const tocId = `toc-local-${Math.random().toString(36).slice(2, 9)}`;
return;
}
const stored = readState();
setOpen(stored == null ? true : stored, { persist: false, emit: false });
setOpen(stored == null ? false : stored, { persist: false, emit: false });
};
toggle.addEventListener("click", () => {
@@ -162,7 +168,8 @@ const tocId = `toc-local-${Math.random().toString(36).slice(2, 9)}`;
t.a.setAttribute("aria-current", "true");
t.li.classList.add("is-current");
if (mq.matches && autoOpen && toc.classList.contains("is-collapsed")) {
// Sur mobile/tablette, le suivi actif ne doit pas rouvrir automatiquement la TOC.
if (!mq.matches && autoOpen && toc.classList.contains("is-collapsed")) {
setOpen(true);
}
@@ -216,7 +223,7 @@ const tocId = `toc-local-${Math.random().toString(36).slice(2, 9)}`;
const el = document.getElementById(id);
if (el) openDetailsIfNeeded(el);
setCurrent(id, { autoOpen: true });
setCurrent(id, { autoOpen: false });
};
toc.addEventListener("click", (ev) => {
@@ -427,5 +434,9 @@ const tocId = `toc-local-${Math.random().toString(36).slice(2, 9)}`;
margin-top: .42em;
opacity: .55;
}
.toc-local__body-clip[hidden]{
display: none !important;
}
}
</style>

View File

@@ -1,17 +1,15 @@
<nav class="site-nav" aria-label="Navigation principale">
<a href="/">Accueil</a>
<span aria-hidden="true"> · </span>
<a href="/">Accueil</a>
<span aria-hidden="true"> · </span>
<a href="/archicrat-ia/">Essai-thèse — ArchiCraT-IA</a>
<span aria-hidden="true"> · </span>
<a href="/archicrat-ia/">Essai-thèse</a>
<span aria-hidden="true"> · </span>
<a href="/cas-ia/">Cas pratique — Gouvernance IA</a>
<span aria-hidden="true"> · </span>
<a href="/cas-ia/">Cas IA</a>
<span aria-hidden="true"> · </span>
<a href="/glossaire/">Glossaire</a>
<span aria-hidden="true"> · </span>
<a href="/recherche/">Recherche</a>
<a href="/glossaire/">Glossaire</a>
<span aria-hidden="true"> · </span>
<a href="/recherche/">Recherche</a>
</nav>