@wordpress/components
Version:
UI components for WordPress.
67 lines (66 loc) • 1.86 kB
JavaScript
/* eslint-disable jsdoc/require-param */
/**
* WordPress dependencies
*/
import { useState, useEffect } from '@wordpress/element';
import { useEvent } from '@wordpress/compose';
/**
* Tracks if an element contains overflow and on which end by tracking the
* first and last child elements with an `IntersectionObserver` in relation
* to the parent element.
*
* Note that the returned value will only indicate whether the first or last
* element is currently "going out of bounds" but not whether it happens on
* the X or Y axis.
*/
export function useTrackOverflow(parent, children) {
const [first, setFirst] = useState(false);
const [last, setLast] = useState(false);
const [observer, setObserver] = useState();
const callback = useEvent(entries => {
for (const entry of entries) {
if (entry.target === children.first) {
setFirst(!entry.isIntersecting);
}
if (entry.target === children.last) {
setLast(!entry.isIntersecting);
}
}
});
useEffect(() => {
if (!parent || !window.IntersectionObserver) {
return;
}
const newObserver = new IntersectionObserver(callback, {
root: parent,
threshold: 0.9
});
setObserver(newObserver);
return () => newObserver.disconnect();
}, [callback, parent]);
useEffect(() => {
if (!observer) {
return;
}
if (children.first) {
observer.observe(children.first);
}
if (children.last) {
observer.observe(children.last);
}
return () => {
if (children.first) {
observer.unobserve(children.first);
}
if (children.last) {
observer.unobserve(children.last);
}
};
}, [children.first, children.last, observer]);
return {
first,
last
};
}
/* eslint-enable jsdoc/require-param */
//# sourceMappingURL=use-track-overflow.js.map