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

View File

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