mirror of
https://github.com/Unleash/unleash.git
synced 2024-11-01 19:07:38 +01:00
24cb1b21ef
* fix: virtualize project toggles list * refactor: improve type for feature dialogs * fix: formatting - prettier
39 lines
1.3 KiB
TypeScript
39 lines
1.3 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
|
|
/**
|
|
* Get index of first and last displayed item in current window scroll offset.
|
|
* This is done to optimize performance for large lists.
|
|
*
|
|
* @param rowHeight height of single item in pixels
|
|
* @param scrollOffset how many items above and below to render -- TODO: calculate from window height
|
|
* @param dampening cause less re-renders -- only after jumping this x of elements, "staircase" effect
|
|
* @returns [firstIndex, lastIndex]
|
|
*/
|
|
export const useVirtualizedRange = (
|
|
rowHeight: number,
|
|
scrollOffset = 40,
|
|
dampening = 5
|
|
) => {
|
|
const [scrollIndex, setScrollIndex] = useState(
|
|
Math.floor(window.pageYOffset / rowHeight)
|
|
);
|
|
|
|
useEffect(() => {
|
|
const handleScroll = () => {
|
|
requestAnimationFrame(() => {
|
|
setScrollIndex(
|
|
Math.floor(window.pageYOffset / (rowHeight * dampening)) *
|
|
dampening
|
|
);
|
|
});
|
|
};
|
|
window.addEventListener('scroll', handleScroll, { passive: true });
|
|
|
|
return () => {
|
|
window.removeEventListener('scroll', handleScroll);
|
|
};
|
|
}, [rowHeight, dampening]);
|
|
|
|
return [scrollIndex - scrollOffset, scrollIndex + scrollOffset] as const;
|
|
};
|