mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-25 04:20:02 +00:00
Core: Improve active anchor observer
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-core': patch
|
||||
---
|
||||
|
||||
Improve active anchor observer
|
||||
@@ -1,6 +1,9 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
/**
|
||||
* Find the active heading of page
|
||||
*
|
||||
* It selects the top heading by default, and the last item when reached the bottom of page.
|
||||
*
|
||||
* @param watch - An array of element ids to watch
|
||||
* @returns Active anchor
|
||||
@@ -13,12 +16,7 @@ export function useAnchorObserver(watch: string[]): string | undefined {
|
||||
(entries) => {
|
||||
setActiveAnchor((f) => {
|
||||
for (const entry of entries) {
|
||||
// If above half the viewport
|
||||
const aboveHalf =
|
||||
window.innerHeight / 2 > entry.boundingClientRect.y;
|
||||
const active = aboveHalf && entry.isIntersecting;
|
||||
|
||||
if (active) {
|
||||
if (entry.isIntersecting) {
|
||||
return entry.target.id;
|
||||
}
|
||||
}
|
||||
@@ -27,9 +25,25 @@ export function useAnchorObserver(watch: string[]): string | undefined {
|
||||
return f ?? watch[0];
|
||||
});
|
||||
},
|
||||
{ rootMargin: `0% 0% -80% 0%` },
|
||||
{ rootMargin: `-60px 0% -70% 0%`, threshold: 1 },
|
||||
);
|
||||
|
||||
const scroll = (): void => {
|
||||
const element = document.scrollingElement;
|
||||
if (!element) return;
|
||||
|
||||
// select the last item when reached the bottom
|
||||
if (
|
||||
element.scrollTop >=
|
||||
// assume you have a 100px margin (including footer & padding)
|
||||
element.scrollHeight - element.clientHeight - 100
|
||||
) {
|
||||
setActiveAnchor(watch.at(-1));
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('scroll', scroll);
|
||||
|
||||
for (const heading of watch) {
|
||||
const element = document.getElementById(heading);
|
||||
|
||||
@@ -39,6 +53,7 @@ export function useAnchorObserver(watch: string[]): string | undefined {
|
||||
}
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('scroll', scroll);
|
||||
observer.disconnect();
|
||||
};
|
||||
}, [watch]);
|
||||
|
||||
Reference in New Issue
Block a user