Skip to content

Commit

Permalink
feat: display title in frontmatter as heading fallback (#1556)
Browse files Browse the repository at this point in the history
  • Loading branch information
JounQin authored Dec 17, 2024
1 parent 10e77df commit 5309967
Show file tree
Hide file tree
Showing 14 changed files with 143 additions and 2 deletions.
3 changes: 3 additions & 0 deletions e2e/fixtures/heading-title/doc/guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
title: Heading Title
---
16 changes: 16 additions & 0 deletions e2e/fixtures/heading-title/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "@rspress-fixture/rspress-heading-title",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "rspress dev",
"build": "rspress build",
"preview": "rspress preview"
},
"dependencies": {
"rspress": "workspace:*"
},
"devDependencies": {
"@types/node": "^18.11.17"
}
}
6 changes: 6 additions & 0 deletions e2e/fixtures/heading-title/rspress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as path from 'node:path';
import { defineConfig } from 'rspress/config';

export default defineConfig({
root: path.join(__dirname, 'doc'),
});
1 change: 1 addition & 0 deletions e2e/fixtures/heading-title/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
36 changes: 36 additions & 0 deletions e2e/tests/heading-title.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { expect, test } from '@playwright/test';
import path from 'node:path';
import { getPort, killProcess, runDevCommand } from '../utils/runCommands';

const fixtureDir = path.resolve(__dirname, '../fixtures');

test.describe('heading-title test', async () => {
let appPort;
let app;
test.beforeAll(async () => {
const appDir = path.join(fixtureDir, 'heading-title');
appPort = await getPort();
app = await runDevCommand(appDir, appPort);
});

test.afterAll(async () => {
if (app) {
await killProcess(app);
}
});

test('Guide page', async ({ page }) => {
await page.goto(`http://localhost:${appPort}/guide`, {
waitUntil: 'networkidle',
});
const h1 = await page.$('h1');
const className = await page.evaluate(h1 => h1?.className, h1);
expect(className).toContain('title_3b154'); // hash in css module should stable
const text = await page.evaluate(h1 => h1?.textContent, h1);
expect(text).toContain('Heading Title');
expect(await page.evaluate(h1 => h1?.id, h1)).toBe('heading-title');
expect(await page.evaluate(link => link?.hash, await h1?.$('a'))).toBe(
'#heading-title',
);
});
});
3 changes: 3 additions & 0 deletions packages/core/src/node/mdx/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ interface LoaderOptions {
export interface PageMeta {
toc: TocItem[];
title: string;
headingTitle: string;
frontmatter?: Record<string, any>;
}

Expand Down Expand Up @@ -167,6 +168,7 @@ export default async function mdxLoader(
pageMeta = {
...compilationMeta,
title: frontmatter.title || compilationMeta.title || '',
headingTitle: compilationMeta.title,
frontmatter,
} as PageMeta;
} else {
Expand All @@ -183,6 +185,7 @@ export default async function mdxLoader(
pageMeta = {
toc,
title: frontmatter.title || title || '',
headingTitle: title,
frontmatter,
};
// We should check dead links in mdx-rs mode
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/runtime/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export enum QueryStatus {

type PageMeta = {
title: string;
headingTitle: string;
toc: Header[];
frontmatter: Record<string, any>;
};
Expand Down
17 changes: 17 additions & 0 deletions packages/document/docs/en/api/config/config-theme.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -687,3 +687,20 @@ export default defineConfig({
},
});
```

## fallbackHeadingTitle

- Type: `boolean`
- Default: `true`

Whether to display [`frontmatter.title`](./config-frontmatter#title) as fallback when the heading title is not presented. For example:

```ts title="rspress.config.ts"
import { defineConfig } from 'rspress/config';

export default defineConfig({
themeConfig: {
fallbackHeadingTitle: false,
},
});
```
18 changes: 18 additions & 0 deletions packages/document/docs/zh/api/config/config-theme.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -673,3 +673,21 @@ export default defineConfig({
},
});
```

## fallbackHeadingTitle

- Type: `boolean`
- Default: `true`

是否在文档标题未提供时将 [`frontmatter.title`](./config-frontmatter#title) 作为后备内容。比如:


```ts title="rspress.config.ts"
import { defineConfig } from 'rspress/config';

export default defineConfig({
themeConfig: {
fallbackHeadingTitle: false,
},
});
```
5 changes: 5 additions & 0 deletions packages/shared/src/types/defaultTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ export interface Config {
* @default 'auto'
*/
localeRedirect?: 'auto' | 'never';
/**
* Whether to show the fallback heading title when the heading title is not presented but `frontmatter.title` exists
* @default true
*/
fallbackHeadingTitle?: boolean;
}

/**
Expand Down
1 change: 1 addition & 0 deletions packages/shared/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ export interface FrontMatterMeta {
export interface PageData {
siteData: SiteData<DefaultThemeConfig>;
page: BaseRuntimePageInfo & {
headingTitle?: string;
pagePath: string;
lastUpdatedTime?: string;
description?: string;
Expand Down
1 change: 1 addition & 0 deletions packages/theme-default/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"htmr": "^1.0.2",
"lodash-es": "^4.17.21",
"nprogress": "^0.2.0",
"github-slugger": "^2.0.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-helmet-async": "^1.3.0",
Expand Down
24 changes: 22 additions & 2 deletions packages/theme-default/src/layout/DocLayout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useState } from 'react';
import { useMemo, useState } from 'react';
import { MDXProvider } from '@mdx-js/react';
import { slug } from 'github-slugger';
import { getCustomMDXComponent, ScrollToTop, Overview } from '@theme';
import { Content, usePageData, NoSSR } from '@rspress/runtime';
import { Aside } from '../../components/Aside';
Expand All @@ -9,6 +10,8 @@ import { SideMenu } from '../../components/LocalSideBar';
import { TabDataContext } from '../../logic/TabDataContext';
import styles from './index.module.scss';
import type { UISwitchResult } from '../../logic/useUISwitch';
import { H1 } from './docComponents/title';
import { A } from './docComponents/link';

export interface DocLayoutProps {
beforeSidebar?: React.ReactNode;
Expand Down Expand Up @@ -43,7 +46,7 @@ export function DocLayout(props: DocLayoutProps) {
components,
} = props;
const { siteData, page } = usePageData();
const { toc = [], frontmatter } = page;
const { headingTitle, title, toc = [], frontmatter } = page;
const [tabData, setTabData] = useState({});
const headers = toc;
const { themeConfig } = siteData;
Expand All @@ -64,6 +67,22 @@ export function DocLayout(props: DocLayoutProps) {
</TabDataContext.Provider>
);

const fallbackTitle = useMemo(() => {
const titleSlug = title && slug(title);
return (
siteData.themeConfig.fallbackHeadingTitle !== false &&
!headingTitle &&
titleSlug && (
<H1 id={titleSlug}>
{title}
<A className="header-anchor" href={`#${titleSlug}`} aria-hidden>
#
</A>
</H1>
)
);
}, [headingTitle, title]);

return (
<div
className={`${styles.docLayout} pt-0`}
Expand Down Expand Up @@ -93,6 +112,7 @@ export function DocLayout(props: DocLayoutProps) {
<div>
<div className="rspress-doc">
{beforeDocContent}
{fallbackTitle}
{docContent}
{afterDocContent}
</div>
Expand Down
13 changes: 13 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 5309967

Please sign in to comment.