66 lines
1.5 KiB
TypeScript
66 lines
1.5 KiB
TypeScript
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>
|
|
);
|
|
}
|