UNPKG

wix-style-react

Version:
205 lines (168 loc) • 7.65 kB
import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; 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 _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } import React, { Component } from 'react'; import PropTypes from 'prop-types'; // This is a copy of https://github.com/CassetteRocks/react-infinite-scroller with https://github.com/CassetteRocks/react-infinite-scroller/pull/38/files merged var InfiniteScroll = /*#__PURE__*/function (_Component) { _inherits(InfiniteScroll, _Component); var _super = _createSuper(InfiniteScroll); function InfiniteScroll(props) { var _this; _classCallCheck(this, InfiniteScroll); _this = _super.call(this, props); _defineProperty(_assertThisInitialized(_this), "detachScrollListener", function () {}); _this.scrollListener = _this.scrollListener.bind(_assertThisInitialized(_this)); return _this; } _createClass(InfiniteScroll, [{ key: "componentDidMount", value: function componentDidMount() { var _this$props$data; this.pageLoaded = this.props.pageStart; this.attachScrollListener(); if (this.props.initialLoad) { this.scrollListener(); } // when component mounts try to load more only when initial data was already rendered else if ((_this$props$data = this.props.data) !== null && _this$props$data !== void 0 && _this$props$data.length) { var _this$scrollComponent; ((_this$scrollComponent = this.scrollComponent) === null || _this$scrollComponent === void 0 ? void 0 : _this$scrollComponent.scrollHeight) && this.scrollListener(); } } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps) { var _prevProps$data, _this$props$data2; this.attachScrollListener(); // scroll element might be not scrollable - trigger scroll listener when new data changes the scroll element height if (((_prevProps$data = prevProps.data) === null || _prevProps$data === void 0 ? void 0 : _prevProps$data.length) !== ((_this$props$data2 = this.props.data) === null || _this$props$data2 === void 0 ? void 0 : _this$props$data2.length)) { var _this$scrollComponent2; // To avoid infinite loop of `loadMore` in `jsdom` we require the scroll element to have height before we trigger `scrollListener` as a reaction to new `props.data`. ((_this$scrollComponent2 = this.scrollComponent) === null || _this$scrollComponent2 === void 0 ? void 0 : _this$scrollComponent2.scrollHeight) && this.scrollListener(); } } }, { key: "render", value: function render() { var _this2 = this; var _this$props = this.props, children = _this$props.children, hasMore = _this$props.hasMore, loader = _this$props.loader, scrollElement = _this$props.scrollElement, dataHook = _this$props.dataHook; var ref; if (scrollElement) { ref = function ref() { return _this2.scrollComponent = scrollElement; }; } else { ref = function ref(node) { return _this2.scrollComponent = node; }; } return /*#__PURE__*/React.createElement('div', { ref: ref, 'data-hook': dataHook }, children, hasMore && (loader || this._defaultLoader)); } }, { key: "calculateTopPosition", value: function calculateTopPosition(el) { if (!el) { return 0; } return el.offsetTop + this.calculateTopPosition(el.offsetParent); } }, { key: "scrollListener", value: function scrollListener() { var el = this.scrollComponent; var offset; if (this.props.scrollElement) { if (this.props.isReverse) { offset = el.scrollTop; } else { offset = el.scrollHeight - el.scrollTop - el.clientHeight; } } else if (this.props.useWindow) { var scrollTop = window.pageYOffset !== undefined ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop; if (this.props.isReverse) { offset = scrollTop; } else { offset = this.calculateTopPosition(el) + el.offsetHeight - scrollTop - window.innerHeight; } } else if (this.props.isReverse) { offset = el.parentNode.scrollTop; } else { offset = el.scrollHeight - el.parentNode.scrollTop - el.parentNode.clientHeight; } if (offset < Number(this.props.threshold)) { this.detachScrollListener(); // Call loadMore after detachScrollListener to allow for non-async loadMore functions if (typeof this.props.loadMore === 'function') { this.props.loadMore(this.pageLoaded += 1); } } } }, { key: "attachScrollListener", value: function attachScrollListener() { var _this3 = this; this.detachScrollListener(); if (!this.props.hasMore) { return; } var scrollEl = window; if (this.props.scrollElement) { scrollEl = this.scrollComponent; } else if (this.props.useWindow === false) { scrollEl = this.scrollComponent.parentNode; } scrollEl.addEventListener('scroll', this.scrollListener); scrollEl.addEventListener('resize', this.scrollListener); this.detachScrollListener = function () { scrollEl.removeEventListener('scroll', _this3.scrollListener); scrollEl.removeEventListener('resize', _this3.scrollListener); _this3.detachScrollListener = function () {}; }; } }, { key: "componentWillUnmount", value: function componentWillUnmount() { this.detachScrollListener(); } // Set a default loader for all your `InfiniteScroll` components }, { key: "setDefaultLoader", value: function setDefaultLoader(loader) { this._defaultLoader = loader; } }]); return InfiniteScroll; }(Component); _defineProperty(InfiniteScroll, "propTypes", { hasMore: PropTypes.bool, initialLoad: PropTypes.bool, data: PropTypes.array, loadMore: PropTypes.func.isRequired, pageStart: PropTypes.number, threshold: PropTypes.number, useWindow: PropTypes.bool, isReverse: PropTypes.bool, scrollElement: PropTypes.object, children: PropTypes.node, loader: PropTypes.node }); _defineProperty(InfiniteScroll, "defaultProps", { hasMore: false, initialLoad: true, pageStart: 0, threshold: 250, useWindow: true, isReverse: false, scrollElement: null }); export { InfiniteScroll as default };