Permalink
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
react-virtualized/source/Table/Table.example.js /
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
315 lines (283 sloc)
8.81 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** @flow */ | |
| import Immutable from 'immutable'; | |
| import PropTypes from 'prop-types'; | |
| import * as React 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 React.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 ( | |
| <ContentBox> | |
| <ContentBoxHeader | |
| text="Table" | |
| sourceLink="https://github.com/bvaughn/react-virtualized/blob/master/source/Table/Table.example.js" | |
| docsLink="https://github.com/bvaughn/react-virtualized/blob/master/docs/Table.md" | |
| /> | |
| <ContentBoxParagraph> | |
| 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{' '} | |
| <code>Grid</code> for windowing table content so that large lists are | |
| rendered efficiently. Adjust its configurable properties below to see | |
| how it reacts. | |
| </ContentBoxParagraph> | |
| <ContentBoxParagraph> | |
| <label className={styles.checkboxLabel}> | |
| <input | |
| aria-label="Use dynamic row heights?" | |
| checked={useDynamicRowHeight} | |
| className={styles.checkbox} | |
| type="checkbox" | |
| onChange={event => | |
| this._updateUseDynamicRowHeight(event.target.checked) | |
| } | |
| /> | |
| Use dynamic row heights? | |
| </label> | |
| <label className={styles.checkboxLabel}> | |
| <input | |
| aria-label="Hide index?" | |
| checked={hideIndexRow} | |
| className={styles.checkbox} | |
| type="checkbox" | |
| onChange={event => | |
| this.setState({hideIndexRow: event.target.checked}) | |
| } | |
| /> | |
| Hide index? | |
| </label> | |
| <label className={styles.checkboxLabel}> | |
| <input | |
| aria-label="Hide header?" | |
| checked={disableHeader} | |
| className={styles.checkbox} | |
| type="checkbox" | |
| onChange={event => | |
| this.setState({disableHeader: event.target.checked}) | |
| } | |
| /> | |
| Hide header? | |
| </label> | |
| </ContentBoxParagraph> | |
| <InputRow> | |
| <LabeledInput | |
| label="Num rows" | |
| name="rowCount" | |
| onChange={this._onRowCountChange} | |
| value={rowCount} | |
| /> | |
| <LabeledInput | |
| label="Scroll to" | |
| name="onScrollToRow" | |
| placeholder="Index..." | |
| onChange={this._onScrollToRowChange} | |
| value={scrollToIndex || ''} | |
| /> | |
| <LabeledInput | |
| label="List height" | |
| name="height" | |
| onChange={event => | |
| this.setState({height: parseInt(event.target.value, 10) || 1}) | |
| } | |
| value={height} | |
| /> | |
| <LabeledInput | |
| disabled={useDynamicRowHeight} | |
| label="Row height" | |
| name="rowHeight" | |
| onChange={event => | |
| this.setState({ | |
| rowHeight: parseInt(event.target.value, 10) || 1, | |
| }) | |
| } | |
| value={rowHeight} | |
| /> | |
| <LabeledInput | |
| label="Header height" | |
| name="headerHeight" | |
| onChange={event => | |
| this.setState({ | |
| headerHeight: parseInt(event.target.value, 10) || 1, | |
| }) | |
| } | |
| value={headerHeight} | |
| /> | |
| <LabeledInput | |
| label="Overscan" | |
| name="overscanRowCount" | |
| onChange={event => | |
| this.setState({ | |
| overscanRowCount: parseInt(event.target.value, 10) || 0, | |
| }) | |
| } | |
| value={overscanRowCount} | |
| /> | |
| </InputRow> | |
| <div> | |
| <AutoSizer disableHeight> | |
| {({width}) => ( | |
| <Table | |
| ref="Table" | |
| disableHeader={disableHeader} | |
| headerClassName={styles.headerColumn} | |
| headerHeight={headerHeight} | |
| height={height} | |
| noRowsRenderer={this._noRowsRenderer} | |
| overscanRowCount={overscanRowCount} | |
| rowClassName={this._rowClassName} | |
| rowHeight={useDynamicRowHeight ? this._getRowHeight : rowHeight} | |
| rowGetter={rowGetter} | |
| rowCount={rowCount} | |
| scrollToIndex={scrollToIndex} | |
| sort={this._sort} | |
| sortBy={sortBy} | |
| sortDirection={sortDirection} | |
| width={width}> | |
| {!hideIndexRow && ( | |
| <Column | |
| label="Index" | |
| cellDataGetter={({rowData}) => rowData.index} | |
| dataKey="index" | |
| disableSort={!this._isSortEnabled()} | |
| width={60} | |
| /> | |
| )} | |
| <Column | |
| dataKey="name" | |
| disableSort={!this._isSortEnabled()} | |
| headerRenderer={this._headerRenderer} | |
| width={90} | |
| /> | |
| <Column | |
| width={210} | |
| disableSort | |
| label="The description label is really long so that it will be truncated" | |
| dataKey="random" | |
| className={styles.exampleColumn} | |
| cellRenderer={({cellData}) => cellData} | |
| flexGrow={1} | |
| /> | |
| </Table> | |
| )} | |
| </AutoSizer> | |
| </div> | |
| </ContentBox> | |
| ); | |
| } | |
| _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 ( | |
| <div> | |
| Full Name | |
| {sortBy === dataKey && <SortIndicator sortDirection={sortDirection} />} | |
| </div> | |
| ); | |
| } | |
| _isSortEnabled() { | |
| const {list} = this.context; | |
| const {rowCount} = this.state; | |
| return rowCount <= list.size; | |
| } | |
| _noRowsRenderer() { | |
| return <div className={styles.noRows}>No rows</div>; | |
| } | |
| _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, | |
| }); | |
| } | |
| } |