From a5e6692f6dcab2157dc92b509f61418c06b2ebd7 Mon Sep 17 00:00:00 2001
From: Armand Philippot <git@armandphilippot.com>
Date: Wed, 21 Sep 2022 13:50:18 +0200
Subject: fix(projects): load content dynamically and refresh table of contents

The previous way of handling content import was causing issue. So I use
dynamic import instead. However, the table of contents was not
displayed because the wrapper is first empty. I added a mutation
observer to refresh the table of contents when the body is updated.
---
 src/utils/hooks/use-headings-tree.tsx | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

(limited to 'src/utils/hooks/use-headings-tree.tsx')

diff --git a/src/utils/hooks/use-headings-tree.tsx b/src/utils/hooks/use-headings-tree.tsx
index 4646b4a..f7ab452 100644
--- a/src/utils/hooks/use-headings-tree.tsx
+++ b/src/utils/hooks/use-headings-tree.tsx
@@ -1,5 +1,6 @@
 import { slugify } from '@utils/helpers/strings';
 import { useCallback, useEffect, useMemo, useState } from 'react';
+import { useMutationObserver } from './use-mutation-observer';
 
 export type Heading = {
   /**
@@ -32,13 +33,23 @@ const useHeadingsTree = (wrapper: HTMLElement): Heading[] => {
     useState<NodeListOf<HTMLHeadingElement>>();
   const [headingsTree, setHeadingsTree] = useState<Heading[]>([]);
 
-  useEffect(() => {
+  const getHeadingsInWrapper = useCallback(() => {
     const query = depths.join(', ');
     const result: NodeListOf<HTMLHeadingElement> =
       wrapper.querySelectorAll(query);
     setAllHeadings(result);
   }, [depths, wrapper]);
 
+  useEffect(() => {
+    getHeadingsInWrapper();
+  }, [getHeadingsInWrapper]);
+
+  useMutationObserver({
+    callback: getHeadingsInWrapper,
+    options: { childList: true },
+    nodeOrSelector: wrapper,
+  });
+
   const getDepth = useCallback(
     /**
      * Retrieve the heading element depth.
-- 
cgit v1.2.3

