From abac2ca2c51786a32bdea5cc175f2c6942746b11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=9E=E6=B3=95=E6=93=8D=E4=BD=9C?= Date: Mon, 3 Mar 2025 18:54:01 +0800 Subject: [PATCH] Feat: add toc to api doc (#5552) ### What problem does this PR solve? the api doc is too long, add a toc might be better ![CleanShot 2025-03-03 at 16 53 17](https://github.com/user-attachments/assets/9dfbc682-fdbf-4b37-8a01-87049db51f86) ### Type of change - [ ] Bug Fix (non-breaking change which fixes an issue) - [x] New Feature (non-breaking change which adds functionality) - [ ] Documentation Update - [ ] Refactoring - [ ] Performance Improvement - [ ] Other (please describe): --- .../chat-overview-modal/api-content.tsx | 4 + .../chat-overview-modal/markdown-toc.tsx | 74 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 web/src/components/api-service/chat-overview-modal/markdown-toc.tsx diff --git a/web/src/components/api-service/chat-overview-modal/api-content.tsx b/web/src/components/api-service/chat-overview-modal/api-content.tsx index cd00e69fe..c2189998a 100644 --- a/web/src/components/api-service/chat-overview-modal/api-content.tsx +++ b/web/src/components/api-service/chat-overview-modal/api-content.tsx @@ -5,6 +5,7 @@ import { Button, Card, Flex, Space } from 'antd'; import ChatApiKeyModal from '../chat-api-key-modal'; import { usePreviewChat } from '../hooks'; import BackendServiceApi from './backend-service-api'; +import MarkdownToc from './markdown-toc'; const ApiContent = ({ id, @@ -42,6 +43,9 @@ const ApiContent = ({ )} +
+ +
{apiKeyVisible && ( diff --git a/web/src/components/api-service/chat-overview-modal/markdown-toc.tsx b/web/src/components/api-service/chat-overview-modal/markdown-toc.tsx new file mode 100644 index 000000000..25e29b1a1 --- /dev/null +++ b/web/src/components/api-service/chat-overview-modal/markdown-toc.tsx @@ -0,0 +1,74 @@ +import { Anchor } from 'antd'; +import type { AnchorLinkItemProps } from 'antd/es/anchor/Anchor'; +import React, { useEffect, useState } from 'react'; + +interface MarkdownTocProps { + content: string; +} + +const MarkdownToc: React.FC = ({ content }) => { + const [items, setItems] = useState([]); + + useEffect(() => { + const generateTocItems = () => { + const headings = document.querySelectorAll( + '.wmde-markdown h2, .wmde-markdown h3', + ); + const tocItems: AnchorLinkItemProps[] = []; + let currentH2Item: AnchorLinkItemProps | null = null; + + headings.forEach((heading) => { + const title = heading.textContent || ''; + const id = heading.id; + const isH2 = heading.tagName.toLowerCase() === 'h2'; + + if (id && title) { + const item: AnchorLinkItemProps = { + key: id, + href: `#${id}`, + title, + }; + + if (isH2) { + currentH2Item = item; + tocItems.push(item); + } else { + if (currentH2Item) { + if (!currentH2Item.children) { + currentH2Item.children = []; + } + currentH2Item.children.push(item); + } else { + tocItems.push(item); + } + } + } + }); + + setItems(tocItems.slice(1)); + }; + + setTimeout(generateTocItems, 100); + }, [content]); + + return ( +
+ +
+ ); +}; + +export default MarkdownToc;