From 683d1b75039dcf469fcde0ba65d68620a1359143 Mon Sep 17 00:00:00 2001 From: olayway Date: Wed, 1 Jun 2022 16:17:59 +0200 Subject: [PATCH] [components/MDX][m]: logic moved to custom hook --- site/components/Heading.js | 3 +- site/components/MDX.js | 48 ++------------------- site/components/_getIntersectionObserver.js | 16 ------- 3 files changed, 5 insertions(+), 62 deletions(-) delete mode 100644 site/components/_getIntersectionObserver.js diff --git a/site/components/Heading.js b/site/components/Heading.js index 9265ef6..74b91fd 100644 --- a/site/components/Heading.js +++ b/site/components/Heading.js @@ -3,7 +3,8 @@ import React, { useEffect, useState } from 'react'; export const Heading = ({ level, observer }) => (props) => { useEffect(() => { - // start observing heading's intersection with the bounding box set by observer's `rootMargin` + /* start observing heading's intersection with the bounding box + * set by observer's `rootMargin` */ if (observer) { observer.observe(document.getElementById(props.id)); } diff --git a/site/components/MDX.js b/site/components/MDX.js index 90e1549..3ff9d1d 100644 --- a/site/components/MDX.js +++ b/site/components/MDX.js @@ -4,9 +4,8 @@ import { useState, useEffect } from "react"; import { YOUTUBE_REGEX } from "../lib/constants"; import siteConfig from "../config/siteConfig"; -import getMDXComponents from "./_getMDXComponents"; -import getObserver from "./_getIntersectionObserver" -import MdxContent from "./MdxContent" +import MdxContent from './MdxContent' +import useHeadingsObserver from '../hooks/useHeadingsObserver' // import { Paragraph } from "./Paragraph"; // import { Anchor } from "./Anchor"; @@ -18,48 +17,7 @@ import MdxContent from "./MdxContent" // const Paragraph = dynamic(() => import("./Paragraph").then(mod => mod.Paragraph)) export default function MdxPage({ body, frontMatter, editUrl }) { - const [activeHeading, setActiveHeading] = useState(""); - const [observer, setObserver] = useState(null); - - // run only after first render, in order to preserve the observer - // between component rerenders - useEffect((() => { - const observer = getObserver((entry) => { - if (entry.isIntersecting) { - setActiveHeading(entry.target.id); - } - }); - setObserver(observer); - - return observer.disconnect(); - }), []) - - useEffect(() => { - // on initial render activeHeading will be `null` - // however, we still want to highlight the current heading in the toc - // based on the current url - if (!activeHeading) { - try { - const path = window.location.hash; - if (path) { - setActiveHeading(path.slice(1)) - } else { - const firstTocHeading = document.querySelector(".toc-link"); - const href = firstTocHeading.href; - setActiveHeading(href.match(/.+#(.+)/)[1]); - } - } finally { - return - } - } - - const tocLink = document.querySelector(`.toc-link[href="#${activeHeading}"]`) - tocLink.classList.add("active"); - - return () => { - tocLink.classList.remove("active") - } - }, [activeHeading]) + const observer = useHeadingsObserver(); const { title, description, date, authors, youtube, podcast, image, _raw diff --git a/site/components/_getIntersectionObserver.js b/site/components/_getIntersectionObserver.js deleted file mode 100644 index b69fce2..0000000 --- a/site/components/_getIntersectionObserver.js +++ /dev/null @@ -1,16 +0,0 @@ -// an Intersection Observer to keep track of currently viewed headings -const getIntersectionObserver = (callback) => { - return new IntersectionObserver( - (entries) => { - entries.forEach((entry) => { - callback(entry); - }); - }, - { - root: null, - rootMargin: "-65px 0% -90% 0%" // 65px is a navbar height - } - ); -}; - -export default getIntersectionObserver;