mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-01 00:08:27 +01:00
4167a60588
Follows up on https://github.com/Unleash/unleash/pull/4853 to add Biome to the frontend as well. ![image](https://github.com/Unleash/unleash/assets/14320932/1906faf1-fc29-4172-a4d4-b2716d72cd65) Added a few `biome-ignore` to speed up the process but we may want to check and fix them in the future.
51 lines
1.6 KiB
TypeScript
51 lines
1.6 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,
|
|
parentElement?: HTMLElement | null,
|
|
) => {
|
|
const parent = parentElement ? parentElement : window;
|
|
|
|
const [scrollIndex, setScrollIndex] = useState(
|
|
Math.floor(
|
|
(parent instanceof HTMLElement
|
|
? parent.scrollTop
|
|
: parent.pageYOffset) / rowHeight,
|
|
),
|
|
);
|
|
|
|
useEffect(() => {
|
|
const handleScroll = () => {
|
|
requestAnimationFrame(() => {
|
|
setScrollIndex(
|
|
Math.floor(
|
|
(parent instanceof HTMLElement
|
|
? parent.scrollTop
|
|
: parent.pageYOffset) /
|
|
(rowHeight * dampening),
|
|
) * dampening,
|
|
);
|
|
});
|
|
};
|
|
handleScroll();
|
|
parent.addEventListener('scroll', handleScroll, { passive: true });
|
|
|
|
return () => {
|
|
parent.removeEventListener('scroll', handleScroll);
|
|
};
|
|
}, [rowHeight, dampening, parent]);
|
|
|
|
return [scrollIndex - scrollOffset, scrollIndex + scrollOffset] as const;
|
|
};
|