react-mdxutils
Version:
Utilities for MDX content, including anchor extraction.
2 lines (1 loc) • 1.64 kB
JavaScript
import{unified as v}from"unified";import H from"remark-parse";import y from"github-slugger";import{toc as E}from"mdast-util-toc";function L(n){let f=new y,g=E(n),o=[];function t(s,i){s.type==="list"&&s.children.forEach(e=>{let c=e.children?.[0]?.children?.[0]?.children?.[0]?.value||"";if(c&&i>1){let l=f.slug(c);o.push({content:c,slug:l,level:i})}let r=e.children?.find(l=>l.type==="list");r&&t(r,i+1)})}return g.map&&t(g.map,1),o}var w=n=>{let f=v().use(H).parse(n);return L(f)};import{useCallback as I,useEffect as b,useRef as h,useState as M}from"react";var S=n=>{let[f,g]=M(""),o=h({}),t=h(null),s=h(null),i=I((e,a)=>{g(a||""),!(!t.current||!e)&&requestAnimationFrame(()=>{t.current.style.height=`${e.offsetHeight}px`,t.current.style.top=`${e.offsetTop}px`,t.current.style.width=`${e.offsetWidth}px`,t.current.style.left=`${e.offsetLeft}px`})},[]);return b(()=>{if(!n)return;let e=setTimeout(()=>{let a=document.querySelectorAll("h2[id], h3[id], h4[id], h5[id], h6[id]"),c=new IntersectionObserver(r=>{let l=r.filter(p=>p.isIntersecting);if(l.length>0){let d=l.sort((u,m)=>u.target.getBoundingClientRect().top-m.target.getBoundingClientRect().top)?.[0]?.target.id;if(d&&o.current){let u=o.current[d];if(s.current&&u){let m=s.current,T=u.offsetTop,x=u.offsetHeight;m.scrollTo({top:T-m.clientHeight/2+x/2,behavior:"smooth"})}i(u,`#${d}`)}}},{rootMargin:"0px 0px -90% 0px",threshold:.2});return a.forEach(r=>c.observe(r)),()=>{a.forEach(r=>c.unobserve(r))}},100);return()=>clearTimeout(e)},[n]),{activeHeading:f,handleActiveHeading:i,headingListRefs:o,activeIndicatorRef:t,asideRef:s}};export{w as generateTocFromMdx,S as useActiveHeading};