summaryrefslogtreecommitdiffstats
path: root/src/components/organisms/widgets/table-of-contents.tsx
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2022-05-24 19:35:12 +0200
committerGitHub <noreply@github.com>2022-05-24 19:35:12 +0200
commitc85ab5ad43ccf52881ee224672c41ec30021cf48 (patch)
tree8058808d9bfca19383f120c46b34d99ff2f89f63 /src/components/organisms/widgets/table-of-contents.tsx
parent52404177c07a2aab7fc894362fb3060dff2431a0 (diff)
parent11b9de44a4b2f305a6a484187805e429b2767118 (diff)
refactor: use storybook and atomic design (#16)
BREAKING CHANGE: rewrite most of the Typescript types, so the content format (the meta in particular) needs to be updated.
Diffstat (limited to 'src/components/organisms/widgets/table-of-contents.tsx')
-rw-r--r--src/components/organisms/widgets/table-of-contents.tsx55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/components/organisms/widgets/table-of-contents.tsx b/src/components/organisms/widgets/table-of-contents.tsx
new file mode 100644
index 0000000..800ff58
--- /dev/null
+++ b/src/components/organisms/widgets/table-of-contents.tsx
@@ -0,0 +1,55 @@
+import useHeadingsTree, { type Heading } from '@utils/hooks/use-headings-tree';
+import { FC } from 'react';
+import { useIntl } from 'react-intl';
+import LinksListWidget, { type LinksListItems } from './links-list-widget';
+import styles from './table-of-contents.module.scss';
+
+type TableOfContentsProps = {
+ /**
+ * A reference to the HTML element that contains the headings.
+ */
+ wrapper: HTMLElement;
+};
+
+/**
+ * Table of Contents widget component
+ *
+ * Render a table of contents.
+ */
+const TableOfContents: FC<TableOfContentsProps> = ({ wrapper }) => {
+ const intl = useIntl();
+ const headingsTree = useHeadingsTree(wrapper);
+ const title = intl.formatMessage({
+ defaultMessage: 'Table of Contents',
+ description: 'TableOfContents: the widget title',
+ id: 'WKG9wj',
+ });
+
+ /**
+ * Convert an headings tree to list items.
+ *
+ * @param {Heading[]} tree - The headings tree.
+ * @returns {LinksListItems[]} The list items.
+ */
+ const getItems = (tree: Heading[]): LinksListItems[] => {
+ return tree.map((heading) => {
+ return {
+ name: heading.title,
+ url: `#${heading.id}`,
+ child: getItems(heading.children),
+ };
+ });
+ };
+
+ return (
+ <LinksListWidget
+ kind="ordered"
+ title={title}
+ level={2}
+ items={getItems(headingsTree)}
+ className={styles.list}
+ />
+ );
+};
+
+export default TableOfContents;