feat(docs): improve table of contents loading and display (#667)

- Hide table of contents components when only a single heading exists
- Prevent initial transition flash on TOC progress indicators and dots
- Update sidebar scrollbar styling and hover behavior

Generated-by: aiautocommit
This commit is contained in:
Michael Bianco
2026-07-31 07:37:59 -06:00
committed by GitHub
parent 0b6006a549
commit 012d2c2f10
5 changed files with 89 additions and 4 deletions
+1
View File
@@ -271,6 +271,7 @@ export default defineConfig({
},
],
components: {
MobileTableOfContents: "./src/components/MobileTableOfContents.astro",
TableOfContents: "./src/components/TableOfContents.astro",
},
}),
@@ -0,0 +1,16 @@
---
import DefaultMobileTableOfContents from "@astrojs/starlight/components/MobileTableOfContents.astro";
const { toc } = Astro.locals.starlightRoute;
function countTocItems(items: NonNullable<typeof toc>["items"]): number {
return items.reduce(
(count, item) => count + 1 + countTocItems(item.children),
0,
);
}
const hasMultipleHeadings = toc ? countTocItems(toc.items) > 1 : false;
---
{hasMultipleHeadings && <DefaultMobileTableOfContents />}
+27 -2
View File
@@ -1,8 +1,19 @@
---
import PageActionsTableOfContents from "starlight-page-actions/overrides/TableOfContents.astro";
const { toc } = Astro.locals.starlightRoute;
function countTocItems(items: NonNullable<typeof toc>["items"]): number {
return items.reduce(
(count, item) => count + 1 + countTocItems(item.children),
0,
);
}
const hasMultipleHeadings = toc ? countTocItems(toc.items) > 1 : false;
---
<railpack-toc-progress>
<railpack-toc-progress data-single-heading={hasMultipleHeadings ? undefined : ""}>
<PageActionsTableOfContents />
</railpack-toc-progress>
@@ -19,6 +30,7 @@ import PageActionsTableOfContents from "starlight-page-actions/overrides/TableOf
connectedCallback() {
this.addActionsHeading();
if (this.hasAttribute("data-single-heading")) return;
this.buildIndicator();
}
@@ -54,6 +66,7 @@ import PageActionsTableOfContents from "starlight-page-actions/overrides/TableOf
this.mutationObserver = new MutationObserver(() => {
this.updateProgress();
this.enableProgressAnimation();
});
this.mutationObserver.observe(nav, {
attributeFilter: ["aria-current"],
@@ -119,8 +132,12 @@ import PageActionsTableOfContents from "starlight-page-actions/overrides/TableOf
this.activeDot.classList.add("railpack-toc-active-dot");
this.activeDot.setAttribute("r", "3");
svg.append(this.activeDot);
list.prepend(svg);
this.updateProgress();
list.prepend(svg);
if (this.links.some((link) => link.getAttribute("aria-current") === "true")) {
this.enableProgressAnimation();
}
}
private createPath(height: number) {
@@ -186,6 +203,14 @@ import PageActionsTableOfContents from "starlight-page-actions/overrides/TableOf
this.activeDot.setAttribute("cx", String(activePoint.x));
this.activeDot.setAttribute("cy", String(activePoint.y));
}
private enableProgressAnimation() {
if (this.hasAttribute("data-progress-ready")) return;
requestAnimationFrame(() => {
this.setAttribute("data-progress-ready", "");
});
}
}
if (!customElements.get("railpack-toc-progress")) {
@@ -4,7 +4,7 @@ description: Make it easy for users to containerize their application on your
hosting platform.
---
Although Railpack is Railway's default build path, it's a completely open source build system
that can be used by other commercial hosting platforms.
Railpack is a open source build system. We encourage other platforms to use it and welcome
improvements and bugs to improve Railway's compatibility with other hosting platforms.
If you run into issues using it on your platform create an issue or pull request on GitHub.
+43
View File
@@ -72,6 +72,29 @@ site-search button[data-open-modal] {
.sidebar-pane {
border-inline-end: 1px solid var(--gray-6);
background-color: var(--gray-1);
scrollbar-gutter: auto;
scrollbar-width: thin;
scrollbar-color: transparent transparent;
}
/* Keep the desktop navigation scroller available without making it a fixture. */
.sidebar-pane:hover {
scrollbar-color: var(--gray-8) transparent;
}
.sidebar-pane::-webkit-scrollbar {
width: 0.5rem;
}
.sidebar-pane::-webkit-scrollbar-thumb {
border: 0.1875rem solid transparent;
border-radius: 999px;
background-clip: content-box;
background-color: transparent;
}
.sidebar-pane:hover::-webkit-scrollbar-thumb {
background-color: var(--gray-8);
}
@media (min-width: 50rem) {
@@ -780,6 +803,18 @@ railpack-toc-progress {
display: block;
}
railpack-toc-progress[data-single-heading] starlight-toc {
display: none;
}
railpack-toc-progress[data-single-heading]
.page-actions-toc-desktop
.toc-actions {
margin-top: 0;
padding-top: 0;
border-top-width: 0;
}
.right-sidebar-panel starlight-toc nav > h2 {
margin-bottom: 1rem;
color: var(--gray-11);
@@ -836,6 +871,10 @@ railpack-toc-progress {
.railpack-toc-progress {
stroke: var(--purple-9);
transition: none;
}
railpack-toc-progress[data-progress-ready] .railpack-toc-progress {
transition: stroke-dashoffset 0.2s ease-out;
}
@@ -845,6 +884,10 @@ railpack-toc-progress {
.railpack-toc-active-dot {
fill: var(--purple-9);
transition: none;
}
railpack-toc-progress[data-progress-ready] .railpack-toc-active-dot {
transition:
cx 0.2s ease-out,
cy 0.2s ease-out;