import * as React from "react"; import { useList } from "./fixed-hooks"; import { getContainerStyle, defaultGetItemKey } from "./utils"; import type { ListPropsBase, ListItemProps } from "./types"; export function List({ items, width, height, overscanBy = 2, scrollTop, itemHeight, itemGap = 0, as: Container = "div", id, className, style, role = "list", tabIndex, itemAs: WrapperComponent = "div", itemKey = defaultGetItemKey, isScrolling, onRender, innerRef, render: RenderComponent, }: ListProps) { const children: ( | ListItemProps | React.ReactElement> )[] = useList({ items, width, height, overscanBy, scrollTop, itemHeight, itemGap, }); const itemRole = role && role + "item"; const startIndex = children[0] ? (children[0] as ListItemProps).index : 0; let stopIndex: number | undefined; let i = 0; for (; i < children.length; i++) { const child = children[i] as ListItemProps; stopIndex = child.index; children[i] = ( ); } // Calls the onRender callback if the rendered indices changed React.useEffect(() => { if (typeof onRender === "function" && stopIndex !== void 0) onRender(startIndex, stopIndex, items); // eslint-disable-next-line react-hooks/exhaustive-deps }, [onRender, items, startIndex, stopIndex]); const containerStyle = getContainerStyle( isScrolling, (itemHeight + itemGap) * items.length - itemGap ); return ( ); } export interface ListProps extends ListPropsBase { readonly itemHeight: number; readonly render: React.ComponentType>; } export interface ListRenderProps { index: number; data: Item; width: number; [prop: string]: any; }