endlessflow
Version:
A lightweight and customizable infinite scroll library
65 lines (63 loc) • 3.63 kB
JavaScript
;
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = InfiniteScroll;
var React = _interopRequireWildcard(require("react"));
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
function InfiniteScroll(_ref) {
var isLoading = _ref.isLoading,
hasMore = _ref.hasMore,
next = _ref.next,
_ref$threshold = _ref.threshold,
threshold = _ref$threshold === void 0 ? 1 : _ref$threshold,
_ref$root = _ref.root,
root = _ref$root === void 0 ? null : _ref$root,
_ref$rootMargin = _ref.rootMargin,
rootMargin = _ref$rootMargin === void 0 ? "0px" : _ref$rootMargin,
reverse = _ref.reverse,
children = _ref.children;
var observer = React.useRef();
// This callback ref will be called when it is dispatched to an element or detached from an element,
// or when the callback function changes.
var observerRef = React.useCallback(function (element) {
var safeThreshold = threshold;
if (threshold < 0 || threshold > 1) {
console.warn("threshold should be between 0 and 1. You are exceed the range. will use default value: 1");
safeThreshold = 1;
}
// When isLoading is true, this callback will do nothing.
// It means that the next function will never be called.
// It is safe because the intersection observer has disconnected the previous element.
if (isLoading) return;
if (observer.current) observer.current.disconnect();
if (!element) return;
// Create a new IntersectionObserver instance because hasMore or next may be changed.
observer.current = new IntersectionObserver(function (entries) {
if (entries[0].isIntersecting && hasMore) {
next();
}
}, {
threshold: safeThreshold,
root: root,
rootMargin: rootMargin
});
observer.current.observe(element);
}, [hasMore, isLoading, next, threshold, root, rootMargin]);
var flattenChildren = React.useMemo(function () {
return React.Children.toArray(children);
}, [children]);
return /*#__PURE__*/React.createElement(React.Fragment, null, flattenChildren.map(function (child, index) {
if (! /*#__PURE__*/React.isValidElement(child)) {
process.env.NODE_ENV === "development" && console.warn("You should use a valid element with InfiniteScroll");
return child;
}
var isObserveTarget = reverse ? index === 0 : index === flattenChildren.length - 1;
var ref = isObserveTarget ? observerRef : null;
return /*#__PURE__*/React.cloneElement(child, {
ref: ref
});
}));
}