@scrolia/react
Version:
A headless scrollbar component
147 lines (145 loc) • 4.06 kB
JavaScript
import { useScrollCore } from "../contexts/scrollcore.mjs";
import { tryPlugin } from "../functions/plugin.mjs";
import * as React from "react";
const setLengthFn = ({ axis, disabled, page, plugins, contentRef, hvTrack, hvThumb, total, view, viewOffset, scrollbarLength, setScrollbarLength }) => {
let _total = 0;
let _view = 0;
if (page) if (axis === "x") {
_total = document.body.scrollWidth;
_view = window.innerWidth;
} else {
_total = document.body.scrollHeight;
_view = window.innerHeight;
}
else if (contentRef.current) if (axis === "x") {
_total = contentRef.current.scrollWidth;
_view = contentRef.current.clientWidth;
} else {
_total = contentRef.current.scrollHeight;
_view = contentRef.current.clientHeight;
}
if (total.current === _total && view.current === _view) return void 0;
total.current = _total;
view.current = _view;
const scrollbarLengthNext = _view / _total * _view;
let result;
for (const plugin of plugins) {
if (!plugin.onSetLength) continue;
result = tryPlugin(plugin, plugin.onSetLength, {
axis,
isDisabled: disabled,
isPage: page,
isDefined: hvTrack && hvThumb,
total: _total,
view: _view,
viewOffset: viewOffset.current,
scrollbarLengthPrev: scrollbarLength,
scrollbarLengthNext: result?.scrollbarLength ?? scrollbarLengthNext
}) ?? result;
}
let length;
if (result?.scrollbarLength) length = result.scrollbarLength;
else length = scrollbarLengthNext;
if (_view >= _total) setScrollbarLength(0);
else setScrollbarLength(length);
};
/** Hook for setting the length of the scrollbar. */
const useLengthHandler = () => {
const { options: { disabled, page, plugins }, contentRef, x, y } = useScrollCore();
React.useEffect(() => {
const setLength = () => {
x.hvTrack && x.hvThumb && setLengthFn({
axis: "x",
disabled,
page,
plugins,
contentRef,
hvTrack: x.hvTrack,
hvThumb: x.hvThumb,
total: x.total,
view: x.view,
viewOffset: x.viewOffset,
scrollbarLength: x.scrollbarLength,
setScrollbarLength: x.setScrollbarLength
});
};
setLength();
if (page) {
window.addEventListener("resize", setLength);
window.addEventListener("scroll", setLength);
} else if (contentRef.current) {
contentRef.current.addEventListener("resize", setLength);
contentRef.current.addEventListener("scroll", setLength);
}
return () => {
if (page) {
window.removeEventListener("resize", setLength);
window.removeEventListener("scroll", setLength);
} else if (contentRef.current) {
contentRef.current.removeEventListener("resize", setLength);
contentRef.current.removeEventListener("scroll", setLength);
}
};
}, [
disabled,
page,
plugins,
contentRef,
x.hvTrack,
x.hvThumb,
x.total,
x.view,
x.viewOffset,
x.scrollbarLength,
x.setScrollbarLength
]);
React.useEffect(() => {
const setLength = () => {
y.hvTrack && y.hvThumb && setLengthFn({
axis: "y",
disabled,
page,
plugins,
contentRef,
hvTrack: y.hvTrack,
hvThumb: y.hvThumb,
total: y.total,
view: y.view,
viewOffset: y.viewOffset,
scrollbarLength: y.scrollbarLength,
setScrollbarLength: y.setScrollbarLength
});
};
setLength();
if (page) {
window.addEventListener("resize", setLength);
window.addEventListener("scroll", setLength);
} else if (contentRef.current) {
contentRef.current.addEventListener("resize", setLength);
contentRef.current.addEventListener("scroll", setLength);
}
return () => {
if (page) {
window.removeEventListener("resize", setLength);
window.removeEventListener("scroll", setLength);
} else if (contentRef.current) {
contentRef.current.removeEventListener("resize", setLength);
contentRef.current.removeEventListener("scroll", setLength);
}
};
}, [
disabled,
page,
plugins,
contentRef,
y.hvTrack,
y.hvThumb,
y.total,
y.view,
y.viewOffset,
y.scrollbarLength,
y.setScrollbarLength
]);
};
export { useLengthHandler };
//# sourceMappingURL=length.mjs.map