@nebulaai/lumina-ui
Version:
Enterprise-grade glass morphism UI components with neural-inspired design system
52 lines (44 loc) • 1.31 kB
text/typescript
import { useState, useEffect, useMemo } from 'react';
interface VirtualizationOptions {
itemHeight: number;
containerHeight: number;
overscan?: number;
}
export function useVirtualization<T>(
items: T[],
options: VirtualizationOptions
) {
const { itemHeight, containerHeight, overscan = 5 } = options;
const [scrollTop, setScrollTop] = useState(0);
const visibleRange = useMemo(() => {
const startIndex = Math.floor(scrollTop / itemHeight);
const endIndex = Math.min(
startIndex + Math.ceil(containerHeight / itemHeight) + overscan,
items.length - 1
);
return {
startIndex: Math.max(0, startIndex - overscan),
endIndex
};
}, [scrollTop, itemHeight, containerHeight, overscan, items.length]);
const visibleItems = useMemo(() => {
return items.slice(visibleRange.startIndex, visibleRange.endIndex + 1).map((item, index) => ({
item,
index: visibleRange.startIndex + index
}));
}, [items, visibleRange]);
const totalHeight = items.length * itemHeight;
const getItemStyle = (index: number) => ({
position: 'absolute' as const,
top: index * itemHeight,
height: itemHeight,
width: '100%'
});
return {
visibleItems,
totalHeight,
getItemStyle,
setScrollTop,
visibleRange
};
}