UNPKG

@researchgate/react-intersection-list

Version:

React List Component using the Intersection Observer API

228 lines (181 loc) 8.23 kB
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import warning from 'warning'; import Sentinel from './Sentinel'; import { getItemCount, computeSize } from './utils'; var AXIS_CSS_MAP = { x: 'overflowX', y: 'overflowY' }; var List = /*#__PURE__*/function (_PureComponent) { _inheritsLoose(List, _PureComponent); var _super = _createSuper(List); function List() { var _this; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _PureComponent.call.apply(_PureComponent, [this].concat(args)) || this; _defineProperty(_assertThisInitialized(_this), "state", { size: 0 }); _defineProperty(_assertThisInitialized(_this), "setRef", function (callback) { var prevRootNode; _this.setRootNode = function (node) { if (node !== prevRootNode) { prevRootNode = node; var overflow = window.getComputedStyle(node)[AXIS_CSS_MAP[_this.props.axis]]; callback(['auto', 'scroll', 'overlay'].indexOf(overflow) !== -1 ? node : null); } }; }); _defineProperty(_assertThisInitialized(_this), "handleUpdate", function (_ref) { var isIntersecting = _ref.isIntersecting; var _this$props = _this.props, awaitMore = _this$props.awaitMore, onIntersection = _this$props.onIntersection; var _this$state = _this.state, size = _this$state.size, itemCount = _this$state.itemCount, pageSize = _this$state.pageSize; if (!_this.prematureIntersectionChecked) { _this.prematureIntersectionChecked = true; warning(!isIntersecting, 'ReactIntersectionList: the sentinel detected a viewport with a bigger size than the size of its items. ' + 'This could lead to detrimental behavior, e.g.: triggering more than one onIntersection callback at the start.\n' + 'To prevent this, use either a bigger `pageSize` value or avoid using the prop awaitMore initially.'); } if (isIntersecting) { var nextSize = computeSize(size + pageSize, itemCount); if (size !== nextSize) { _this.setState({ size: nextSize }); } if (onIntersection && (!awaitMore || _this.awaitIntersection)) { if (_this.awaitIntersection) { _this.awaitIntersection = false; } onIntersection(nextSize, pageSize); } } }); return _this; } List.getDerivedStateFromProps = function getDerivedStateFromProps(_ref2, prevState) { var pageSize = _ref2.pageSize, props = _objectWithoutPropertiesLoose(_ref2, ["pageSize"]); var itemCount = getItemCount(props, true); var newSize; if (prevState.size === 0) { newSize = pageSize; } else { if (prevState.itemCount < itemCount) { newSize = prevState.size + pageSize; } else { newSize = prevState.size + -(prevState.pageSize - pageSize); } } return { pageSize: pageSize, itemCount: itemCount, size: computeSize(newSize, itemCount) }; }; var _proto = List.prototype; _proto.componentDidMount = function componentDidMount() { this.prematureIntersectionChecked = this.state.size === 0; }; _proto.getItemRenderer = function getItemRenderer() { var _this$props2 = this.props, children = _this$props2.children, renderItem = _this$props2.renderItem; var hasChildren = typeof children !== 'undefined'; var hasRender = typeof renderItem !== 'undefined'; warning(!(hasChildren && hasRender), 'ReactIntersectionList: cannot use children and renderItem props as render function at the same time.'); if (hasChildren) { return children; } return hasRender ? renderItem : function (index, key) { return /*#__PURE__*/React.createElement("div", { key: key }, index); }; }; _proto.renderItems = function renderItems() { var _this2 = this; var _this$props3 = this.props, awaitMore = _this$props3.awaitMore, axis = _this$props3.axis, initialIndex = _this$props3.initialIndex, itemsRenderer = _this$props3.itemsRenderer, threshold = _this$props3.threshold; var _this$state2 = this.state, size = _this$state2.size, itemCount = _this$state2.itemCount; var itemRenderer = this.getItemRenderer(); var items = []; for (var i = 0; i < size; ++i) { items.push(itemRenderer(initialIndex + i, i)); } var sentinel; if (size < itemCount || awaitMore) { sentinel = /*#__PURE__*/React.createElement(Sentinel, { key: "sentinel", threshold: threshold, axis: axis, setRef: this.setRef, onChange: this.handleUpdate }); items.push(sentinel); if (awaitMore) { this.awaitIntersection = true; } } return itemsRenderer(items, function (node) { if (node && sentinel) { _this2.setRootNode(node); } }); }; _proto.render = function render() { return this.renderItems(); }; return List; }(PureComponent); _defineProperty(List, "defaultProps", { axis: 'y', initialIndex: 0, itemsRenderer: function itemsRenderer(items, ref) { return /*#__PURE__*/React.createElement("div", { ref: ref }, items); }, pageSize: 10, threshold: '100px' }); process.env.NODE_ENV !== "production" ? List.propTypes = { awaitMore: PropTypes.bool, axis: PropTypes.oneOf(['x', 'y']), children: PropTypes.func, initialIndex: PropTypes.number, items: function items(props, propName) { var object = props[propName]; if (object != null && !(Array.isArray(object) || typeof object[Symbol.iterator] === 'function')) { return new Error("`" + propName + "` must be of type Array or a native type implementing the iterable interface"); } return undefined; }, itemCount: PropTypes.number, itemsRenderer: PropTypes.func, onIntersection: PropTypes.func, pageSize: PropTypes.number, renderItem: PropTypes.func, threshold: PropTypes.string } : void 0; export default List;