Skip to content

Commit

Permalink
feat: 根据MD文件标题级别展示出锚点层级 (#259)
Browse files Browse the repository at this point in the history
* feat: 添加文档锚点功能

* fix: 优化代码

* feat: 根据MD文件标题级别展示出锚点层级
  • Loading branch information
nullptr-z authored Jun 12, 2023
1 parent e2a2e03 commit 02f4bbd
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 26 deletions.
4 changes: 0 additions & 4 deletions examples/website/src/components/Layouts/index/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import React, { useState, useEffect } from 'react'
import { ConfigProvider, theme } from 'antd'
import '@wcj/dark-mode';
import HomeFooter from './HomeFooter';
import AnchorRight from '../Anchor';

export default function Layout(props: KktproPageProps) {
const { pathname } = useLocation();
Expand Down Expand Up @@ -37,9 +36,6 @@ export default function Layout(props: KktproPageProps) {
<Menu />
<div style={{ paddingLeft: 240, paddingTop: 58, height: '100%' }}>
<Outlet />
<div style={{ position: 'fixed', marginLeft: 1150, top: 100 }}>
<AnchorRight />
</div>
</div>
</React.Fragment>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export function useComponentMarkdown() {
const componentName = pathname?.split('/').at(-1);
if (componentName) {
try {
const mdText = require(`../../../pages/${componentName}/README.md`)
?.default?.source;
const mdText = require(`src/pages/${componentName}/README.md`)?.default
?.source;
return mdText;
} catch {}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,54 +1,53 @@
import { Anchor } from 'antd';
import { useEffect, useState } from 'react';
import remark from 'remark';
import { useComponentMarkdown } from './hooks';

export default function Anchors() {
const markdownText = useComponentMarkdown();
export default function Anchors({ markdownText }) {
const [items, setItems] = useState([]);

function traverse(node, headers = []) {
function traverse(node, stack = [{ children: [] }]) {
let currentHeader = null;

if (node.type === 'heading') {
// 英文转小写,去首尾空白和标点符号,中间空格替换成-
const text = node.children[0].value;
const href = text
?.toLowerCase()
.replace(/^[^\w\u4e00-\u9fa5]+|[^\w\u4e00-\u9fa5]+$/g, '')
.replace(/\s+/g, '-')
.replace(/\./g, '');
.replace(/^[^\w\u4e00-\u9fa5]+|[^\w\u4e00-\u9fa5]+$|[\n+/\/@\.]/g, '')
.replace(/\s+/g, '-');

const level = node.depth;
currentHeader = { text, href, level, children: [] };

if (level === 1) {
headers.push(currentHeader);
} else {
const parentHeader = headers[headers.length - 1];
if (parentHeader) {
parentHeader.children.push(currentHeader);
let top = stack[stack.length - 1];

while (stack.length > level) {
stack.pop();
top = stack[stack.length - 1];
}

if (level > stack.length) {
if (top.children.length > 0) {
stack.push(top.children[top.children.length - 1]);
}
}

top.children.push(currentHeader);
}

if (node.children) {
for (let i = 0; i < node.children.length; i++) {
traverse(
node.children[i],
currentHeader ? currentHeader.children : headers,
);
traverse(node.children[i], stack);
}
}

return headers;
return stack[0].children;
}

useEffect(() => {
const processor = remark();
const ast = processor.parse(markdownText);
const headers = traverse(ast);

const items = createItems(headers);
setItems(items);
}, [markdownText]);
Expand All @@ -73,6 +72,7 @@ export default function Anchors() {
<Anchor
items={items}
onClick={(e, link) => {
console.log('link: ', link);
e.preventDefault();
const element = document.getElementById(link.href);
element?.scrollIntoView({ behavior: 'instant', block: 'start' });
Expand Down
6 changes: 6 additions & 0 deletions examples/website/src/components/Preview/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import Loading from '../Loading';
import BackToUp from '@uiw/react-back-to-top';
import Footer from "../Footer"
import './nodes/toc.less';
import { useHyperlink } from './useHyperlink';
import Anchors from './Anchor';

const Preview = CodeLayout.Preview;
const Code = CodeLayout.Code;
Expand Down Expand Up @@ -58,6 +60,7 @@ const Markdown = styled<
const PreviewDocument = ({ path, editePath }: { path: MdDataHandle, editePath: string; }) => {
const $dom = useRef<HTMLDivElement>(null);
const { mdData, loading } = useMdData(path);
useHyperlink($dom.current);
return (
<Wrapper ref={$dom}>
<Loading loading={loading}>
Expand Down Expand Up @@ -151,6 +154,9 @@ const PreviewDocument = ({ path, editePath }: { path: MdDataHandle, editePath: s
<BackToUp element={$dom.current} style={{ float: 'right' }}>
Top
</BackToUp>
<div style={{ position: 'fixed', marginLeft: 1150, top: 100 }}>
<Anchors markdownText={mdData.source} />
</div>
</Wrapper>
);
};
Expand Down
2 changes: 1 addition & 1 deletion examples/website/src/components/Preview/useHyperlink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const useHyperlink = (dom: HTMLDivElement | null) => {
target.classList.add('active');
}
};
const scrollFn = () => {};
const scrollFn = () => { };
const scrollEndFn = () => {
const $main = document.getElementsByTagName(
'main',
Expand Down

0 comments on commit 02f4bbd

Please sign in to comment.