UNPKG

tdesign-react

Version:
223 lines (217 loc) 9.57 kB
/** * tdesign v1.13.2 * (c) 2025 tdesign * @license MIT */ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var slicedToArray = require('../_chunks/dep-e17e2d31.js'); var React = require('react'); var hooks_useResizeObserver = require('./useResizeObserver.js'); require('../_chunks/dep-b7d577ac.js'); require('./useLayoutEffect.js'); require('../_chunks/dep-3f65dfe7.js'); require('../_chunks/dep-3e2d2665.js'); require('../_chunks/dep-f0379c5f.js'); require('../_chunks/dep-6d4d8660.js'); require('../_chunks/dep-028b759d.js'); require('../_chunks/dep-ddacd27a.js'); require('./useLatest.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 _useState = React.useState([]), _useState2 = slicedToArray._slicedToArray(_useState, 2), visibleData = _useState2[0], setVisibleData = _useState2[1]; var _useState3 = React.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._slicedToArray(_useState3, 2), translateY = _useState4[0], setTranslateY = _useState4[1]; var _useState5 = React.useState(0), _useState6 = slicedToArray._slicedToArray(_useState5, 2), scrollHeight = _useState6[0], setScrollHeight = _useState6[1]; var trScrollTopHeightList = React.useRef([]); var _useState7 = React.useState([]), _useState8 = slicedToArray._slicedToArray(_useState7, 2), trHeightList = _useState8[0], setTrHeightList = _useState8[1]; var containerWidth = React.useRef(0); var containerHeight = React.useRef(0); var _useState9 = React.useState(function () { return [0, ((scroll === null || scroll === void 0 ? void 0 : scroll.bufferSize) || 10) * 3]; }), _useState0 = slicedToArray._slicedToArray(_useState9, 2), startAndEndIndex = _useState0[0], setStartAndEndIndex = _useState0[1]; var tScroll = React.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 = React.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._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 refreshVirtualScroll = function refreshVirtualScroll(_ref) { var _ref2 = slicedToArray._slicedToArray(_ref, 1), contentRect = _ref2[0].contentRect; var maxScrollbarWidth = 16; if (Math.abs(contentRect.width - containerWidth.current) > maxScrollbarWidth) { container.current.scrollTop = 0; handleScroll(); } containerWidth.current = contentRect.width; containerHeight.current = contentRect.height; }; var addIndexToData = function addIndexToData(data2) { data2.forEach(function (item, index) { Reflect.set(item, "__VIRTUAL_SCROLL_INDEX", index); }); }; var updateScrollTop = function updateScrollTop(_ref3) { var _container$current; var index = _ref3.index, _ref3$top = _ref3.top, top = _ref3$top === void 0 ? 0 : _ref3$top, behavior = _ref3.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); }); } }; hooks_useResizeObserver["default"](container, refreshVirtualScroll, isVirtualScroll); React.useEffect(function () { if (!isVirtualScroll) { trScrollTopHeightList.current = getTrScrollTopHeightList(trHeightList); return; } addIndexToData(data); var scrollTopHeightList = trScrollTopHeightList.current; if ((scrollTopHeightList === null || scrollTopHeightList === void 0 ? void 0 : scrollTopHeightList.length) === (data === null || data === void 0 ? void 0 : data.length)) { var lastIndex = scrollTopHeightList.length - 1; setScrollHeight(scrollTopHeightList[lastIndex]); updateVisibleData(scrollTopHeightList, container.current.scrollTop); } else { setScrollHeight(data.length * tScroll.rowHeight); var tmpData = data.slice(0, ((scroll === null || scroll === void 0 ? void 0 : scroll.bufferSize) || 10) * 3); setVisibleData(tmpData); setTranslateY(0); } 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 }; }; exports["default"] = useVirtualScroll; //# sourceMappingURL=useVirtualScroll.js.map