UNPKG

@antmjs/vantui

Version:

一套适用于Taro3及React的vantui组件库

246 lines 9.91 kB
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray"; import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import _regeneratorRuntime from "@babel/runtime/regenerator"; 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 { useState, useCallback, forwardRef, useImperativeHandle, useEffect, useRef, useMemo, useLayoutEffect } from 'react'; import { View, ScrollView } from '@tarojs/components'; import { nextTick } from '@tarojs/taro'; import { getRect, addUnit } from '../common/utils'; import { Icon } from '../icon'; import { get } from '../default-props'; import { getClosestIndex } from './utils'; import { jsx as _jsx } from "react/jsx-runtime"; import { jsxs as _jsxs } from "react/jsx-runtime"; var clsPrefix = 'van-virtual-half-list'; function VirtualList_(props, ref) { var _useState = useState(get().VirtualList), _useState2 = _slicedToArray(_useState, 1), d = _useState2[0]; var _d$props = _objectSpread(_objectSpread({}, d), props), className = _d$props.className, height = _d$props.height, style = _d$props.style, footer = _d$props.footer, dataSource = _d$props.dataSource, _d$props$showCount = _d$props.showCount, showCount = _d$props$showCount === void 0 ? 10 : _d$props$showCount, _d$props$listClssName = _d$props.listClssName, listClssName = _d$props$listClssName === void 0 ? '' : _d$props$listClssName, ItemRender = _d$props.ItemRender, _d$props$listStyle = _d$props.listStyle, listStyle = _d$props$listStyle === void 0 ? {} : _d$props$listStyle, renderBackToTop = _d$props.renderBackToTop, backToTopCritical = _d$props.backToTopCritical, backToTopSuccess = _d$props.backToTopSuccess; var prevDataLength = useRef(0); var _useState3 = useState(''), _useState4 = _slicedToArray(_useState3, 2), scrollIntoView = _useState4[0], setScrollIntoView = _useState4[1]; var _useState5 = useState({}), _useState6 = _slicedToArray(_useState5, 2), rects = _useState6[0], setRects = _useState6[1]; var _useState7 = useState({ head: 0, tail: showCount, nextHead: showCount, NextTail: showCount * 2, transformY: "translateY(0px)" }), _useState8 = _slicedToArray(_useState7, 2), showConfig = _useState8[0], setShowConfig = _useState8[1]; var updateRects = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() { var head, nextHead, target, nextTarget, shouldUpdate, rect1, prev, rect2, _prev; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: head = showConfig.head; nextHead = showConfig.nextHead; target = ".".concat(clsPrefix, "-box").concat(head); nextTarget = ".".concat(clsPrefix, "-box").concat(nextHead); if (process.env.TARO_ENV === 'weapp') { target = ".".concat(clsPrefix, " >>> ").concat(target); nextTarget = ".".concat(clsPrefix, " >>> ").concat(nextTarget); } shouldUpdate = false; if (rects[head]) { _context.next = 12; break; } shouldUpdate = true; _context.next = 10; return getRect(null, target); case 10: rect1 = _context.sent; if ("".concat(head) === '0') { rects[head] = _objectSpread(_objectSpread({}, rect1), {}, { top: 0 }); } else { prev = rects[head - showCount]; rects[head] = _objectSpread(_objectSpread({}, rect1), {}, { top: prev.height + prev.top }); } case 12: if (rects[nextHead]) { _context.next = 19; break; } shouldUpdate = true; _context.next = 16; return getRect(null, nextTarget); case 16: rect2 = _context.sent; _prev = rects[nextHead - showCount]; rects[nextHead] = _objectSpread(_objectSpread({}, rect2), {}, { top: _prev.height + _prev.top }); case 19: if (shouldUpdate) setRects(_objectSpread({}, rects)); case 20: case "end": return _context.stop(); } }, _callee); })), [showCount, rects, showConfig]); var handleScroll = useCallback(function (e) { var scrollTop = Math.floor(e.detail.scrollTop); updateRects(); nextTick(function () { if (Object.keys(rects).length) { var startIndex = getClosestIndex(rects, scrollTop); setShowConfig({ head: startIndex, tail: startIndex + showCount, nextHead: startIndex + showCount, NextTail: startIndex + showCount * 2, transformY: "translateY(".concat(rects["".concat(startIndex)].top, "px)") }); } }); }, [showCount, rects, updateRects]); var reset = useCallback(function () { prevDataLength.current = 0; setRects({}); setShowConfig({ head: 0, tail: showCount, nextHead: showCount, NextTail: showCount * 2, transformY: "translateY(0px)" }); }, [showCount]); var scrollToTop = useCallback(function () { setShowConfig({ head: 0, tail: showCount, nextHead: showCount, NextTail: showCount * 2, transformY: "translateY(0px)" }); setScrollIntoView('van-virtual-box-item0'); nextTick(function () { setTimeout(function () { setScrollIntoView(''); backToTopSuccess === null || backToTopSuccess === void 0 ? void 0 : backToTopSuccess(); }, 33.33); }); }, [backToTopSuccess, showCount]); useImperativeHandle(ref, function () { return { reset: reset, backToTop: scrollToTop }; }); useEffect(function () { if (dataSource.length > prevDataLength.current) { setTimeout(function () { updateRects(); }, 66.66); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [dataSource.length]); useLayoutEffect(function () { reset(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); var onTouch = useCallback(function (e) { if (showConfig.head > 0) { e.preventDefault(); e.stopPropagation(); } }, [showConfig.head]); var wrapperHeight = useMemo(function () { var keys = Object.keys(rects); if (keys.length) { var maxIndex = Math.max.apply(Math, _toConsumableArray(keys.map(function (item) { return Number(item); }))); var lastRect = rects["".concat(maxIndex)]; return lastRect.height + lastRect.top; } else return 0; }, [rects]); return /*#__PURE__*/_jsxs(ScrollView // @ts-ignore , { catchMove: true, className: "van-virtual-list ".concat(clsPrefix, " ").concat(className), scrollY: true, style: _objectSpread({ height: addUnit(height) }, style), onScroll: handleScroll, scrollIntoView: scrollIntoView, onTouchStart: onTouch, onTouchMove: onTouch, children: [/*#__PURE__*/_jsx(View, { style: { minHeight: wrapperHeight || 'auto' }, children: /*#__PURE__*/_jsxs(View, { style: { transform: showConfig.transformY }, children: [/*#__PURE__*/_jsx(View, { className: "".concat(clsPrefix, "-box").concat(showConfig.head, " ").concat(listClssName), style: listStyle, children: dataSource.slice(showConfig.head, showConfig.tail).map(function (item, i) { return /*#__PURE__*/_jsx(ItemRender, { item: item, index: showConfig.head + i, id: "van-virtual-box-item".concat(i + showConfig.head) }, "van-virtual-box-item".concat(i + showConfig.head)); }) }), /*#__PURE__*/_jsx(View, { className: "".concat(clsPrefix, "-box").concat(showConfig.nextHead, " ").concat(listClssName), style: listStyle, children: dataSource.slice(showConfig.nextHead, showConfig.NextTail).map(function (item, i) { return /*#__PURE__*/_jsx(ItemRender, { item: item, index: showConfig.nextHead + i, id: "van-virtual-box-item".concat(i + showConfig.nextHead) }, "van-virtual-box-next-item".concat(i + showConfig.nextHead)); }) })] }) }), footer, /*#__PURE__*/_jsx(View, { className: "van-virtual-backto-top-".concat(showConfig.head > (backToTopCritical || showCount * 2) ? 'show' : 'hidden'), children: renderBackToTop || /*#__PURE__*/_jsx(View, { className: "van-virtual-backto-top", children: /*#__PURE__*/_jsx(Icon, { name: "back-top", size: "20px", onClick: scrollToTop }) }) })] }); } export var VirtualList = /*#__PURE__*/forwardRef(VirtualList_); export default VirtualList;