@coreui/react-pro
Version:
UI Components Library for React.js
83 lines (80 loc) • 4.29 kB
JavaScript
import { __assign } from '../../node_modules/tslib/tslib.es6.js';
import React, { forwardRef, useRef, useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import classNames from '../../node_modules/classnames/index.js';
import { useForkedRef } from '../../hooks/useForkedRef.js';
import '@popperjs/core';
var CVirtualScroller = forwardRef(function (_a, ref) {
var children = _a.children, className = _a.className, visibleItems = _a.visibleItems, onScroll = _a.onScroll;
var virtualScrollRef = useRef(null);
var virtualScrollContentRef = useRef(null);
var forkedRef = useForkedRef(ref, virtualScrollRef);
var _b = useState(Math.floor(visibleItems / 2)), buffer = _b[0], setBuffer = _b[1];
var _c = useState(1), currentItemIndex = _c[0], setCurrentItemIndex = _c[1];
var _d = useState(0), itemHeight = _d[0], setItemHeight = _d[1];
var _e = useState(React.Children.count(children)), itemsNumber = _e[0], setItemsNumber = _e[1];
var _f = useState(0), viewportPadding = _f[0], setViewportPadding = _f[1];
var _g = useState(visibleItems * itemHeight + 2 * viewportPadding), viewportHeight = _g[0], setViewportHeight = _g[1];
var _h = useState(itemsNumber * itemHeight + 2 * viewportPadding), maxHeight = _h[0], setMaxHeight = _h[1];
useEffect(function () {
virtualScrollRef.current && virtualScrollRef.current.scrollTop;
virtualScrollRef.current &&
setViewportPadding(Number.parseFloat(getComputedStyle(virtualScrollRef.current).paddingTop));
});
useEffect(function () {
setItemsNumber(React.Children.count(children));
}, [children]);
useEffect(function () {
setViewportHeight(Math.min(visibleItems, itemsNumber) * itemHeight + 2 * viewportPadding);
}, [itemHeight, itemsNumber, viewportPadding, visibleItems]);
useEffect(function () {
setMaxHeight(itemsNumber * itemHeight);
virtualScrollRef.current && virtualScrollRef.current.scrollTop;
}, [itemHeight, itemsNumber]);
useEffect(function () {
setBuffer(Math.floor(visibleItems / 2));
}, [visibleItems]);
var handleScroll = function (scrollTop) {
var _currentItemIndex = itemHeight && Math.max(Math.ceil(scrollTop / itemHeight), 1);
setCurrentItemIndex(_currentItemIndex);
onScroll && onScroll(_currentItemIndex);
};
return (React.createElement("div", { className: classNames('virtual-scroller', className), onScroll: function (event) {
return handleScroll(event.target.scrollTop);
}, ref: forkedRef, style: {
height: viewportHeight,
overflowY: 'auto',
} },
React.createElement("div", { className: "virtual-scroller-content", style: {
height: maxHeight,
}, ref: virtualScrollContentRef }, React.Children.map(children, function (child, index) {
if (React.isValidElement(child) &&
index + 1 > Math.max(currentItemIndex - buffer, 0) &&
index + 1 <= currentItemIndex + visibleItems + buffer) {
return React.cloneElement(child, {
className: classNames(child.props.className, {
'virtual-scroller-item-preload': index + 1 > currentItemIndex + visibleItems || index + 1 < currentItemIndex,
}),
key: index,
style: __assign({}, (currentItemIndex > buffer && {
transform: "translateY(".concat((currentItemIndex - buffer) * itemHeight, "px)"),
})),
ref: function (node) {
return node &&
node.offsetHeight &&
setItemHeight(node.offsetHeight +
Number.parseFloat(getComputedStyle(node).marginTop) +
Number.parseFloat(getComputedStyle(node).marginBottom));
},
});
}
return;
}))));
});
CVirtualScroller.propTypes = {
onScroll: PropTypes.func,
visibleItems: PropTypes.number.isRequired,
};
CVirtualScroller.displayName = 'CVirtualScroller';
export { CVirtualScroller };
//# sourceMappingURL=CVirtualScroller.js.map