gui-one-nutui-react-taro
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
189 lines (188 loc) • 7.81 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
import React__default, { useState, useRef, useEffect } from 'react';
import classNames from 'classnames';
import { ScrollView } from '@tarojs/components';
import Taro from '@tarojs/taro';
import { c as cn } from './bem-893ad28d.js';
import { I as Icon } from './icon.taro-1d0d4fb7.js';
import { u as useConfig } from './configprovider.taro-6c7b3056.js';
import { C as ComponentDefaults } from './typings-1c5f2628.js';
var defaultProps = _objectSpread(_objectSpread({}, ComponentDefaults), {}, {
hasMore: true,
upperThreshold: 40,
containerId: '',
isOpenRefresh: false,
pullIcon: 'https://img10.360buyimg.com/imagetools/jfs/t1/169863/6/4565/6306/60125948E7e92774e/40b3a0cf42852bcb.png',
pullTxt: '松开刷新',
loadIcon: 'https://img10.360buyimg.com/imagetools/jfs/t1/169863/6/4565/6306/60125948E7e92774e/40b3a0cf42852bcb.png',
loadTxt: '加载中···',
loadMoreTxt: '哎呀,这里是底部了啦'
});
var Infiniteloading = function Infiniteloading(props) {
var _useConfig = useConfig(),
locale = _useConfig.locale;
var _defaultProps$props = _objectSpread(_objectSpread({}, defaultProps), props),
children = _defaultProps$props.children,
hasMore = _defaultProps$props.hasMore,
upperThreshold = _defaultProps$props.upperThreshold,
containerId = _defaultProps$props.containerId,
isOpenRefresh = _defaultProps$props.isOpenRefresh,
pullIcon = _defaultProps$props.pullIcon,
pullTxt = _defaultProps$props.pullTxt,
loadIcon = _defaultProps$props.loadIcon,
loadTxt = _defaultProps$props.loadTxt,
loadMoreTxt = _defaultProps$props.loadMoreTxt,
className = _defaultProps$props.className,
onRefresh = _defaultProps$props.onRefresh,
onLoadMore = _defaultProps$props.onLoadMore,
onScrollChange = _defaultProps$props.onScrollChange,
iconClassPrefix = _defaultProps$props.iconClassPrefix,
iconFontClassName = _defaultProps$props.iconFontClassName;
var _useState = useState(false),
_useState2 = _slicedToArray(_useState, 2),
isInfiniting = _useState2[0],
setIsInfiniting = _useState2[1];
var _useState3 = useState(0),
_useState4 = _slicedToArray(_useState3, 2),
topDisScoll = _useState4[0],
setTopDisScoll = _useState4[1];
var refreshTop = useRef(null);
var scrollHeight = useRef(0);
var scrollTop = useRef(0);
var direction = useRef('down');
var isTouching = useRef(false);
var y = useRef(0);
var refreshMaxH = useRef(0);
var distance = useRef(0);
var b = cn('infiniteloading');
var classes = classNames(className, b());
useEffect(function () {
refreshMaxH.current = upperThreshold;
setTimeout(function () {
getScrollHeight();
}, 200);
}, [hasMore, isInfiniting]);
/** 获取需要滚动的距离 */
var getScrollHeight = function getScrollHeight() {
var parentElement = getParentElement('scroller');
parentElement.boundingClientRect(function (rect) {
scrollHeight.current = rect.height;
}).exec();
};
var getStyle = function getStyle() {
return {
height: topDisScoll < 0 ? "0px" : "".concat(topDisScoll, "px"),
transition: "height 0.2s cubic-bezier(0.25,0.1,0.25,1)"
};
};
var getParentElement = function getParentElement(el) {
return Taro.createSelectorQuery().select(containerId ? "#".concat(containerId, " #").concat(el) : "#".concat(el));
};
var infiniteDone = function infiniteDone() {
setIsInfiniting(false);
};
var refreshDone = function refreshDone() {
distance.current = 0;
setTopDisScoll(0);
isTouching.current = false;
};
var scrollAction = function scrollAction(e) {
if (e.detail.scrollTop <= 0) {
// 滚动到最顶部
e.detail.scrollTop = 0;
} else if (e.detail.scrollTop >= scrollHeight.current) {
// 滚动到最底部
e.detail.scrollTop = scrollHeight.current;
}
if (e.detail.scrollTop > scrollTop.current || e.detail.scrollTop >= scrollHeight.current) {
direction.current = 'down';
} else {
direction.current = 'up';
}
scrollTop.current = e.detail.scrollTop;
onScrollChange && onScrollChange(e.detail.scrollTop);
};
var lower = function lower() {
if (direction.current == 'up' || !hasMore || isInfiniting) {
return false;
}
setIsInfiniting(true);
onLoadMore && onLoadMore(infiniteDone);
};
var touchStart = function touchStart(event) {
if (scrollTop.current == 0 && !isTouching.current && isOpenRefresh) {
y.current = event.touches[0].pageY;
isTouching.current = true;
}
};
var touchMove = function 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;
}
};
var touchEnd = function touchEnd() {
if (distance.current < refreshMaxH.current) {
distance.current = 0;
setTopDisScoll(0);
} else {
onRefresh && onRefresh(refreshDone);
}
};
return React__default.createElement(ScrollView, {
className: classes,
scrollY: true,
id: "scroller",
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: "top-box"
}, React__default.createElement(Icon, {
classPrefix: iconClassPrefix,
fontClassName: iconFontClassName,
className: "top-img",
name: pullIcon
}), React__default.createElement("span", {
className: "top-text"
}, pullTxt || 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: "bottom-box"
}, React__default.createElement(Icon, {
classPrefix: iconClassPrefix,
fontClassName: iconFontClassName,
className: "bottom-img",
name: loadIcon
}), React__default.createElement("div", {
className: "bottom-text"
}, loadTxt || locale.infiniteloading.loadText)) : !hasMore && React__default.createElement("div", {
className: "tips"
}, loadMoreTxt || locale.infiniteloading.loadMoreText)));
};
Infiniteloading.defaultProps = defaultProps;
Infiniteloading.displayName = 'NutInfiniteloading';
export { Infiniteloading as I };