UNPKG

wix-style-react

Version:
145 lines (142 loc) 5.96 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = void 0; var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } // This is a copy of https://github.com/CassetteRocks/react-infinite-scroller with https://github.com/CassetteRocks/react-infinite-scroller/pull/38/files merged class InfiniteScroll extends _react.Component { constructor(props) { super(props); this.detachScrollListener = () => {}; this.scrollListener = this.scrollListener.bind(this); } 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.length && this.props.hasMore) { var _this$scrollComponent; ((_this$scrollComponent = this.scrollComponent) == null ? void 0 : _this$scrollComponent.scrollHeight) && this.scrollListener(); } } 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 ? void 0 : _prevProps$data.length) !== ((_this$props$data2 = this.props.data) == null ? void 0 : _this$props$data2.length) && this.props.hasMore) { 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 ? void 0 : _this$scrollComponent2.scrollHeight) && this.scrollListener(); } } render() { var { children, hasMore, loader, scrollElement, dataHook } = this.props; var ref; if (scrollElement) { ref = () => this.scrollComponent = scrollElement; } else { ref = node => this.scrollComponent = node; } return /*#__PURE__*/_react.default.createElement('div', { ref, 'data-hook': dataHook }, children, hasMore && (loader || this._defaultLoader)); } calculateTopPosition(el) { if (!el) { return 0; } return el.offsetTop + this.calculateTopPosition(el.offsetParent); } 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.hasMore) { this.props.loadMore(this.pageLoaded += 1); } } } attachScrollListener() { 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 = () => { scrollEl.removeEventListener('scroll', this.scrollListener); scrollEl.removeEventListener('resize', this.scrollListener); this.detachScrollListener = () => {}; }; } componentWillUnmount() { this.detachScrollListener(); } // Set a default loader for all your `InfiniteScroll` components setDefaultLoader(loader) { this._defaultLoader = loader; } } exports.default = InfiniteScroll; InfiniteScroll.propTypes = { hasMore: _propTypes.default.bool, initialLoad: _propTypes.default.bool, data: _propTypes.default.array, loadMore: _propTypes.default.func.isRequired, pageStart: _propTypes.default.number, threshold: _propTypes.default.number, useWindow: _propTypes.default.bool, isReverse: _propTypes.default.bool, scrollElement: _propTypes.default.object, children: _propTypes.default.node, loader: _propTypes.default.node }; InfiniteScroll.defaultProps = { hasMore: false, initialLoad: true, pageStart: 0, threshold: 250, useWindow: true, isReverse: false, scrollElement: null }; //# sourceMappingURL=InfiniteScroll.js.map