@nutui/nutui-react-taro
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
116 lines (115 loc) • 5.09 kB
JavaScript
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
};