UNPKG

tdesign-react

Version:
219 lines (215 loc) 9.76 kB
/** * tdesign v1.15.1 * (c) 2025 tdesign * @license MIT */ import { _ as _slicedToArray } from '../_chunks/dep-48805ab8.js'; import { useRef, useState, useMemo, useEffect } from 'react'; import { isEqual } from 'lodash-es'; import '../_chunks/dep-026a4c6b.js'; var requestAnimationFrame = (typeof window === "undefined" ? false : window.requestAnimationFrame) || function (cb) { return setTimeout(cb, 16.6); }; var useVirtualScroll = function useVirtualScroll(container, params) { var data = params.data, scroll = params.scroll; var dataRef = useRef(data); var _useState = useState([]), _useState2 = _slicedToArray(_useState, 2), visibleData = _useState2[0], setVisibleData = _useState2[1]; var _useState3 = useState(function () { return ((data === null || data === void 0 ? void 0 : data.length) || 0) * ((scroll === null || scroll === void 0 ? void 0 : scroll.rowHeight) || 50); }), _useState4 = _slicedToArray(_useState3, 2), translateY = _useState4[0], setTranslateY = _useState4[1]; var _useState5 = useState(0), _useState6 = _slicedToArray(_useState5, 2), scrollHeight = _useState6[0], setScrollHeight = _useState6[1]; var trScrollTopHeightList = useRef([]); var _useState7 = useState([]), _useState8 = _slicedToArray(_useState7, 2), trHeightList = _useState8[0], setTrHeightList = _useState8[1]; var containerHeight = useRef(0); var _useState9 = useState(function () { return [0, ((scroll === null || scroll === void 0 ? void 0 : scroll.bufferSize) || 10) * 3]; }), _useState0 = _slicedToArray(_useState9, 2), startAndEndIndex = _useState0[0], setStartAndEndIndex = _useState0[1]; var tScroll = useMemo(function () { var _scroll$isFixedRowHei, _scroll$fixedRows; if (!scroll) return {}; return { bufferSize: scroll.bufferSize || 10, isFixedRowHeight: (_scroll$isFixedRowHei = scroll.isFixedRowHeight) !== null && _scroll$isFixedRowHei !== void 0 ? _scroll$isFixedRowHei : false, rowHeight: scroll.rowHeight || 47, threshold: scroll.threshold || 100, type: scroll.type, fixedRows: (_scroll$fixedRows = scroll.fixedRows) !== null && _scroll$fixedRows !== void 0 ? _scroll$fixedRows : [0, 0] }; }, [scroll]); var isVirtualScroll = useMemo(function () { return tScroll.type === "virtual" && tScroll.threshold < data.length; }, [tScroll, data]); var getTrScrollTopHeightList = function getTrScrollTopHeightList(trHeightList2) { var list = []; for (var i = 0, len = data.length; i < len; i++) { list[i] = (list[i - 1] || 0) + (trHeightList2[i] || tScroll.rowHeight); } return list; }; var updateVisibleData = function updateVisibleData(trScrollTopHeightList2, scrollTop) { var currentIndex = -1; for (var i = 0, len = trScrollTopHeightList2.length; i < len; i++) { if (trScrollTopHeightList2[i] >= scrollTop) { currentIndex = i; break; } } var lastIndex = trScrollTopHeightList2.length; var containerCurrentHeight = containerHeight.current || container.current.getBoundingClientRect().height; var scrollBottom = scrollTop + containerCurrentHeight; for (var _i = currentIndex, _len = trScrollTopHeightList2.length; _i < _len; _i++) { if (trScrollTopHeightList2[_i] >= scrollBottom) { lastIndex = _i; break; } } if (currentIndex < 0) return; var startIndex = Math.max(currentIndex - tScroll.bufferSize, 0); var endIndex = Math.min(lastIndex + tScroll.bufferSize, trScrollTopHeightList2.length); var fixedRows = tScroll.fixedRows; var _fixedRows = _slicedToArray(fixedRows, 2), fixedStart = _fixedRows[0], fixedEnd = _fixedRows[1]; var fixedStartData = fixedStart ? data.slice(0, fixedStart) : []; if (fixedStart && startIndex < fixedStart) { fixedStartData = fixedStartData.slice(0, startIndex); } var fixedEndData = fixedEnd ? data.slice(data.length - fixedEnd) : []; var bottomStartIndex = endIndex - data.length + 1 + (fixedEnd !== null && fixedEnd !== void 0 ? fixedEnd : 0); if (fixedEnd && bottomStartIndex > 0) { fixedEndData = fixedEndData.slice(bottomStartIndex); } if (startAndEndIndex.join() !== [startIndex, endIndex].join() && startIndex >= 0) { var tmpVisibleData = fixedStartData.concat(data.slice(startIndex, endIndex)).concat(fixedEndData); setVisibleData(tmpVisibleData); var lastScrollTop = trScrollTopHeightList2[startIndex - 1]; var top = lastScrollTop > 0 ? lastScrollTop : 0; var stickyHeight = trScrollTopHeightList2[Math.min(startIndex, fixedStart) - 1] || 0; setTranslateY(top - stickyHeight); setStartAndEndIndex([startIndex, endIndex]); } }; var handleRowMounted = function handleRowMounted(rowData) { if (!isVirtualScroll || !rowData || tScroll.isFixedRowHeight || !(container !== null && container !== void 0 && container.current)) return; var trHeight = rowData.ref.offsetHeight; var rowIndex = rowData.data.__VIRTUAL_SCROLL_INDEX; var newTrHeightList = trHeightList; if (newTrHeightList[rowIndex] !== trHeight) { newTrHeightList[rowIndex] = trHeight; setTrHeightList(newTrHeightList); var scrollTopHeightList = getTrScrollTopHeightList(newTrHeightList); trScrollTopHeightList.current = scrollTopHeightList; var lastIndex = scrollTopHeightList.length - 1; setScrollHeight(scrollTopHeightList[lastIndex] - containerHeight.current); updateVisibleData(scrollTopHeightList, container.current.scrollTop); } }; var handleScroll = function handleScroll() { if (!isVirtualScroll) return; updateVisibleData(trScrollTopHeightList.current, container.current.scrollTop); }; var addIndexToData = function addIndexToData(data2) { data2.forEach(function (item, index) { Reflect.set(item, "__VIRTUAL_SCROLL_INDEX", index); }); }; var updateScrollTop = function updateScrollTop(_ref) { var _container$current; var index = _ref.index, _ref$top = _ref.top, top = _ref$top === void 0 ? 0 : _ref$top, behavior = _ref.behavior; var scrollTop = trScrollTopHeightList.current[index] - top; (_container$current = container.current) === null || _container$current === void 0 || _container$current.scrollTo({ top: scrollTop, behavior: behavior || "auto" }); }; var scrollToElement = function scrollToElement(p) { updateScrollTop(p); if (!tScroll.isFixedRowHeight) { requestAnimationFrame(function () { var _p$time; var duration = (_p$time = p.time) !== null && _p$time !== void 0 ? _p$time : 60; var timer = setTimeout(function () { updateScrollTop(p); clearTimeout(timer); }, duration); }); } }; useEffect(function () { if (!isVirtualScroll) { trScrollTopHeightList.current = getTrScrollTopHeightList(trHeightList); return; } addIndexToData(data); var scrollTopHeightList = trScrollTopHeightList.current; var dataChanged = !isEqual(dataRef.current, data); if ((scrollTopHeightList === null || scrollTopHeightList === void 0 ? void 0 : scrollTopHeightList.length) === (data === null || data === void 0 ? void 0 : data.length) && !dataChanged) { var lastIndex = scrollTopHeightList.length - 1; setScrollHeight(scrollTopHeightList[lastIndex]); updateVisibleData(scrollTopHeightList, container.current.scrollTop); } else { var _container$current2; dataRef.current = data; setScrollHeight(data.length * tScroll.rowHeight); var currentScrollTop = ((_container$current2 = container.current) === null || _container$current2 === void 0 ? void 0 : _container$current2.scrollTop) || 0; var currentIndex = Math.floor(currentScrollTop / tScroll.rowHeight); var prevScrollTopHeightList = trScrollTopHeightList.current; for (var i = 0; i < (prevScrollTopHeightList === null || prevScrollTopHeightList === void 0 ? void 0 : prevScrollTopHeightList.length); i++) { if (prevScrollTopHeightList[i] >= currentScrollTop) { currentIndex = i; break; } } var startIndex = Math.max(currentIndex - tScroll.bufferSize, 0); var visibleCount = Math.min(tScroll.bufferSize * 3, data.length); var endIndex = Math.min(startIndex + visibleCount, data.length); var tmpData = data.slice(startIndex, endIndex); var translateY2 = startIndex * tScroll.rowHeight; if ((prevScrollTopHeightList === null || prevScrollTopHeightList === void 0 ? void 0 : prevScrollTopHeightList.length) > 0 && startIndex > 0) { var prevHeight = prevScrollTopHeightList[Math.min(startIndex - 1, prevScrollTopHeightList.length - 1)] || 0; translateY2 = Math.max(0, prevHeight); } setVisibleData(tmpData); setTranslateY(translateY2); } var timer = setTimeout(function () { if (container.current) { var tmpContainerHeight = container.current.getBoundingClientRect().height; containerHeight.current = tmpContainerHeight; var scrollTopHeightList2 = getTrScrollTopHeightList(trHeightList); trScrollTopHeightList.current = scrollTopHeightList2; clearTimeout(timer); } }, 1); }, [container, data, tScroll, isVirtualScroll, startAndEndIndex, trHeightList]); return { visibleData: visibleData, translateY: translateY, scrollHeight: scrollHeight, isVirtualScroll: isVirtualScroll, handleScroll: handleScroll, handleRowMounted: handleRowMounted, scrollToElement: scrollToElement }; }; export { useVirtualScroll as default }; //# sourceMappingURL=useVirtualScroll.js.map