diff --git a/types/react-virtualized/dist/es/AutoSizer.d.ts b/types/react-virtualized/dist/es/AutoSizer.d.ts index ea72c43c1e..1da48c8120 100644 --- a/types/react-virtualized/dist/es/AutoSizer.d.ts +++ b/types/react-virtualized/dist/es/AutoSizer.d.ts @@ -6,9 +6,19 @@ export type Dimensions = { } export type AutoSizerProps = { + /** Disable dynamic :height property */ disableHeight?: boolean; + /** Disable dynamic :width property */ disableWidth?: boolean; + /** Nonce of the inlined stylesheet for Content Security Policy */ + nonce?: string; + /** Callback to be invoked on-resize: ({ height, width }) */ onResize?: (info: { height: number, width: number }) => any; + /** + * Function responsible for rendering children. + * This function should implement the following signature: + * ({ height, width }) => PropTypes.element + */ children?: (props: Dimensions) => React.ReactNode }; /** @@ -18,20 +28,10 @@ export type AutoSizerProps = { */ export class AutoSizer extends PureComponent { static propTypes: { - /** - * Function responsible for rendering children. - * This function should implement the following signature: - * ({ height, width }) => PropTypes.element - */ children: Validator<(props: Dimensions) => React.ReactNode>, - - /** Disable dynamic :height property */ disableHeight: Requireable, - - /** Disable dynamic :width property */ disableWidth: Requireable, - - /** Callback to be invoked on-resize: ({ height, width }) */ + nonce: Validator, onResize: Validator<(props: Dimensions) => any> }; diff --git a/types/react-virtualized/dist/es/CellMeasurer.d.ts b/types/react-virtualized/dist/es/CellMeasurer.d.ts index 5e1e0db3fb..1f7d2de8b3 100644 --- a/types/react-virtualized/dist/es/CellMeasurer.d.ts +++ b/types/react-virtualized/dist/es/CellMeasurer.d.ts @@ -45,17 +45,9 @@ export class CellMeasurerCache { ): void; } -export type CellMeasurerChildProps = { - getColumnWidth: () => number, - getRowHeight: () => number, - resetMeasurements: () => any, - resetMeasurementsForColumn: (index: number) => any, - resetMeasurementsForRow: (index: number) => any, -} - export type CellMeasurerProps = { cache?: CellMeasurerCache; - children?: (props: CellMeasurerChildProps) => React.ReactNode; + children?: ((props: {measure: () => void}) => React.ReactNode) | JSX.Element; columnIndex?: number; index?: number; parent?: React.ReactType; diff --git a/types/react-virtualized/dist/es/Collection.d.ts b/types/react-virtualized/dist/es/Collection.d.ts index 404d329222..9f37eea8f6 100644 --- a/types/react-virtualized/dist/es/Collection.d.ts +++ b/types/react-virtualized/dist/es/Collection.d.ts @@ -23,10 +23,32 @@ export type CollectionCellRendererParams = { export type CollectionCellRenderer = (params: CollectionCellRendererParams) => React.ReactNode; export type CollectionProps = { 'aria-label'?: string; + /** + * Number of cells in Collection. + */ cellCount: number; + /** + * Responsible for rendering a group of cells given their indices. + * Should implement the following interface: ({ + * cellSizeAndPositionGetter:Function, + * indices: Array, + * cellRenderer: Function + * }): Array + */ cellGroupRenderer?: CollectionCellGroupRenderer, + /** + * Responsible for rendering a cell given an row and column index. + * Should implement the following interface: ({ index: number, key: string, style: object }): PropTypes.element + */ cellRenderer: CollectionCellRenderer, + /** + * Callback responsible for returning size and offset/position information for a given cell (index). + * ({ index: number }): { height: number, width: number, x: number, y: number } + */ cellSizeAndPositionGetter: CollectionCellSizeAndPositionGetter, + /** + * Optionally override the size of the sections a Collection's cells are split into. + */ sectionSize?: number; className?: string; height: number; @@ -44,37 +66,10 @@ export type CollectionProps = { export class Collection extends PureComponent { static propTypes: { 'aria-label': Requireable, - - /** - * Number of cells in Collection. - */ cellCount: Validator, - - /** - * Responsible for rendering a group of cells given their indices. - * Should implement the following interface: ({ - * cellSizeAndPositionGetter:Function, - * indices: Array, - * cellRenderer: Function - * }): Array - */ cellGroupRenderer: Validator, - - /** - * Responsible for rendering a cell given an row and column index. - * Should implement the following interface: ({ index: number, key: string, style: object }): PropTypes.element - */ cellRenderer: Validator, - - /** - * Callback responsible for returning size and offset/position information for a given cell (index). - * ({ index: number }): { height: number, width: number, x: number, y: number } - */ cellSizeAndPositionGetter: Validator, - - /** - * Optionally override the size of the sections a Collection's cells are split into. - */ sectionSize: Requireable }; diff --git a/types/react-virtualized/dist/es/ColumnSizer.d.ts b/types/react-virtualized/dist/es/ColumnSizer.d.ts index 6efcf8c044..fa6788ca02 100644 --- a/types/react-virtualized/dist/es/ColumnSizer.d.ts +++ b/types/react-virtualized/dist/es/ColumnSizer.d.ts @@ -2,15 +2,29 @@ import { PureComponent, Validator, Requireable } from 'react' export type SizedColumnProps = { adjustedWidth: number, + columnWidth: number, getColumnWidth: () => number, registerChild: any } export type ColumnSizerProps = { + /** + * Function responsible for rendering a virtualized Grid. + * This function should implement the following signature: + * ({ adjustedWidth, getColumnWidth, registerChild }) => PropTypes.element + * + * The specified :getColumnWidth function should be passed to the Grid's :columnWidth property. + * The :registerChild should be passed to the Grid's :ref property. + * The :adjustedWidth property is optional; it reflects the lesser of the overall width or the width of all columns. + */ children?: (props: SizedColumnProps) => React.ReactNode; + /** Optional maximum allowed column width */ columnMaxWidth?: number; + /** Optional minimum allowed column width */ columnMinWidth?: number; + /** Number of columns in Grid or Table child */ columnCount?: number; + /** Width of Grid or Table child */ width: number; } /** @@ -18,27 +32,10 @@ export type ColumnSizerProps = { */ export class ColumnSizer extends PureComponent { static propTypes: { - /** - * Function responsible for rendering a virtualized Grid. - * This function should implement the following signature: - * ({ adjustedWidth, getColumnWidth, registerChild }) => PropTypes.element - * - * The specified :getColumnWidth function should be passed to the Grid's :columnWidth property. - * The :registerChild should be passed to the Grid's :ref property. - * The :adjustedWidth property is optional; it reflects the lesser of the overall width or the width of all columns. - */ children: Validator<(props: SizedColumnProps) => React.ReactNode>, - - /** Optional maximum allowed column width */ columnMaxWidth: Requireable, - - /** Optional minimum allowed column width */ columnMinWidth: Requireable, - - /** Number of columns in Grid or Table child */ columnCount: Validator, - - /** Width of Grid or Table child */ width: Validator }; diff --git a/types/react-virtualized/dist/es/Grid.d.ts b/types/react-virtualized/dist/es/Grid.d.ts index c0856f1de7..66801c4592 100644 --- a/types/react-virtualized/dist/es/Grid.d.ts +++ b/types/react-virtualized/dist/es/Grid.d.ts @@ -49,17 +49,26 @@ export type SectionRenderedParams = { rowStartIndex: number, rowStopIndex: number }; +export type SCROLL_DIRECTION_HORIZONTAL = 'horizontal'; +export type SCROLL_DIRECTION_VERTICAL = 'vertical'; export type OverscanIndicesGetterParams = { - cellCount: number, - overscanCellsCount: number, - scrollDirection: number, - startIndex: number, - stopIndex: number + direction?: SCROLL_DIRECTION_HORIZONTAL | SCROLL_DIRECTION_VERTICAL; + cellCount: number; + overscanCellsCount: number; + scrollDirection: SCROLL_DIRECTION_HORIZONTAL | SCROLL_DIRECTION_VERTICAL; + startIndex: number; + stopIndex: number; }; export type OverscanIndices = { overscanStartIndex: number, overscanStopIndex: number }; +export type OverscanIndicesGetter = (params: OverscanIndicesGetterParams) => OverscanIndices; + +export type ScrollOffset = { + scrollLeft: number, + scrollTop: number +} export type CellSizeAndPositionManager = { areOffsetsAdjusted(): boolean; @@ -123,40 +132,170 @@ export type GridCellRangeRenderer = (params: GridCellRangeProps) => React.ReactN export type GridCoreProps = { 'aria-label'?: string; + /** + * Set the width of the inner scrollable container to 'auto'. + * This is useful for single-column Grids to ensure that the column doesn't extend below a vertical scrollbar. + */ autoContainerWidth?: boolean; + /** + * Removes fixed height from the scrollingContainer so that the total height of rows can stretch the window. + * Intended for use with WindowScroller + */ autoHeight?: boolean; + /** + * Removes fixed width from the scrollingContainer so that the total width of rows can stretch the window. + * Intended for use with WindowScroller + */ + autoWidth?: boolean; + /** + * Responsible for rendering a group of cells given their index ranges. + * Should implement the following interface: ({ + * cellCache: Map, + * cellRenderer: Function, + * columnSizeAndPositionManager: CellSizeAndPositionManager, + * columnStartIndex: number, + * columnStopIndex: number, + * isScrolling: boolean, + * rowSizeAndPositionManager: CellSizeAndPositionManager, + * rowStartIndex: number, + * rowStopIndex: number, + * scrollLeft: number, + * scrollTop: number + * }): Array + */ cellRangeRenderer?: GridCellRangeRenderer; + /** + * Optional custom CSS class name to attach to root Grid element. + */ className?: string; + /** Optional inline style applied to inner cell-container */ containerStyle?: React.CSSProperties; + /** + * If CellMeasurer is used to measure this Grid's children, this should be a pointer to its CellMeasurerCache. + * A shared CellMeasurerCache reference enables Grid and CellMeasurer to share measurement data. + */ deferredMeasurementCache?: CellMeasurerCache; + /** + * Used to estimate the total width of a Grid before all of its columns have actually been measured. + * The estimated total width is adjusted as columns are rendered. + */ estimatedColumnSize?: number; + /** + * Used to estimate the total height of a Grid before all of its rows have actually been measured. + * The estimated total height is adjusted as rows are rendered. + */ estimatedRowSize?: number; + /** + * Exposed for testing purposes only. + */ getScrollbarSize?: () => number; + /** + * Height of Grid; this property determines the number of visible (vs virtualized) rows. + */ height: number; + /** + * Optional custom id to attach to root Grid element. + */ id?: string; + /** + * Override internal is-scrolling state tracking. + * This property is primarily intended for use with the WindowScroller component. + */ isScrolling?: boolean, + /** + * Optional renderer to be used in place of rows when either :rowCount or :columnCount is 0. + */ noContentRenderer?: () => React.ReactNode; + /** + * Callback invoked whenever the scroll offset changes within the inner scrollable region. + * This callback can be used to sync scrolling between lists, tables, or grids. + * ({ clientHeight, clientWidth, scrollHeight, scrollLeft, scrollTop, scrollWidth }): void + */ onScroll?: (params: ScrollParams) => any; + /** + * Callback invoked with information about the section of the Grid that was just rendered. + * ({ columnStartIndex, columnStopIndex, rowStartIndex, rowStopIndex }): void + */ onSectionRendered?: (params: SectionRenderedParams) => any; + /** + * Number of columns to render before/after the visible section of the grid. + * These columns can help for smoother scrolling on touch devices or browsers that send scroll events infrequently. + */ overscanColumnCount?: number; - overscanIndicesGetter?: (params: OverscanIndicesGetterParams) => OverscanIndices; + /** + * Calculates the number of cells to overscan before and after a specified range. + * This function ensures that overscanning doesn't exceed the available cells. + * Should implement the following interface: ({ + * cellCount: number, + * overscanCellsCount: number, + * scrollDirection: number, + * startIndex: number, + * stopIndex: number + * }): {overscanStartIndex: number, overscanStopIndex: number} + */ + overscanIndicesGetter?: OverscanIndicesGetter; + /** + * Number of rows to render above/below the visible section of the grid. + * These rows can help for smoother scrolling on touch devices or browsers that send scroll events infrequently. + */ overscanRowCount?: number; + /** + * ARIA role for the grid element. + */ + role?: string; + /** + * Either a fixed row height (number) or a function that returns the height of a row given its index. + * Should implement the following interface: ({ index: number }): number + */ rowHeight: number | ((params: Index) => number); + /** + * Number of rows in grid. + */ rowCount: number; + /** Wait this amount of time after the last scroll event before resetting Grid `pointer-events`. */ scrollingResetTimeInterval?: number; + /** Horizontal offset. */ scrollLeft?: number; + /** + * Controls scroll-to-cell behavior of the Grid. + * The default ("auto") scrolls the least amount possible to ensure that the specified cell is fully visible. + * Use "start" to align cells to the top/left of the Grid and "end" to align bottom/right. + */ scrollToAlignment?: Alignment; + /** + * Column index to ensure visible (by forcefully scrolling if necessary) + */ scrollToColumn?: number; + /** Vertical offset. */ scrollTop?: number; + /** + * Row index to ensure visible (by forcefully scrolling if necessary) + */ scrollToRow?: number; + /** Optional inline style */ style?: React.CSSProperties; + /** Tab index for focus */ tabIndex?: number; + /** + * Width of Grid; this property determines the number of visible (vs virtualized) columns. + */ width: number; } export type GridProps = GridCoreProps & { + /** + * Responsible for rendering a cell given an row and column index. + * Should implement the following interface: ({ columnIndex: number, rowIndex: number }): PropTypes.node + */ cellRenderer: GridCellRenderer; + /** + * Number of columns in grid. + */ columnCount: number; + /** + * Either a fixed column width (number) or a function that returns the width of a column given its index. + * Should implement the following interface: (index: number): number + */ columnWidth: number | ((params: Index) => number); }; @@ -183,195 +322,38 @@ export const DEFAULT_SCROLLING_RESET_TIME_INTERVAL = 150 export class Grid extends PureComponent { static propTypes: { 'aria-label': Requireable, - - /** - * Set the width of the inner scrollable container to 'auto'. - * This is useful for single-column Grids to ensure that the column doesn't extend below a vertical scrollbar. - */ autoContainerWidth: Requireable, - - /** - * Removes fixed height from the scrollingContainer so that the total height - * of rows can stretch the window. Intended for use with WindowScroller - */ autoHeight: Requireable, - - /** - * Responsible for rendering a cell given an row and column index. - * Should implement the following interface: ({ columnIndex: number, rowIndex: number }): PropTypes.node - */ cellRenderer: Validator<(props: GridCellProps) => React.ReactNode>, - - /** - * Responsible for rendering a group of cells given their index ranges. - * Should implement the following interface: ({ - * cellCache: Map, - * cellRenderer: Function, - * columnSizeAndPositionManager: CellSizeAndPositionManager, - * columnStartIndex: number, - * columnStopIndex: number, - * isScrolling: boolean, - * rowSizeAndPositionManager: CellSizeAndPositionManager, - * rowStartIndex: number, - * rowStopIndex: number, - * scrollLeft: number, - * scrollTop: number - * }): Array - */ cellRangeRenderer: Validator<(params: GridCellRangeProps) => React.ReactNode[]>, - - /** - * Optional custom CSS class name to attach to root Grid element. - */ className: Requireable, - - /** - * Number of columns in grid. - */ columnCount: Validator, - - /** - * Either a fixed column width (number) or a function that returns the width of a column given its index. - * Should implement the following interface: (index: number): number - */ columnWidth: Validator number)>, - - /** Optional inline style applied to inner cell-container */ containerStyle: Requireable, - - /** - * If CellMeasurer is used to measure this Grid's children, this should be a pointer to its CellMeasurerCache. - * A shared CellMeasurerCache reference enables Grid and CellMeasurer to share measurement data. - */ deferredMeasurementCache: Requireable, - - /** - * Used to estimate the total width of a Grid before all of its columns have actually been measured. - * The estimated total width is adjusted as columns are rendered. - */ estimatedColumnSize: Validator, - - /** - * Used to estimate the total height of a Grid before all of its rows have actually been measured. - * The estimated total height is adjusted as rows are rendered. - */ estimatedRowSize: Validator, - - /** - * Exposed for testing purposes only. - */ getScrollbarSize: Validator<() => number>, - - /** - * Height of Grid; this property determines the number of visible (vs virtualized) rows. - */ height: Validator, - - /** - * Optional custom id to attach to root Grid element. - */ id: Requireable, - - /** - * Override internal is-scrolling state tracking. - * This property is primarily intended for use with the WindowScroller component. - */ isScrolling: Requireable, - - /** - * Optional renderer to be used in place of rows when either :rowCount or :columnCount is 0. - */ noContentRenderer: Requireable<() => JSX.Element>, - - /** - * Callback invoked whenever the scroll offset changes within the inner scrollable region. - * This callback can be used to sync scrolling between lists, tables, or grids. - * ({ clientHeight, clientWidth, scrollHeight, scrollLeft, scrollTop, scrollWidth }): void - */ onScroll: Validator<(params: ScrollParams) => void>, - - /** - * Callback invoked with information about the section of the Grid that was just rendered. - * ({ columnStartIndex, columnStopIndex, rowStartIndex, rowStopIndex }): void - */ onSectionRendered: Validator<(params: SectionRenderedParams) => void>, - - /** - * Number of columns to render before/after the visible section of the grid. - * These columns can help for smoother scrolling on touch devices or browsers that send scroll events infrequently. - */ overscanColumnCount: Validator, - - /** - * Calculates the number of cells to overscan before and after a specified range. - * This function ensures that overscanning doesn't exceed the available cells. - * Should implement the following interface: ({ - * cellCount: number, - * overscanCellsCount: number, - * scrollDirection: number, - * startIndex: number, - * stopIndex: number - * }): {overscanStartIndex: number, overscanStopIndex: number} - */ - overscanIndicesGetter: Validator<(params: OverscanIndicesGetterParams) => OverscanIndices>, - - /** - * Number of rows to render above/below the visible section of the grid. - * These rows can help for smoother scrolling on touch devices or browsers that send scroll events infrequently. - */ + overscanIndicesGetter: Validator, overscanRowCount: Validator, - - /** - * ARIA role for the grid element. - */ role: Requireable, - - /** - * Either a fixed row height (number) or a function that returns the height of a row given its index. - * Should implement the following interface: ({ index: number }): number - */ rowHeight: Validator number)>, - - /** - * Number of rows in grid. - */ rowCount: Validator, - - /** Wait this amount of time after the last scroll event before resetting Grid `pointer-events`. */ scrollingResetTimeInterval: Requireable, - - /** Horizontal offset. */ scrollLeft: Requireable, - - /** - * Controls scroll-to-cell behavior of the Grid. - * The default ("auto") scrolls the least amount possible to ensure that the specified cell is fully visible. - * Use "start" to align cells to the top/left of the Grid and "end" to align bottom/right. - */ scrollToAlignment: Validator, - - /** - * Column index to ensure visible (by forcefully scrolling if necessary) - */ scrollToColumn: Validator, - - /** Vertical offset. */ scrollTop: Requireable, - - /** - * Row index to ensure visible (by forcefully scrolling if necessary) - */ scrollToRow: Validator, - - /** Optional inline style */ style: Requireable, - - /** Tab index for focus */ tabIndex: Requireable, - - /** - * Width of Grid; this property determines the number of visible (vs virtualized) columns. - */ width: Validator }; @@ -398,6 +380,15 @@ export class Grid extends PureComponent { constructor(props: GridProps, context: any); + /** + * Gets offsets for a given cell and alignment. + */ + getOffsetForCell(params?: { + alignment?: Alignment, + columnIndex?: number, + rowIndex?: number + }): ScrollOffset + /** * Invalidate Grid size and recompute visible cells. * This is a deferred wrapper for recomputeGridSize(). @@ -435,6 +426,15 @@ export class Grid extends PureComponent { rowIndex: number }): void; + /** + * Scroll to the specified offset(s). + * Useful for animating position changes. + */ + scrollToPosition(params?: { + scrollLeft: number, + scrollTop: number + }): void; + componentDidMount(): void; /** @@ -463,3 +463,7 @@ export class Grid extends PureComponent { } export const defaultCellRangeRenderer: GridCellRangeRenderer; + +export const accessibilityOverscanIndicesGetter: OverscanIndicesGetter + +export const defaultOverscanIndicesGetter: OverscanIndicesGetter; diff --git a/types/react-virtualized/dist/es/InfiniteLoader.d.ts b/types/react-virtualized/dist/es/InfiniteLoader.d.ts index e16359adca..f26afd3f90 100644 --- a/types/react-virtualized/dist/es/InfiniteLoader.d.ts +++ b/types/react-virtualized/dist/es/InfiniteLoader.d.ts @@ -7,11 +7,42 @@ export type InfiniteLoaderChildProps = { } export type InfiniteLoaderProps = { + /** + * Function responsible for rendering a virtualized component. + * This function should implement the following signature: + * ({ onRowsRendered, registerChild }) => PropTypes.element + * + * The specified :onRowsRendered function should be passed through to the child's :onRowsRendered property. + * The :registerChild callback should be set as the virtualized component's :ref. + */ children?: (props: InfiniteLoaderChildProps) => React.ReactNode; + /** + * Function responsible for tracking the loaded state of each row. + * It should implement the following signature: ({ index: number }): boolean + */ isRowLoaded: (params: Index) => boolean; + /** + * Callback to be invoked when more rows must be loaded. + * It should implement the following signature: ({ startIndex, stopIndex }): Promise + * The returned Promise should be resolved once row data has finished loading. + * It will be used to determine when to refresh the list with the newly-loaded data. + * This callback may be called multiple times in reaction to a single scroll event. + */ loadMoreRows: (params: IndexRange) => Promise; + /** + * Minimum number of rows to be loaded at a time. + * This property can be used to batch requests to reduce HTTP requests. + */ minimumBatchSize?: number; + /** + * Number of rows in list; can be arbitrary high number if actual number is unknown. + */ rowCount?: number; + /** + * Threshold at which to pre-fetch data. + * A threshold X means that data will start loading when a user scrolls within X rows. + * This value defaults to 15. + */ threshold?: number; }; @@ -22,47 +53,11 @@ export type InfiniteLoaderProps = { */ export class InfiniteLoader extends PureComponent { static propTypes: { - /** - * Function responsible for rendering a virtualized component. - * This function should implement the following signature: - * ({ onRowsRendered, registerChild }) => PropTypes.element - * - * The specified :onRowsRendered function should be passed through to the child's :onRowsRendered property. - * The :registerChild callback should be set as the virtualized component's :ref. - */ children: Validator<(props: InfiniteLoaderChildProps) => React.ReactNode>, - - /** - * Function responsible for tracking the loaded state of each row. - * It should implement the following signature: ({ index: number }): boolean - */ isRowLoaded: Validator<(params: Index) => boolean>, - - /** - * Callback to be invoked when more rows must be loaded. - * It should implement the following signature: ({ startIndex, stopIndex }): Promise - * The returned Promise should be resolved once row data has finished loading. - * It will be used to determine when to refresh the list with the newly-loaded data. - * This callback may be called multiple times in reaction to a single scroll event. - */ loadMoreRows: Validator<(params: IndexRange) => Promise>, - - /** - * Minimum number of rows to be loaded at a time. - * This property can be used to batch requests to reduce HTTP requests. - */ minimumBatchSize: Validator, - - /** - * Number of rows in list; can be arbitrary high number if actual number is unknown. - */ rowCount: Validator, - - /** - * Threshold at which to pre-fetch data. - * A threshold X means that data will start loading when a user scrolls within X rows. - * This value defaults to 15. - */ threshold: Validator }; diff --git a/types/react-virtualized/dist/es/List.d.ts b/types/react-virtualized/dist/es/List.d.ts index 49fb618ad4..c38a20c182 100644 --- a/types/react-virtualized/dist/es/List.d.ts +++ b/types/react-virtualized/dist/es/List.d.ts @@ -1,5 +1,5 @@ import { PureComponent, Validator, Requireable } from 'react' -import { Grid, GridCoreProps, GridCellProps } from './Grid' +import { Grid, GridCoreProps, GridCellProps, OverscanIndicesGetter } from './Grid' import { Index, IndexRange, Alignment } from '../../index' import { CellMeasurerCache } from './CellMeasurer' @@ -8,22 +8,60 @@ export type ListRowProps = GridCellProps & { index: number, style: React.CSSProp export type ListRowRenderer = (props: ListRowProps) => React.ReactNode; export type ListProps = GridCoreProps & { deferredMeasurementCache?: CellMeasurerCache; - className?: string; + /** + * Removes fixed height from the scrollingContainer so that the total height + * of rows can stretch the window. Intended for use with WindowScroller + */ autoHeight?: boolean; + /** Optional CSS class name */ + className?: string; + /** + * Used to estimate the total height of a List before all of its rows have actually been measured. + * The estimated total height is adjusted as rows are rendered. + */ estimatedRowSize?: number; + /** Height constraint for list (determines how many actual rows are rendered) */ height: number; + /** Optional renderer to be used in place of rows when rowCount is 0 */ noRowsRenderer?: () => JSX.Element; + /** + * Callback invoked with information about the slice of rows that were just rendered. + * ({ startIndex, stopIndex }): void + */ onRowsRendered?: (info: { overscanStartIndex: number, overscanStopIndex: number, startIndex: number, stopIndex: number }) => void; - onScroll?: (info: { clientHeight: number, scrollHeight: number, scrollTop: number }) => void; + /** + * Number of rows to render above/below the visible bounds of the list. + * These rows can help for smoother scrolling on touch devices. + */ overscanRowCount?: number; + /** + * Callback invoked whenever the scroll offset changes within the inner scrollable region. + * This callback can be used to sync scrolling between lists, tables, or grids. + * ({ clientHeight, scrollHeight, scrollTop }): void + */ + onScroll?: (info: { clientHeight: number, scrollHeight: number, scrollTop: number }) => void; + /** See Grid#overscanIndicesGetter */ + overscanIndicesGetter?: OverscanIndicesGetter, + /** + * Either a fixed row height (number) or a function that returns the height of a row given its index. + * ({ index: number }): number + */ rowHeight: number | ((info: Index) => number); + /** Responsible for rendering a row given an index; ({ index: number }): node */ rowRenderer: ListRowRenderer; + /** Number of rows in list. */ rowCount: number; + /** See Grid#scrollToAlignment */ scrollToAlignment?: string; + /** Row index to ensure visible (by forcefully scrolling if necessary) */ scrollToIndex?: number; + /** Vertical offset. */ scrollTop?: number; + /** Optional inline style */ style?: React.CSSProperties; + /** Tab index for focus */ tabIndex?: number; + /** Width of list */ width: number; } /** @@ -37,75 +75,23 @@ export type ListProps = GridCoreProps & { export class List extends PureComponent { static propTypes: { 'aria-label': Requireable, - - /** - * Removes fixed height from the scrollingContainer so that the total height - * of rows can stretch the window. Intended for use with WindowScroller - */ autoHeight: Requireable, - - /** Optional CSS class name */ className: Requireable, - - /** - * Used to estimate the total height of a List before all of its rows have actually been measured. - * The estimated total height is adjusted as rows are rendered. - */ estimatedRowSize: Validator, - - /** Height constraint for list (determines how many actual rows are rendered) */ height: Validator, - - /** Optional renderer to be used in place of rows when rowCount is 0 */ noRowsRenderer: Validator<() => JSX.Element>, - - /** - * Callback invoked with information about the slice of rows that were just rendered. - * ({ startIndex, stopIndex }): void - */ onRowsRendered: Validator<(params: IndexRange) => void>, - - /** - * Number of rows to render above/below the visible bounds of the list. - * These rows can help for smoother scrolling on touch devices. - */ overscanRowCount: Validator, - - /** - * Callback invoked whenever the scroll offset changes within the inner scrollable region. - * This callback can be used to sync scrolling between lists, tables, or grids. - * ({ clientHeight, scrollHeight, scrollTop }): void - */ onScroll: Validator<(params: { clientHeight: number, scrollHeight: number, scrollTop: number }) => void>, - - /** - * Either a fixed row height (number) or a function that returns the height of a row given its index. - * ({ index: number }): number - */ + overscanIndicesGetter: Validator, rowHeight: Validator number)>, - - /** Responsible for rendering a row given an index; ({ index: number }): node */ rowRenderer: Validator, - - /** Number of rows in list. */ rowCount: Validator, - - /** See Grid#scrollToAlignment */ scrollToAlignment: Validator, - - /** Row index to ensure visible (by forcefully scrolling if necessary) */ scrollToIndex: Validator, - - /** Vertical offset. */ scrollTop: Requireable, - - /** Optional inline style */ style: Validator, - - /** Tab index for focus */ tabIndex: Requireable, - - /** Width of list */ width: Validator }; @@ -130,6 +116,15 @@ export class List extends PureComponent { /** See Grid#recomputeGridSize */ recomputeRowHeights(index?: number): void; + /** See Grid#getOffsetForCell */ + getOffsetForRow(params: { + alignment?: Alignment, + index?: number + }): number; + + /** See Grid#scrollToPosition */ + scrollToPosition(scrollTop?: number): void; + /** See Grid#scrollToCell */ scrollToRow(index?: number): void; diff --git a/types/react-virtualized/dist/es/ScrollSync.d.ts b/types/react-virtualized/dist/es/ScrollSync.d.ts index d244262d25..2d49bee5d0 100644 --- a/types/react-virtualized/dist/es/ScrollSync.d.ts +++ b/types/react-virtualized/dist/es/ScrollSync.d.ts @@ -20,6 +20,11 @@ export type ScrollSyncChildProps = { } export type ScrollSyncProps = { + /** + * Function responsible for rendering 2 or more virtualized components. + * This function should implement the following signature: + * ({ onScroll, scrollLeft, scrollTop }) => PropTypes.element + */ children?: (props: ScrollSyncChildProps) => React.ReactNode }; @@ -37,11 +42,6 @@ export type ScrollSyncState = { */ export class ScrollSync extends PureComponent { static propTypes: { - /** - * Function responsible for rendering 2 or more virtualized components. - * This function should implement the following signature: - * ({ onScroll, scrollLeft, scrollTop }) => PropTypes.element - */ children: Validator<(props: ScrollSyncChildProps) => React.ReactNode> }; diff --git a/types/react-virtualized/dist/es/Table.d.ts b/types/react-virtualized/dist/es/Table.d.ts index 6f1e27df5f..7e23446fc4 100644 --- a/types/react-virtualized/dist/es/Table.d.ts +++ b/types/react-virtualized/dist/es/Table.d.ts @@ -11,7 +11,9 @@ export type TableCellDataGetterParams = { export type TableCellProps = { cellData?: any, columnData?: any, + columnIndex: number, dataKey: string, + isScrolling: boolean, rowData: any, rowIndex: number }; @@ -52,79 +54,65 @@ export type TableRowRenderer = (props: TableRowProps) => React.ReactNode; // https://github.com/bvaughn/react-virtualized/blob/master/docs/Column.md export type ColumnProps = { + /** Optional aria-label value to set on the column header */ + 'aria-label'?: string, + /** + * Callback responsible for returning a cell's data, given its :dataKey + * ({ columnData: any, dataKey: string, rowData: any }): any + */ cellDataGetter?: TableCellDataGetter; + /** + * Callback responsible for rendering a cell's contents. + * ({ cellData: any, columnData: any, dataKey: string, rowData: any, rowIndex: number }): node + */ cellRenderer?: TableCellRenderer; + /** Optional CSS class to apply to cell */ className?: string; + /** Optional additional data passed to this column's :cellDataGetter */ columnData?: any; + /** Uniquely identifies the row-data attribute correspnding to this cell */ dataKey: any; + /** If sort is enabled for the table at large, disable it for this column */ disableSort?: boolean; + /** Flex grow style; defaults to 0 */ flexGrow?: number; + /** Flex shrink style; defaults to 1 */ flexShrink?: number; + /** Optional CSS class to apply to this column's header */ headerClassName?: string; + /** + * Optional callback responsible for rendering a column header contents. + * ({ columnData: object, dataKey: string, disableSort: boolean, label: string, sortBy: string, sortDirection: string }): PropTypes.node + */ headerRenderer?: TableHeaderRenderer; + /** Header label for this column */ label?: string; + /** Maximum width of column; this property will only be used if :flexGrow is > 0. */ maxWidth?: number; + /** Minimum width of column. */ minWidth?: number; + /** Optional inline style to apply to cell */ style?: React.CSSProperties; + /** Flex basis (width) for this column; This value can grow or shrink based on :flexGrow and :flexShrink properties. */ width: number; } export class Column extends Component { static propTypes: { - /** Optional aria-label value to set on the column header */ 'aria-label': Requireable, - - /** - * Callback responsible for returning a cell's data, given its :dataKey - * ({ columnData: any, dataKey: string, rowData: any }): any - */ cellDataGetter: Requireable, - - /** - * Callback responsible for rendering a cell's contents. - * ({ cellData: any, columnData: any, dataKey: string, rowData: any, rowIndex: number }): node - */ cellRenderer: Requireable, - - /** Optional CSS class to apply to cell */ className: Requireable, - - /** Optional additional data passed to this column's :cellDataGetter */ columnData: Requireable, - - /** Uniquely identifies the row-data attribute correspnding to this cell */ dataKey: Validator, - - /** If sort is enabled for the table at large, disable it for this column */ disableSort: Requireable, - - /** Flex grow style; defaults to 0 */ flexGrow: Requireable, - - /** Flex shrink style; defaults to 1 */ flexShrink: Requireable, - - /** Optional CSS class to apply to this column's header */ headerClassName: Requireable, - - /** - * Optional callback responsible for rendering a column header contents. - * ({ columnData: object, dataKey: string, disableSort: boolean, label: string, sortBy: string, sortDirection: string }): PropTypes.node - */ headerRenderer: Validator, - - /** Header label for this column */ label: Requireable, - - /** Maximum width of column; this property will only be used if :flexGrow is > 0. */ maxWidth: Requireable, - - /** Minimum width of column. */ minWidth: Requireable, - - /** Optional inline style to apply to cell */ style: Requireable, - - /** Flex basis (width) for this column; This value can grow or shrink based on :flexGrow and :flexShrink properties. */ width: Validator }; @@ -156,49 +144,152 @@ export type HeaderMouseEventHandlerParams = { // ref: https://github.com/bvaughn/react-virtualized/blob/master/docs/Table.md export type TableProps = GridCoreProps & { + 'aria-label'?: string, deferredMeasurementCache?: CellMeasurerCache; + /** + * Removes fixed height from the scrollingContainer so that the total height + * of rows can stretch the window. Intended for use with WindowScroller + */ autoHeight?: boolean; - children?: React.ReactChildren; + /** One or more Columns describing the data displayed in this row */ + children?: React.ReactElement[] | React.ReactElement; + /** Optional CSS class name */ className?: string; + /** Disable rendering the header at all */ disableHeader?: boolean; + /** + * Used to estimate the total height of a Table before all of its rows have actually been measured. + * The estimated total height is adjusted as rows are rendered. + */ estimatedRowSize?: number; + /** Optional custom CSS class name to attach to inner Grid element. */ gridClassName?: string; + /** Optional inline style to attach to inner Grid element. */ gridStyle?: any; + /** Optional CSS class to apply to all column headers */ headerClassName?: string; + /** Fixed height of header row */ headerHeight: number; - headerStyle?: any; - height?: number; - id?: string; - noRowsRenderer?: () => void; - onHeaderClick?: (params: HeaderMouseEventHandlerParams) => void; - onRowClick?: (info: RowMouseEventHandlerParams) => void; - onRowDoubleClick?: (info: RowMouseEventHandlerParams) => void; - onRowMouseOut?: (info: RowMouseEventHandlerParams) => void; - onRowMouseOver?: (info: RowMouseEventHandlerParams) => void; - onRowsRendered?: (info: IndexRange & OverscanIndexRange) => void; - overscanRowCount?: number; - onScroll?: (info: ScrollEventData) => void; - rowClassName?: string | ((info: Index) => string); - rowCount: number; - rowGetter?: (info: Index) => any; - rowHeight: number | ((info: Index) => number); - rowRenderer?: TableRowRenderer; + /** + * Responsible for rendering a table row given an array of columns: + * Should implement the following interface: ({ + * className: string, + * columns: any[], + * style: any + * }): PropTypes.node + */ headerRowRenderer?: TableHeaderRowRenderer; + /** Optional custom inline style to attach to table header columns. */ + headerStyle?: any; + /** Fixed/available height for out DOM element */ + height?: number; + /** Optional id */ + id?: string; + /** Optional renderer to be used in place of table body rows when rowCount is 0 */ + noRowsRenderer?: () => void; + /** + * Optional callback when a column's header is clicked. + * ({ columnData: any, dataKey: string }): void + */ + onHeaderClick?: (params: HeaderMouseEventHandlerParams) => void; + /** + * Callback invoked when a user clicks on a table row. + * ({ index: number }): void + */ + onRowClick?: (info: RowMouseEventHandlerParams) => void; + /** + * Callback invoked when a user double-clicks on a table row. + * ({ index: number }): void + */ + onRowDoubleClick?: (info: RowMouseEventHandlerParams) => void; + /** + * Callback invoked when the mouse leaves a table row. + * ({ index: number }): void + */ + onRowMouseOut?: (info: RowMouseEventHandlerParams) => void; + /** + * Callback invoked when a user moves the mouse over a table row. + * ({ index: number }): void + */ + onRowMouseOver?: (info: RowMouseEventHandlerParams) => void; + /** + * Callback invoked with information about the slice of rows that were just rendered. + * ({ startIndex, stopIndex }): void + */ + onRowsRendered?: (info: IndexRange & OverscanIndexRange) => void; + /** + * Callback invoked whenever the scroll offset changes within the inner scrollable region. + * This callback can be used to sync scrolling between lists, tables, or grids. + * ({ clientHeight, scrollHeight, scrollTop }): void + */ + onScroll?: (info: ScrollEventData) => void; + /** + * Number of rows to render above/below the visible bounds of the list. + * These rows can help for smoother scrolling on touch devices. + */ + overscanRowCount?: number; + /** + * Optional CSS class to apply to all table rows (including the header row). + * This property can be a CSS class name (string) or a function that returns a class name. + * If a function is provided its signature should be: ({ index: number }): string + */ + rowClassName?: string | ((info: Index) => string); + /** + * Callback responsible for returning a data row given an index. + * ({ index: number }): any + */ + rowGetter?: (info: Index) => any; + /** + * Either a fixed row height (number) or a function that returns the height of a row given its index. + * ({ index: number }): number + */ + rowHeight: number | ((info: Index) => number); + /** Number of rows in table. */ + rowCount: number; + /** + * Responsible for rendering a table row given an array of columns: + * Should implement the following interface: ({ + * className: string, + * columns: Array, + * index: number, + * isScrolling: boolean, + * onRowClick: ?Function, + * onRowDoubleClick: ?Function, + * onRowMouseOver: ?Function, + * onRowMouseOut: ?Function, + * rowData: any, + * style: any + * }): PropTypes.node + */ + rowRenderer?: TableRowRenderer; + /** Optional custom inline style to attach to table rows. */ rowStyle?: React.CSSProperties | ((info: Index) => React.CSSProperties); + /** See Grid#scrollToAlignment */ scrollToAlignment?: string; + /** Row index to ensure visible (by forcefully scrolling if necessary) */ scrollToIndex?: number; + /** Vertical offset. */ scrollTop?: number; + /** + * Sort function to be called if a sortable header is clicked. + * ({ sortBy: string, sortDirection: SortDirection }): void + */ sort?: (info: { sortBy: string, sortDirection: SortDirectionType }) => void; + /** Table data is currently sorted by this :dataKey (if it is sorted at all) */ sortBy?: string; + /** Table data is currently sorted in this direction (if it is sorted at all) */ sortDirection?: SortDirectionType; + /** Optional inline style */ style?: React.CSSProperties; + /** Tab index for focus */ tabIndex?: number; + /** Width of list */ width?: number; } export const defaultTableCellDataGetter: TableCellDataGetter; export const defaultTableCellRenderer: TableCellRenderer; -export const defaultTableHeaderRenderer: () => Array>; +export const defaultTableHeaderRenderer: () => React.ReactElement[]; export const defaultTableHeaderRowRenderer: TableHeaderRowRenderer; export const defaultTableRowRenderer: TableRowRenderer; @@ -229,181 +320,42 @@ export const SortIndicator: React.StatelessComponent<{ sortDirection: SortDirect export class Table extends PureComponent { static propTypes: { 'aria-label': Requireable, - - /** - * Removes fixed height from the scrollingContainer so that the total height - * of rows can stretch the window. Intended for use with WindowScroller - */ autoHeight: Requireable, - - /** One or more Columns describing the data displayed in this row */ children: Validator, - - /** Optional CSS class name */ className: Requireable, - - /** Disable rendering the header at all */ disableHeader: Requireable, - - /** - * Used to estimate the total height of a Table before all of its rows have actually been measured. - * The estimated total height is adjusted as rows are rendered. - */ estimatedRowSize: Validator, - - /** Optional custom CSS class name to attach to inner Grid element. */ gridClassName: Requireable, - - /** Optional inline style to attach to inner Grid element. */ gridStyle: Requireable, - - /** Optional CSS class to apply to all column headers */ headerClassName: Requireable, - - /** Fixed height of header row */ headerHeight: Validator, - - /** - * Responsible for rendering a table row given an array of columns: - * Should implement the following interface: ({ - * className: string, - * columns: any[], - * style: any - * }): PropTypes.node - */ headerRowRenderer: Requireable, - - /** Optional custom inline style to attach to table header columns. */ headerStyle: Requireable, - - /** Fixed/available height for out DOM element */ height: Validator, - - /** Optional id */ id: Requireable, - - /** Optional renderer to be used in place of table body rows when rowCount is 0 */ noRowsRenderer: Requireable<() => JSX.Element>, - - /** - * Optional callback when a column's header is clicked. - * ({ columnData: any, dataKey: string }): void - */ onHeaderClick: Requireable<(params: HeaderMouseEventHandlerParams) => void>, - - /** - * Callback invoked when a user clicks on a table row. - * ({ index: number }): void - */ onRowClick: Requireable<(params: RowMouseEventHandlerParams) => void>, - - /** - * Callback invoked when a user double-clicks on a table row. - * ({ index: number }): void - */ onRowDoubleClick: Requireable<(params: RowMouseEventHandlerParams) => void>, - - /** - * Callback invoked when the mouse leaves a table row. - * ({ index: number }): void - */ onRowMouseOut: Requireable<(params: RowMouseEventHandlerParams) => void>, - - /** - * Callback invoked when a user moves the mouse over a table row. - * ({ index: number }): void - */ onRowMouseOver: Requireable<(params: RowMouseEventHandlerParams) => void>, - - /** - * Callback invoked with information about the slice of rows that were just rendered. - * ({ startIndex, stopIndex }): void - */ onRowsRendered: Requireable<(params: RowMouseEventHandlerParams) => void>, - - /** - * Callback invoked whenever the scroll offset changes within the inner scrollable region. - * This callback can be used to sync scrolling between lists, tables, or grids. - * ({ clientHeight, scrollHeight, scrollTop }): void - */ onScroll: Requireable<(params: ScrollEventData) => void>, - - /** - * Number of rows to render above/below the visible bounds of the list. - * These rows can help for smoother scrolling on touch devices. - */ overscanRowCount: Validator, - - /** - * Optional CSS class to apply to all table rows (including the header row). - * This property can be a CSS class name (string) or a function that returns a class name. - * If a function is provided its signature should be: ({ index: number }): string - */ rowClassName: Requireable string)>, - - /** - * Callback responsible for returning a data row given an index. - * ({ index: number }): any - */ rowGetter: Validator<(params: Index) => any>, - - /** - * Either a fixed row height (number) or a function that returns the height of a row given its index. - * ({ index: number }): number - */ rowHeight: Validator number)>, - - /** Number of rows in table. */ rowCount: Validator, - - /** - * Responsible for rendering a table row given an array of columns: - * Should implement the following interface: ({ - * className: string, - * columns: Array, - * index: number, - * isScrolling: boolean, - * onRowClick: ?Function, - * onRowDoubleClick: ?Function, - * onRowMouseOver: ?Function, - * onRowMouseOut: ?Function, - * rowData: any, - * style: any - * }): PropTypes.node - */ rowRenderer: Requireable<(props: TableRowProps) => React.ReactNode>, - - /** Optional custom inline style to attach to table rows. */ rowStyle: Validator React.CSSProperties)>, - - /** See Grid#scrollToAlignment */ scrollToAlignment: Validator, - - /** Row index to ensure visible (by forcefully scrolling if necessary) */ scrollToIndex: Validator, - - /** Vertical offset. */ scrollTop: Requireable, - - /** - * Sort function to be called if a sortable header is clicked. - * ({ sortBy: string, sortDirection: SortDirection }): void - */ sort: Requireable<(params: { sortBy: string, sortDirection: SortDirectionType }) => void>, - - /** Table data is currently sorted by this :dataKey (if it is sorted at all) */ sortBy: Requireable, - - /** Table data is currently sorted in this direction (if it is sorted at all) */ sortDirection: Validator, - - /** Optional inline style */ style: Requireable, - - /** Tab index for focus */ tabIndex: Requireable, - - /** Width of list */ width: Validator }; @@ -430,6 +382,15 @@ export class Table extends PureComponent { forceUpdateGrid(): void; + /** See Grid#getOffsetForCell */ + getOffsetForRow(params: { + alignment?: Alignment, + index?: number + }): number; + + /** See Grid#scrollToPosition */ + scrollToPosition(scrollTop?: number): void; + /** See Grid#measureAllCells */ measureAllRows(): void; diff --git a/types/react-virtualized/dist/es/WindowScroller.d.ts b/types/react-virtualized/dist/es/WindowScroller.d.ts index 7e0a09379e..16be9f8e1a 100644 --- a/types/react-virtualized/dist/es/WindowScroller.d.ts +++ b/types/react-virtualized/dist/es/WindowScroller.d.ts @@ -7,9 +7,17 @@ export type WindowScrollerChildProps = { }; export type WindowScrollerProps = { + /** + * Function responsible for rendering children. + * This function should implement the following signature: + * ({ height, isScrolling, scrollTop }) => PropTypes.element + */ children?: (props: WindowScrollerChildProps) => React.ReactNode; + /** Callback to be invoked on-resize: ({ height }) */ onResize?: (prams: { height: number }) => void; + /** Callback to be invoked on-scroll: ({ scrollTop }) */ onScroll?: (params: { scrollTop: number }) => void; + /** Element to attach scroll event listeners. Defaults to window. */ scrollElement?: HTMLElement; } export type WindowScrollerState = { @@ -20,20 +28,9 @@ export type WindowScrollerState = { export class WindowScroller extends PureComponent { static propTypes: { - /** - * Function responsible for rendering children. - * This function should implement the following signature: - * ({ height, isScrolling, scrollTop }) => PropTypes.element - */ children: Validator<(props: WindowScrollerChildProps) => React.ReactNode>, - - /** Callback to be invoked on-resize: ({ height }) */ onResize: Validator<(params: { height: number }) => void>, - - /** Callback to be invoked on-scroll: ({ scrollTop }) */ onScroll: Validator<(params: { scrollTop: number }) => void>, - - /** Element to attach scroll event listeners. Defaults to window. */ scrollElement: HTMLElement }; diff --git a/types/react-virtualized/index.d.ts b/types/react-virtualized/index.d.ts index 82fb2a3daf..c1586de906 100644 --- a/types/react-virtualized/index.d.ts +++ b/types/react-virtualized/index.d.ts @@ -1,4 +1,4 @@ -// Type definitions for react-virtualized 9.5 +// Type definitions for react-virtualized 9.7 // Project: https://github.com/bvaughn/react-virtualized // Definitions by: Kalle Ott // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped @@ -37,6 +37,8 @@ export { SizedColumnProps } from './dist/es/ColumnSizer' export { + accessibilityOverscanIndicesGetter, + defaultOverscanIndicesGetter, defaultCellRangeRenderer, Grid, CellSizeAndPositionManager, diff --git a/types/react-virtualized/react-virtualized-tests.tsx b/types/react-virtualized/react-virtualized-tests.tsx index aa44909cdf..504a6e2c17 100644 --- a/types/react-virtualized/react-virtualized-tests.tsx +++ b/types/react-virtualized/react-virtualized-tests.tsx @@ -1,2 +1,1751 @@ +import * as React from 'react'; +import { PureComponent } from 'react' +import { ArrowKeyStepper, AutoSizer, Grid } from 'react-virtualized' + +export class ArrowKeyStepperExample extends PureComponent { + constructor(props) { + super(props) + + this._getColumnWidth = this._getColumnWidth.bind(this) + this._getRowHeight = this._getRowHeight.bind(this) + this._cellRenderer = this._cellRenderer.bind(this) + } + + render() { + const { mode } = this.state + + return ( + + + {({ onSectionRendered, scrollToColumn, scrollToRow }) => ( +
+ + + {({ width }) => ( + this._cellRenderer({ columnIndex, key, rowIndex, scrollToColumn, scrollToRow, style })} + rowHeight={this._getRowHeight} + rowCount={100} + scrollToColumn={scrollToColumn} + scrollToRow={scrollToRow} + width={width} + /> + )} + +
+ )} +
+ ) + } + + _getColumnWidth({ index }) { + return (1 + (index % 3)) * 60 + } + + _getRowHeight({ index }) { + return (1 + (index % 3)) * 30 + } + + _cellRenderer({ columnIndex, key, rowIndex, scrollToColumn, scrollToRow, style }) { + + return ( +
+ {`r:${rowIndex}, c:${columnIndex}`} +
+ ) + } +} + +import { List } from 'react-virtualized' + +export class AutoSizerExample extends PureComponent { + constructor(props) { + super(props) + + this._rowRenderer = this._rowRenderer.bind(this) + } + + render() { + const { list } = this.context + const { hideDescription } = this.state + + return ( + + {({ width, height }) => ( + + )} + + ) + } + + _rowRenderer({ index, key, style }) { + const { list } = this.context + const row = list.get(index) + + return ( +
+ {row.name} +
+ ) + } +} import { } from 'react' import { CellMeasurer, CellMeasurerCache } from 'react-virtualized' + +export class DynamicHeightList extends PureComponent { + + _cache: CellMeasurerCache + + constructor(props, context) { + super(props, context) + + this._cache = new CellMeasurerCache({ + fixedWidth: true, + minHeight: 50 + }) + + this._rowRenderer = this._rowRenderer.bind(this) + } + + render() { + const { width } = this.props + + return ( + + ) + } + + _rowRenderer({ index, isScrolling, key, parent, style }) { + const { getClassName, list } = this.props + + const datum = list.get(index % list.size) + const classNames = getClassName({ columnIndex: 0, rowIndex: index }) + + const imageWidth = 300 + const imageHeight = datum.size * 2 + + const source = `http://fillmurray.com/${imageWidth}/${imageHeight}` + + return ( + + {({ measure }) => ( +
+ +
+ )} +
+ ) + } +} + +import { Collection } from 'react-virtualized' + +// Defines a pattern of sizes and positions for a range of 10 rotating cells +// These cells cover an area of 600 (wide) x 400 (tall) +const GUTTER_SIZE = 3 +const CELL_WIDTH = 75 + +export class CollectionExample extends PureComponent { + _columnYMap: any; + + constructor(props, context) { + super(props, context) + + this.context = context; + + this.state = { + cellCount: context.list.size, + columnCount: this._getColumnCount(context.list.size), + height: 300, + horizontalOverscanSize: 0, + scrollToCell: undefined, + showScrollingPlaceholder: false, + verticalOverscanSize: 0 + } + + this._columnYMap = [] + + this._cellRenderer = this._cellRenderer.bind(this) + this._cellSizeAndPositionGetter = this._cellSizeAndPositionGetter.bind(this) + this._noContentRenderer = this._noContentRenderer.bind(this) + this._onCellCountChange = this._onCellCountChange.bind(this) + this._onHeightChange = this._onHeightChange.bind(this) + this._onHorizontalOverscanSizeChange = this._onHorizontalOverscanSizeChange.bind(this) + this._onScrollToCellChange = this._onScrollToCellChange.bind(this) + this._onVerticalOverscanSizeChange = this._onVerticalOverscanSizeChange.bind(this) + } + + render() { + const { cellCount, height, horizontalOverscanSize, scrollToCell, showScrollingPlaceholder, verticalOverscanSize } = this.state + + return ( + + {({ width }) => ( + + )} + + ) + } + + _cellRenderer({ index, isScrolling, key, style }) { + const { list } = this.context + const { showScrollingPlaceholder } = this.state + + const datum = list.get(index % list.size) + + // Customize style + style.backgroundColor = datum.color + + return ( +
+ {showScrollingPlaceholder && isScrolling ? '...' : index} +
+ ) + } + + _cellSizeAndPositionGetter({ index }) { + const { list } = this.context + const { columnCount } = this.state + + const columnPosition = index % (columnCount || 1) + const datum = list.get(index % list.size) + + // Poor man's Masonry layout; columns won't all line up equally with the bottom. + const height = datum.size + const width = CELL_WIDTH + const x = columnPosition * (GUTTER_SIZE + width) + const y = this._columnYMap[columnPosition] || 0 + + this._columnYMap[columnPosition] = y + height + GUTTER_SIZE + + return { + height, + width, + x, + y + } + } + + _getColumnCount(cellCount) { + return Math.round(Math.sqrt(cellCount)) + } + + _onHorizontalOverscanSizeChange(event) { + const horizontalOverscanSize = parseInt(event.target.value, 10) || 0 + + this.setState({ horizontalOverscanSize }) + } + + _noContentRenderer() { + return ( +
+ No cells +
+ ) + } + + _onCellCountChange(event) { + const cellCount = parseInt(event.target.value, 10) || 0 + + this._columnYMap = [] + + this.setState({ + cellCount, + columnCount: this._getColumnCount(cellCount) + }) + } + + _onHeightChange(event) { + const height = parseInt(event.target.value, 10) || 0 + + this.setState({ height }) + } + + _onScrollToCellChange(event) { + const { cellCount } = this.state + + let scrollToCell = Math.min(cellCount - 1, parseInt(event.target.value, 10)) + + if (isNaN(scrollToCell)) { + scrollToCell = undefined + } + + this.setState({ scrollToCell }) + } + + _onVerticalOverscanSizeChange(event) { + const verticalOverscanSize = parseInt(event.target.value, 10) || 0 + + this.setState({ verticalOverscanSize }) + } +} + +import { ColumnSizer } from 'react-virtualized' + +export class ColumnSizerExample extends PureComponent { + constructor(props) { + super(props) + + this._noColumnMaxWidthChange = this._noColumnMaxWidthChange.bind(this) + this._noColumnMinWidthChange = this._noColumnMinWidthChange.bind(this) + this._onColumnCountChange = this._onColumnCountChange.bind(this) + this._noContentRenderer = this._noContentRenderer.bind(this) + this._cellRenderer = this._cellRenderer.bind(this) + } + + render() { + const { + columnMaxWidth, + columnMinWidth, + columnCount + } = this.state + + return ( +
+ + {({ width }) => ( + + {({ adjustedWidth, getColumnWidth, registerChild }) => ( +
+ +
+ )} +
+ )} +
+
+ ) + } + + _noColumnMaxWidthChange(event) { + let columnMaxWidth = parseInt(event.target.value, 10) + + if (isNaN(columnMaxWidth)) { + columnMaxWidth = undefined + } else { + columnMaxWidth = Math.min(1000, columnMaxWidth) + } + + this.setState({ columnMaxWidth }) + } + + _noColumnMinWidthChange(event) { + let columnMinWidth = parseInt(event.target.value, 10) + + if (isNaN(columnMinWidth)) { + columnMinWidth = undefined + } else { + columnMinWidth = Math.max(1, columnMinWidth) + } + + this.setState({ columnMinWidth }) + } + + _onColumnCountChange(event) { + this.setState({ columnCount: parseInt(event.target.value, 10) || 0 }) + } + + _noContentRenderer() { + return ( +
+ No cells +
+ ) + } + + _cellRenderer({ columnIndex, key, rowIndex, style }) { + const className = columnIndex === 0 + ? 'styles.firstCell' + : 'styles.cell' + + return ( +
+ {`R:${rowIndex}, C:${columnIndex}`} +
+ ) + } +} + +export class GridExample extends PureComponent { + constructor(props, context) { + super(props, context) + + this.state = { + columnCount: 1000, + height: 300, + overscanColumnCount: 0, + overscanRowCount: 10, + rowHeight: 40, + rowCount: 1000, + scrollToColumn: undefined, + scrollToRow: undefined, + useDynamicRowHeight: false + } + + this._cellRenderer = this._cellRenderer.bind(this) + this._getColumnWidth = this._getColumnWidth.bind(this) + this._getRowClassName = this._getRowClassName.bind(this) + this._getRowHeight = this._getRowHeight.bind(this) + this._noContentRenderer = this._noContentRenderer.bind(this) + this._onColumnCountChange = this._onColumnCountChange.bind(this) + this._onRowCountChange = this._onRowCountChange.bind(this) + this._onScrollToColumnChange = this._onScrollToColumnChange.bind(this) + this._onScrollToRowChange = this._onScrollToRowChange.bind(this) + this._renderBodyCell = this._renderBodyCell.bind(this) + this._renderLeftSideCell = this._renderLeftSideCell.bind(this) + } + + render() { + const { + columnCount, + height, + overscanColumnCount, + overscanRowCount, + rowHeight, + rowCount, + scrollToColumn, + scrollToRow, + useDynamicRowHeight + } = this.state + + return ( + + + {({ width }) => ( + + )} + + ) + } + + _cellRenderer({ columnIndex, key, rowIndex, style }) { + if (columnIndex === 0) { + return this._renderLeftSideCell({ key, rowIndex, style }) + } else { + return this._renderBodyCell({ columnIndex, key, rowIndex, style }) + } + } + + _getColumnWidth({ index }) { + switch (index) { + case 0: + return 50 + case 1: + return 100 + case 2: + return 300 + default: + return 80 + } + } + + _getDatum(index) { + const { list } = this.context + + return list.get(index % list.size) + } + + _getRowClassName(row) { + return row % 2 === 0 ? 'styles.evenRow' : 'styles.oddRow' + } + + _getRowHeight({ index }) { + return this._getDatum(index).size + } + + _noContentRenderer() { + return ( +
+ No cells +
+ ) + } + + _renderBodyCell({ columnIndex, key, rowIndex, style }) { + const rowClass = this._getRowClassName(rowIndex) + const datum = this._getDatum(rowIndex) + + let content + + switch (columnIndex) { + case 1: + content = datum.name + break + case 2: + content = datum.random + break + default: + content = `r:${rowIndex}, c:${columnIndex}` + break + } + + return ( +
+ {content} +
+ ) + } + + _renderLeftSideCell({ key, rowIndex, style }) { + const datum = this._getDatum(rowIndex) + + // Don't modify styles. + // These are frozen by React now (as of 16.0.0). + // Since Grid caches and re-uses them, they aren't safe to modify. + style = { + ...style, + backgroundColor: datum.color + } + + return ( +
+ {datum.name.charAt(0)} +
+ ) + } + + _updateUseDynamicRowHeights(value) { + this.setState({ + useDynamicRowHeight: value + }) + } + + _onColumnCountChange(event) { + const columnCount = parseInt(event.target.value, 10) || 0 + + this.setState({ columnCount }) + } + + _onRowCountChange(event) { + const rowCount = parseInt(event.target.value, 10) || 0 + + this.setState({ rowCount }) + } + + _onScrollToColumnChange(event) { + const { columnCount } = this.state + let scrollToColumn = Math.min(columnCount - 1, parseInt(event.target.value, 10)) + + if (isNaN(scrollToColumn)) { + scrollToColumn = undefined + } + + this.setState({ scrollToColumn }) + } + + _onScrollToRowChange(event) { + const { rowCount } = this.state + let scrollToRow = Math.min(rowCount - 1, parseInt(event.target.value, 10)) + + if (isNaN(scrollToRow)) { + scrollToRow = undefined + } + + this.setState({ scrollToRow }) + } +} + +import { InfiniteLoader } from 'react-virtualized' + +const STATUS_LOADING = 1 +const STATUS_LOADED = 2 + +export class InfiniteLoaderExample extends PureComponent { + _timeoutIdMap: any; + + constructor(props) { + super(props) + + this._timeoutIdMap = {} + + this._clearData = this._clearData.bind(this) + this._isRowLoaded = this._isRowLoaded.bind(this) + this._loadMoreRows = this._loadMoreRows.bind(this) + this._rowRenderer = this._rowRenderer.bind(this) + } + + componentWillUnmount() { + Object.keys(this._timeoutIdMap).forEach(timeoutId => { + clearTimeout(timeoutId as any) + }) + } + + render() { + const { list } = this.context + const { loadedRowCount, loadingRowCount } = this.state + + return ( + + {({ onRowsRendered, registerChild }) => ( + + {({ width }) => ( + + )} + + )} + + ) + } + + _clearData() { + this.setState({ + loadedRowCount: 0, + loadedRowsMap: {}, + loadingRowCount: 0 + }) + } + + _isRowLoaded({ index }) { + const { loadedRowsMap } = this.state + return !!loadedRowsMap[index] // STATUS_LOADING or STATUS_LOADED + } + + _loadMoreRows({ startIndex, stopIndex }) { + const { loadedRowsMap, loadingRowCount } = this.state + const increment = stopIndex - startIndex + 1 + + for (let i = startIndex; i <= stopIndex; i++) { + loadedRowsMap[i] = STATUS_LOADING + } + + this.setState({ + loadingRowCount: loadingRowCount + increment + }) + + const timeoutId = setTimeout(() => { + const { loadedRowCount, loadingRowCount } = this.state + + delete this._timeoutIdMap[timeoutId] + + for (let i = startIndex; i <= stopIndex; i++) { + loadedRowsMap[i] = STATUS_LOADED + } + + this.setState({ + loadingRowCount: loadingRowCount - increment, + loadedRowCount: loadedRowCount + increment + }) + + promiseResolver() + }, 1000 + Math.round(Math.random() * 2000)) + + this._timeoutIdMap[timeoutId] = true + + let promiseResolver + + return new Promise(resolve => { + promiseResolver = resolve + }) + } + + _rowRenderer({ index, key, style }) { + const { list } = this.context + const { loadedRowsMap } = this.state + + const row = list.get(index) + let content + + if (loadedRowsMap[index] === STATUS_LOADED) { + content = row.name + } else { + content = ( +
+ ) + } + + return ( +
+ {content} +
+ ) + } +} + +export class ListExample extends PureComponent { + + constructor(props, context) { + super(props, context) + + this.state = { + listHeight: 300, + listRowHeight: 50, + overscanRowCount: 10, + rowCount: context.list.size, + scrollToIndex: undefined, + showScrollingPlaceholder: false, + useDynamicRowHeight: false + } + + this._getRowHeight = this._getRowHeight.bind(this) + this._noRowsRenderer = this._noRowsRenderer.bind(this) + this._onRowCountChange = this._onRowCountChange.bind(this) + this._onScrollToRowChange = this._onScrollToRowChange.bind(this) + this._rowRenderer = this._rowRenderer.bind(this) + } + + render() { + const { + listHeight, + listRowHeight, + overscanRowCount, + rowCount, + scrollToIndex, + showScrollingPlaceholder, + useDynamicRowHeight + } = this.state + + return ( + + {({ width }) => ( + + )} + + ) + } + + _getDatum(index) { + const { list } = this.context + + return list.get(index % list.size) + } + + _getRowHeight({ index }) { + return this._getDatum(index).size + } + + _noRowsRenderer() { + return ( +
+ No rows +
+ ) + } + + _onRowCountChange(event) { + const rowCount = parseInt(event.target.value, 10) || 0 + + this.setState({ rowCount }) + } + + _onScrollToRowChange(event) { + const { rowCount } = this.state + let scrollToIndex = Math.min(rowCount - 1, parseInt(event.target.value, 10)) + + if (isNaN(scrollToIndex)) { + scrollToIndex = undefined + } + + this.setState({ scrollToIndex }) + } + + _rowRenderer({ index, isScrolling, key, style }) { + const { + showScrollingPlaceholder, + useDynamicRowHeight + } = this.state + + if ( + showScrollingPlaceholder && + isScrolling + ) { + return ( +
+ Scrolling... +
+ ) + } + + const datum = this._getDatum(index) + + let additionalContent + + if (useDynamicRowHeight) { + switch (datum.size) { + case 75: + additionalContent =
It is medium-sized.
+ break + case 100: + additionalContent =
It is large-sized.
It has a 3rd row.
+ break + } + } + + return ( +
+
+ {datum.name.charAt(0)} +
+
+
+ {datum.name} +
+
+ This is row {index} +
+ {additionalContent} +
+ {useDynamicRowHeight && + + {datum.size}px + + } +
+ ) + } +} + +import { + WindowScroller, + createMasonryCellPositioner as createCellPositioner, + Positioner, + Masonry, + MasonryCellProps +} from 'react-virtualized' + +export class GridExample2 extends PureComponent { + _columnCount: number; + _cache: CellMeasurerCache; + _columnHeights: any; + _width: number; + _height: number; + _scrollTop: number; + _cellPositioner?: Positioner; + _masonry: Masonry; + + constructor(props, context) { + super(props, context) + + this._columnCount = 0 + + this._cache = new CellMeasurerCache({ + defaultHeight: 250, + defaultWidth: 200, + fixedWidth: true + }) + + this._columnHeights = {} + + this.state = { + columnWidth: 200, + height: 300, + gutterSize: 10, + windowScrollerEnabled: false + } + + this._cellRenderer = this._cellRenderer.bind(this) + this._onResize = this._onResize.bind(this) + this._renderAutoSizer = this._renderAutoSizer.bind(this) + this._renderMasonry = this._renderMasonry.bind(this) + this._setMasonryRef = this._setMasonryRef.bind(this) + } + + render() { + const { + columnWidth, + height, + gutterSize, + windowScrollerEnabled + } = this.state + + let child + + if (windowScrollerEnabled) { + child = ( + + {this._renderAutoSizer} + + ) + } else { + child = this._renderAutoSizer({ height }) + } + + return ( +
+ {child} +
+ ) + } + + _calculateColumnCount() { + const { + columnWidth, + gutterSize + } = this.state + + this._columnCount = Math.floor(this._width / (columnWidth + gutterSize)) + } + + _cellRenderer({ index, key, parent, style }: MasonryCellProps) { + const { list } = this.context + const { columnWidth } = this.state + + const datum = list.get(index % list.size) + + return ( + +
+
+ {datum.random} +
+ + ) + } + + _initCellPositioner() { + if (typeof this._cellPositioner === 'undefined') { + const { + columnWidth, + gutterSize + } = this.state + + this._cellPositioner = createCellPositioner({ + cellMeasurerCache: this._cache, + columnCount: this._columnCount, + columnWidth, + spacer: gutterSize + }) + } + } + + _onResize({ height, width }) { + this._width = width + + this._columnHeights = {} + this._calculateColumnCount() + this._resetCellPositioner() + this._masonry.recomputeCellPositions() + } + + _renderAutoSizer({ height, scrollTop }: { height: number, scrollTop?: number }) { + this._height = height + this._scrollTop = scrollTop + + return ( + + {this._renderMasonry} + + ) + } + + _renderMasonry({ width }) { + this._width = width + + this._calculateColumnCount() + this._initCellPositioner() + + const { height, windowScrollerEnabled } = this.state + + return ( + + ) + } + + _resetCellPositioner() { + const { + columnWidth, + gutterSize + } = this.state + + this._cellPositioner.reset({ + columnCount: this._columnCount, + columnWidth, + spacer: gutterSize + }) + } + + _setMasonryRef(ref) { + this._masonry = ref + } +} + +import { MultiGrid } from 'react-virtualized' + +const STYLE: React.CSSProperties = { + border: '1px solid #ddd', + overflow: 'hidden' +} +const STYLE_BOTTOM_LEFT_GRID: React.CSSProperties = { + borderRight: '2px solid #aaa', + backgroundColor: '#f7f7f7' +} +const STYLE_TOP_LEFT_GRID: React.CSSProperties = { + borderBottom: '2px solid #aaa', + borderRight: '2px solid #aaa', + fontWeight: 'bold' +} +const STYLE_TOP_RIGHT_GRID: React.CSSProperties = { + borderBottom: '2px solid #aaa', + fontWeight: 'bold' +} + +export class MultiGridExample extends PureComponent { + state + _onFixedColumnCountChange + _onFixedRowCountChange + _onScrollToColumnChange + _onScrollToRowChange + + constructor(props, context) { + super(props, context) + + this.state = { + fixedColumnCount: 2, + fixedRowCount: 1, + scrollToColumn: 0, + scrollToRow: 0 + } + + this._cellRenderer = this._cellRenderer.bind(this) + this._onFixedColumnCountChange = this._createEventHandler('fixedColumnCount') + this._onFixedRowCountChange = this._createEventHandler('fixedRowCount') + this._onScrollToColumnChange = this._createEventHandler('scrollToColumn') + this._onScrollToRowChange = this._createEventHandler('scrollToRow') + } + + render() { + return ( + + {({ width }) => ( + + )} + + ) + } + + _cellRenderer({ columnIndex, key, rowIndex, style }) { + return ( +
+ {columnIndex}, {rowIndex} +
+ ) + } + + _createEventHandler(property) { + return (event) => { + const value = parseInt(event.target.value, 10) || 0 + + this.setState({ + [property]: value + }) + } + } + + _createLabeledInput(property, eventHandler) { + const value = this.state[property] + + return ( + `` + ) + } +} + +import { ScrollSync } from 'react-virtualized' + +const LEFT_COLOR_FROM = hexToRgb('#471061') +const LEFT_COLOR_TO = hexToRgb('#BC3959') +const TOP_COLOR_FROM = hexToRgb('#000000') +const TOP_COLOR_TO = hexToRgb('#333333') + +function scrollbarSize() { return 42; } +export class GridExample3 extends PureComponent { + state + constructor(props, context) { + super(props, context) + + this.state = { + columnWidth: 75, + columnCount: 50, + height: 300, + overscanColumnCount: 0, + overscanRowCount: 5, + rowHeight: 40, + rowCount: 100 + } + + this._renderBodyCell = this._renderBodyCell.bind(this) + this._renderHeaderCell = this._renderHeaderCell.bind(this) + this._renderLeftSideCell = this._renderLeftSideCell.bind(this) + } + + render() { + const { + columnCount, + columnWidth, + height, + overscanColumnCount, + overscanRowCount, + rowHeight, + rowCount + } = this.state + + return ( + + + {({ clientHeight, clientWidth, onScroll, scrollHeight, scrollLeft, scrollTop, scrollWidth }) => { + const x = scrollLeft / (scrollWidth - clientWidth) + const y = scrollTop / (scrollHeight - clientHeight) + + const leftBackgroundColor = mixColors(LEFT_COLOR_FROM, LEFT_COLOR_TO, y) + const leftColor = '#ffffff' + const topBackgroundColor = mixColors(TOP_COLOR_FROM, TOP_COLOR_TO, x) + const topColor = '#ffffff' + const middleBackgroundColor = mixColors(leftBackgroundColor, topBackgroundColor, 0.5) + const middleColor = '#ffffff' + + return ( +
+
+ +
+
+ +
+
+ + {({ width }) => ( +
+
+ +
+
+ +
+
+ )} +
+
+
+ ) + }} +
+ ) + } + + _renderBodyCell({ columnIndex, key, rowIndex, style }) { + if (columnIndex < 1) { + return + } + + return this._renderLeftSideCell({ columnIndex, key, rowIndex, style }) + } + + _renderHeaderCell({ columnIndex, key, rowIndex, style }) { + if (columnIndex < 1) { + return + } + + return this._renderLeftHeaderCell({ columnIndex, key, rowIndex, style }) + } + + _renderLeftHeaderCell({ columnIndex, key, rowIndex, style }) { + return ( +
+ {`C${columnIndex}`} +
+ ) + } + + _renderLeftSideCell({ columnIndex, key, rowIndex, style }) { + return ( +
+ {`R${rowIndex}, C${columnIndex}`} +
+ ) + } +} + +function hexToRgb(hex) { + const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) + return result ? { + r: parseInt(result[1], 16), + g: parseInt(result[2], 16), + b: parseInt(result[3], 16) + } : null +} + +/** + * Ported from sass implementation in C + * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209 + */ +function mixColors(color1, color2, amount) { + const weight1 = amount + const weight2 = 1 - amount + + const r = Math.round(weight1 * color1.r + weight2 * color2.r) + const g = Math.round(weight1 * color1.g + weight2 * color2.g) + const b = Math.round(weight1 * color1.b + weight2 * color2.b) + + return { r, g, b } +} + +import { Column, Table, SortDirection, SortIndicator } from 'react-virtualized' + +export class TableExample extends PureComponent { + state; + context; + constructor(props, context) { + super(props, context) + + this.state = { + disableHeader: false, + headerHeight: 30, + height: 270, + hideIndexRow: false, + overscanRowCount: 10, + rowHeight: 40, + rowCount: 1000, + scrollToIndex: undefined, + sortBy: 'index', + sortDirection: SortDirection.ASC, + useDynamicRowHeight: false + } + + this._getRowHeight = this._getRowHeight.bind(this) + this._headerRenderer = this._headerRenderer.bind(this) + this._noRowsRenderer = this._noRowsRenderer.bind(this) + this._onRowCountChange = this._onRowCountChange.bind(this) + this._onScrollToRowChange = this._onScrollToRowChange.bind(this) + this._rowClassName = this._rowClassName.bind(this) + this._sort = this._sort.bind(this) + } + + render() { + const { + disableHeader, + headerHeight, + height, + hideIndexRow, + overscanRowCount, + rowHeight, + rowCount, + scrollToIndex, + sortBy, + sortDirection, + useDynamicRowHeight + } = this.state + + const { list } = this.context + const sortedList = this._isSortEnabled() + ? list + .sortBy(item => item[sortBy]) + .update(list => + sortDirection === SortDirection.DESC + ? list.reverse() + : list + ) + : list + + const rowGetter = ({ index }) => this._getDatum(sortedList, index) + + return ( +
+ + {({ width }) => ( + + {!hideIndexRow && + rowData.index + } + dataKey='index' + disableSort={!this._isSortEnabled()} + width={60} + /> + } + + cellData + } + flexGrow={1} + /> +
+ )} +
+
+ ) + } + + _getDatum(list, index) { + return list.get(index % list.size) + } + + _getRowHeight({ index }) { + const { list } = this.context + + return this._getDatum(list, index).size + } + + _headerRenderer({ + columnData, + dataKey, + disableSort, + label, + sortBy, + sortDirection + }) { + return ( +
+ Full Name + {sortBy === dataKey && + + } +
+ ) + } + + _isSortEnabled() { + const { list } = this.context + const { rowCount } = this.state + + return rowCount <= list.size + } + + _noRowsRenderer() { + return ( +
+ No rows +
+ ) + } + + _onRowCountChange(event) { + const rowCount = parseInt(event.target.value, 10) || 0 + + this.setState({ rowCount }) + } + + _onScrollToRowChange(event) { + const { rowCount } = this.state + let scrollToIndex = Math.min(rowCount - 1, parseInt(event.target.value, 10)) + + if (isNaN(scrollToIndex)) { + scrollToIndex = undefined + } + + this.setState({ scrollToIndex }) + } + + _rowClassName({ index }) { + if (index < 0) { + return 'styles.headerRow' + } else { + return index % 2 === 0 ? 'styles.evenRow' : 'styles.oddRow' + } + } + + _sort({ sortBy, sortDirection }) { + this.setState({ sortBy, sortDirection }) + } + + _updateUseDynamicRowHeight(value) { + this.setState({ + useDynamicRowHeight: value + }) + } +} + +export class WindowScrollerExample extends PureComponent { + state; + context; + _windowScroller: WindowScroller; + + constructor(props) { + super(props) + + this.state = { + showHeaderText: true + } + + this._hideHeader = this._hideHeader.bind(this) + this._rowRenderer = this._rowRenderer.bind(this) + this._onCheckboxChange = this._onCheckboxChange.bind(this) + this._setRef = this._setRef.bind(this) + } + + render() { + const { list, isScrollingCustomElement, customElement } = this.context + const { showHeaderText } = this.state + + return ( + +
+ + {({ height, isScrolling, scrollTop }) => ( + + {({ width }) => ( + this._rowRenderer({ index, isScrolling, isVisible, key, style })} + scrollTop={scrollTop} + width={width} + /> + )} + + )} + +
+ ) + } + + _hideHeader() { + const { showHeaderText } = this.state + + this.setState({ + showHeaderText: !showHeaderText + }, () => { + this._windowScroller.updatePosition() + }) + } + + _rowRenderer({ index, isScrolling, isVisible, key, style }) { + const { list } = this.context + const row = list.get(index) + + return ( +
+ {row.name} +
+ ) + } + + _setRef(windowScroller) { + this._windowScroller = windowScroller + } + + _onCheckboxChange(event) { + this.context.setScrollingCustomElement(event.target.checked) + } +} diff --git a/types/react-virtualized/tslint.json b/types/react-virtualized/tslint.json index a28671ebce..1b94f68dea 100644 --- a/types/react-virtualized/tslint.json +++ b/types/react-virtualized/tslint.json @@ -7,6 +7,7 @@ ], "prefer-method-signature": false, "prefer-declare-function": false, - "no-padding": false + "no-padding": false, + "array-type": [true, "array"] } }