Compare commits

..
3 Commits
24 changed files with 224 additions and 757 deletions
-2
View File
@@ -25,7 +25,6 @@ import CustomExpanderPosition from '../stories/CustomExpanderPosition.js'
import NoDataText from '../stories/NoDataText.js'
import Footers from '../stories/Footers.js'
import Filtering from '../stories/Filtering.js'
import ControlledTable from '../stories/ControlledTable.js'
//
configure(() => {
storiesOf('1. Docs')
@@ -56,5 +55,4 @@ configure(() => {
.add('Custom "No Data" Text', NoDataText)
.add('Footers', Footers)
.add('Custom Filtering', Filtering)
.add('Controlled Component', ControlledTable)
}, module)
-1
View File
@@ -14,5 +14,4 @@ h1 {
p {
margin-bottom: 15px;
line-height: 22px;
}
-15
View File
@@ -1,15 +0,0 @@
## Problem Description
include a detailed explanation of the problem here...
## Code Snippet(s)
## Steps to Reproduce
1. list the steps
2. to reproduce the issue
## System Information
* **Browser & Browser Version:**
* **Node Version:**
* **OS Version:**
* **NPM Version:**
* **Yarn Version:**
+43 -83
View File
@@ -47,7 +47,7 @@
- [Props](#props)
- [Columns](#columns)
- [Column Header Groups](#column-header-groups)
- [Custom Cell and Header and Footer Rendering](#custom-cell-header-and-footer-rendering)
- [Custom Cell and Header Rendering](#custom-cell-and-header-rendering)
- [Styles](#styles)
- [Custom Props](#custom-props)
- [Pivoting and Aggregation](#pivoting-and-aggregation)
@@ -56,7 +56,6 @@
- [Fully Controlled Component](#fully-controlled-component)
- [Functional Rendering](#functional-rendering)
- [Multi-Sort](#multi-sort)
- [Filtering](#filtering)
- [Component Overrides](#component-overrides)
- [Contributing](#contributing)
- [Scripts](#scripts)
@@ -90,39 +89,36 @@ import 'react-table/react-table.css'
```javascript
import ReactTable from 'react-table'
render() {
const data = [{
name: 'Tanner Linsley',
age: 26,
friend: {
name: 'Jason Maurer',
age: 23,
}
},{
...
}]
const data = [{
name: 'Tanner Linsley',
age: 26,
friend: {
name: 'Jason Maurer',
age: 23,
}
},{
...
}]
const columns = [{
header: 'Name',
accessor: 'name' // String-based value accessors!
}, {
header: 'Age',
accessor: 'age',
render: props => <span className='number'>{props.value}</span> // Custom cell components!
}, {
id: 'friendName', // Required because our accessor is not a string
header: 'Friend Name',
accessor: d => d.friend.name // Custom value accessors!
}, {
header: props => <span>Friend Age</span>, // Custom header components!
accessor: 'friend.age'
}]
const columns = [{
header: 'Name',
accessor: 'name' // String-based value accessors!
}, {
header: 'Age',
accessor: 'age',
render: props => <span className='number'>{props.value}</span> // Custom cell components!
}, {
header: 'Friend Name',
accessor: d => d.friend.name // Custom value accessors!
}, {
header: props => <span>Friend Age</span>, // Custom header components!
accessor: 'friend.age'
}]
<ReactTable
data={data}
columns={columns}
/>
}
<ReactTable
data={data}
columns={columns}
/>
```
## Data
@@ -149,17 +145,12 @@ These are all of the available props (and their default values) for the main `<R
defaultSorting: [],
showFilters: false,
defaultFiltering: [],
defaultFilterMethod: (filter, row, column) => {
const id = filter.pivotId || filter.id
return row[id] !== undefined ? String(row[id]).startsWith(filter.value) : true
},
resizable: true,
defaultResizing: [],
defaultFilterMethod: (filter, row) => (row[filter.id] == filter.value),
// Controlled State Overrides (see Fully Controlled Component section)
page: undefined,
pageSize: undefined,
sorting: undefined,
sorting: undefined
// Controlled State Callbacks
onExpandSubComponent: undefined,
@@ -167,7 +158,6 @@ These are all of the available props (and their default values) for the main `<R
onPageSizeChange: undefined,
onSortingChange: undefined,
onFilteringChange: undefined,
onResize: undefined,
// Pivoting
pivotBy: undefined,
@@ -212,7 +202,6 @@ These are all of the available props (and their default values) for the main `<R
getPaginationProps: () => ({}),
getLoadingProps: () => ({}),
getNoDataProps: () => ({}),
getResizerProps: () => ({}),
// Global Column Defaults
column: {
@@ -234,17 +223,7 @@ These are all of the available props (and their default values) for the main `<R
footerClassName: '',
footerStyle: {},
getFooterProps: () => ({}),
filterMethod: undefined,
hideFilter: false,
filterRender: ({filter, onFilterChange}) => (
<input type='text'
style={{
width: '100%'
}}
value={filter ? filter.value : ''}
onChange={(event) => onFilterChange(event.target.value)}
/>
)
filterMethod: undefined
},
// Text
@@ -286,16 +265,16 @@ Or just define them as props
```javascript
[{
// General
accessor: 'propertyName', // or Accessor eg. (row) => row.propertyName (see "Accessors" section for more details)
accessor: 'propertyName' // or Accessor eg. (row) => row.propertyName (see "Accessors" section for more details)
id: 'myProperty', // Conditional - A unique ID is required if the accessor is not a string or if you would like to override the column name used in server-side calls
sortable: true,
show: true, // can be used to hide a column
width: undefined, // A hardcoded width for the column. This overrides both min and max width options
minWidth: 100, // A minimum width for this column. If there is extra room, column will flex to fill available space (up to the max-width, if set)
maxWidth: undefined, // A maximum width for this column.
minWidth: 100 // A minimum width for this column. If there is extra room, column will flex to fill available space (up to the max-width, if set)
maxWidth: undefined // A maximum width for this column.
// Special
expander: false, // This option will override all data-related options and designates the column to be used
expander: false // This option will override all data-related options and designates the column to be used
// for pivoting and sub-component expansion
// Cell Options
@@ -312,24 +291,22 @@ Or just define them as props
header: 'Header Name', a function that returns a primitive, or JSX / React Component eg. ({data, column}) => <div>Header Name</div>,
headerClassName: '', // Set the classname of the `th` element of the column
headerStyle: {}, // Set the style of the `th` element of the column
getHeaderProps: (state, rowInfo, column, instance) => ({}), // a function that returns props to decorate the `th` element of the column
getHeaderProps: (state, rowInfo, column, instance) => ({}) // a function that returns props to decorate the `th` element of the column
// Header Groups only
columns: [...], // See Header Groups section below
columns: [...] // See Header Groups section below
// Footer
footer: 'Footer Name' or JSX eg. ({data, column}) => <div>Footer Name</div>,
footer: 'Header Name' or JSX eg. ({data, column}) => <div>Header Name</div>,
footerClassName: '', // Set the classname of the `td` element of the column's footer
footerStyle: {}, // Set the style of the `td` element of the column's footer
getFooterProps: (state, rowInfo, column, instance) => ({}), // A function that returns props to decorate the `td` element of the column's footer
getFooterProps: (state, rowInfo, column, instance) => ({}) // A function that returns props to decorate the `td` element of the column's footer
// Filtering
filterMethod: (filter, row, column) => {return true}, // A function returning a boolean that specifies the filtering logic for the column
// filter == an object specifying which filter is being applied. Format: {id: [the filter column's id], value: [the value the user typed in the filter field], pivotId: [if filtering on a pivot column, the pivotId will be set to the pivot column's id and the `id` field will be set to the top level pivoting column]}
filterMethod: (filter, row, column) => {return true} // A function returning a boolean that specifies the filtering logic for the column
// filter == an object specifying which filter is being applied. Format: {id: [the filter column's id], value: [the value the user typed in the filter field]}
// row == the row of data supplied to the table
// column == the column that the filter is on
hideFilter: false, // If `showFilters` is set on the table, this option will let you selectively hide the filter on a particular row
filterRender: JSX // eg. ({filter, onFilterChange}) => <select onChange={event => onFilterChange(event.target.value)} value={filter ? filter.value : ''}></select> // The value passed to onFilterChange will be the value passed to filter.value of the filterMethod
}]
```
@@ -453,8 +430,6 @@ Every single built-in component's props can be dynamically extended using any on
getTdProps={fn}
getPaginationProps={fn}
getLoadingProps={fn}
getNoDataProps: {fn},
getResizerProps: {fn}
/>
```
@@ -640,8 +615,7 @@ Here are the props and their corresponding callbacks that control the state of t
onPageSizeChange={(pageSize, pageIndex) => {...}} // Called when the pageSize is changed by the user. The resolve page is also sent to maintain approximate position in the data
onSortingChange={(column, shiftKey) => {...}} // Called when a sortable column header is clicked with the column itself and if the shiftkey was held. If the column is a pivoted column, `column` will be an array of columns
onExpandRow={(index, event) => {...}} // Called when an expander is clicked. Use this to manage `expandedRows`
onFilteringChange={(column, value) => {...}} // Called when a user enters a value into a filter input field or the value passed to the onFilterChange handler by the filterRender option.
onResize={(column, event, isTouch) => {...}} // Called when a user clicks on a resizing component (the right edge of a column header)
onFilteringChange={(column, event) => {...}} // Called when a user enters a value into a filter input field. The event is the onChange event of the input field.
/>
```
@@ -685,19 +659,6 @@ The possibilities are endless!
## Multi-Sort
When clicking on a column header, hold shift to multi-sort! You can toggle `ascending` `descending` and `none` for multi-sort columns. Clicking on a header without holding shift will clear the multi-sort and replace it with the single sort of that column. It's quite handy!
## Filtering
Filtering can be enabled by setting the `showFilters` option on the table.
If you don't want particular column to be filtered you can set the `hideFilter` option on the column.
By default the table tries to filter by checking if the row's value starts with the filter text. The default method for filtering the table can be set with the table's `defaultFilterMethod` option.
If you want to override a particular column's filtering method, you can set the `filterMethod` option on a column.
To completely override the filter that is shown, you can set the `filterRender` column option. Using this option you can specify the JSX that is shown. The option is passed an `onFilterChange` method which must be called with the the value that you wan't to pass to the `filterMethod` option whenever the filter has changed.
See <a href="http://react-table.js.org/?selectedKind=2.%20Demos&selectedStory=Custom%20Filtering&full=0&down=1&left=1&panelRight=0&downPanel=kadirahq%2Fstorybook-addon-actions%2Factions-panel" target="\_parent">Custom Filtering</a> demo for examples.
## Component Overrides
Though we confidently stand by the markup and architecture behind it, `react-table` does offer the ability to change the core componentry it uses to render everything. You can extend or override these internal components by passing a react component to it's corresponding prop on either the global props or on a one-off basis like so:
```javascript
@@ -718,7 +679,6 @@ Object.assign(ReactTableDefaults, {
NextComponent: undefined,
LoadingComponent: component,
NoDataComponent: component,
ResizerComponent: component
})
// Or change per instance
+1 -1
View File
@@ -16,7 +16,7 @@
<body>
<div id="root"></div>
<div id="error-display"></div>
<script src="static/preview.0cd0bb2bf09f3220bea7.bundle.js"></script>
<script src="static/preview.ea1bdf726a82703c8f6f.bundle.js"></script>
</body>
</html>
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
{"version":3,"file":"static/preview.0cd0bb2bf09f3220bea7.bundle.js","sources":["webpack:///static/preview.0cd0bb2bf09f3220bea7.bundle.js"],"mappings":"AAAA;AAkuDA;AA62DA;AAwtFA;AAsiFA;AA0uOA;AAgmGA;AA6rDA;AA0iEA;AA0xDA;AA25DA;AAmqDA;AA0vDA;AA+9CA;AAg5DA;AAwoDA;AAk7CA;AA2pDA;AAmjEA;AA27DA;AAghCA;AA4vDA;AA8kDA;AAwpEA;AAk3DA;AAy0DA;AA8xCA;AAu3EA;AAi4GA;AAwoDA;AAk+CA;AA+oCA;AAutCA;AA4jDA;AAwcA;AA+jFA","sourceRoot":""}
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"version":3,"file":"static/preview.ea1bdf726a82703c8f6f.bundle.js","sources":["webpack:///static/preview.ea1bdf726a82703c8f6f.bundle.js"],"mappings":"AAAA;AAkuDA;AAo/DA;AAgrFA;AAmmFA;AA07OA;AAuwFA;AAwtDA;AA+jEA;AA4uDA;AAi8DA;AA+lDA;AA4yDA;AA28CA;AAw7DA;AAooDA;AA67CA;AAiqDA;AAynEA;AAwxDA;AA+rCA;AA+mDA;AA2lDA;AAkqEA;AAs2DA;AA2zDA;AAo4CA;AAksFA;AAmjGA;AAksDA;AA02CA;AAgoCA;AAm/CA;AA+4CA;AAsCA;AA+jFA","sourceRoot":""}
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "react-table",
"version": "5.5.2",
"version": "5.3.4",
"description": "A fast, lightweight, opinionated table and datagrid built on React",
"license": "MIT",
"homepage": "https://github.com/tannerlinsley/react-table#readme",
@@ -61,7 +61,7 @@
"react": "^15.4.2",
"react-dom": "^15.4.2",
"react-json-tree": "^0.10.1",
"rimraf": "^2.6.1",
"rimraf": "^2.6.1",
"standard": "^8.0.0",
"storybook": "^0.0.0",
"stylus": "^0.54.5",
+3 -21
View File
@@ -23,12 +23,7 @@ export default {
defaultSorting: [],
showFilters: false,
defaultFiltering: [],
defaultFilterMethod: (filter, row, column) => {
const id = filter.pivotId || filter.id
return row[id] !== undefined ? String(row[id]).startsWith(filter.value) : true
},
resizable: true,
defaultResizing: [],
defaultFilterMethod: (filter, row, column) => (row[filter.id] === filter.value),
// Controlled State Overrides
// page: undefined,
@@ -41,7 +36,6 @@ export default {
onPageSizeChange: undefined,
onSortingChange: undefined,
onFilteringChange: undefined,
onResize: undefined,
// Pivoting
pivotBy: undefined,
@@ -85,7 +79,6 @@ export default {
getPaginationProps: emptyObj,
getLoadingProps: emptyObj,
getNoDataProps: emptyObj,
getResizerProps: emptyObj,
// Global Column Defaults
column: {
@@ -107,17 +100,7 @@ export default {
footerClassName: '',
footerStyle: {},
getFooterProps: emptyObj,
filterMethod: undefined,
hideFilter: false,
filterRender: ({filter, onFilterChange}) => (
<input type='text'
style={{
width: '100%'
}}
value={filter ? filter.value : ''}
onChange={(event) => onFilterChange(event.target.value)}
/>
)
filterMethod: undefined
},
// Text
@@ -174,6 +157,5 @@ export default {
</div>
</div>
),
NoDataComponent: _.makeTemplateComponent('rt-noData'),
ResizerComponent: _.makeTemplateComponent('rt-resizer')
NoDataComponent: _.makeTemplateComponent('rt-noData')
}
+73 -118
View File
@@ -39,21 +39,18 @@ export default React.createClass({
getPaginationProps,
getLoadingProps,
getNoDataProps,
getResizerProps,
showPagination,
expanderColumnWidth,
manual,
loadingText,
noDataText,
showFilters,
resizable,
// State
loading,
pageSize,
page,
sorting,
filtering,
resizing,
pages,
// Pivoting State
pivotValKey,
@@ -74,7 +71,6 @@ export default React.createClass({
LoadingComponent,
SubComponent,
NoDataComponent,
ResizerComponent,
// Data model
resolvedData,
allVisibleColumns,
@@ -87,39 +83,32 @@ export default React.createClass({
// Pagination
const startRow = pageSize * page
const endRow = startRow + pageSize
let pageRows = manual ? resolvedData : sortedData.slice(startRow, endRow)
const pageRows = manual ? resolvedData : sortedData.slice(startRow, endRow)
const minRows = this.getMinRows()
const padRows = _.range(Math.max(minRows - pageRows.length, 0))
const padRows = pages > 1 ? _.range(pageSize - pageRows.length)
: minRows ? _.range(Math.max(minRows - pageRows.length, 0))
: []
const hasColumnFooter = allVisibleColumns.some(d => d.footer)
const recurseRowsViewIndex = (rows, path = [], index = -1) => {
return [
rows.map((row, i) => {
index++
const rowWithViewIndex = {
...row,
_viewIndex: index
}
const newPath = path.concat([i])
if (rowWithViewIndex[subRowsKey] && _.get(expandedRows, newPath)) {
[rowWithViewIndex[subRowsKey], index] = recurseRowsViewIndex(rowWithViewIndex[subRowsKey], newPath, index)
}
return rowWithViewIndex
}),
index
]
rows.forEach((row, i) => {
index++
row._viewIndex = index
const newPath = path.concat([i])
if (row[subRowsKey] && _.get(expandedRows, newPath)) {
index = recurseRowsViewIndex(row[subRowsKey], newPath, index)
}
})
return index
}
[pageRows] = recurseRowsViewIndex(pageRows)
recurseRowsViewIndex(pageRows)
const canPrevious = page > 0
const canNext = page + 1 < pages
const rowMinWidth = _.sum(allVisibleColumns.map(d => {
const resized = resizing.find(x => x.id === d.id) || {}
return _.getFirstDefined(resized.value, d.width, d.minWidth)
}))
const rowMinWidth = _.sum(allVisibleColumns.map(d => _.getFirstDefined(d.width, d.minWidth)))
let rowIndex = -1
@@ -162,18 +151,9 @@ export default React.createClass({
}
const makeHeaderGroup = (column, i) => {
const flex = _.sum(column.columns.map(d => {
const resized = resizing.find(x => x.id === d.id) || {}
return d.width || resized.value ? 0 : d.minWidth
}))
const width = _.sum(column.columns.map(d => {
const resized = resizing.find(x => x.id === d.id) || {}
return _.getFirstDefined(resized.value, d.width, d.minWidth)
}))
const maxWidth = _.sum(column.columns.map(d => {
const resized = resizing.find(x => x.id === d.id) || {}
return _.getFirstDefined(resized.value, d.width, d.maxWidth)
}))
const flex = _.sum(column.columns.map(d => d.width ? 0 : d.minWidth))
const width = _.sum(column.columns.map(d => _.getFirstDefined(d.width, d.minWidth)))
const maxWidth = _.sum(column.columns.map(d => _.getFirstDefined(d.width, d.maxWidth)))
const theadGroupThProps = _.splitProps(getTheadGroupThProps(finalState, undefined, column, this))
const columnHeaderProps = _.splitProps(column.getHeaderProps(finalState, undefined, column, this))
@@ -277,11 +257,10 @@ export default React.createClass({
}
const makeHeader = (column, i) => {
const resized = resizing.find(x => x.id === column.id) || {}
const sort = sorting.find(d => d.id === column.id)
const show = typeof column.show === 'function' ? column.show() : column.show
const width = _.getFirstDefined(resized.value, column.width, column.minWidth)
const maxWidth = _.getFirstDefined(resized.value, column.width, column.maxWidth)
const width = _.getFirstDefined(column.width, column.minWidth)
const maxWidth = _.getFirstDefined(column.width, column.maxWidth)
const theadThProps = _.splitProps(getTheadThProps(finalState, undefined, column, this))
const columnHeaderProps = _.splitProps(column.getHeaderProps(finalState, undefined, column, this))
@@ -302,14 +281,6 @@ export default React.createClass({
...columnHeaderProps.rest
}
const resizer = resizable ? (
<ResizerComponent
onMouseDown={e => this.resizeColumnStart(column, e, false)}
onTouchStart={e => this.resizeColumnStart(column, e, true)}
{...resizerProps}
/>
) : null
if (column.expander) {
if (column.pivotColumns) {
const pivotSort = sorting.find(d => d.id === column.id)
@@ -318,7 +289,6 @@ export default React.createClass({
key={i}
className={classnames(
'rt-pivot-header',
'rt-resizable-header',
column.sortable && '-cursor-pointer',
classes,
pivotSort ? (pivotSort.desc ? '-sort-desc' : '-sort-asc') : ''
@@ -334,22 +304,19 @@ export default React.createClass({
}}
{...rest}
>
<div className='rt-resizable-header-content'>
{column.pivotColumns.map((pivotColumn, i) => {
return (
<span key={pivotColumn.id}>
{_.normalizeComponent(pivotColumn.header, {
data: sortedData,
column: column
})}
{i < column.pivotColumns.length - 1 && (
<ExpanderComponent />
)}
</span>
)
})}
</div>
{resizer}
{column.pivotColumns.map((pivotColumn, i) => {
return (
<span key={pivotColumn.id}>
{_.normalizeComponent(pivotColumn.header, {
data: sortedData,
column: column
})}
{i < column.pivotColumns.length - 1 && (
<ExpanderComponent />
)}
</span>
)
})}
</ThComponent>
)
}
@@ -375,7 +342,6 @@ export default React.createClass({
key={i}
className={classnames(
classes,
'rt-resizable-header',
sort ? (sort.desc ? '-sort-desc' : '-sort-asc') : '',
column.sortable && '-cursor-pointer',
!show && '-hidden',
@@ -391,13 +357,10 @@ export default React.createClass({
}}
{...rest}
>
<div className='rt-resizable-header-content'>
{_.normalizeComponent(column.header, {
data: sortedData,
column: column
})}
</div>
{resizer}
{_.normalizeComponent(column.header, {
data: sortedData,
column: column
})}
</ThComponent>
)
}
@@ -426,9 +389,8 @@ export default React.createClass({
}
const makeFilter = (column, i) => {
const resized = resizing.find(x => x.id === column.id) || {}
const width = _.getFirstDefined(resized.value, column.width, column.minWidth)
const maxWidth = _.getFirstDefined(resized.value, column.width, column.maxWidth)
const width = _.getFirstDefined(column.width, column.minWidth)
const maxWidth = _.getFirstDefined(column.width, column.maxWidth)
const theadFilterThProps = _.splitProps(getTheadFilterThProps(finalState, undefined, column, this))
const columnHeaderProps = _.splitProps(column.getHeaderProps(finalState, undefined, column, this))
@@ -454,20 +416,20 @@ export default React.createClass({
const pivotCols = []
for (let i = 0; i < column.pivotColumns.length; i++) {
const col = column.pivotColumns[i]
const filter = filtering.find(filter => filter.id === column.id && filter.pivotId === col.id)
const filter = filtering.find(filter => filter.id === col.id)
pivotCols.push(
<span key={col.id}
style={{flex: 1}}>
{!col.hideFilter ? (
_.normalizeComponent(col.filterRender,
{
col,
filter,
onFilterChange: (value) => (this.filterColumn(column, value, col))
},
defaults.column.filterRender
)
) : null}
style={{display: 'flex', alignContent: 'flex-end', flex: 1}}>
<input type='text'
style={{
flex: 1,
width: 20,
backgroundColor: i > 0 ? '#f3f3f3' : '#fff'
}}
value={filter ? filter.value : ''}
disabled={i > 0}
onChange={(event) => this.filterColumn(col, event)}
/>
</span>
)
if (i < column.pivotColumns.length - 1) {
@@ -528,16 +490,13 @@ export default React.createClass({
}}
{...rest}
>
{!column.hideFilter ? (
_.normalizeComponent(column.filterRender,
{
column,
filter,
onFilterChange: (value) => (this.filterColumn(column, value))
},
defaults.column.filterRender
)
) : null}
<input type='text'
style={{
width: `100%`
}}
value={filter ? filter.value : ''}
onChange={(event) => this.filterColumn(column, event)}
/>
</ThComponent>
)
}
@@ -570,10 +529,9 @@ export default React.createClass({
{...trProps.rest}
>
{allVisibleColumns.map((column, i2) => {
const resized = resizing.find(x => x.id === column.id) || {}
const show = typeof column.show === 'function' ? column.show() : column.show
const width = _.getFirstDefined(resized.value, column.width, column.minWidth)
const maxWidth = _.getFirstDefined(resized.value, column.width, column.maxWidth)
const width = _.getFirstDefined(column.width, column.minWidth)
const maxWidth = _.getFirstDefined(column.width, column.maxWidth)
const tdProps = _.splitProps(getTdProps(finalState, rowInfo, column, this))
const columnProps = _.splitProps(column.getProps(finalState, rowInfo, column, this))
@@ -635,15 +593,15 @@ export default React.createClass({
{...rowInfo}
value={rowInfo.rowValues[pivotValKey]}
/>
) : <span>{row[pivotValKey]} ({rowInfo.subRows.length})</span>}
) : <span>{row[pivotValKey]} ({rowInfo.subRows.length})</span>}
</span>
) : SubComponent ? (
<span>
<ExpanderComponent
isExpanded={isExpanded}
/>
</span>
) : null}
) : SubComponent ? (
<span>
<ExpanderComponent
isExpanded={isExpanded}
/>
</span>
) : null}
</TdComponent>
)
}
@@ -722,10 +680,9 @@ export default React.createClass({
style={trProps.style || {}}
>
{allVisibleColumns.map((column, i2) => {
const resized = resizing.find(x => x.id === column.id) || {}
const show = typeof column.show === 'function' ? column.show() : column.show
const width = _.getFirstDefined(resized.value, column.width, column.minWidth)
const maxWidth = _.getFirstDefined(resized.value, column.width, column.maxWidth)
const width = _.getFirstDefined(column.width, column.minWidth)
const maxWidth = _.getFirstDefined(column.width, column.maxWidth)
const tdProps = _.splitProps(getTdProps(finalState, undefined, column, this))
const columnProps = _.splitProps(column.getProps(finalState, undefined, column, this))
@@ -785,10 +742,9 @@ export default React.createClass({
{...tFootTrProps.rest}
>
{allVisibleColumns.map((column, i2) => {
const resized = resizing.find(x => x.id === column.id) || {}
const show = typeof column.show === 'function' ? column.show() : column.show
const width = _.getFirstDefined(resized.value, column.width, column.minWidth)
const maxWidth = _.getFirstDefined(resized.value, column.width, column.maxWidth)
const width = _.getFirstDefined(column.width, column.minWidth)
const maxWidth = _.getFirstDefined(column.width, column.maxWidth)
const tFootTdProps = _.splitProps(getTfootTdProps(finalState, undefined, undefined, this))
const columnProps = _.splitProps(column.getProps(finalState, undefined, column, this))
const columnFooterProps = _.splitProps(column.getFooterProps(finalState, undefined, column, this))
@@ -884,7 +840,6 @@ export default React.createClass({
const paginationProps = _.splitProps(getPaginationProps(finalState, undefined, undefined, this))
const loadingProps = getLoadingProps(finalState, undefined, undefined, this)
const noDataProps = getNoDataProps(finalState, undefined, undefined, this)
const resizerProps = getResizerProps(finalState, undefined, undefined, this)
const makeTable = () => (
<div
@@ -932,7 +887,7 @@ export default React.createClass({
style={paginationProps.style}
{...paginationProps.rest}
/>
) : null}
) : null}
{!pageRows.length && (
<NoDataComponent
{...noDataProps}
+1 -33
View File
@@ -18,11 +18,6 @@ $expandSize = 7px
.rt-thead
display: flex
flex-direction: column
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
&.-headerGroups
background: alpha(black, .03)
border-bottom: 1px solid alpha(black, .05)
@@ -41,9 +36,6 @@ $expandSize = 7px
.rt-th
.rt-td
padding: 5px 5px
line-height: normal
position: relative
border-right: 1px solid alpha(black, .05)
transition box-shadow .3s $easeOutBack
box-shadow:inset 0 0 0 0 transparent
@@ -55,16 +47,6 @@ $expandSize = 7px
cursor: pointer
&:last-child
border-right: 0
.rt-resizable-header
overflow: visible
&:last-child
overflow: hidden
.rt-resizable-header-content
overflow: hidden
text-overflow: ellipsis
.rt-tbody
display: flex
flex-direction: column
@@ -123,17 +105,6 @@ $expandSize = 7px
cursor: pointer
&.-open:after
transform: translate(-50%, -50%) rotate(0deg)
.rt-resizer
display: inline-block
position: absolute
width: 36px
top: 0
bottom: 0
right: -18px
cursor: col-resize
z-index: 10
.rt-tfoot
display: flex
flex-direction: column
@@ -260,6 +231,7 @@ $expandSize = 7px
input
select
appearance: none
border: 1px solid rgba(0,0,0,0.1)
background: white
padding: 5px 7px
@@ -268,10 +240,6 @@ $expandSize = 7px
font-weight: normal
outline:none
input:not([type="checkbox"]):not([type="radio"])
select
appearance: none
.select-wrap
position:relative
display:inline-block
+2 -6
View File
@@ -12,18 +12,15 @@ export default {
pageSize: this.props.defaultPageSize || 10,
sorting: this.props.defaultSorting,
expandedRows: {},
filtering: this.props.defaultFiltering,
resizing: this.props.defaultResizing,
currentlyResizing: undefined,
skipNextSort: false
filtering: this.props.defaultFiltering
}
},
getResolvedState (props, state) {
const resolvedState = {
..._.compactObject(this.state),
..._.compactObject(this.props),
..._.compactObject(state),
..._.compactObject(this.props),
..._.compactObject(props)
}
return resolvedState
@@ -108,7 +105,6 @@ export default {
// Calculate pageSize all the time
if (newResolvedState.sortedData) {
newResolvedState.pages = newResolvedState.manual ? newResolvedState.pages : Math.ceil(newResolvedState.sortedData.length / newResolvedState.pageSize)
newResolvedState.page = Math.max(newResolvedState.page >= newResolvedState.pages ? newResolvedState.pages - 1 : newResolvedState.page, 0)
}
return this.setState(newResolvedState, cb)
+30 -157
View File
@@ -10,7 +10,10 @@ export default {
pivotValKey,
subRowsKey,
expanderColumnWidth,
SubComponent
SubComponent,
page,
pages,
pageSize
} = newState
// Determine Header Groups
@@ -189,14 +192,14 @@ export default {
// Group the rows together for this level
let groupedRows = Object.entries(
_.groupBy(rows, keys[i]))
.map(([key, value]) => {
return {
[pivotIDKey]: keys[i],
[pivotValKey]: key,
[keys[i]]: key,
[subRowsKey]: value
}
})
.map(([key, value]) => {
return {
[pivotIDKey]: keys[i],
[pivotValKey]: key,
[keys[i]]: key,
[subRowsKey]: value
}
})
// Recurse into the subRows
groupedRows = groupedRows.map(rowGroup => {
let subRows = groupRecursively(rowGroup[subRowsKey], keys, i + 1)
@@ -211,6 +214,9 @@ export default {
resolvedData = groupRecursively(resolvedData, pivotBy)
}
const newPages = _.getFirstDefined(pages, Math.ceil(resolvedData.length / pageSize))
const newPage = page > newPages ? newPage - 1 : page
return {
...newState,
resolvedData,
@@ -218,7 +224,8 @@ export default {
allVisibleColumns,
headerGroups,
allDecoratedColumns,
hasHeaderGroups
hasHeaderGroups,
page: Math.max(newPage, 0)
}
},
getSortedData (resolvedState) {
@@ -234,9 +241,10 @@ export default {
// Resolve the data from either manual data or sorted data
return {
sortedData: manual ? resolvedData : this.sortData(this.filterData(resolvedData, showFilters, filtering, defaultFilterMethod, allVisibleColumns), sorting)
sortedData: manual ? resolvedData : this.sortData(resolvedData, sorting, showFilters, filtering, defaultFilterMethod, allVisibleColumns)
}
},
fireOnChange () {
this.props.onChange(this.getResolvedState(), this)
},
@@ -246,7 +254,7 @@ export default {
getStateOrProp (key) {
return _.getFirstDefined(this.state[key], this.props[key])
},
filterData (data, showFilters, filtering, defaultFilterMethod, allVisibleColumns) {
sortData (data, sorting, showFilters, filtering, defaultFilterMethod, allVisibleColumns) {
let filteredData = data
if (showFilters && filtering.length) {
@@ -254,49 +262,20 @@ export default {
(filteredSoFar, nextFilter) => {
return filteredSoFar.filter(
(row) => {
let column
if (nextFilter.pivotId) {
const parentColumn = allVisibleColumns.find(x => x.id === nextFilter.id)
column = parentColumn.pivotColumns.find(x => x.id === nextFilter.pivotId)
} else {
column = allVisibleColumns.find(x => x.id === nextFilter.id)
}
const column = allVisibleColumns.find(x => x.id === nextFilter.id) || {}
const filterMethod = column.filterMethod || defaultFilterMethod
return filterMethod(nextFilter, row, column)
})
}
, filteredData
)
// Apply the filter to the subrows if we are pivoting, and then
// filter any rows without subcolumns because it would be strange to show
filteredData = filteredData.map(row => {
if (!row[this.props.subRowsKey]) {
return row
}
return {
...row,
[this.props.subRowsKey]: this.filterData(row[this.props.subRowsKey], showFilters, filtering, defaultFilterMethod, allVisibleColumns)
}
}).filter(row => {
if (!row[this.props.subRowsKey]) {
return true
}
return row[this.props.subRowsKey].length > 0
})
}
return filteredData
},
sortData (data, sorting) {
if (!sorting.length) {
return data
return filteredData
}
const sorted = _.orderBy(data, sorting.map(sort => {
const sorted = _.orderBy(filteredData, sorting.map(sort => {
return row => {
if (row[sort.id] === null || row[sort.id] === undefined) {
return -Infinity
@@ -356,19 +335,7 @@ export default {
})
},
sortColumn (column, additive) {
const {sorting, skipNextSort} = this.getResolvedState()
// we can't stop event propagation from the column resize move handlers
// attached to the document because of react's synthetic events
// so we have to prevent the sort function from actually sorting
// if we click on the column resize element within a header.
if (skipNextSort) {
this.setStateWithData({
skipNextSort: false
})
return
}
const {sorting} = this.getResolvedState()
const {onSortingChange} = this.props
if (onSortingChange) {
return onSortingChange(column, additive)
@@ -452,123 +419,29 @@ export default {
this.fireOnChange()
})
},
filterColumn (column, value, pivotColumn) {
filterColumn (column, event) {
const {filtering} = this.getResolvedState()
const {onFilteringChange} = this.props
if (onFilteringChange) {
return onFilteringChange(column, value, pivotColumn)
return onFilteringChange(column, event)
}
// Remove old filter first if it exists
const newFiltering = (filtering || []).filter(x => {
if (x.id !== column.id) {
return true
}
if (x.pivotId) {
if (pivotColumn) {
return x.pivotId !== pivotColumn.id
}
return true
}
})
const newFiltering = (filtering || []).filter(x => x.id !== column.id)
if (value !== '') {
if (event.target.value !== '') {
newFiltering.push({
id: column.id,
value: value,
pivotId: pivotColumn ? pivotColumn.id : undefined
value: event.target.value
})
}
this.setStateWithData({
page: 0,
filtering: newFiltering
}, () => {
this.fireOnChange()
})
},
resizeColumnStart (column, event, isTouch) {
const {onResize} = this.props
if (onResize) {
return onResize(column, event, isTouch)
}
const parentWidth = event.target.parentElement.getBoundingClientRect().width
let pageX
if (isTouch) {
pageX = event.changedTouches[0].pageX
} else {
pageX = event.pageX
}
this.setStateWithData({
currentlyResizing: {
id: column.id,
startX: pageX,
parentWidth: parentWidth
}
}, () => {
if (isTouch) {
document.addEventListener('touchmove', this.resizeColumnMoving)
document.addEventListener('touchcancel', this.resizeColumnEnd)
document.addEventListener('touchend', this.resizeColumnEnd)
} else {
document.addEventListener('mousemove', this.resizeColumnMoving)
document.addEventListener('mouseup', this.resizeColumnEnd)
document.addEventListener('mouseleave', this.resizeColumnEnd)
}
})
},
resizeColumnEnd (event) {
let isTouch = event.type === 'touchend' || event.type === 'touchcancel'
if (isTouch) {
document.removeEventListener('touchmove', this.resizeColumnMoving)
document.removeEventListener('touchcancel', this.resizeColumnEnd)
document.removeEventListener('touchend', this.resizeColumnEnd)
}
// If its a touch event clear the mouse one's as well because sometimes
// the mouseDown event gets called as well, but the mouseUp event doesn't
document.removeEventListener('mousemove', this.resizeColumnMoving)
document.removeEventListener('mouseup', this.resizeColumnEnd)
document.removeEventListener('mouseleave', this.resizeColumnEnd)
// The touch events don't propagate up to the sorting's onMouseDown event so
// no need to prevent it from happening or else the first click after a touch
// event resize will not sort the column.
if (!isTouch) {
this.setStateWithData({
skipNextSort: true
})
}
},
resizeColumnMoving (event) {
const {resizing, currentlyResizing} = this.getResolvedState()
// Delete old value
const newResizing = resizing.filter(x => x.id !== currentlyResizing.id)
let pageX
if (event.type === 'touchmove') {
pageX = event.changedTouches[0].pageX
} else if (event.type === 'mousemove') {
pageX = event.pageX
}
// Set the min size to 10 to account for margin and border or else the group headers don't line up correctly
const newWidth = Math.max(currentlyResizing.parentWidth + pageX - currentlyResizing.startX, 11)
newResizing.push({
id: currentlyResizing.id,
value: newWidth
})
this.setStateWithData({
resizing: newResizing
})
}
}
+1 -6
View File
@@ -17,17 +17,12 @@ export default React.createClass({
this.setState({page: nextProps.page})
},
getSafePage (page) {
if (isNaN(page)) {
page = this.props.page
}
return Math.min(Math.max(page, 0), this.props.pages - 1)
},
changePage (page) {
page = this.getSafePage(page)
this.setState({page})
if (this.props.page !== page) {
this.props.onPageChange(page)
}
this.props.onPageChange(page)
},
applyPage (e) {
e && e.preventDefault()
+1 -1
View File
@@ -80,7 +80,7 @@ function orderBy (arr, funcs, dirs) {
}
return dirs[0]
? a.__index - b.__index
: b.__index - a.__index
: b.__index - b.__index
})
}
-1
View File
@@ -161,7 +161,6 @@ const columns = [{
return (
<ReactTable
className='-striped -highlight'
data={data}
columns={columns}
defaultPageSize={10}
-153
View File
@@ -1,153 +0,0 @@
import React from 'react'
import _ from 'lodash'
import namor from 'namor'
import CodeHighlight from './components/codeHighlight'
import ReactTable from '../src/index'
const data = _.map(_.range(5553), d => {
return {
firstName: namor.generate({ words: 1, numLen: 0 }),
lastName: namor.generate({ words: 1, numLen: 0 }),
age: Math.floor(Math.random() * 30)
}
})
const columns = [{
header: 'Name',
columns: [{
header: 'First Name',
accessor: 'firstName'
}, {
header: 'Last Name',
id: 'lastName',
accessor: d => d.lastName
}]
}, {
header: 'Info',
columns: [{
header: 'Age',
accessor: 'age'
}]
}]
class ControlledTable extends React.Component {
constructor() {
super()
this.sortChange = this.sortChange.bind(this)
this.state = {
sorting: [],
page: 0,
pageSize: 10
}
}
sortChange(column, shift) {
if(shift)
alert('Shift click not implemented in this demo')
var sort = {id: column.id}
if(this.state.sorting.length && this.state.sorting[0].id == column.id)
this.state.sorting[0].asc ? sort.desc = true : sort.asc = true
else
sort.asc = true
this.setState({
sorting: [sort]
})
}
render() {
return (
<div>
<div className='table-wrap'>
<ReactTable
className='-striped -highlight'
data={data}
columns={columns}
sorting={this.state.sorting}
onSortingChange={this.sortChange}
page={this.state.page}
onPageChange={page => this.setState({page})}
pageSize={this.state.pageSize}
onPageSizeChange={(pageSize, page) => this.setState({page, pageSize})}
/>
</div>
<div style={{textAlign: 'center'}}>
<br />
<em>Tip: For simplicity, multi-sort is not implemented in this demo</em>
</div>
<CodeHighlight>{() => getCode()}</CodeHighlight>
</div>
)
}
}
function getCode () {
return `const data = _.map(_.range(5553), d => {
return {
firstName: namor.generate({ words: 1, numLen: 0 }),
lastName: namor.generate({ words: 1, numLen: 0 }),
age: Math.floor(Math.random() * 30)
}
})
const columns = [{
header: 'Name',
columns: [{
header: 'First Name',
accessor: 'firstName'
}, {
header: 'Last Name',
id: 'lastName',
accessor: d => d.lastName
}]
}, {
header: 'Info',
columns: [{
header: 'Age',
accessor: 'age'
}]
}]
class ControlledTable extends React.Component {
constructor() {
super()
this.sortChange = this.sortChange.bind(this)
this.state = {
sorting: [],
page: 0,
pageSize: 10
}
}
sortChange(column, shift) {
if(shift)
alert('Shift click not implemented in this demo')
var sort = {id: column.id}
if(this.state.sorting.length && this.state.sorting[0].id == column.id)
this.state.sorting[0].asc ? sort.desc = true : sort.asc = true
else
sort.asc = true
this.setState({
sorting: [sort]
})
}
render() {
return (
<ReactTable
className='-striped -highlight'
data={data}
columns={columns}
sorting={this.state.sorting}
onSortingChange={this.sortChange}
page={this.state.page}
onPageChange={page => this.setState({page})}
pageSize={this.state.pageSize}
onPageSizeChange={(pageSize, page) => this.setState({page, pageSize})}
/>
)
}
}`
}
export default () => <ControlledTable />
+21 -79
View File
@@ -7,7 +7,7 @@ import ReactTable from '../src/index'
class Filtering extends React.Component {
constructor (props) {
constructor(props) {
super(props)
const data = _.map(_.range(5553), d => {
@@ -33,10 +33,10 @@ class Filtering extends React.Component {
data: data
}
this.setTableOption = this.setTableOption.bind(this)
this.setTableOption = this.setTableOption.bind(this);
}
render () {
render() {
const columns = [{
header: 'Name',
columns: [{
@@ -54,51 +54,26 @@ class Filtering extends React.Component {
columns: [{
header: 'Age',
accessor: 'age'
}, {
header: 'Over 21',
accessor: 'age',
id: 'over',
render: ({value}) => (value >= 21 ? 'Yes' : 'No'),
filterMethod: (filter, row) => {
if (filter.value === 'all') {
return true
}
if (filter.value === 'true') {
return row[filter.id] >= 21
}
return row[filter.id] < 21
},
filterRender: ({filter, onFilterChange}) => (
<select
onChange={event => onFilterChange(event.target.value)}
style={{width: '100%'}}
value={filter ? filter.value : 'all'}>
<option value="all"></option>
<option value="true">Can Drink</option>
<option value="false">Can't Drink</option>
</select>
)
}
]
}]
}]
return (
<div>
<div style={{float: 'left'}}>
<div style={{float: "left"}}>
<h1>Table Options</h1>
<table>
<tbody>
{
Object.keys(this.state.tableOptions).map(optionKey => {
const optionValue = this.state.tableOptions[optionKey]
const optionValue = this.state.tableOptions[optionKey];
return (
<tr key={optionKey}>
<td>{optionKey}</td>
<td style={{paddingLeft: 10, paddingTop: 5}}>
<input type="checkbox"
name={optionKey}
checked={optionValue}
onChange={this.setTableOption}
name={optionKey}
checked={optionValue}
onChange={this.setTableOption}
/>
</td>
</tr>
@@ -114,7 +89,7 @@ class Filtering extends React.Component {
data={this.state.data}
columns={columns}
defaultPageSize={10}
defaultFilterMethod={(filter, row) => (String(row[filter.id]) === filter.value)}
defaultFilterMethod={(filter, row) => ((row[filter.id] + "").startsWith(filter.value))}
{...this.state.tableOptions}
SubComponent={(row) => {
return (
@@ -147,30 +122,21 @@ class Filtering extends React.Component {
</div>
<div>
<h1>Custom Filters In This Example</h1>
<p>The default filter for all columns of a table if it is not specified in the configuration is set to match
on values that start with the filter text. Example: age.startsWith("2").</p>
<p>This example overrides the default filter behavior by setting
the <strong>defaultFilterMethod</strong> table option to match on values that are exactly equal to the
filter text. Example: age == "23")</p>
<p>The default filter for all columns of a table if it is not specified in the configuration is set to be an exact match. Example: age == "23".</p>
<p>This example overrides the default filter behavior by setting the <strong>defaultFilterMethod</strong> table option to match on values that start with the filter text. Example: age.startsWith("2")</p>
<p>Each column can also be customized with the column <strong>filterMethod</strong> option:</p>
<p>In this example the firstName column filters on the value starting with and ending with the filter
value.</p>
<p>In this example the lastName column filters on the value including the filter value anywhere in its
text.</p>
<p>To completely override the filter that is shown, you can set the <strong>filterRender</strong> column
option. Using this option you can specify the JSX that is shown. The option is passed
an <strong>onFilterChange</strong> method that must be called with the value that you wan't to
pass to the <strong>filterMethod</strong> option whenever the filter has changed.</p>
<p>In this example the firstName column filters on the value starting with and ending with the filter value.</p>
<p>In this example the lastName column filters on the value including the filter value anywhere in its text.</p>
</div>
<CodeHighlight>{() => this.getCode()}</CodeHighlight>
</div>
)
}
setTableOption (event) {
const target = event.target
const value = target.type === 'checkbox' ? target.checked : target.value
const name = target.name
setTableOption(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
tableOptions: {
...this.state.tableOptions,
@@ -179,7 +145,7 @@ class Filtering extends React.Component {
})
}
getCode () {
getCode() {
return `
const columns = [{
header: 'Name',
@@ -198,30 +164,6 @@ const columns = [{
columns: [{
header: 'Age',
accessor: 'age'
}, {
header: 'Over 21',
accessor: 'age',
id: 'over',
render: ({value}) => (value >= 21 ? 'Yes' : 'No'),
filterMethod: (filter, row) => {
if (filter.value === 'all') {
return true
}
if (filter.value === 'true') {
return row[filter.id] >= 21
}
return row[filter.id] < 21
},
filterRender: ({filter, onFilterChange}) => (
<select
onChange={event => onFilterChange(event.target.value)}
style={{width: '100%'}}
value={filter ? filter.value : 'all'}>
<option value="all"></option>
<option value="true">Can Drink</option>
<option value="false">Can't Drink</option>
</select>
)
}]
}]
@@ -230,7 +172,7 @@ export default (
data={data}
columns={columns}
defaultPageSize={10}
defaultFilterMethod={(filter, row) => (String(row[filter.id]) === filter.value)}
defaultFilterMethod={(filter, row) => ((row[filter.id] + \"\").startsWith(filter.value))}
{...otherOptions}
SubComponent={(row) => {
return (
@@ -261,4 +203,4 @@ export default (
}
}
export default () => <Filtering />
export default () => <Filtering/>
+3 -32
View File
@@ -88,52 +88,23 @@ const columns = [{
header: 'Name',
columns: [{
header: 'First Name',
accessor: 'firstName',
footer: (
<span><strong>Popular:</strong> {
_.first(
_.reduce(
_.map(
_.groupBy(
data, d => d.firstName
)
),
(a, b) => a.length > b.length ? a : b
)
).firstName}
</span>
)
accessor: 'firstName'
}, {
header: 'Last Name',
id: 'lastName',
accessor: d => d.lastName,
footer: (
<span><strong>Longest:</strong> {
_.reduce(
_.map(
_.groupBy(
data, d => d.lastName
),
(d, key) => key
),
(a, b) => a.length > b.length ? a : b
)}
</span>
)
accessor: d => d.lastName
}]
}, {
header: 'Info',
columns: [{
header: 'Age',
accessor: 'age',
footer: <span><strong>Average:</strong> {_.round(_.mean(_.map(data, d => d.age)))}</span>
accessor: 'age'
}]
}]
// Display your table!
return (
<ReactTable
className='-striped -highlight'
data={data}
columns={columns}
defaultPageSize={10}
+2 -4
View File
@@ -38,8 +38,7 @@ export default () => {
}, {
header: 'Visits',
accessor: 'visits',
aggregate: vals => _.sum(vals),
hideFilter: true
aggregate: vals => _.sum(vals)
}]
}]
@@ -112,8 +111,7 @@ const columns = [{
}, {
header: 'Visits',
accessor: 'visits',
aggregate: vals => _.sum(vals),
hideFilter: true
aggregate: vals => _.sum(vals)
}]
}]
+3 -3
View File
@@ -18,13 +18,13 @@ const requestData = (pageSize, page, sorting, filtering) => {
return new Promise((resolve, reject) => {
// On the server, you'll likely use SQL or noSQL or some other query language to do this.
// For this mock, we'll just use lodash
let filteredData = rawData;
let filteredData = rawData
if (filtering.length) {
filteredData = filtering.reduce(
(filteredSoFar, nextFilter) => {
return filteredSoFar.filter(
(row) => {
return (row[nextFilter.id]+"").includes(nextFilter.value)
return (row[nextFilter.id] + '').includes(nextFilter.value)
})
}
, filteredData)
@@ -93,7 +93,7 @@ const ServerSide = React.createClass({
}]}
manual // Forces table not to paginate or sort automatically, so we can handle it server-side
defaultPageSize={10}
showFilters={true}
showFilters
data={this.state.data} // Set the rows to be displayed
pages={this.state.pages} // Display the total number of pages
loading={this.state.loading} // Display the loading overlay when we need it
-1
View File
@@ -77,7 +77,6 @@ const columns = [{
// Display your table!
return (
<ReactTable
className='-striped -highlight'
data={data}
columns={columns}
defaultPageSize={10}