/** @flow */ import Immutable from 'immutable' import React, { PropTypes, PureComponent } from 'react' import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox' import { LabeledInput, InputRow } from '../demo/LabeledInput' import AutoSizer from '../AutoSizer' import Grid from './Grid' import cn from 'classnames' import styles from './Grid.example.css' export default class GridExample extends PureComponent { static contextTypes = { list: PropTypes.instanceOf(Immutable.List).isRequired }; 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 ( Renders tabular data with virtualization along the vertical and horizontal axes. Row heights and column widths must be calculated ahead of time and specified as a fixed size or returned by a getter function. this.setState({ height: parseInt(event.target.value, 10) || 1 })} value={height} /> this.setState({ rowHeight: parseInt(event.target.value, 10) || 1 })} value={rowHeight} /> this.setState({ overscanColumnCount: parseInt(event.target.value, 10) || 0 })} value={overscanColumnCount} /> this.setState({ overscanRowCount: parseInt(event.target.value, 10) || 0 })} value={overscanRowCount} /> {({ width }) => ( )} ) } _cellRenderer ({ columnIndex, key, rowIndex, style }) { if (columnIndex === 0) { return this._renderLeftSideCell({ columnIndex, 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 } const classNames = cn(rowClass, styles.cell, { [styles.centeredCell]: columnIndex > 2 }) return (
{content}
) } _renderLeftSideCell ({ key, rowIndex, style }) { const datum = this._getDatum(rowIndex) const classNames = cn(styles.cell, styles.letterCell) // 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 }) } }