UNPKG

@nutui/nutui-react

Version:

京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序

252 lines (251 loc) 10.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "InfiniteLoading", { enumerable: true, get: function() { return InfiniteLoading; } }); var _interop_require_default = require("@swc/helpers/_/_interop_require_default"); var _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard"); var _async_to_generator = require("@swc/helpers/_/_async_to_generator"); var _object_spread = require("@swc/helpers/_/_object_spread"); var _object_spread_props = require("@swc/helpers/_/_object_spread_props"); var _object_without_properties = require("@swc/helpers/_/_object_without_properties"); var _sliced_to_array = require("@swc/helpers/_/_sliced_to_array"); var _ts_generator = require("@swc/helpers/_/_ts_generator"); var _react = /*#__PURE__*/ _interop_require_wildcard._(require("react")); var _classnames = /*#__PURE__*/ _interop_require_default._(require("classnames")); var _configprovider = require("../configprovider"); var _typings = require("../../utils/typings"); var defaultProps = (0, _object_spread_props._)((0, _object_spread._)({}, _typings.ComponentDefaults), { type: 'default', hasMore: true, threshold: 200, target: '', capture: false, pullRefresh: false }); var classPrefix = "nut-infiniteloading"; var InfiniteLoading = function InfiniteLoading(props) { var getBottomTipsText = function getBottomTipsText() { if (isInfiniting) { return loadingText || locale.infiniteloading.loadText; } if (!hasMore) { return loadMoreText || locale.infiniteloading.loadMoreText; } return null; }; var locale = (0, _configprovider.useConfig)().locale; var _ref = (0, _object_spread._)({}, defaultProps, props), children = _ref.children, type = _ref.type, hasMore = _ref.hasMore, threshold = _ref.threshold, target = _ref.target, capture = _ref.capture, pullRefresh = _ref.pullRefresh, pullingText = _ref.pullingText, loadingText = _ref.loadingText, loadMoreText = _ref.loadMoreText, className = _ref.className, onRefresh = _ref.onRefresh, onLoadMore = _ref.onLoadMore, onScroll = _ref.onScroll, restProps = (0, _object_without_properties._)(_ref, [ "children", "type", "hasMore", "threshold", "target", "capture", "pullRefresh", "pullingText", "loadingText", "loadMoreText", "className", "onRefresh", "onLoadMore", "onScroll" ]); var _useState = (0, _sliced_to_array._)((0, _react.useState)(false), 2), isInfiniting = _useState[0], setIsInfiniting = _useState[1]; var scroller = (0, _react.useRef)(null); var refreshTop = (0, _react.useRef)(null); var scrollEl = (0, _react.useRef)(null); var isTouching = (0, _react.useRef)(false); var beforeScrollTop = (0, _react.useRef)(0); var refreshMaxH = (0, _react.useRef)(0); var y = (0, _react.useRef)(0); var distance = (0, _react.useRef)(0); var classes = (0, _classnames.default)(classPrefix, className, "".concat(classPrefix, "-").concat(type)); (0, _react.useEffect)(function() { var _scrollEl_current; if (target && document.getElementById(target)) { scrollEl.current = document.getElementById(target); } else { scrollEl.current = window; } (_scrollEl_current = scrollEl.current) === null || _scrollEl_current === void 0 ? void 0 : _scrollEl_current.addEventListener('scroll', handleScroll, capture); return function() { var _scrollEl_current; (_scrollEl_current = scrollEl.current) === null || _scrollEl_current === void 0 ? void 0 : _scrollEl_current.removeEventListener('scroll', handleScroll, capture); }; }, [ hasMore, isInfiniting, onLoadMore ]); (0, _react.useEffect)(function() { var element = scroller.current; element.addEventListener('touchmove', touchMove, { passive: false }); return function() { element.removeEventListener('touchmove', touchMove, { passive: false }); }; }, []); var getStyle = function getStyle() { return { height: distance.current < 0 ? "0px" : "".concat(distance.current, "px"), transition: isTouching.current ? "height 0s cubic-bezier(0.25,0.1,0.25,1)" : "height 0.2s cubic-bezier(0.25,0.1,0.25,1)" }; }; var handleScroll = /*#__PURE__*/ function() { var _ref = (0, _async_to_generator._)(function() { return (0, _ts_generator._)(this, function(_state) { switch(_state.label){ case 0: if (!isScrollAtBottom() || !hasMore || isInfiniting) { return [ 2 ]; } setIsInfiniting(true); return [ 4, onLoadMore === null || onLoadMore === void 0 ? void 0 : onLoadMore() ]; case 1: _state.sent(); infiniteDone(); return [ 2 ]; } }); }); return function handleScroll() { return _ref.apply(this, arguments); }; }(); var infiniteDone = function infiniteDone() { setIsInfiniting(false); }; var getRefreshTop = function getRefreshTop() { return refreshTop.current; }; var refreshDone = function refreshDone() { distance.current = 0; getRefreshTop().style.height = "".concat(distance.current, "px"); isTouching.current = false; }; var touchStart = function touchStart(event) { if (beforeScrollTop.current === 0 && !isTouching.current && pullRefresh) { y.current = event.touches[0].pageY; isTouching.current = true; var childHeight = getRefreshTop().firstElementChild.offsetHeight; refreshMaxH.current = Math.floor(childHeight * 1 + 10); } }; var touchMove = function touchMove(event) { distance.current = event.touches[0].pageY - y.current; if (distance.current > 0 && isTouching.current) { event.preventDefault(); if (distance.current >= refreshMaxH.current) { distance.current = refreshMaxH.current; getRefreshTop().style.height = "".concat(distance.current, "px"); } else { getRefreshTop().style.height = "".concat(distance.current, "px"); } } else { distance.current = 0; getRefreshTop().style.height = "".concat(distance.current, "px"); isTouching.current = false; } }; var touchEnd = /*#__PURE__*/ function() { var _ref = (0, _async_to_generator._)(function() { return (0, _ts_generator._)(this, function(_state) { switch(_state.label){ case 0: if (!(distance.current < refreshMaxH.current)) return [ 3, 1 ]; distance.current = 0; getRefreshTop().style.height = "".concat(distance.current, "px"); isTouching.current = false; return [ 3, 3 ]; case 1: return [ 4, onRefresh === null || onRefresh === void 0 ? void 0 : onRefresh() ]; case 2: _state.sent(); refreshDone(); _state.label = 3; case 3: return [ 2 ]; } }); }); return function touchEnd() { return _ref.apply(this, arguments); }; }(); var getWindowScrollTop = function getWindowScrollTop() { return window.scrollY !== undefined ? window.scrollY : (document.documentElement || document.body.parentNode || document.body).scrollTop; }; var calculateTopPosition = function calculateTopPosition1(el) { return !el ? 0 : el.offsetTop + calculateTopPosition(el.offsetParent); }; var isScrollAtBottom = function isScrollAtBottom() { var offsetDistance = 0; var resScrollTop = 0; var direction = 'down'; var windowScrollTop = getWindowScrollTop(); if (!target || !document.getElementById(target)) { if (scroller.current) { offsetDistance = calculateTopPosition(scroller.current) + scroller.current.offsetHeight - windowScrollTop - window.innerHeight; } resScrollTop = windowScrollTop; } else { var _scrollEl_current = scrollEl.current, scrollHeight = _scrollEl_current.scrollHeight, clientHeight = _scrollEl_current.clientHeight, scrollTop = _scrollEl_current.scrollTop; offsetDistance = scrollHeight - clientHeight - scrollTop; resScrollTop = scrollTop; } if (beforeScrollTop.current > resScrollTop) { direction = 'up'; } else { direction = 'down'; } beforeScrollTop.current = resScrollTop; onScroll && onScroll(resScrollTop); return offsetDistance <= threshold && direction === 'down'; }; return /*#__PURE__*/ _react.default.createElement("div", (0, _object_spread._)({ className: classes, ref: scroller, onTouchStart: touchStart, onTouchEnd: touchEnd }, restProps), /*#__PURE__*/ _react.default.createElement("div", { className: "nut-infinite-top", ref: refreshTop, style: getStyle() }, /*#__PURE__*/ _react.default.createElement("div", { className: "nut-infinite-top-tips" }, pullingText || locale.infiniteloading.pullRefreshText)), /*#__PURE__*/ _react.default.createElement("div", { className: "nut-infinite-container" }, children), /*#__PURE__*/ _react.default.createElement("div", { className: "nut-infinite-bottom" }, /*#__PURE__*/ _react.default.createElement("div", { className: "nut-infinite-bottom-tips" }, getBottomTipsText()))); }; InfiniteLoading.displayName = 'NutInfiniteLoading';