@mantine/hooks
Version:
A collection of 50+ hooks for state and UI management
68 lines (67 loc) • 2.25 kB
JavaScript
"use client";
const require_random_id = require("../utils/random-id/random-id.cjs");
let react = require("react");
//#region packages/@mantine/hooks/src/use-scroll-spy/use-scroll-spy.ts
function getHeadingsData(headings, getDepth, getValue) {
const result = [];
for (let i = 0; i < headings.length; i += 1) {
const heading = headings[i];
result.push({
depth: getDepth(heading),
value: getValue(heading),
id: heading.id || require_random_id.randomId(),
getNode: () => heading.id ? document.getElementById(heading.id) : heading
});
}
return result;
}
function getActiveElement(rects, offset = 0) {
if (rects.length === 0) return -1;
return rects.reduce((acc, item, index) => {
if (Math.abs(acc.position - offset) < Math.abs(item.y - offset)) return acc;
return {
index,
position: item.y
};
}, {
index: 0,
position: rects[0].y
}).index;
}
function getDefaultDepth(element) {
return Number(element.tagName[1]);
}
function getDefaultValue(element) {
return element.textContent || "";
}
function useScrollSpy({ selector = "h1, h2, h3, h4, h5, h6", getDepth = getDefaultDepth, getValue = getDefaultValue, offset = 0, scrollHost } = {}) {
const [active, setActive] = (0, react.useState)(-1);
const [initialized, setInitialized] = (0, react.useState)(false);
const [data, setData] = (0, react.useState)([]);
const headingsRef = (0, react.useRef)([]);
const handleScroll = () => {
setActive(getActiveElement(headingsRef.current.map((d) => d.getNode().getBoundingClientRect()), offset));
};
const initialize = () => {
const headings = getHeadingsData(Array.from(document.querySelectorAll(selector)), getDepth, getValue);
headingsRef.current = headings;
setInitialized(true);
setData(headings);
setActive(getActiveElement(headings.map((d) => d.getNode().getBoundingClientRect()), offset));
};
(0, react.useEffect)(() => {
initialize();
const _scrollHost = scrollHost || window;
_scrollHost.addEventListener("scroll", handleScroll);
return () => _scrollHost.removeEventListener("scroll", handleScroll);
}, [scrollHost]);
return {
reinitialize: initialize,
active,
initialized,
data
};
}
//#endregion
exports.useScrollSpy = useScrollSpy;
//# sourceMappingURL=use-scroll-spy.cjs.map