How to make this documentation index effect?

I'm struggling to do this right now, using framer-motion
25 Replies
Keef
Keef14mo ago
The source code is probably online if you check their github but looking at your video. I haven't looked at it but heres what I'm thinking: First look at the URL. As you scroll into sections its manipulating the URL and adding an id for the section you are scrolling into as you do it. The sidebar on the right is likely just doing some conditional rendering like active ? bg-purple : "" and the active case is just checking if the id is in the url You'll just need something to tell you when something is in view of the user and then add to your url. https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API Theres a hook for this on npm/all over the internet if you attach react/flavor of framework
Intersection Observer API - Web APIs | MDN
The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport.
Keef
Keef14mo ago
Component in question
bmariano
bmariano14mo ago
Well, no, scrolling doesn't manipulate the URL. It changes when you click the links. Actually, I could make this work, by doing what you said, checking if something is in the view. The problem is, when I click the link, it goes to the element, but some other elements are present in the viewport, so, that other element, changes the state and the link ends up being incorrect
bmariano
bmariano14mo ago
bmariano
bmariano14mo ago
Do you see?
Keef
Keef14mo ago
ACTUALLY YEAH IT DOES NOT MY BAD But it doesn't matter what method you interact with it the state is stored in that url and clicking it does the same thing
bmariano
bmariano14mo ago
I'm feelling somehow stupid, but really I'm not being able to solve this lol
Keef
Keef14mo ago
Just dump the url stuff I mentioned And just check for inview I didn't realize you were clicking in your original post* Once the original "in view element" is out of view it seems to be changing on the astro docs so you could probably weight them? but I imagine their docs has a much cleaner approach then this
Keef
Keef14mo ago
Even their's is kinda buggy Sometimes the state doesnt reconcile correctly so you don't have any selected even when one is clearly in view hmm
bmariano
bmariano14mo ago
I see examples like this everywhere, take a look at nextjs docs, it works similarly, there should be a concise way of doing this
Keef
Keef14mo ago
useEffect(() => {
const setCurrent: IntersectionObserverCallback = (entries) => {
for (const entry of entries) {
if (entry.isIntersecting) {
const { id } = entry.target;
if (id === onThisPageID) continue;
setCurrentHeading({
slug: entry.target.id,
text: entry.target.textContent || '',
});
break;
}
}
};

const observerOptions: IntersectionObserverInit = {
// Negative top margin accounts for `scroll-margin`.
// Negative bottom margin means heading needs to be towards top of viewport to trigger intersection.
rootMargin: '-100px 0% -66%',
threshold: 1,
};

const headingsObserver = new IntersectionObserver(setCurrent, observerOptions);

// Observe all the headings in the main page content.
document.querySelectorAll('article :is(h1,h2,h3)').forEach((h) => headingsObserver.observe(h));

// Stop observing when the component is unmounted.
return () => headingsObserver.disconnect();
}, []);
useEffect(() => {
const setCurrent: IntersectionObserverCallback = (entries) => {
for (const entry of entries) {
if (entry.isIntersecting) {
const { id } = entry.target;
if (id === onThisPageID) continue;
setCurrentHeading({
slug: entry.target.id,
text: entry.target.textContent || '',
});
break;
}
}
};

const observerOptions: IntersectionObserverInit = {
// Negative top margin accounts for `scroll-margin`.
// Negative bottom margin means heading needs to be towards top of viewport to trigger intersection.
rootMargin: '-100px 0% -66%',
threshold: 1,
};

const headingsObserver = new IntersectionObserver(setCurrent, observerOptions);

// Observe all the headings in the main page content.
document.querySelectorAll('article :is(h1,h2,h3)').forEach((h) => headingsObserver.observe(h));

// Stop observing when the component is unmounted.
return () => headingsObserver.disconnect();
}, []);
This is the meat of it lets seeeee It really does look like they are doing the same thing from just examining the react state Idk where the next docs repo is So this is my cope Its also slightly buggy on the next site too sip
bmariano
bmariano14mo ago
GitHub
next.js/docs/02-app/01-building-your-application at canary · vercel...
The React Framework. Contribute to vercel/next.js development by creating an account on GitHub.
bmariano
bmariano14mo ago
Anyways, thanks man, if those are buggy too, i'll try to find a workaround
Want results from more Discord servers?
Add your server