@intility/bifrost-react
Version:
React library for Intility's design system, Bifrost.
69 lines (68 loc) • 2.06 kB
JavaScript
"use client";
import { c as _c } from "react-compiler-runtime";
import { useEffect, useState } from "react";
import closestElement, { isEverScrollable } from "../utils/closestElement.js";
/**
* Listens to scroll event and reports which direction (`'up'` or `'down'`) the user is scrolling,
* or `'none'` if not scrolled yet.
* @param options Optional options object, with `threshold` and `elementRef`
* @returns `'none'` if not scrolled yet, otherwise `'up'` or `'down'`
*/
export default function useScrollDirection(t0) {
const $ = _c(6);
let t1;
if ($[0] !== t0) {
t1 = t0 === undefined ? {} : t0;
$[0] = t0;
$[1] = t1;
} else {
t1 = $[1];
}
const {
threshold: t2,
elementRef
} = t1;
const threshold = t2 === undefined ? 50 : t2;
const [scrollDir, setScrollDir] = useState("none");
let t3;
let t4;
if ($[2] !== elementRef || $[3] !== threshold) {
t3 = () => {
const scrollableElement = closestElement(isEverScrollable, elementRef?.current);
let lastScrollY = scrollableElement.scrollTop;
let ticking = false;
const updateScrollDir = () => {
const scrollY = scrollableElement.scrollTop;
if (Math.abs(scrollY - lastScrollY) < threshold) {
ticking = false;
return;
}
setScrollDir(scrollY > lastScrollY ? "down" : "up");
lastScrollY = scrollY > 0 ? scrollY : 0;
ticking = false;
};
const onScroll = () => {
if (!ticking) {
requestAnimationFrame(updateScrollDir);
ticking = true;
}
};
let eventTarget = scrollableElement;
if (scrollableElement === document.documentElement) {
eventTarget = document;
}
eventTarget.addEventListener("scroll", onScroll);
return () => eventTarget.removeEventListener("scroll", onScroll);
};
t4 = [threshold, elementRef];
$[2] = elementRef;
$[3] = threshold;
$[4] = t3;
$[5] = t4;
} else {
t3 = $[4];
t4 = $[5];
}
useEffect(t3, t4);
return scrollDir;
}