aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/organisms/widgets/toc-widget/toc-widget.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/organisms/widgets/toc-widget/toc-widget.tsx')
-rw-r--r--src/components/organisms/widgets/toc-widget/toc-widget.tsx44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/components/organisms/widgets/toc-widget/toc-widget.tsx b/src/components/organisms/widgets/toc-widget/toc-widget.tsx
new file mode 100644
index 0000000..c2d015a
--- /dev/null
+++ b/src/components/organisms/widgets/toc-widget/toc-widget.tsx
@@ -0,0 +1,44 @@
+import { type ForwardRefRenderFunction, forwardRef } from 'react';
+import type { HeadingsTreeNode } from '../../../../utils/hooks';
+import {
+ LinksWidget,
+ type LinksWidgetItemData,
+ type LinksWidgetProps,
+} from '../links-widget';
+import styles from './toc-widget.module.scss';
+
+const getLinksItemFrom = (tree: HeadingsTreeNode[]): LinksWidgetItemData[] =>
+ tree.map((node) => {
+ return {
+ child: node.children.length ? getLinksItemFrom(node.children) : undefined,
+ id: node.id,
+ label: node.label,
+ url: `#${node.id}`,
+ };
+ });
+
+export type TocWidgetProps = Omit<LinksWidgetProps, 'isOrdered' | 'items'> & {
+ /**
+ * The headings tree.
+ */
+ tree: HeadingsTreeNode[];
+};
+
+const TocWidgetWithRef: ForwardRefRenderFunction<
+ HTMLDivElement,
+ TocWidgetProps
+> = ({ className = '', tree, ...props }, ref) => {
+ const wrapperClass = `${styles.toc} ${className}`;
+
+ return (
+ <LinksWidget
+ {...props}
+ className={wrapperClass}
+ isOrdered
+ items={getLinksItemFrom(tree)}
+ ref={ref}
+ />
+ );
+};
+
+export const TocWidget = forwardRef(TocWidgetWithRef);