UNPKG

react-window-reversed

Version:

React components for efficiently rendering large, scrollable lists and tabular data

103 lines (89 loc) 2.84 kB
// @flow import createListComponent from './createListComponent'; import type { Props, ScrollToAlign } from './createListComponent'; const FixedSizeList = createListComponent({ getItemOffset: ({ itemSize, size }: Props<any>, index: number): number => index * ((itemSize: any): number), getItemSize: ({ itemSize, size }: Props<any>, index: number): number => ((itemSize: any): number), getEstimatedTotalSize: ({ itemCount, itemSize }: Props<any>) => ((itemSize: any): number) * itemCount, getOffsetForIndexAndAlignment: ( { direction, height, itemCount, itemSize, width }: Props<any>, index: number, align: ScrollToAlign, scrollOffset: number ): number => { const size = (((direction === 'horizontal' ? width : height): any): number); const maxOffset = Math.max( 0, Math.min( itemCount * ((itemSize: any): number) - size, index * ((itemSize: any): number) ) ); const minOffset = Math.max( 0, index * ((itemSize: any): number) - size + ((itemSize: any): number) ); switch (align) { case 'start': return maxOffset; case 'end': return minOffset; case 'center': return Math.round(minOffset + (maxOffset - minOffset) / 2); case 'auto': default: if (scrollOffset >= minOffset && scrollOffset <= maxOffset) { return scrollOffset; } else if (scrollOffset - minOffset < maxOffset - scrollOffset) { return minOffset; } else { return maxOffset; } } }, getStartIndexForOffset: ( { itemCount, itemSize }: Props<any>, offset: number ): number => Math.max( 0, Math.min(itemCount - 1, Math.floor(offset / ((itemSize: any): number))) ), getStopIndexForStartIndex: ( { direction, height, itemCount, itemSize, width }: Props<any>, startIndex: number, scrollOffset: number ): number => { const offset = startIndex * ((itemSize: any): number); const size = (((direction === 'horizontal' ? width : height): any): number); return Math.max( 0, Math.min( itemCount - 1, startIndex + Math.floor( (size + (scrollOffset - offset)) / ((itemSize: any): number) ) ) ); }, initInstanceProps(props: Props<any>): any { // Noop }, shouldResetStyleCacheOnItemSizeChange: true, validateProps: ({ itemSize }: Props<any>): void => { if (process.env.NODE_ENV !== 'production') { if (typeof itemSize !== 'number') { throw Error( 'An invalid "itemSize" prop has been specified. ' + 'Value should be a number. ' + `"${itemSize === null ? 'null' : typeof itemSize}" was specified.` ); } } }, }); export default FixedSizeList;