Skip to content

Commit 79ba391

Browse files
committed
feat: on this page subsections
1 parent 3ac1105 commit 79ba391

File tree

3 files changed

+52
-21
lines changed

3 files changed

+52
-21
lines changed

apps/svelte.dev/src/routes/docs/[topic]/[...path]/OnThisPage.svelte

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
1010
afterNavigate(() => {
1111
current = location.hash.slice(1);
12-
headings = content.querySelectorAll('h2');
12+
headings = content.querySelectorAll('h2, h3');
1313
update(); // Ensure active link is set correctly on navigation
1414
});
1515
@@ -57,9 +57,22 @@
5757
</li>
5858

5959
{#each document.sections as section}
60-
<li>
60+
<li
61+
data-has-subsections={section.subsections.length > 0}
62+
data-subsections-active={current === section.slug ||
63+
section.subsections.some((child) => `${section.slug}-${child.slug}` === current)}
64+
>
6165
<a href="#{section.slug}" class:active={current === section.slug}>{@html section.title}</a
6266
>
67+
68+
<ul>
69+
{#each section.subsections as child}
70+
{@const slug = `${section.slug}-${child.slug}`}
71+
<li>
72+
<a href="#{slug}" class:active={current === slug}>{@html child.title}</a>
73+
</li>
74+
{/each}
75+
</ul>
6376
</li>
6477
{/each}
6578
</ul>
@@ -76,6 +89,10 @@
7689
font: var(--sk-font-body-small);
7790
}
7891
92+
li ul {
93+
margin: 0 0 0 1.6rem;
94+
}
95+
7996
/* Only show the title link if it's in the sidebar */
8097
li:first-child {
8198
display: none;
@@ -183,6 +200,10 @@
183200
nav {
184201
display: none;
185202
padding: 0 0 0 3rem;
203+
204+
li[data-has-subsections='true'] ul {
205+
display: block;
206+
}
186207
}
187208
}
188209
@@ -228,6 +249,14 @@
228249
display: list-item;
229250
}
230251
252+
li[data-has-subsections='true'] ul {
253+
display: none;
254+
}
255+
256+
li[data-has-subsections='true'][data-subsections-active='true'] ul {
257+
display: block;
258+
}
259+
231260
a.active {
232261
color: var(--sk-fg-1);
233262
text-decoration: underline;

packages/site-kit/src/lib/server/content/index.ts

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { extract_frontmatter, is_in_code_block, slugify, smart_quotes } from '../../markdown/utils';
2-
import type { Document } from '../../types';
2+
import type { Document, Section } from '../../types';
33

44
export async function create_index(
55
documents: Record<string, string>,
@@ -32,24 +32,25 @@ export async function create_index(
3232
'<code>$1</code>'
3333
);
3434

35-
const sections = Array.from(body.matchAll(/^##\s+(.*)$/gm)).reduce(
36-
(arr, match) => {
37-
if (is_in_code_block(body, match.index || 0)) return arr;
38-
const title = smart_quotes(match[1])
39-
// replace < and > inside code spans
40-
.replace(/`(.+?)`/g, (_, contents) =>
41-
contents.replace(/</g, '&lt;').replace(/>/g, '&gt;')
42-
)
43-
// turn e.g. `class:_name_` into `class:<em>name</em>`
44-
.replace(/_(.+)_/g, (_, contents) => `<em>${contents}</em>`);
45-
46-
const slug = slugify(title);
47-
48-
arr.push({ slug, title });
49-
return arr;
50-
},
51-
[] as Array<{ slug: string; title: string }>
52-
);
35+
const sections = Array.from(body.matchAll(/^#{2,3}\s+(.*)$/gm)).reduce((arr, match) => {
36+
if (is_in_code_block(body, match.index || 0)) return arr;
37+
const title = smart_quotes(match[1])
38+
// replace < and > inside code spans
39+
.replace(/`(.+?)`/g, (_, contents) => contents.replace(/</g, '&lt;').replace(/>/g, '&gt;'))
40+
// turn e.g. `class:_name_` into `class:<em>name</em>`
41+
.replace(/_(.+)_/g, (_, contents) => `<em>${contents}</em>`);
42+
43+
const slug = slugify(title);
44+
45+
if (match[0].startsWith('###')) {
46+
const section = arr.at(-1);
47+
if (section) section.subsections.push({ slug, title });
48+
} else {
49+
arr.push({ slug, title, subsections: [] });
50+
}
51+
52+
return arr;
53+
}, [] as Array<Section>);
5354

5455
content[slug] = {
5556
slug,

packages/site-kit/src/lib/types.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export interface DocumentSummary {
4444
export interface Section {
4545
slug: string;
4646
title: string;
47+
subsections: Omit<Section, 'subsections'>[];
4748
}
4849

4950
export interface BannerData {

0 commit comments

Comments
 (0)