@mantine/hooks
Version:
A collection of 50+ hooks for state and UI management
84 lines (80 loc) • 2.2 kB
JavaScript
'use client';
;
var React = require('react');
var randomId = require('../utils/random-id/random-id.cjs');
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 || randomId.randomId(),
getNode: () => heading.id ? document.getElementById(heading.id) : heading
});
}
return result;
}
function getActiveElement(rects) {
if (rects.length === 0) {
return -1;
}
const closest = rects.reduce(
(acc, item, index) => {
if (Math.abs(acc.position) < Math.abs(item.y)) {
return acc;
}
return {
index,
position: item.y
};
},
{ index: 0, position: rects[0].y }
);
return closest.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
} = {}) {
const [active, setActive] = React.useState(-1);
const [initialized, setInitialized] = React.useState(false);
const [data, setData] = React.useState([]);
const headingsRef = React.useRef([]);
const handleScroll = () => {
setActive(
getActiveElement(headingsRef.current.map((d) => d.getNode().getBoundingClientRect()))
);
};
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())));
};
React.useEffect(() => {
initialize();
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
return {
reinitialize: initialize,
active,
initialized,
data
};
}
exports.useScrollSpy = useScrollSpy;
//# sourceMappingURL=use-scroll-spy.cjs.map