vite-bolt/plugin/common/MdToc.tsx

66 lines
1.5 KiB
TypeScript
Raw Permalink Normal View History

2023-02-01 17:52:53 +08:00
import { useEffect, useState } from "react";
import { TToc } from "../types";
import { scroller } from "react-scroll";
interface IProps {
children?: any;
toc: TToc[];
}
const tocEndItem: TToc = {
content: "API",
slug: "API",
lvl: 1,
anchor: "anchor-api-table",
};
export default function Toc(props: IProps) {
const [contentTable, setContentTable] = useState<TToc[]>([]);
useEffect(() => {
const tocWithApiItem = [...props.toc, tocEndItem];
props.toc?.length > 0
? setContentTable(tocWithApiItem.map((i) => ({ ...i, active: false })))
: setContentTable([]);
}, [props.toc]);
/**
* toc
*/
const onClickTocItem = (anchor: string) => {
setContentTable((p) =>
p?.map((i) => ({ ...i, active: i.anchor === anchor }))
);
scroller.scrollTo(anchor, {
duration: 800,
delay: 0,
smooth: "easeInOutQuart",
offset: -28,
});
};
return (
<div className="toc curtain-bottom">
<h4></h4>
{contentTable && (
<ul className="hidden-scrollbar">
{contentTable.map((item: TToc) => {
return (
<li key={item.content}>
<div
onClick={() => onClickTocItem(item.anchor)}
className={`toc-lvl toc-lvl-${item.lvl} ${
item.active ? "active" : ""
}`}
>
{item.content}
</div>
</li>
);
})}
</ul>
)}
</div>
);
}