From 97fd2fc247ed9996d7faf87f0ca3cd3e67eef208 Mon Sep 17 00:00:00 2001 From: Kalle Ott Date: Mon, 27 Mar 2017 21:54:40 +0200 Subject: [PATCH] replaced mulstiple testfiles with on to obey definitely typed naming --- .../ArrowKeyStepper.test.tsx | 71 - types/react-virtualized/AutoSizer.test.tsx | 47 - types/react-virtualized/CellMeasurer.test.tsx | 74 - types/react-virtualized/Collection.test.tsx | 160 -- types/react-virtualized/ColumnSizer.test.tsx | 113 -- types/react-virtualized/Grid.test.tsx | 207 -- .../react-virtualized/InfiniteLoader.test.tsx | 138 -- types/react-virtualized/List.test.tsx | 160 -- types/react-virtualized/Masonry.test.tsx | 200 -- types/react-virtualized/MultiGrid.test.tsx | 105 - types/react-virtualized/ScrollSync.test.tsx | 222 --- types/react-virtualized/Table.test.tsx | 196 -- .../react-virtualized/WindowScroller.test.tsx | 88 - .../react-virtualized-tests.tsx | 1753 +++++++++++++++++ types/react-virtualized/tsconfig.json | 14 +- 15 files changed, 1754 insertions(+), 1794 deletions(-) delete mode 100644 types/react-virtualized/ArrowKeyStepper.test.tsx delete mode 100644 types/react-virtualized/AutoSizer.test.tsx delete mode 100644 types/react-virtualized/CellMeasurer.test.tsx delete mode 100644 types/react-virtualized/Collection.test.tsx delete mode 100644 types/react-virtualized/ColumnSizer.test.tsx delete mode 100644 types/react-virtualized/Grid.test.tsx delete mode 100644 types/react-virtualized/InfiniteLoader.test.tsx delete mode 100644 types/react-virtualized/List.test.tsx delete mode 100644 types/react-virtualized/Masonry.test.tsx delete mode 100644 types/react-virtualized/MultiGrid.test.tsx delete mode 100644 types/react-virtualized/ScrollSync.test.tsx delete mode 100644 types/react-virtualized/Table.test.tsx delete mode 100644 types/react-virtualized/WindowScroller.test.tsx create mode 100644 types/react-virtualized/react-virtualized-tests.tsx diff --git a/types/react-virtualized/ArrowKeyStepper.test.tsx b/types/react-virtualized/ArrowKeyStepper.test.tsx deleted file mode 100644 index 8204aafdd6..0000000000 --- a/types/react-virtualized/ArrowKeyStepper.test.tsx +++ /dev/null @@ -1,71 +0,0 @@ -/** @flow */ -import * as React from 'react'; -import { PureComponent } from 'react' -import { ArrowKeyStepper, AutoSizer, Grid } from 'react-virtualized' - -export default 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}`} -
- ) - } -} diff --git a/types/react-virtualized/AutoSizer.test.tsx b/types/react-virtualized/AutoSizer.test.tsx deleted file mode 100644 index 670d77b52b..0000000000 --- a/types/react-virtualized/AutoSizer.test.tsx +++ /dev/null @@ -1,47 +0,0 @@ -/** @flow */ -import * as React from 'react'; -import { PureComponent } from 'react' -import { AutoSizer, List } from 'react-virtualized' - -export default 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} -
- ) - } -} diff --git a/types/react-virtualized/CellMeasurer.test.tsx b/types/react-virtualized/CellMeasurer.test.tsx deleted file mode 100644 index 5b510704c0..0000000000 --- a/types/react-virtualized/CellMeasurer.test.tsx +++ /dev/null @@ -1,74 +0,0 @@ -/** @flow */ -import * as React from 'react' -import { PropTypes, PureComponent } from 'react' -import { CellMeasurer, CellMeasurerCache, List } from 'react-virtualized' - -export default 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 }) => ( -
- -
- )} -
- ) - } -} diff --git a/types/react-virtualized/Collection.test.tsx b/types/react-virtualized/Collection.test.tsx deleted file mode 100644 index 8a7860b3c7..0000000000 --- a/types/react-virtualized/Collection.test.tsx +++ /dev/null @@ -1,160 +0,0 @@ -/** @flow */ -import * as React from 'react' -import { PropTypes, PureComponent } from 'react' -import { AutoSizer, 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 default 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 }) - } -} diff --git a/types/react-virtualized/ColumnSizer.test.tsx b/types/react-virtualized/ColumnSizer.test.tsx deleted file mode 100644 index 97de9fff45..0000000000 --- a/types/react-virtualized/ColumnSizer.test.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import * as React from 'react' -import { PureComponent } from 'react' -import { AutoSizer, ColumnSizer, Grid } from 'react-virtualized' - -export default 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}`} -
- ) - } -} diff --git a/types/react-virtualized/Grid.test.tsx b/types/react-virtualized/Grid.test.tsx deleted file mode 100644 index 634fcdc137..0000000000 --- a/types/react-virtualized/Grid.test.tsx +++ /dev/null @@ -1,207 +0,0 @@ -/** @flow */ -import * as React from 'react' -import { PropTypes, PureComponent } from 'react' -import { AutoSizer, Grid } from 'react-virtualized' - -export default 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 }) - } -} diff --git a/types/react-virtualized/InfiniteLoader.test.tsx b/types/react-virtualized/InfiniteLoader.test.tsx deleted file mode 100644 index 0509f46216..0000000000 --- a/types/react-virtualized/InfiniteLoader.test.tsx +++ /dev/null @@ -1,138 +0,0 @@ -/** @flow */ -import * as React from 'react' -import { PropTypes, PureComponent } from 'react' -import { AutoSizer, InfiniteLoader, List } from 'react-virtualized' - -const STATUS_LOADING = 1 -const STATUS_LOADED = 2 - -export default 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 (var 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 (var 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} -
- ) - } -} diff --git a/types/react-virtualized/List.test.tsx b/types/react-virtualized/List.test.tsx deleted file mode 100644 index 86763a95f8..0000000000 --- a/types/react-virtualized/List.test.tsx +++ /dev/null @@ -1,160 +0,0 @@ -import * as React from 'react' -import { PropTypes, PureComponent } from 'react' -import { AutoSizer, List } from 'react-virtualized' - -export default 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 - - } -
- ) - } -} diff --git a/types/react-virtualized/Masonry.test.tsx b/types/react-virtualized/Masonry.test.tsx deleted file mode 100644 index 902e5498c5..0000000000 --- a/types/react-virtualized/Masonry.test.tsx +++ /dev/null @@ -1,200 +0,0 @@ -import * as React from 'react' -import { PropTypes, PureComponent } from 'react' -import { - CellMeasurer, - CellMeasurerCache, - AutoSizer, - WindowScroller, - createMasonryCellPositioner as createCellPositioner, - Positioner, - Masonry, - MasonryCellProps -} from 'react-virtualized' - -export default class GridExample 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 - } -} diff --git a/types/react-virtualized/MultiGrid.test.tsx b/types/react-virtualized/MultiGrid.test.tsx deleted file mode 100644 index f2f3af9397..0000000000 --- a/types/react-virtualized/MultiGrid.test.tsx +++ /dev/null @@ -1,105 +0,0 @@ -/** @flow */ -import * as React from 'react' -import { PropTypes, PureComponent } from 'react' -import { AutoSizer, 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 default 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 ( - `` - ) - } -} diff --git a/types/react-virtualized/ScrollSync.test.tsx b/types/react-virtualized/ScrollSync.test.tsx deleted file mode 100644 index 9919b72ab3..0000000000 --- a/types/react-virtualized/ScrollSync.test.tsx +++ /dev/null @@ -1,222 +0,0 @@ -import * as React from 'react' -import { PureComponent } from 'react' -import { AutoSizer, Grid, 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 default class GridExample 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 } -} diff --git a/types/react-virtualized/Table.test.tsx b/types/react-virtualized/Table.test.tsx deleted file mode 100644 index 8714634d1d..0000000000 --- a/types/react-virtualized/Table.test.tsx +++ /dev/null @@ -1,196 +0,0 @@ -import * as React from 'react' -import { PropTypes, PureComponent } from 'react' -import { AutoSizer, Column, Table, SortDirection, SortIndicator } from 'react-virtualized' - -export default 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 - }) - } -} diff --git a/types/react-virtualized/WindowScroller.test.tsx b/types/react-virtualized/WindowScroller.test.tsx deleted file mode 100644 index c72a1b197a..0000000000 --- a/types/react-virtualized/WindowScroller.test.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import * as React from 'react' -import { PropTypes, PureComponent } from 'react' -import { WindowScroller, List, AutoSizer } from 'react-virtualized' - -export default 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/react-virtualized-tests.tsx b/types/react-virtualized/react-virtualized-tests.tsx new file mode 100644 index 0000000000..71386b2780 --- /dev/null +++ b/types/react-virtualized/react-virtualized-tests.tsx @@ -0,0 +1,1753 @@ +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 (var 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 (var 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/tsconfig.json b/types/react-virtualized/tsconfig.json index 21a0e43a0d..6be15dbe8a 100644 --- a/types/react-virtualized/tsconfig.json +++ b/types/react-virtualized/tsconfig.json @@ -20,31 +20,19 @@ "files": [ "index.d.ts", "ArrowKeyStepper.d.ts", - "ArrowKeyStepper.test.tsx", "AutoSizer.d.ts", - "AutoSizer.test.tsx", "CellMeasurer.d.ts", - "CellMeasurer.test.tsx", "Collection.d.ts", - "Collection.test.tsx", "ColumnSizer.d.ts", - "ColumnSizer.test.tsx", "genericTypes.d.ts", "Grid.d.ts", - "Grid.test.tsx", "InfiniteLoader.d.ts", - "InfiniteLoader.test.tsx", "List.d.ts", - "List.test.tsx", "Masonry.d.ts", - "Masonry.test.tsx", "MultiGrid.d.ts", - "MultiGrid.test.tsx", "ScrollSync.d.ts", - "ScrollSync.test.tsx", "Table.d.ts", - "Table.test.tsx", "WindowScroller.d.ts", - "WindowScroller.test.tsx" + "react-virtualized-tests.tsx" ] } \ No newline at end of file