UNPKG

@coreui/react-pro

Version:

UI Components Library for React.js

83 lines (80 loc) 4.29 kB
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