This commit is contained in:
fantasticit 2023-04-09 12:13:13 +08:00
parent 9a91dd2f6d
commit c840aa140b
2 changed files with 36 additions and 16 deletions

View File

@ -9,7 +9,7 @@ import { TableOfContents } from 'tiptap/core/extensions/table-of-contents';
import { findNode } from 'tiptap/prose-utils';
import styles from './index.module.scss';
import { flattenHeadingsToTree } from './util';
import { flattenHeadingsToTree, parseHeadingsToTocs } from './util';
interface IHeading {
level: number;
@ -124,7 +124,7 @@ export const Tocs: React.FC<{ editor: Editor; getContainer: () => HTMLElement }>
editor.view.dispatch(transaction);
setHeadings(headings);
setNestedHeadings(flattenHeadingsToTree(headings));
setNestedHeadings(parseHeadingsToTocs(headings));
}, [editor]);
useEffect(() => {
@ -161,7 +161,7 @@ export const Tocs: React.FC<{ editor: Editor; getContainer: () => HTMLElement }>
? headings.map((toc) => {
return (
<Anchor.Link
key={'collapsed-' + toc.text}
key={'collapsed-' + toc.id}
href={`#${toc.id}`}
title={
<Tooltip key={toc.text} content={toc.text} position="right">
@ -171,7 +171,7 @@ export const Tocs: React.FC<{ editor: Editor; getContainer: () => HTMLElement }>
/>
);
})
: nestedHeadings.map((toc) => <Toc key={'!collapsed-' + toc.text} toc={toc} collapsed={collapsed} />)}
: nestedHeadings.map((toc) => <Toc key={'!collapsed-' + toc.id} toc={toc} collapsed={collapsed} />)}
</Anchor>
</div>
);

View File

@ -1,18 +1,38 @@
export const flattenHeadingsToTree = (tocs) => {
const result = [];
const levels = [result];
export const parseHeadingsToTocs = (headings) => {
const list = JSON.parse(JSON.stringify(headings));
const ret = [];
tocs.forEach((o) => {
let offset = -1;
let parent = levels[o.level + offset];
list.forEach((heading, index) => {
const prev = list[index - 1];
while (!parent) {
offset -= 1;
parent = levels[o.level + offset];
if (!prev) {
ret.push(heading);
} else {
if (prev.level < heading.level) {
heading.parent = prev;
prev.children = prev.children || [];
prev.children.push(heading);
} else {
let parent = prev.parent;
let shouldContinue = true;
while (shouldContinue) {
if (!parent) {
shouldContinue = false;
ret.push(heading);
} else if (parent.level < heading.level) {
heading.parent = parent;
parent.children = parent.children || [];
parent.children.push(heading);
shouldContinue = false;
} else {
parent = parent.parent;
}
}
}
}
parent.push({ ...o, children: (levels[o.level] = []) });
});
return result;
return ret;
};