Skip to content
Draft
Show file tree
Hide file tree
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
5 changes: 5 additions & 0 deletions .changeset/weak-spiders-itch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/starlight': patch
---

Fixes and issue where the Table of Contents is unable to find any current heading when the page has a banner with custom styling regarding its height.
10 changes: 10 additions & 0 deletions docs/src/content/docs/getting-started.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
---
title: Getting Started
description: Learn how to start building your next documentation site with Starlight by Astro.
banner:
content: 'TODO(trueberryless): Remove'
head:
- tag: style
content: |
:root .sl-banner {
background-color: red;
color: white;
padding-block: 2rem;
}
---

import { Tabs, TabItem } from '@astrojs/starlight/components';
Expand Down
24 changes: 24 additions & 0 deletions packages/starlight/components/TableOfContents/starlight-toc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,40 @@ export class StarlightTOC extends HTMLElement {

/** Handle intersections and set the current link to the heading for the current intersection. */
const setCurrent: IntersectionObserverCallback = (entries) => {
let found = false;

for (const { isIntersecting, target } of entries) {
if (!isIntersecting) continue;
const heading = getElementHeading(target);
if (!heading) continue;
const link = links.find((link) => link.hash === '#' + encodeURIComponent(heading.id));
if (link) {
this.current = link;
found = true;
break;
}
}

// Fallback: if no heading intersects (because the banner is higher and moves the content down too much),
// create a temporal IntersectionObserver without rootMargin that finds the nearest heading.
// See https://github.com/withastro/starlight/issues/3047
if (!found) {
const tempObserver = new IntersectionObserver((tempEntries) => {
for (const { isIntersecting, target } of tempEntries) {
if (!isIntersecting) continue;
const heading = getElementHeading(target);
if (!heading) continue;
const link = links.find((link) => link.hash === '#' + encodeURIComponent(heading.id));
if (link) {
this.current = link;
break;
}
}
tempObserver.disconnect();
});

document.querySelectorAll('main [id]').forEach((el) => tempObserver.observe(el));
}
};

// Observe elements with an `id` (most likely headings) and their siblings.
Expand Down
Loading