/** @flow */ import Immutable from 'immutable'; import PropTypes from 'prop-types'; import React, {PureComponent} from 'react'; import { ContentBox, ContentBoxHeader, ContentBoxParagraph, } from '../demo/ContentBox'; import {LabeledInput, InputRow} from '../demo/LabeledInput'; import AutoSizer from '../AutoSizer'; import Column from './Column'; import Table from './Table'; import SortDirection from './SortDirection'; import SortIndicator from './SortIndicator'; import styles from './Table.example.css'; export default class TableExample extends PureComponent { static contextTypes = { list: PropTypes.instanceOf(Immutable.List).isRequired, }; constructor(props, context) { super(props, context); const sortBy = 'index'; const sortDirection = SortDirection.ASC; const sortedList = this._sortList({sortBy, sortDirection}); this.state = { disableHeader: false, headerHeight: 30, height: 270, hideIndexRow: false, overscanRowCount: 10, rowHeight: 40, rowCount: 1000, scrollToIndex: undefined, sortBy, sortDirection, sortedList, 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, sortedList, useDynamicRowHeight, } = this.state; const rowGetter = ({index}) => this._getDatum(sortedList, index); return ( The table layout below is created with flexboxes. This allows it to have a fixed header and scrollable body content. It also makes use of{' '} Grid for windowing table content so that large lists are rendered efficiently. Adjust its configurable properties below to see how it reacts. this.setState({height: parseInt(event.target.value, 10) || 1}) } value={height} /> this.setState({ rowHeight: parseInt(event.target.value, 10) || 1, }) } value={rowHeight} /> this.setState({ headerHeight: parseInt(event.target.value, 10) || 1, }) } value={headerHeight} /> this.setState({ overscanRowCount: parseInt(event.target.value, 10) || 0, }) } value={overscanRowCount} />
{({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({dataKey, 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}) { const sortedList = this._sortList({sortBy, sortDirection}); this.setState({sortBy, sortDirection, sortedList}); } _sortList({sortBy, sortDirection}) { const {list} = this.context; return list .sortBy(item => item[sortBy]) .update( list => (sortDirection === SortDirection.DESC ? list.reverse() : list), ); } _updateUseDynamicRowHeight(value) { this.setState({ useDynamicRowHeight: value, }); } }