[components/MDX][m]: logic moved to custom hook
This commit is contained in:
parent
f83027bd8e
commit
683d1b7503
|
|
@ -3,7 +3,8 @@ import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
export const Heading = ({ level, observer }) => (props) => {
|
export const Heading = ({ level, observer }) => (props) => {
|
||||||
useEffect(() => {
|
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) {
|
if (observer) {
|
||||||
observer.observe(document.getElementById(props.id));
|
observer.observe(document.getElementById(props.id));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,8 @@ import { useState, useEffect } from "react";
|
||||||
|
|
||||||
import { YOUTUBE_REGEX } from "../lib/constants";
|
import { YOUTUBE_REGEX } from "../lib/constants";
|
||||||
import siteConfig from "../config/siteConfig";
|
import siteConfig from "../config/siteConfig";
|
||||||
import getMDXComponents from "./_getMDXComponents";
|
import MdxContent from './MdxContent'
|
||||||
import getObserver from "./_getIntersectionObserver"
|
import useHeadingsObserver from '../hooks/useHeadingsObserver'
|
||||||
import MdxContent from "./MdxContent"
|
|
||||||
|
|
||||||
// import { Paragraph } from "./Paragraph";
|
// import { Paragraph } from "./Paragraph";
|
||||||
// import { Anchor } from "./Anchor";
|
// import { Anchor } from "./Anchor";
|
||||||
|
|
@ -18,48 +17,7 @@ import MdxContent from "./MdxContent"
|
||||||
// const Paragraph = dynamic(() => import("./Paragraph").then(mod => mod.Paragraph))
|
// const Paragraph = dynamic(() => import("./Paragraph").then(mod => mod.Paragraph))
|
||||||
|
|
||||||
export default function MdxPage({ body, frontMatter, editUrl }) {
|
export default function MdxPage({ body, frontMatter, editUrl }) {
|
||||||
const [activeHeading, setActiveHeading] = useState("");
|
const observer = useHeadingsObserver();
|
||||||
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 {
|
const {
|
||||||
title, description, date, authors, youtube, podcast, image, _raw
|
title, description, date, authors, youtube, podcast, image, _raw
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
Loading…
Reference in New Issue