1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-06 00:07:44 +01:00
unleash.unleash/frontend/src/hooks/useVirtualizedRange.ts
Nuno Góis 4167a60588
feat: biome lint frontend (#4903)
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.
2023-10-02 13:25:46 +01:00

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;
};