@amaui/ui-react
Version:
UI for React
56 lines (52 loc) • 1.8 kB
JavaScript
import React from 'react';
const useScroll = props => {
const {
offset,
direction,
element,
target
} = props;
const [response, setResponse] = React.useState(false);
const [root, setRoot] = React.useState();
const refs = {
root: React.useRef(root),
previous: React.useRef(0),
offset: React.useRef(),
direction: React.useRef(),
response: React.useRef(response)
};
refs.root.current = root;
refs.offset.current = offset;
refs.direction.current = direction;
refs.response.current = response;
// Root
React.useEffect(() => {
const rootNew = target || element?.ownerDocument?.defaultView || window;
setRoot(rootNew);
refs.root.current = rootNew;
}, [target, element]);
const method = React.useCallback(() => {
if (!refs.root.current) return;
const value = refs.root.current?.scrollTop !== undefined ? refs.root.current.scrollTop : refs.root.current?.scrollY;
let responseNew = true;
// Direction
if (refs.direction.current !== undefined) responseNew = responseNew && (refs.direction.current === 'down' && value > refs.previous.current || refs.direction.current === 'up' && value < refs.previous.current);
// Offset
if (refs.offset.current !== undefined) responseNew = responseNew && value > refs.offset.current;
if (refs.response.current !== responseNew) setResponse(responseNew);
// Previous
refs.previous.current = value;
}, []);
React.useEffect(() => {
// Add new event listener
if (root) root.addEventListener('scroll', method);
method();
return () => {
// Remove previous event listener
if (root) root.removeEventListener('scroll', method);
};
}, [root]);
return response;
};
useScroll.displayName = 'amaui-UseScroll';
export default useScroll;