Skip to content

Commit

Permalink
tweak: toc with heading & styles (#573)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
shhdgit authored Jan 10, 2025
1 parent ac2d151 commit d9fa7ad
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 129 deletions.
56 changes: 26 additions & 30 deletions gatsby/create-types.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { CreatePagesArgs } from 'gatsby'
import { generateConfig } from './path'
import { mdxAstToToc } from './toc'
import { Root, List } from 'mdast'
import { CreatePagesArgs } from "gatsby";
import { generateConfig } from "./path";
import { mdxAstToToc } from "./toc";
import { Root, List } from "mdast";

export const createExtraType = ({ actions }: CreatePagesArgs) => {
const { createTypes, createFieldExtension } = actions
const { createTypes, createFieldExtension } = actions;

const typeDefs = `
"""
Expand All @@ -26,12 +26,12 @@ export const createExtraType = ({ actions }: CreatePagesArgs) => {
hide_commit: Boolean
hide_leftNav: Boolean
}
`
`;

createTypes(typeDefs)
createTypes(typeDefs);

createFieldExtension({
name: 'navigation',
name: "navigation",
extend() {
return {
async resolve(
Expand All @@ -40,38 +40,34 @@ export const createExtraType = ({ actions }: CreatePagesArgs) => {
context: unknown,
info: any
) {
if (mdxNode.nav) return mdxNode.nav
const types = info.schema.getType('Mdx').getFields()
const slug = await types['slug'].resolve(mdxNode, args, context, {
fieldName: 'slug',
})
if (mdxNode.nav) return mdxNode.nav;
const types = info.schema.getType("Mdx").getFields();
const slug = await types["slug"].resolve(mdxNode, args, context, {
fieldName: "slug",
});

const mdxAST: Root = await types['mdxAST'].resolve(
const mdxAST: Root = await types["mdxAST"].resolve(
mdxNode,
args,
context,
{
fieldName: 'mdxAST',
fieldName: "mdxAST",
}
)
);

if (!slug.endsWith('TOC'))
throw new Error(`unsupported query in ${slug}`)
const { config } = generateConfig(slug)
const res = mdxAstToToc(
(mdxAST.children.find(node => node.type === 'list') as List)
.children,
config
)
mdxNode.nav = res
return res
if (!slug.endsWith("TOC"))
throw new Error(`unsupported query in ${slug}`);
const { config } = generateConfig(slug);
const res = mdxAstToToc(mdxAST.children, config);
mdxNode.nav = res;
return res;
},
}
};
},
})
});
createTypes(`
type Mdx implements Node {
navigation: JSON! @navigation
}
`)
}
`);
};
64 changes: 57 additions & 7 deletions gatsby/toc.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,86 @@
import { ListItem, List, Link, Paragraph, Text } from "mdast";
import {
ListItem,
List,
Link,
Paragraph,
Text,
Content,
PhrasingContent,
Heading,
} from "mdast";

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

export function mdxAstToToc(
ast: ListItem[],
ast: Content[],
config: PathConfig,
prefixId = `0`
): RepoNav {
return ast
.filter(
(node) =>
node.type === "list" || (node.type === "heading" && node.depth > 1)
)
.map((node, idx) => {
if (node.type === "list") {
return handleList(node.children, config, `${prefixId}-${idx}`);
} else {
return handleHeading((node as Heading).children, `${prefixId}-${idx}`);
}
})
.flat();
}

function handleList(ast: ListItem[], config: PathConfig, prefixId = `0`) {
return ast.map((node, idx) => {
const content = node.children as [Paragraph, List | undefined];
if (content.length > 0 && content.length <= 2) {
const ret = getContentFromLink(content[0], config);
const ret = getContentFromLink(content[0], config, `${prefixId}-${idx}`);

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

ret.children = mdxAstToToc(list.children, config, `${prefixId}-${idx}`);
ret.children = handleList(list.children, config, `${prefixId}-${idx}`);
}

ret.id = `${prefixId}-${idx}`;

return ret;
}

throw new Error(`incorrect format in TOC.md`);
});
}

function handleHeading(ast: PhrasingContent[], id = `0`): RepoNavLink[] {
const child = ast[0] as Text;
return [
{
type: "heading",
content: [child.value],
id,
},
];
}

function getContentFromLink(
content: Paragraph,
config: PathConfig
config: PathConfig,
id: string
): RepoNavLink {
if (content.type !== "paragraph" || content.children.length === 0) {
throw new Error(`incorrect format in TOC.md`);
}

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

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

if (child.url.startsWith("https://")) {
return {
type: "nav",
link: child.url,
content,
tag,
id,
};
}

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

return {
type: "nav",
link: generateUrl(filename, config),
content,
tag,
id,
};
} else {
return {
type: "nav",
content: [child.value],
tag,
id,
};
}
}
5 changes: 4 additions & 1 deletion src/components/Layout/Seo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,13 @@ export default function Seo({
...meta,
]}
link={[
{
rel: "icon",
href: favicon.publicURL,
},
{
rel: "shortcut icon",
href: favicon.publicURL,
type: "image/x-icon",
},
...link,
]}
Expand Down
11 changes: 6 additions & 5 deletions src/components/Navigation/LeftNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Divider from "@mui/material/Divider";
import IconButton from "@mui/material/IconButton";
import MenuIcon from "@mui/icons-material/Menu";

import { DocLeftNav, PathConfig, BuildType } from "shared/interface";
import { RepoNav, PathConfig, BuildType } from "shared/interface";
import LinkComponent from "components/Link";
import LeftNavTree from "components/Navigation/LeftNavTree";
import VersionSelect, {
Expand All @@ -18,7 +18,7 @@ import VersionSelect, {
import TiDBLogoWithoutText from "media/logo/tidb-logo.svg";

interface LeftNavProps {
data: DocLeftNav;
data: RepoNav;
current: string;
name: string;
pathConfig: PathConfig;
Expand All @@ -44,11 +44,12 @@ export function LeftNavDesktop(props: LeftNavProps) {
<Box
sx={{
position: "sticky",
top: "5rem",
top: "80px",
height: "100%",
maxHeight: "calc(100vh - 7rem)",
maxHeight: "calc(100vh - 80px)",
boxSizing: "border-box",
overflowY: "auto",
padding: "28px 1rem",
padding: "20px 14px",
}}
>
{pathConfig.repo !== "tidbcloud" && (
Expand Down
Loading

0 comments on commit d9fa7ad

Please sign in to comment.