UNPKG

@nutui/nutui-react-taro

Version:

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

212 lines (211 loc) 8.33 kB
import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator"; import { _ as _object_spread } from "@swc/helpers/_/_object_spread"; import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props"; import { _ as _object_without_properties } from "@swc/helpers/_/_object_without_properties"; import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array"; import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator"; import React, { useEffect, useRef, useState } from "react"; import classNames from "classnames"; import { ScrollView, View } from "@tarojs/components"; import { createSelectorQuery } from "@tarojs/taro"; import { useConfig } from "../configprovider/index"; import { ComponentDefaults } from "../../utils/typings"; import { pxTransform } from "../../utils/taro/px-transform"; var defaultProps = _object_spread_props(_object_spread({}, ComponentDefaults), { type: 'default', hasMore: true, threshold: 40, target: '', pullRefresh: false }); var classPrefix = "nut-infiniteloading"; export var InfiniteLoading = function(props) { var getBottomTipsText = function getBottomTipsText() { if (isInfiniting) { return loadingText || locale.infiniteloading.loadText; } if (!hasMore) { return loadMoreText || locale.infiniteloading.loadMoreText; } return null; }; var locale = useConfig().locale; var _ref = _object_spread({}, defaultProps, props), children = _ref.children, type = _ref.type, hasMore = _ref.hasMore, threshold = _ref.threshold, target = _ref.target, pullRefresh = _ref.pullRefresh, pullingText = _ref.pullingText, loadingText = _ref.loadingText, loadMoreText = _ref.loadMoreText, className = _ref.className, onRefresh = _ref.onRefresh, onLoadMore = _ref.onLoadMore, onScroll = _ref.onScroll, rest = _object_without_properties(_ref, [ "children", "type", "hasMore", "threshold", "target", "pullRefresh", "pullingText", "loadingText", "loadMoreText", "className", "onRefresh", "onLoadMore", "onScroll" ]); var _useState = _sliced_to_array(useState(false), 2), isInfiniting = _useState[0], setIsInfiniting = _useState[1]; var _useState1 = _sliced_to_array(useState(0), 2), topDisScoll = _useState1[0], setTopDisScoll = _useState1[1]; var refreshTop = useRef(null); var scrollHeight = useRef(0); var scrollTop = useRef(0); var isTouching = useRef(false); var y = useRef(0); var refreshMaxH = useRef(0); var distance = useRef(0); var classes = classNames(classPrefix, className, "".concat(classPrefix, "-").concat(type)); useEffect(function() { refreshMaxH.current = threshold; var timer = setTimeout(function() { getScrollHeight(); }, 200); return function() { return clearTimeout(timer); }; }, [ hasMore, isInfiniting, threshold ]); /** 获取需要滚动的距离 */ var getScrollHeight = function() { var parentElement = getParentElement('scroller'); parentElement.boundingClientRect(function(rect) { var _rect_height; scrollHeight.current = (_rect_height = rect === null || rect === void 0 ? void 0 : rect.height) !== null && _rect_height !== void 0 ? _rect_height : 0; }).exec(); }; var getStyle = function() { return { height: topDisScoll < 0 ? pxTransform(0) : pxTransform(topDisScoll), transition: "height 0.2s cubic-bezier(0.25,0.1,0.25,1)" }; }; var getParentElement = function(el) { return createSelectorQuery().select(target ? "#".concat(target, " #").concat(el) : "#".concat(el)); }; var infiniteDone = function() { setIsInfiniting(false); }; var refreshDone = function() { distance.current = 0; setTopDisScoll(0); isTouching.current = false; }; var scrollAction = function(e) { var _e_target; scrollTop.current = (_e_target = e.target) === null || _e_target === void 0 ? void 0 : _e_target.scrollTop; if (e.target.scrollTop <= 0) { // 滚动到最顶部 e.target.scrollTop = 0; } onScroll && onScroll(e.target.scrollTop); }; var lower = function() { return _async_to_generator(function() { return _ts_generator(this, function(_state) { switch(_state.label){ case 0: if (!hasMore || isInfiniting) { return [ 2, false ]; } setIsInfiniting(true); return [ 4, onLoadMore === null || onLoadMore === void 0 ? void 0 : onLoadMore() ]; case 1: _state.sent(); infiniteDone(); return [ 2 ]; } }); })(); }; var touchStart = function(event) { if (scrollTop.current === 0 && !isTouching.current && pullRefresh) { y.current = event.touches[0].pageY; isTouching.current = true; } }; var touchMove = function(event) { distance.current = event.touches[0].pageY - y.current; if (distance.current > 0 && isTouching.current) { event.preventDefault(); setTopDisScoll(distance.current); if (distance.current >= refreshMaxH.current) { distance.current = refreshMaxH.current; setTopDisScoll(refreshMaxH.current); } } else { distance.current = 0; setTopDisScoll(0); isTouching.current = false; } }; var touchEnd = function() { return _async_to_generator(function() { return _ts_generator(this, function(_state) { switch(_state.label){ case 0: if (!(distance.current < refreshMaxH.current)) return [ 3, 1 ]; distance.current = 0; setTopDisScoll(0); 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 /*#__PURE__*/ React.createElement(ScrollView, _object_spread_props(_object_spread({}, rest), { className: classes, scrollY: true, id: "scroller", type: "list", style: { height: '100%' }, onScroll: scrollAction, onScrollToLower: lower, onTouchStart: touchStart, onTouchMove: touchMove, onTouchEnd: touchEnd }), /*#__PURE__*/ React.createElement(View, { className: "nut-infinite-top", ref: refreshTop, style: getStyle() }, /*#__PURE__*/ React.createElement(View, { className: "nut-infinite-top-tips" }, pullingText || locale.infiniteloading.pullRefreshText)), /*#__PURE__*/ React.createElement(View, { className: "nut-infinite-container" }, children), /*#__PURE__*/ React.createElement(View, { className: "nut-infinite-bottom" }, /*#__PURE__*/ React.createElement(View, { className: "nut-infinite-bottom-tips" }, getBottomTipsText()))); }; InfiniteLoading.displayName = 'NutInfiniteLoading';