UNPKG

test-nut-ui

Version:

<p align="center"> <img alt="logo" src="https://img11.360buyimg.com/imagetools/jfs/t1/211965/25/7152/22022/61b16785E433119bb/aa41d7a9f7e823f3.png" width="150" style="margin-bottom: 10px;"> </p>

285 lines (284 loc) 11.4 kB
import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; var _excluded = ["list", "ItemRender", "itemEqual", "itemHeight", "direction", "overscan", "key", "onScroll", "className", "containerHeight"]; 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), true).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, { useRef, useState, useEffect, useCallback } from "react"; import { C as ComponentDefaults } from "./typings.js"; var initPositinoCache = function initPositinoCache2(reaItemSize) { var length = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 0; var index = 0; var positions = Array(length); while (index < length) { positions[index] = { index, height: reaItemSize, width: reaItemSize, top: index * reaItemSize, bottom: (index + 1) * reaItemSize, left: index * reaItemSize, right: (index + 1) * reaItemSize }; index++; } return positions; }; var getListTotalSize = function getListTotalSize2(positions, horizontal) { var index = positions.length - 1; var size = 0; if (index < 0) { size = 0; } else { size = horizontal ? positions[index].right : positions[index].bottom; } return size; }; var binarySearch = function binarySearch2(positionsList) { var value = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 0; var horizontal = arguments.length > 2 ? arguments[2] : void 0; var start = 0; var end = positionsList.length - 1; var tempIndex = null; var key = horizontal ? "right" : "bottom"; while (start <= end) { var midIndex = Math.floor((start + end) / 2); var midValue = positionsList[midIndex][key]; if (midValue === value) { return midIndex + 1; } if (midValue < value) { start = midIndex + 1; } else if (midValue > value) { if (tempIndex === null || tempIndex > midIndex) { tempIndex = midIndex; } end = midIndex - 1; } } tempIndex = tempIndex || 0; return tempIndex; }; var getEndIndex = function getEndIndex2(_ref) { var list = _ref.list, startIndex = _ref.startIndex, visibleCount = _ref.visibleCount, _ref$itemEqual = _ref.itemEqual, itemEqual = _ref$itemEqual === void 0 ? true : _ref$itemEqual, positions = _ref.positions, offSetSize = _ref.offSetSize, overscan = _ref.overscan, _ref$sizeKey = _ref.sizeKey, sizeKey = _ref$sizeKey === void 0 ? "width" : _ref$sizeKey; var dataLength = list.length; var tempIndex = null; if (itemEqual) { var endIndex = startIndex + visibleCount; tempIndex = dataLength > 0 ? Math.min(dataLength, endIndex) : endIndex; } else { var sizeNum = 0; for (var i = startIndex; i < dataLength; i++) { sizeNum += positions[i][sizeKey] || 0; if (sizeNum > offSetSize) { var _endIndex = i + overscan; tempIndex = dataLength > 0 ? Math.min(dataLength, _endIndex) : _endIndex; break; } } if (sizeNum < offSetSize) { tempIndex = dataLength; } } tempIndex = tempIndex || 0; return tempIndex; }; var updateItemSize = function updateItemSize2(positions, items, sizeKey) { var newPos = positions.concat(); Array.from(items).forEach(function(item) { var index = Number(item.getAttribute("data-index")); var styleVal = item.getAttribute("style"); if (styleVal && styleVal.includes("none")) return; var nowSize = item.getBoundingClientRect()[sizeKey]; var oldSize = positions[index][sizeKey]; var dValue = oldSize - nowSize; if (dValue) { if (sizeKey === "width") { newPos[index].right -= dValue; newPos[index][sizeKey] = nowSize; for (var k = index + 1; k < positions.length; k++) { newPos[k].left = positions[k - 1].right; newPos[k].right -= dValue; } } else if (sizeKey === "height") { newPos[index].bottom -= dValue; newPos[index][sizeKey] = nowSize; for (var _k = index + 1; _k < positions.length; _k++) { newPos[_k].top = positions[_k - 1].bottom; newPos[_k].bottom -= dValue; } } } }); }; var defaultProps = _objectSpread(_objectSpread({}, ComponentDefaults), {}, { list: [], itemHeight: 66, itemEqual: true, direction: "vertical", overscan: 2 }); var VirtualList = function VirtualList2(props) { var _defaultProps$props = _objectSpread(_objectSpread({}, defaultProps), props), list = _defaultProps$props.list, ItemRender = _defaultProps$props.ItemRender, itemEqual = _defaultProps$props.itemEqual, itemHeight = _defaultProps$props.itemHeight, direction = _defaultProps$props.direction, overscan = _defaultProps$props.overscan, key = _defaultProps$props.key, onScroll = _defaultProps$props.onScroll, className = _defaultProps$props.className, containerHeight = _defaultProps$props.containerHeight, rest = _objectWithoutProperties(_defaultProps$props, _excluded); var horizontal = direction === "horizontal"; var sizeKey = horizontal ? "width" : "height"; var scrollKey = horizontal ? "scrollLeft" : "scrollTop"; var offsetKey = horizontal ? "left" : "top"; var scrollRef = useRef(null); var itemsRef = useRef(null); var firstItemRef = useRef(null); var _useState = useState([{ index: 0, left: 0, top: 0, bottom: 0, width: 0, height: 0, right: 0 }]), _useState2 = _slicedToArray(_useState, 2), positions = _useState2[0], setPositions = _useState2[1]; var _useState3 = useState(99999999), _useState4 = _slicedToArray(_useState3, 2), listTotalSize = _useState4[0], setListTotalSize = _useState4[1]; var _useState5 = useState(0), _useState6 = _slicedToArray(_useState5, 2), visibleCount = _useState6[0], setVisibleCount = _useState6[1]; var _useState7 = useState(containerHeight || 0), _useState8 = _slicedToArray(_useState7, 2), offSetSize = _useState8[0], setOffSetSize = _useState8[1]; var _useState9 = useState({ startOffset: 0, startIndex: 0, overStart: 0, endIndex: 10 // 可视区域结束索引 }), _useState10 = _slicedToArray(_useState9, 2), options = _useState10[0], setOptions = _useState10[1]; useEffect(function() { var pos = initPositinoCache(itemHeight, list.length); setPositions(pos); var totalSize = getListTotalSize(pos, horizontal); setListTotalSize(totalSize); }, [list, itemHeight, horizontal]); var getElement = useCallback(function() { var _scrollRef$current; return ((_scrollRef$current = scrollRef.current) === null || _scrollRef$current === void 0 ? void 0 : _scrollRef$current.parentElement) || document.body; }, []); useEffect(function() { if (containerHeight) return; var size = horizontal ? getElement().offsetWidth : getElement().offsetHeight; setOffSetSize(size); }, [getElement, horizontal, containerHeight]); useEffect(function() { if (offSetSize === 0) return; var count = Math.ceil(offSetSize / itemHeight) + overscan; setVisibleCount(count); setOptions(function(options2) { return _objectSpread(_objectSpread({}, options2), {}, { endIndex: count }); }); }, [getElement, horizontal, itemHeight, overscan, offSetSize]); var updateTotalSize = useCallback(function() { if (!itemsRef.current) return; var items = itemsRef.current.children; if (!items.length) return; updateItemSize(positions, items, sizeKey); var totalSize = getListTotalSize(positions, horizontal); setListTotalSize(totalSize); }, [positions, sizeKey, horizontal]); var scroll = useCallback(function() { requestAnimationFrame(function(e) { var scrollSize = getElement()[scrollKey]; var startIndex = binarySearch(positions, scrollSize, horizontal); var overStart = startIndex - overscan > -1 ? startIndex - overscan : 0; if (!itemEqual) { updateTotalSize(); } var endIndex = getEndIndex({ list, startIndex, visibleCount, itemEqual, positions, offSetSize, sizeKey, overscan }); var startOffset = positions[startIndex][offsetKey]; setOptions({ startOffset, startIndex, overStart, endIndex }); if (endIndex > list.length - 1) { if (onScroll) { onScroll(); } } }); }, [positions, getElement, list, visibleCount, itemEqual, updateTotalSize, offsetKey, sizeKey, scrollKey, horizontal, overscan, offSetSize]); useEffect(function() { var element = getElement(); element.addEventListener("scroll", scroll, false); return function() { element.removeEventListener("scroll", scroll, false); }; }, [getElement, scroll]); return React__default.createElement("div", _objectSpread(_objectSpread({ className: className ? "".concat(className, " nut-virtualList-box") : "nut-virtualList-box" }, rest), {}, { style: _defineProperty({}, sizeKey, containerHeight ? "".concat(offSetSize, "px") : "") }), React__default.createElement("div", { ref: scrollRef, className: horizontal ? "nut-horizontal-box" : "nut-vertical-box", style: _defineProperty({ position: "relative" }, sizeKey, "".concat(listTotalSize, "px")) }, React__default.createElement("ul", { className: horizontal ? "nut-virtuallist-items nut-horizontal-items" : "nut-virtuallist-items nut-vertical-items", ref: itemsRef, style: { transform: horizontal ? "translate3d(".concat(options.startOffset, "px,0,0)") : "translate3d(0,".concat(options.startOffset, "px,0)") } }, list.slice(options.overStart, options.endIndex).map(function(data, index) { var startIndex = options.startIndex, overStart = options.overStart; var dataIndex = overStart + index; var styleVal = dataIndex < startIndex ? "none" : "block"; var keyVal = key && data[key] ? data[key] : dataIndex; return React__default.createElement("li", { ref: dataIndex === 0 ? firstItemRef : null, "data-index": "".concat(dataIndex), className: dataIndex % 2 === 0 ? "nut-virtuallist-item even" : "nut-virtuallist-item odd", key: "".concat(keyVal), style: { display: styleVal } }, ItemRender ? React__default.createElement(ItemRender, { data, index: "".concat(dataIndex) }) : data); })))); }; VirtualList.defaultProps = defaultProps; VirtualList.displayName = "NutVirtualList"; export { VirtualList as default };