Skip to content

Commit 2e374ad

Browse files
committed
feat: toc config for specific content from frontmatter
1 parent 88ae100 commit 2e374ad

File tree

6 files changed

+39
-21
lines changed

6 files changed

+39
-21
lines changed

packages/astro-friday/src/collection.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,21 @@ export function getSchema(config: ResolvedConfig) {
1515
keywords: z.union([z.string(), z.array(z.string())]).optional().default([]).transform(val => Array.isArray(val) ? val : [val]),
1616
draft: z.boolean().default(false),
1717
lang: z.string().optional().default('en'),
18+
/**
19+
* Table of contents (TOC) generation for posts
20+
*/
21+
toc: z.object({
22+
/**
23+
* Enable or disable the table of contents (TOC) generation for posts.
24+
*/
25+
enable: z.boolean().optional(),
26+
/**
27+
* The heading levels to include in the TOC.
28+
*
29+
* @example [2, 4] will include headings from h2 to h4.
30+
*/
31+
range: z.tuple([z.number().min(1).max(6), z.number().min(1).max(6)]).optional(),
32+
}).optional(),
1833
})
1934
}
2035

packages/astro-friday/src/components/ArticleTOC.astro

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
---
22
import type { MarkdownHeading } from 'astro'
3+
import type { Schema } from '../collection'
34
import ArticleTOCPlain from './ArticleTOCPlain.astro'
45
56
interface Props {
67
headings: MarkdownHeading[]
8+
toc: Required<Omit<NonNullable<Schema['toc']>, 'enable'>>
79
}
810
911
const {
1012
headings,
13+
toc,
1114
} = Astro.props
1215
1316
---
@@ -41,6 +44,7 @@ const {
4144

4245
<ArticleTOCPlain
4346
{headings}
47+
{toc}
4448
class:list={[
4549
'lg:(op-0 [:root:has(.displaying-table-of-contents:hover)_&]:(op-100) transition duration-700)',
4650
'lg:(of-y-auto overscroll-contain max-h-70vh scrollbar-none)',

packages/astro-friday/src/components/ArticleTOCPlain.astro

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
---
22
import type { MarkdownHeading } from 'astro'
3-
import config from 'virtual:astro-friday-config'
3+
import type { Schema } from '../collection'
44
55
interface Props {
66
headings: MarkdownHeading[]
7+
toc: Required<Omit<NonNullable<Schema['toc']>, 'enable'>>
78
isResolved?: boolean
89
class?: string
910
}
@@ -14,11 +15,12 @@ interface MarkdownHeadingNested extends MarkdownHeading {
1415
1516
const {
1617
headings,
18+
toc,
1719
isResolved,
1820
class: className,
1921
} = Astro.props
2022
21-
const includeHeadings = headings.filter(i => i.depth >= config.post.toc.range[0] && i.depth <= config.post.toc.range[1])
23+
const includeHeadings = headings.filter(i => i.depth >= toc.range[0] && i.depth <= toc.range[1])
2224
2325
const resolvedHeadings = isResolved
2426
? (includeHeadings as MarkdownHeadingNested[])
@@ -69,6 +71,7 @@ function resolveHeadings(headings_: MarkdownHeading[]): MarkdownHeadingNested[]
6971
{heading.children && heading.children.length > 0 && (
7072
<Astro.self
7173
headings={heading.children}
74+
{toc}
7275
isResolved={true}
7376
/>
7477
)}

packages/astro-friday/src/config.ts

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type nprogress from 'astro-nprogress'
33
import type { Props as SEO } from 'astro-seo'
44
import type { glob } from 'astro/loaders'
55
import type { SetRequiredDeep } from 'type-fest'
6+
import type { Schema } from './collection'
67
import type { ArtConfig, NavItem, ProjectItem } from './types'
78
import path from 'node:path'
89
import { defu } from 'defu'
@@ -190,24 +191,14 @@ export interface Config {
190191
*/
191192
pathStyle?: 'collection/id' | 'id'
192193
/**
193-
* Table of contents (TOC) generation for posts
194+
* Table of contents (TOC) generation for all content
195+
*
196+
* NOTE: this is just a default config for all content, can be overridden in
197+
* specific content frontmatter
198+
*
199+
* @default { enable: true, range: [2, 4] }
194200
*/
195-
toc?: {
196-
/**
197-
* Enable or disable the table of contents (TOC) generation for posts.
198-
*
199-
* @default true
200-
*/
201-
enable?: boolean
202-
/**
203-
* The heading levels to include in the TOC.
204-
*
205-
* @example [2, 4] will include headings from h2 to h4.
206-
*
207-
* @default [2, 4]
208-
*/
209-
range?: [number, number]
210-
}
201+
toc?: Partial<Schema['toc']>
211202
}
212203
/**
213204
* Define content collections

packages/astro-friday/src/routes/post/[...slug].astro

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ const {
3030
headings,
3131
// @ts-expect-error never
3232
} = await render(entry)
33+
34+
const toc = {
35+
...config.post.toc,
36+
...entry.data.toc,
37+
}
3338
---
3439

3540
<DefaultLayout
@@ -71,7 +76,7 @@ const {
7176
}}
7277
>
7378
<ArticleDetail {entry}>
74-
{ config.post.toc.enable && headings.length ? (<ArticleTOC {headings} />) : null }
79+
{ toc.enable && headings.length ? (<ArticleTOC {headings} {toc} />) : null }
7580

7681
<Content />
7782
</ArticleDetail>

packages/astro-friday/src/routes/project/index.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const headings = Object.entries(categorizedProjects).map(([category, _projects])
2525

2626
<DefaultLayout>
2727
<div class="mx-auto max-w-300">
28-
<ArticleTOC {headings} />
28+
<ArticleTOC {headings} toc={config.post.toc} />
2929

3030
{
3131
Object.entries(categorizedProjects || {}).map(([category, projects], _cidx) => (

0 commit comments

Comments
 (0)