diff --git a/site/src/jsMain/kotlin/App.kt b/site/src/jsMain/kotlin/App.kt index a39ede9..873f236 100644 --- a/site/src/jsMain/kotlin/App.kt +++ b/site/src/jsMain/kotlin/App.kt @@ -28,6 +28,7 @@ fun App() { var toc by remember { mutableStateOf>(emptyList()) } var activeTocId by remember { mutableStateOf(null) } var contentEl by remember { mutableStateOf(null) } + var navEl by remember { mutableStateOf(null) } val isDocsRoute = route.startsWith("docs/") val docKey = stripFragment(route) @@ -60,6 +61,13 @@ fun App() { onDispose { window.removeEventListener("hashchange", listener) } } + LaunchedEffect(activeTocId) { + val activeId = activeTocId ?: return@LaunchedEffect + val nav = navEl ?: return@LaunchedEffect + val activeLink = nav.querySelector("a[data-toc-id=\"$activeId\"]") as? HTMLElement + activeLink?.scrollIntoView(js("({block: 'nearest', behavior: 'smooth'})")) + } + PageTemplate(title = when { isDocsRoute -> null route.startsWith("reference") -> "Reference" @@ -71,7 +79,11 @@ fun App() { Div({ classes("col-12", "col-lg-3") }) { Nav({ classes("position-sticky") - attr("style", "top: calc(var(--navbar-offset) + 1rem)") + attr("style", "top: calc(var(--navbar-offset) + 1rem); max-height: calc(100vh - var(--navbar-offset) - 2rem); overflow-y: auto;") + ref { + navEl = it + onDispose { navEl = null } + } }) { H2({ classes("h6", "text-uppercase", "text-muted") }) { Text("On this page") } Ul({ classes("list-unstyled") }) { @@ -82,6 +94,7 @@ fun App() { val tocHref = "#/$routeNoFrag#${item.id}" A(attrs = { attr("href", tocHref) + attr("data-toc-id", item.id) attr("style", "padding-left: $pad") classes("link-body-emphasis", "text-decoration-none") if (activeTocId == item.id) { diff --git a/site/src/jsMain/kotlin/Main.kt b/site/src/jsMain/kotlin/Main.kt index 38a2f53..ea5d7d7 100644 --- a/site/src/jsMain/kotlin/Main.kt +++ b/site/src/jsMain/kotlin/Main.kt @@ -180,6 +180,17 @@ fun ensureDocsLayoutStyles() { .markdown-body h1:first-child { margin-top: 0 !important; } + /* Hide scrollbar for the TOC nav but allow scrolling */ + nav.position-sticky::-webkit-scrollbar { + width: 4px; + } + nav.position-sticky::-webkit-scrollbar-thumb { + background: rgba(128,128,128,0.2); + border-radius: 4px; + } + nav.position-sticky:hover::-webkit-scrollbar-thumb { + background: rgba(128,128,128,0.5); + } """ .trimIndent() )