From da0bae94bb6645e711a245169516ec476e38d7e2 Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Sat, 24 Oct 2026 21:57:03 -0400 Subject: [PATCH] docs(ui): scroll the sidebar so the active (bold) link is in view on load MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deep-linking into a low doc (e.g. ratings/get_ratings from the overview page) opened the right menus but sat the highlight below the sidebar's visible scroll area. scrollSidebarToActive() runs at docs Alpine init: finds the link for the current path, and if it's outside the sidebar's scrollport, moves ONLY the sidebar's own scrollTop to clamp it into the nearest edge — never the page scroll. Skips the off-canvas mobile drawer. (Same behavior as Docusaurus/MkDocs on deep links.) Live: x-init wired on docs pages, function in the shipped bundle, make test green, 146 vitests. --- templates/docs.templ | 2 +- templates/docs_templ.go | 2 +- web/src/docs.ts | 28 ++++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/templates/docs.templ b/templates/docs.templ index a3360a71..64c7bd92 100644 --- a/templates/docs.templ +++ b/templates/docs.templ @@ -23,7 +23,7 @@ templ DocsLayout(nav Navigation, doc Document, user User, currentPath string) { - + @DocsTopbar(user) diff --git a/templates/docs_templ.go b/templates/docs_templ.go index b3fbef86..062da2b3 100644 --- a/templates/docs_templ.go +++ b/templates/docs_templ.go @@ -71,7 +71,7 @@ func DocsLayout(nav Navigation, doc Document, user User, currentPath string) tem if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "( + `a[href="${location.pathname}"], a[href="${location.pathname.replace(/\.md$/, "")}"]`, + ); + if (!active) return; + + const sb = sidebar.getBoundingClientRect(); + const ar = active.getBoundingClientRect(); + if (ar.top >= sb.top && ar.bottom <= sb.bottom) return; // already visible + + if (ar.top < sb.top) { + sidebar.scrollTop += ar.top - sb.top; + } else { + sidebar.scrollTop += ar.bottom - sb.bottom; + } +} + let docsSearchTimeout: ReturnType | null = null; let docsSearchAbort: AbortController | null = null; @@ -126,4 +153,5 @@ Alpine.data("docs", () => ({ toggleCollapsible, initializeSearch: initializeDocsSearch, initializeCodeCopyButtons, + scrollSidebarToActive, }));