UNPKG

@nutui/nutui-react-taro

Version:

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

116 lines (115 loc) 5.09 kB
import { _ as __rest, a as __awaiter } from "./tslib.es6-iWu3F_1J.js"; import React__default, { useState, useRef, useEffect } from "react"; import classNames from "classnames"; import { ScrollView } from "@tarojs/components"; import { createSelectorQuery } from "@tarojs/taro"; import { u as useConfig } from "./configprovider.taro-DpK4IiCE.js"; import { C as ComponentDefaults } from "./typings-DV9RBfhj.js"; const defaultProps = Object.assign(Object.assign({}, ComponentDefaults), { type: "default", hasMore: true, threshold: 40, target: "", pullRefresh: false }); const classPrefix = `nut-infiniteloading`; const InfiniteLoading = (props) => { const { locale } = useConfig(); const _a = Object.assign(Object.assign({}, defaultProps), props), { children, type, hasMore, threshold, target, pullRefresh, pullingText, loadingText, loadMoreText, className, onRefresh, onLoadMore, onScroll } = _a, rest = __rest(_a, ["children", "type", "hasMore", "threshold", "target", "pullRefresh", "pullingText", "loadingText", "loadMoreText", "className", "onRefresh", "onLoadMore", "onScroll"]); const [isInfiniting, setIsInfiniting] = useState(false); const [topDisScoll, setTopDisScoll] = useState(0); const refreshTop = useRef(null); const scrollHeight = useRef(0); const scrollTop = useRef(0); const isTouching = useRef(false); const y = useRef(0); const refreshMaxH = useRef(0); const distance = useRef(0); const classes = classNames(classPrefix, className, `${classPrefix}-${type}`); useEffect(() => { refreshMaxH.current = threshold; setTimeout(() => { getScrollHeight(); }, 200); }, [hasMore, isInfiniting]); const getScrollHeight = () => { const parentElement = getParentElement("scroller"); parentElement.boundingClientRect((rect) => { var _a2; scrollHeight.current = (_a2 = rect === null || rect === void 0 ? void 0 : rect.height) !== null && _a2 !== void 0 ? _a2 : 0; }).exec(); }; const getStyle = () => { return { height: topDisScoll < 0 ? `0px` : `${topDisScoll}px`, transition: `height 0.2s cubic-bezier(0.25,0.1,0.25,1)` }; }; const getParentElement = (el) => { return createSelectorQuery().select(target ? `#${target} #${el}` : `#${el}`); }; const infiniteDone = () => { setIsInfiniting(false); }; const refreshDone = () => { distance.current = 0; setTopDisScoll(0); isTouching.current = false; }; const scrollAction = (e) => { var _a2; scrollTop.current = (_a2 = e.target) === null || _a2 === void 0 ? void 0 : _a2.scrollTop; if (e.target.scrollTop <= 0) { e.target.scrollTop = 0; } onScroll && onScroll(e.target.scrollTop); }; const lower = () => __awaiter(void 0, void 0, void 0, function* () { if (!hasMore || isInfiniting) { return false; } setIsInfiniting(true); yield onLoadMore === null || onLoadMore === void 0 ? void 0 : onLoadMore(); infiniteDone(); }); const touchStart = (event) => { if (scrollTop.current === 0 && !isTouching.current && pullRefresh) { y.current = event.touches[0].pageY; isTouching.current = true; } }; const touchMove = (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; } }; const touchEnd = () => __awaiter(void 0, void 0, void 0, function* () { if (distance.current < refreshMaxH.current) { distance.current = 0; setTopDisScoll(0); isTouching.current = false; } else { yield onRefresh === null || onRefresh === void 0 ? void 0 : onRefresh(); refreshDone(); } }); return React__default.createElement( ScrollView, Object.assign({}, rest, { className: classes, scrollY: true, id: "scroller", type: "list", style: { height: "100%" }, onScroll: scrollAction, onScrollToLower: lower, onTouchStart: touchStart, onTouchMove: touchMove, onTouchEnd: touchEnd }), React__default.createElement( "div", { className: "nut-infinite-top", ref: refreshTop, style: getStyle() }, React__default.createElement("div", { className: "nut-infinite-top-tips" }, pullingText || locale.infiniteloading.pullRefreshText) ), React__default.createElement("div", { className: "nut-infinite-container" }, children), React__default.createElement("div", { className: "nut-infinite-bottom" }, isInfiniting ? React__default.createElement("div", { className: "nut-infinite-bottom-tips" }, loadingText || locale.infiniteloading.loadText) : !hasMore && React__default.createElement("div", { className: "nut-infinite-bottom-tips" }, loadMoreText || locale.infiniteloading.loadMoreText)) ); }; InfiniteLoading.displayName = "NutInfiniteLoading"; export { InfiniteLoading as I };