UNPKG

react-window-reversed

Version:

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

189 lines (167 loc) 5.01 kB
// @flow import createGridComponent from './createGridComponent'; import type { Props, ScrollToAlign } from './createGridComponent'; const FixedSizeGrid = createGridComponent({ getColumnOffset: ({ columnWidth }: Props<any>, index: number): number => index * ((columnWidth: any): number), getColumnWidth: ({ columnWidth }: Props<any>, index: number): number => ((columnWidth: any): number), getRowOffset: ({ rowHeight }: Props<any>, index: number): number => index * ((rowHeight: any): number), getRowHeight: ({ rowHeight }: Props<any>, index: number): number => ((rowHeight: any): number), getEstimatedTotalHeight: ({ rowCount, rowHeight }: Props<any>) => ((rowHeight: any): number) * rowCount, getEstimatedTotalWidth: ({ columnCount, columnWidth }: Props<any>) => ((columnWidth: any): number) * columnCount, getOffsetForColumnAndAlignment: ( { columnCount, columnWidth, width }: Props<any>, columnIndex: number, align: ScrollToAlign, scrollLeft: number ): number => { const maxOffset = Math.max( 0, Math.min( columnCount * ((columnWidth: any): number) - width, columnIndex * ((columnWidth: any): number) ) ); const minOffset = Math.max( 0, columnIndex * ((columnWidth: any): number) - width + ((columnWidth: 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 (scrollLeft >= minOffset && scrollLeft <= maxOffset) { return scrollLeft; } else if (scrollLeft - minOffset < maxOffset - scrollLeft) { return minOffset; } else { return maxOffset; } } }, getOffsetForRowAndAlignment: ( { rowHeight, height, rowCount }: Props<any>, rowIndex: number, align: ScrollToAlign, scrollTop: number ): number => { const maxOffset = Math.max( 0, Math.min( rowCount * ((rowHeight: any): number) - height, rowIndex * ((rowHeight: any): number) ) ); const minOffset = Math.max( 0, rowIndex * ((rowHeight: any): number) - height + ((rowHeight: 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 (scrollTop >= minOffset && scrollTop <= maxOffset) { return scrollTop; } else if (scrollTop - minOffset < maxOffset - scrollTop) { return minOffset; } else { return maxOffset; } } }, getColumnStartIndexForOffset: ( { columnWidth, columnCount }: Props<any>, scrollLeft: number ): number => Math.max( 0, Math.min( columnCount - 1, Math.floor(scrollLeft / ((columnWidth: any): number)) ) ), getColumnStopIndexForStartIndex: ( { columnWidth, columnCount, width }: Props<any>, startIndex: number, scrollLeft: number ): number => { const left = startIndex * ((columnWidth: any): number); return Math.max( 0, Math.min( columnCount - 1, startIndex + Math.floor( (width + (scrollLeft - left)) / ((columnWidth: any): number) ) ) ); }, getRowStartIndexForOffset: ( { rowHeight, rowCount }: Props<any>, scrollTop: number ): number => Math.max( 0, Math.min(rowCount - 1, Math.floor(scrollTop / ((rowHeight: any): number))) ), getRowStopIndexForStartIndex: ( { rowHeight, rowCount, height }: Props<any>, startIndex: number, scrollTop: number ): number => { const left = startIndex * ((rowHeight: any): number); return Math.max( 0, Math.min( rowCount - 1, startIndex + Math.floor((height + (scrollTop - left)) / ((rowHeight: any): number)) ) ); }, initInstanceProps(props: Props<any>): any { // Noop }, shouldResetStyleCacheOnItemSizeChange: true, validateProps: ({ columnWidth, rowHeight }: Props<any>): void => { if (process.env.NODE_ENV !== 'production') { if (typeof columnWidth !== 'number') { throw Error( 'An invalid "columnWidth" prop has been specified. ' + 'Value should be a number. ' + `"${ columnWidth === null ? 'null' : typeof columnWidth }" was specified.` ); } if (typeof rowHeight !== 'number') { throw Error( 'An invalid "rowHeight" prop has been specified. ' + 'Value should be a number. ' + `"${rowHeight === null ? 'null' : typeof rowHeight}" was specified.` ); } } }, }); export default FixedSizeGrid;