UNPKG

@coreui/react-pro

Version:

UI Components Library for React.js

81 lines (77 loc) 4.17 kB
'use strict'; var tslib_es6 = require('../../node_modules/tslib/tslib.es6.js'); var React = require('react'); var PropTypes = require('prop-types'); var index = require('../../_virtual/index.js'); require('@popperjs/core'); var useForkedRef = require('../../hooks/useForkedRef.js'); const CVirtualScroller = React.forwardRef((_a, ref) => { var { children, className, visibleItems, onScroll } = _a, rest = tslib_es6.__rest(_a, ["children", "className", "visibleItems", "onScroll"]); const virtualScrollRef = React.useRef(null); const virtualScrollContentRef = React.useRef(null); const forkedRef = useForkedRef.useForkedRef(ref, virtualScrollRef); const [buffer, setBuffer] = React.useState(Math.floor(visibleItems / 2)); const [currentItemIndex, setCurrentItemIndex] = React.useState(1); const [itemHeight, setItemHeight] = React.useState(0); const [itemsNumber, setItemsNumber] = React.useState(React.Children.count(children)); const [viewportPadding, setViewportPadding] = React.useState(0); const [viewportHeight, setViewportHeight] = React.useState(visibleItems * itemHeight + 2 * viewportPadding); const [maxHeight, setMaxHeight] = React.useState(itemsNumber * itemHeight + 2 * viewportPadding); React.useEffect(() => { virtualScrollRef.current && virtualScrollRef.current.scrollTop; virtualScrollRef.current && setViewportPadding(Number.parseFloat(getComputedStyle(virtualScrollRef.current).paddingTop)); }); React.useEffect(() => { setItemsNumber(React.Children.count(children)); }, [children]); React.useEffect(() => { setViewportHeight(Math.min(visibleItems, itemsNumber) * itemHeight + 2 * viewportPadding); }, [itemHeight, itemsNumber, viewportPadding, visibleItems]); React.useEffect(() => { setMaxHeight(itemsNumber * itemHeight); virtualScrollRef.current && virtualScrollRef.current.scrollTop; }, [itemHeight, itemsNumber]); React.useEffect(() => { setBuffer(Math.floor(visibleItems / 2)); }, [visibleItems]); const handleScroll = (scrollTop) => { const _currentItemIndex = itemHeight && Math.max(Math.ceil(scrollTop / itemHeight), 1); setCurrentItemIndex(_currentItemIndex); onScroll && onScroll(_currentItemIndex); }; return (React.createElement("div", Object.assign({ className: index.default('virtual-scroller', className), onScroll: (event) => handleScroll(event.target.scrollTop), style: { height: viewportHeight, overflowY: 'auto', }, ref: forkedRef }, rest), React.createElement("div", { className: "virtual-scroller-content", style: { height: maxHeight, }, ref: virtualScrollContentRef }, React.Children.map(children, (child, index$1) => { if (React.isValidElement(child) && index$1 + 1 > Math.max(currentItemIndex - buffer, 0) && index$1 + 1 <= currentItemIndex + visibleItems + buffer) { return React.cloneElement(child, { className: index.default(child.props.className, { 'virtual-scroller-item-preload': index$1 + 1 > currentItemIndex + visibleItems || index$1 + 1 < currentItemIndex, }), key: index$1, style: Object.assign({}, (currentItemIndex > buffer && { transform: `translateY(${(currentItemIndex - buffer) * itemHeight}px)`, })), ref: (node) => 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'; exports.CVirtualScroller = CVirtualScroller; //# sourceMappingURL=CVirtualScroller.js.map