Skip to content

Commit d9fa7ad

Browse files
authored
tweak: toc with heading & styles (#573)
* tweak: toc with heading & styles * test: update docs * test: tidbcloud TOC * test: TOC * tweak: styles * tweak: styles * tweak: query * chore: preview * tweak: toc styles * fix: chevron icon * chore: revert submodule * fix: styles * tweak: styles
1 parent ac2d151 commit d9fa7ad

File tree

6 files changed

+179
-129
lines changed

6 files changed

+179
-129
lines changed

gatsby/create-types.ts

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { CreatePagesArgs } from 'gatsby'
2-
import { generateConfig } from './path'
3-
import { mdxAstToToc } from './toc'
4-
import { Root, List } from 'mdast'
1+
import { CreatePagesArgs } from "gatsby";
2+
import { generateConfig } from "./path";
3+
import { mdxAstToToc } from "./toc";
4+
import { Root, List } from "mdast";
55

66
export const createExtraType = ({ actions }: CreatePagesArgs) => {
7-
const { createTypes, createFieldExtension } = actions
7+
const { createTypes, createFieldExtension } = actions;
88

99
const typeDefs = `
1010
"""
@@ -26,12 +26,12 @@ export const createExtraType = ({ actions }: CreatePagesArgs) => {
2626
hide_commit: Boolean
2727
hide_leftNav: Boolean
2828
}
29-
`
29+
`;
3030

31-
createTypes(typeDefs)
31+
createTypes(typeDefs);
3232

3333
createFieldExtension({
34-
name: 'navigation',
34+
name: "navigation",
3535
extend() {
3636
return {
3737
async resolve(
@@ -40,38 +40,34 @@ export const createExtraType = ({ actions }: CreatePagesArgs) => {
4040
context: unknown,
4141
info: any
4242
) {
43-
if (mdxNode.nav) return mdxNode.nav
44-
const types = info.schema.getType('Mdx').getFields()
45-
const slug = await types['slug'].resolve(mdxNode, args, context, {
46-
fieldName: 'slug',
47-
})
43+
if (mdxNode.nav) return mdxNode.nav;
44+
const types = info.schema.getType("Mdx").getFields();
45+
const slug = await types["slug"].resolve(mdxNode, args, context, {
46+
fieldName: "slug",
47+
});
4848

49-
const mdxAST: Root = await types['mdxAST'].resolve(
49+
const mdxAST: Root = await types["mdxAST"].resolve(
5050
mdxNode,
5151
args,
5252
context,
5353
{
54-
fieldName: 'mdxAST',
54+
fieldName: "mdxAST",
5555
}
56-
)
56+
);
5757

58-
if (!slug.endsWith('TOC'))
59-
throw new Error(`unsupported query in ${slug}`)
60-
const { config } = generateConfig(slug)
61-
const res = mdxAstToToc(
62-
(mdxAST.children.find(node => node.type === 'list') as List)
63-
.children,
64-
config
65-
)
66-
mdxNode.nav = res
67-
return res
58+
if (!slug.endsWith("TOC"))
59+
throw new Error(`unsupported query in ${slug}`);
60+
const { config } = generateConfig(slug);
61+
const res = mdxAstToToc(mdxAST.children, config);
62+
mdxNode.nav = res;
63+
return res;
6864
},
69-
}
65+
};
7066
},
71-
})
67+
});
7268
createTypes(`
7369
type Mdx implements Node {
7470
navigation: JSON! @navigation
7571
}
76-
`)
77-
}
72+
`);
73+
};

gatsby/toc.ts

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,86 @@
1-
import { ListItem, List, Link, Paragraph, Text } from "mdast";
1+
import {
2+
ListItem,
3+
List,
4+
Link,
5+
Paragraph,
6+
Text,
7+
Content,
8+
PhrasingContent,
9+
Heading,
10+
} from "mdast";
211

312
import { RepoNav, RepoNavLink, PathConfig } from "../src/shared/interface";
413
import { generateUrl } from "./path";
514

615
export function mdxAstToToc(
7-
ast: ListItem[],
16+
ast: Content[],
817
config: PathConfig,
918
prefixId = `0`
1019
): RepoNav {
20+
return ast
21+
.filter(
22+
(node) =>
23+
node.type === "list" || (node.type === "heading" && node.depth > 1)
24+
)
25+
.map((node, idx) => {
26+
if (node.type === "list") {
27+
return handleList(node.children, config, `${prefixId}-${idx}`);
28+
} else {
29+
return handleHeading((node as Heading).children, `${prefixId}-${idx}`);
30+
}
31+
})
32+
.flat();
33+
}
34+
35+
function handleList(ast: ListItem[], config: PathConfig, prefixId = `0`) {
1136
return ast.map((node, idx) => {
1237
const content = node.children as [Paragraph, List | undefined];
1338
if (content.length > 0 && content.length <= 2) {
14-
const ret = getContentFromLink(content[0], config);
39+
const ret = getContentFromLink(content[0], config, `${prefixId}-${idx}`);
1540

1641
if (content[1]) {
1742
const list = content[1];
1843
if (list.type !== "list") {
1944
throw new Error(`incorrect listitem in TOC.md`);
2045
}
2146

22-
ret.children = mdxAstToToc(list.children, config, `${prefixId}-${idx}`);
47+
ret.children = handleList(list.children, config, `${prefixId}-${idx}`);
2348
}
2449

25-
ret.id = `${prefixId}-${idx}`;
26-
2750
return ret;
2851
}
2952

3053
throw new Error(`incorrect format in TOC.md`);
3154
});
3255
}
3356

57+
function handleHeading(ast: PhrasingContent[], id = `0`): RepoNavLink[] {
58+
const child = ast[0] as Text;
59+
return [
60+
{
61+
type: "heading",
62+
content: [child.value],
63+
id,
64+
},
65+
];
66+
}
67+
3468
function getContentFromLink(
3569
content: Paragraph,
36-
config: PathConfig
70+
config: PathConfig,
71+
id: string
3772
): RepoNavLink {
3873
if (content.type !== "paragraph" || content.children.length === 0) {
3974
throw new Error(`incorrect format in TOC.md`);
4075
}
4176

4277
const child = content.children[0] as Link | Text;
78+
// use `image` as tag
79+
const image = content.children.find((n) => n.type === "image");
80+
const tag = image && {
81+
value: image.alt!,
82+
query: `?${image.url.split("?")[1]}`,
83+
};
4384

4485
if (child.type === "link") {
4586
if (child.children.length === 0) {
@@ -59,21 +100,30 @@ function getContentFromLink(
59100

60101
if (child.url.startsWith("https://")) {
61102
return {
103+
type: "nav",
62104
link: child.url,
63105
content,
106+
tag,
107+
id,
64108
};
65109
}
66110

67111
const urlSegs = child.url.split("/");
68112
const filename = urlSegs[urlSegs.length - 1].replace(".md", "");
69113

70114
return {
115+
type: "nav",
71116
link: generateUrl(filename, config),
72117
content,
118+
tag,
119+
id,
73120
};
74121
} else {
75122
return {
123+
type: "nav",
76124
content: [child.value],
125+
tag,
126+
id,
77127
};
78128
}
79129
}

src/components/Layout/Seo.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,13 @@ export default function Seo({
123123
...meta,
124124
]}
125125
link={[
126+
{
127+
rel: "icon",
128+
href: favicon.publicURL,
129+
},
126130
{
127131
rel: "shortcut icon",
128132
href: favicon.publicURL,
129-
type: "image/x-icon",
130133
},
131134
...link,
132135
]}

src/components/Navigation/LeftNav.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import Divider from "@mui/material/Divider";
88
import IconButton from "@mui/material/IconButton";
99
import MenuIcon from "@mui/icons-material/Menu";
1010

11-
import { DocLeftNav, PathConfig, BuildType } from "shared/interface";
11+
import { RepoNav, PathConfig, BuildType } from "shared/interface";
1212
import LinkComponent from "components/Link";
1313
import LeftNavTree from "components/Navigation/LeftNavTree";
1414
import VersionSelect, {
@@ -18,7 +18,7 @@ import VersionSelect, {
1818
import TiDBLogoWithoutText from "media/logo/tidb-logo.svg";
1919

2020
interface LeftNavProps {
21-
data: DocLeftNav;
21+
data: RepoNav;
2222
current: string;
2323
name: string;
2424
pathConfig: PathConfig;
@@ -44,11 +44,12 @@ export function LeftNavDesktop(props: LeftNavProps) {
4444
<Box
4545
sx={{
4646
position: "sticky",
47-
top: "5rem",
47+
top: "80px",
4848
height: "100%",
49-
maxHeight: "calc(100vh - 7rem)",
49+
maxHeight: "calc(100vh - 80px)",
50+
boxSizing: "border-box",
5051
overflowY: "auto",
51-
padding: "28px 1rem",
52+
padding: "20px 14px",
5253
}}
5354
>
5455
{pathConfig.repo !== "tidbcloud" && (

0 commit comments

Comments
 (0)