@selfcommunity/react-ui
Version:
React UI Components to integrate a Community created with SelfCommunity Platform.
85 lines (84 loc) • 4.63 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const utils_1 = require("@selfcommunity/utils");
const react_2 = tslib_1.__importDefault(require("virtual-scroller/react"));
/**
* VirtualizedScroller
* A component for efficiently rendering large lists of variable height items.
* VirtualScroller works by measuring each list item's height as it's being rendered, and then, as the user scrolls,
* it hides the items that are no longer visible, and shows the now-visible items as they're scrolled to.
* The hidden items at the top are compensated by setting padding-top on the list element, and the hidden items
* at the bottom are compensated by setting padding-bottom on the list element.
* The component listens to scroll / resize events and re-renders the currently visible items as the user
* scrolls (or if the browser window is resized).
* Set window['VirtualScrollerDebug'] = true; to output debug messages to console.
*/
function VirtualizedScroller(props) {
const { items = [], ItemComponent, getItemId, initialScrollerState, onScrollerStateChange, onScrollerMount, onScrollerPositionChange, onScrollerSaveState, cacheStrategy = utils_1.CacheStrategies.CACHE_FIRST, cacheScrollStateKey = 'virtual_scroller_st', cacheScrollerPositionKey = 'virtual_scroller_sp' } = props, rest = tslib_1.__rest(props, ["items", "ItemComponent", "getItemId", "initialScrollerState", "onScrollerStateChange", "onScrollerMount", "onScrollerPositionChange", "onScrollerSaveState", "cacheStrategy", "cacheScrollStateKey", "cacheScrollerPositionKey"]);
// REF
const virtualScrollerMountState = (0, react_1.useRef)(false);
// HELPERS
/**
* Callback on mount the virtual scroller
*/
const onVirtualScrollerMount = (0, react_1.useMemo)(() => () => {
virtualScrollerMountState.current = true;
onScrollerMount && onScrollerMount();
}, []);
/**
* Get initial scroll position by cacheScrollerPositionKey
* Recovered only if cacheStrategy = CACHE_FIRST
*/
const getInitialScrollPosition = (0, react_1.useMemo)(() => () => cacheStrategy === utils_1.CacheStrategies.CACHE_FIRST && cacheScrollerPositionKey ? utils_1.LRUCache.get(cacheScrollerPositionKey) : 0, [cacheStrategy, cacheScrollerPositionKey]);
/**
* Callback on virtual scroller position change
*/
const onScrollPositionChange = (0, react_1.useMemo)(() => (y) => {
if (cacheScrollerPositionKey) {
utils_1.LRUCache.set(cacheScrollerPositionKey, y);
}
onScrollerPositionChange && onScrollerPositionChange(y);
}, [cacheScrollerPositionKey]);
/**
* Callback on virtual scroller state change
*/
const onStateScrollChange = (0, react_1.useMemo)(() => (state) => {
virtualScrollerState.current = state;
onScrollerStateChange && onScrollerStateChange(state);
}, []);
/**
* Save virtual scroller state
*/
const saveVirtualScrollerState = (0, react_1.useMemo)(() => (state) => {
if (cacheScrollerPositionKey) {
utils_1.LRUCache.set(cacheScrollStateKey, state);
}
onScrollerSaveState && onScrollerSaveState(state);
}, [cacheScrollStateKey]);
/**
* Read virtual scroller state
*/
const readVirtualScrollerState = (0, react_1.useMemo)(() => () => {
if (cacheStrategy === utils_1.CacheStrategies.CACHE_FIRST && cacheScrollStateKey && utils_1.LRUCache.hasKey(cacheScrollStateKey)) {
const _state = utils_1.LRUCache.get(cacheScrollStateKey);
if (_state.items && _state.items.length) {
return _state;
}
}
return null;
}, [cacheScrollStateKey, cacheStrategy]);
// REF
const virtualScrollerState = (0, react_1.useRef)(readVirtualScrollerState());
// EFFECTS
(0, react_1.useEffect)(() => {
return () => {
// Save state before the component unmounts.
saveVirtualScrollerState(virtualScrollerState.current);
};
});
return ((0, jsx_runtime_1.jsx)(react_2.default, Object.assign({ items: items, itemComponent: ItemComponent, onMount: onVirtualScrollerMount }, (getItemId && { getItemId }), { initialState: initialScrollerState ? initialScrollerState : readVirtualScrollerState(), onStateChange: onStateScrollChange, initialScrollPosition: getInitialScrollPosition(), onScrollPositionChange: onScrollPositionChange }, rest)));
}
exports.default = VirtualizedScroller;
;