Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions showcase/src/wasmJsMain/kotlin/dev/kindling/showcase/docs/Site.kt
Original file line number Diff line number Diff line change
Expand Up @@ -229,21 +229,23 @@ private fun PageContent(page: DocPage?, loc: Loc, dark: Boolean, flat: List<DocP
// Scroll-spy: the last heading that has reached the top of the viewport (or the last one at the bottom).
val activeHeading by remember(headings) {
derivedStateOf {
val top = viewport?.takeIf { it.isAttached }?.positionInRoot()?.y ?: 0f
val top = viewport.safeY() ?: 0f
val atEnd = scroll.maxValue > 0 && scroll.value >= scroll.maxValue - 4
var active = headings.firstOrNull()?.first
for ((index, _) in headings) {
val c = coords[index]?.takeIf { it.isAttached } ?: continue
if (c.positionInRoot().y - top <= 110f) active = index else break
val y = coords[index].safeY() ?: continue
if (y - top <= 110f) active = index else break
}
if (atEnd) headings.lastOrNull()?.first ?: active else active
}
}
val scrollTo: (Int) -> Unit = { index ->
val target = coords[index]
val top = viewport
if (target != null && target.isAttached && top != null) {
val y = target.positionInRoot().y - top.positionInRoot().y
val ty = target.safeY()
val vy = top.safeY()
if (ty != null && vy != null) {
val y = ty - vy
scope.launch { scroll.animateScrollTo((scroll.value + y - 24f).toInt().coerceAtLeast(0)) }
}
}
Expand Down Expand Up @@ -381,3 +383,7 @@ private fun SearchOverlay(pages: List<DocPage>, onClose: () -> Unit, onPick: (St
}
}
}

/** Position in the root, or null when the layout is detached (it can be removed between the check and the read). */
private fun LayoutCoordinates?.safeY(): Float? =
if (this == null || !isAttached) null else try { positionInRoot().y } catch (_: IllegalArgumentException) { null }
Loading