From e623d92c2fddc0ff5fe83d2554266885d683a906 Mon Sep 17 00:00:00 2001 From: Florian Kissling Date: Thu, 7 Sep 2023 12:31:32 +0200 Subject: fix(ToC): don't hard-code nav height (#642) Co-authored-by: Chris Swithinbank --- .changeset/nasty-moons-bow.md | 5 +++++ .../TableOfContents/MobileTableOfContents.astro | 2 +- .../components/TableOfContents/starlight-toc.ts | 26 +++++++++++++--------- 3 files changed, 22 insertions(+), 11 deletions(-) create mode 100644 .changeset/nasty-moons-bow.md diff --git a/.changeset/nasty-moons-bow.md b/.changeset/nasty-moons-bow.md new file mode 100644 index 00000000..04212669 --- /dev/null +++ b/.changeset/nasty-moons-bow.md @@ -0,0 +1,5 @@ +--- +'@astrojs/starlight': patch +--- + +Don't hard-code nav height in table of contents highlighting script diff --git a/packages/starlight/components/TableOfContents/MobileTableOfContents.astro b/packages/starlight/components/TableOfContents/MobileTableOfContents.astro index b4fc2000..34fe1d5e 100644 --- a/packages/starlight/components/TableOfContents/MobileTableOfContents.astro +++ b/packages/starlight/components/TableOfContents/MobileTableOfContents.astro @@ -122,7 +122,7 @@ const t = useTranslations(locale); } constructor() { - super({ smallViewport: true }); + super(); const details = this.querySelector('details'); if (!details) return; const closeToC = () => { diff --git a/packages/starlight/components/TableOfContents/starlight-toc.ts b/packages/starlight/components/TableOfContents/starlight-toc.ts index 1d1f4cd0..4283f361 100644 --- a/packages/starlight/components/TableOfContents/starlight-toc.ts +++ b/packages/starlight/components/TableOfContents/starlight-toc.ts @@ -10,7 +10,7 @@ export class StarlightTOC extends HTMLElement { this._current = link; } - constructor({ smallViewport = false } = {}) { + constructor() { super(); /** All the links in the table of contents. */ @@ -68,19 +68,13 @@ export class StarlightTOC extends HTMLElement { // Also observe direct children of `.content` to include elements before // the first heading. const toObserve = document.querySelectorAll('main [id], main [id] ~ *, main .content > *'); - /** Start intersections at nav height + 2rem padding. */ - const top = (smallViewport ? 104 : 64) + 32; - /** End intersections 1.5rem later. */ - const bottom = top + 24; let observer: IntersectionObserver | undefined; - function observe() { + const observe = () => { if (observer) observer.disconnect(); - const height = document.documentElement.clientHeight; - const rootMargin = `-${top}px 0% ${bottom - height}px`; - observer = new IntersectionObserver(setCurrent, { rootMargin }); + observer = new IntersectionObserver(setCurrent, { rootMargin: this.getRootMargin() }); toObserve.forEach((h) => observer!.observe(h)); - } + }; observe(); const onIdle = window.requestIdleCallback || ((cb) => setTimeout(cb, 1)); @@ -92,6 +86,18 @@ export class StarlightTOC extends HTMLElement { timeout = setTimeout(() => onIdle(observe), 200); }); } + + private getRootMargin(): `-${number}px 0% ${number}px` { + const navBarHeight = document.querySelector('header')?.getBoundingClientRect().height || 0; + // `` only exists in mobile ToC, so will fall back to 0 in large viewport component. + const mobileTocHeight = this.querySelector('summary')?.getBoundingClientRect().height || 0; + /** Start intersections at nav height + 2rem padding. */ + const top = navBarHeight + mobileTocHeight + 32; + /** End intersections 1.5rem later. */ + const bottom = top + 24; + const height = document.documentElement.clientHeight; + return `-${top}px 0% ${bottom - height}px`; + } } customElements.define('starlight-toc', StarlightTOC); -- cgit