mirror of
https://github.com/gosticks/react-table.git
synced 2026-08-19 08:20:30 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
085616d858 | ||
|
|
25ef0b2273 | ||
|
|
1fef30311c | ||
|
|
5351f79293 | ||
|
|
0bb3f2421e | ||
|
|
c392c90eb6 | ||
|
|
fc5cc00fce | ||
|
|
a8c8211ef8 | ||
|
|
8bff135119 | ||
|
|
e930d834c6 | ||
|
|
7700f6a1a0 | ||
|
|
7a941b880f | ||
|
|
2e143e8d27 | ||
|
|
ee2345f43c | ||
|
|
e3129a2c80 | ||
|
|
1f943ffe25 | ||
|
|
c854c6914d | ||
|
|
80cef0d4c6 | ||
|
|
302eb3d951 | ||
|
|
4af3637c0b | ||
|
|
4a18536da7 | ||
|
|
850f659309 | ||
|
|
0409463052 | ||
|
|
66afd8cded | ||
|
|
5aa764de03 | ||
|
|
2af8f75de9 | ||
|
|
5615c43b29 |
@@ -0,0 +1,4 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "6"
|
||||
script: npm test
|
||||
@@ -1,7 +1,10 @@
|
||||

|
||||
|
||||
# react-table
|
||||
A fast, lightweight, opinionated table and datagrid built on React
|
||||
|
||||
[](https://react-table-slack.herokuapp.com/)
|
||||
[](https://travis-ci.org/tannerlinsley/react-table)
|
||||
[](https://react-table-slack.herokuapp.com/)
|
||||
|
||||
## Features
|
||||
|
||||
@@ -9,24 +12,31 @@ A fast, lightweight, opinionated table and datagrid built on React
|
||||
- No composition needed
|
||||
- Uses customizable JSX and callbacks for everything
|
||||
- Client-side pagination and sorting
|
||||
- Server-side support
|
||||
- Server-side data
|
||||
- Minimal design & easily themeable
|
||||
|
||||
Why you may **not** want to use this component:
|
||||
- No support for infinite scrolling. We chose to avoid the complex problems that come with it, and instead provide reliable and predictable pagination.
|
||||
- You need tables built in something other than traditional HTML table elements.
|
||||
|
||||
## [Demo](http://react-table.zabapps.com)
|
||||
|
||||
## Table of Contents
|
||||
- [Installation](#nstallation)
|
||||
- [Example](#example)
|
||||
- [Data](#data)
|
||||
- [Default Props](#default-props)
|
||||
- [Columns](#columns)
|
||||
- [Styles](#styles)
|
||||
- [Header Groups](#header-groups)
|
||||
- [Server-side Data](#server-side-data)
|
||||
- [Multi-sort](#multi-sort)
|
||||
- [Component Overrides](#component-overrides)
|
||||
|
||||
<a name="installation"></a>
|
||||
## Installation
|
||||
```bash
|
||||
$ npm install react-table
|
||||
```
|
||||
|
||||
#### Styles
|
||||
React-table is built to be dropped into existing applications or styled from the ground up, but if you'd like a decent starting point, you can optionally include our default theme `react-table.css`. We think it looks great, honestly :)
|
||||
|
||||
## Quick Usage
|
||||
<a name="example"></a>
|
||||
## Example
|
||||
```javascript
|
||||
import ReactTable from 'react-table'
|
||||
|
||||
@@ -61,9 +71,128 @@ const columns = [{
|
||||
/>
|
||||
```
|
||||
|
||||
## Client-side Data
|
||||
To use client-side data, simply pass the `data` prop an array. Client-side filtering and pagination is built in, and your table will update gracefully if you change any props.
|
||||
<a name="data"></a>
|
||||
## Data
|
||||
Every React-Table instance requires you to set the `data` prop. To use client-side data, simply pass the `data` prop anything that resembles an array or object. Client-side filtering and pagination is built in, and your table will update gracefully if you change any props. [Server-side data](#server-side-data) is also supported.
|
||||
|
||||
|
||||
<a name="default-props"></a>
|
||||
## Default Props
|
||||
These are the default props for the main react component `<ReactTable />`
|
||||
```javascript
|
||||
{
|
||||
// Classes
|
||||
className: '-striped -highlight', // The most top level className for the component
|
||||
tableClassName: '', // ClassName for the `table` element
|
||||
theadClassName: '', // ClassName for the `thead` element
|
||||
tbodyClassName: '', // ClassName for the `tbody` element
|
||||
trClassName: '', // ClassName for all `tr` elements
|
||||
trClassCallback: row => null, // A call back to dynamically add classes (via the classnames module) to a row element
|
||||
paginationClassName: '' // ClassName for `pagination` element
|
||||
// Styles
|
||||
style: {}, // Main style object for the component
|
||||
tableStyle: {}, // style object for the `table` component
|
||||
theadStyle: {}, // style object for the `thead` component
|
||||
tbodyStyle: {}, // style object for the `tbody` component
|
||||
trStyle: {}, // style object for the `tr` component
|
||||
trStyleCallback: row => {}, // A call back to dynamically add styles to a row element
|
||||
thStyle: {}, // style object for the `th` component
|
||||
tdStyle: {}, // style object for the `td` component
|
||||
paginationStyle: {}, // style object for the `paginination` component
|
||||
//
|
||||
pageSize: 20,
|
||||
minRows: 0, // Ensure this many rows are always rendered, regardless of rows on page
|
||||
// Global Column Defaults
|
||||
column: { // default properties for every column's model
|
||||
sortable: true,
|
||||
show: true
|
||||
},
|
||||
// Text
|
||||
previousText: 'Previous',
|
||||
nextText: 'Next'
|
||||
}
|
||||
```
|
||||
|
||||
You can easily override the core defaults like so:
|
||||
|
||||
```javascript
|
||||
import { ReactTableDefaults } from 'react-table'
|
||||
|
||||
Object.assign(ReactTableDefaults, {
|
||||
pageSize: 10,
|
||||
minRows: 3,
|
||||
// etc...
|
||||
})
|
||||
```
|
||||
|
||||
Or just define them on the component per-instance
|
||||
|
||||
```javascript
|
||||
<ReactTable
|
||||
pageSize={10}
|
||||
minRows={3}
|
||||
// etc...
|
||||
/>
|
||||
```
|
||||
|
||||
<a name="columns"></a>
|
||||
## Columns
|
||||
Every React-Table instance requires a `columns` prop, which is an array of objects containing the following properties
|
||||
|
||||
```javascript
|
||||
[{
|
||||
// General
|
||||
accessor: 'propertyName' or Accessor eg. (row) => row.propertyName,
|
||||
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,
|
||||
sort: 'asc' or 'desc',
|
||||
show: true,
|
||||
minWidth: Number // Allows the column to flex above this minimum amount
|
||||
|
||||
// Cell Options
|
||||
className: '', // Set the classname of the `td` element of the column
|
||||
style: {}, // Set the style of the `td` element of the column
|
||||
innerClassName: '', // Set the classname of the `.-td-inner` element of the column
|
||||
innerStyle: {}, // Set the style of the `.-td-inner` element of the column
|
||||
render: JSX eg. ({row, value, index, viewIndex}) => <span>{value}</span>, // Provide a JSX element or stateless function to render whatever you want as the column's cell with access to the entire row
|
||||
|
||||
// Header & HeaderGroup Options
|
||||
header: 'Header Name' or JSX 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
|
||||
headerInnerClassName: '', // Set the classname of the `.-th-inner` element of the column
|
||||
headerInnerStyle: {}, // Set the style of the `.th-inner` element of the column
|
||||
|
||||
// Header Groups only
|
||||
columns: [...] // See Header Groups section below
|
||||
|
||||
}]
|
||||
```
|
||||
|
||||
<a name="styles"></a>
|
||||
## Styles
|
||||
React-table is built to be dropped into existing applications or styled from the ground up, but if you'd like a decent starting point, you can optionally include our default theme `react-table.css`. We think it looks great, honestly :)
|
||||
|
||||
<a name="header-groups"></a>
|
||||
## Header Groups
|
||||
To group columns with another header column, just nest your columns in a header column like so:
|
||||
```javascript
|
||||
const columns = [{
|
||||
header: 'Favorites',
|
||||
columns: [{
|
||||
header: 'Color',
|
||||
accessor: 'favorites.color'
|
||||
}, {
|
||||
header: 'Food',
|
||||
accessor: 'favorites.food'
|
||||
} {
|
||||
header: 'Actor',
|
||||
accessor: 'favorites.actor'
|
||||
}]
|
||||
}]
|
||||
```
|
||||
|
||||
<a name="server-side-data"></a>
|
||||
## Server-side Data
|
||||
If you want to handle pagination, and sorting on the server, `react-table` makes it easy on you. Instead of passing the `data` prop an array, you provide a function instead.
|
||||
|
||||
@@ -106,104 +235,56 @@ This function will be called on mount, pagination events, and sorting events. It
|
||||
/>
|
||||
```
|
||||
|
||||
<a name="multi-sort"></a>
|
||||
## Multi-Sort
|
||||
When clicking on a column header, hold shift to multi-sort! You can toggle `aascending` `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!
|
||||
|
||||
## Default Props
|
||||
```javascript
|
||||
{
|
||||
className: '-striped -highlight',
|
||||
pageSize: 20,
|
||||
minRows: 0,
|
||||
data: [],
|
||||
previousComponent: <button {...props} className='-btn'>{props.children}</button>,
|
||||
nextComponent: <button {...props} className='-btn'>{props.children}</button>,
|
||||
previousText: 'Previous',
|
||||
nextText: 'Next',
|
||||
loadingComponent: <span>Loading...</span>,
|
||||
column: { // default properties for every column's model
|
||||
sortable: true,
|
||||
show: true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can easily override the core defaults like so:
|
||||
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!
|
||||
|
||||
<a name="component-overrides"></a>
|
||||
## Component Overrides
|
||||
Though we wouldn't suggest it, `react-table` has the ability to change the core componentry it used to render it's table. You can do so by assigning a react component to it's corresponding global prop, or on a one-off basis like so:
|
||||
```javascript
|
||||
// Change the global default
|
||||
import { ReactTableDefaults } from 'react-table'
|
||||
|
||||
Object.assign(ReactTableDefaults, {
|
||||
pageSize: 10,
|
||||
minRows: 3,
|
||||
// etc...
|
||||
tableComponent: Component,
|
||||
theadComponent: Component,
|
||||
tbodyComponent: Component,
|
||||
trComponent: Component,
|
||||
thComponent: Component,
|
||||
tdComponent: Component,
|
||||
paginationComponent: Component,
|
||||
previousComponent: Component,
|
||||
nextComponent: Component,
|
||||
loadingComponent: Component
|
||||
})
|
||||
```
|
||||
|
||||
Or just define them on the component
|
||||
|
||||
```javascript
|
||||
// Or change per instance
|
||||
<ReactTable
|
||||
pageSize={10}
|
||||
minRows={3}
|
||||
tableComponent={Component},
|
||||
theadComponent={Component},
|
||||
// etc...
|
||||
})
|
||||
/>
|
||||
```
|
||||
|
||||
## Column Props
|
||||
If you choose to change the core components React-Table uses to render, you must make sure your components support and utilized all of the neeeded features for that component to work properly. For a broad reference on how to do this, investigate [the source](https://github.com/tannerlinsley/react-table/blob/master/src/index.js) for the component you wish to replace.
|
||||
|
||||
```javascript
|
||||
[{
|
||||
// Required
|
||||
header: 'Header Name' or JSX eg. ({data, column}) => <div>Header Name</div>,
|
||||
accessor: 'propertyName' or Accessor eg. (row) => row.propertyName,
|
||||
|
||||
// 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
|
||||
id: 'myProperty',
|
||||
|
||||
// Optional
|
||||
columns: [...] // See Header Groups section below
|
||||
render: JSX eg. ({row, value, index}) => <span>{value}</span>, // Provide a JSX element or stateless function to render whatever you want as the column's cell with access to the entire row
|
||||
sortable: true,
|
||||
sort: 'asc' or 'desc',
|
||||
show: true,
|
||||
width: Number, // Locks the column width to this amount
|
||||
minWidth: Number // Allows the column to flex above this minimum amount
|
||||
}]
|
||||
```
|
||||
|
||||
## Header Groups
|
||||
To group columns with another header column, just nest your columns in a header column like so:
|
||||
```javascript
|
||||
const columns = [{
|
||||
header: 'Favorites',
|
||||
columns: [{
|
||||
header: 'Color',
|
||||
accessor: 'favorites.color'
|
||||
}, {
|
||||
header: 'Food',
|
||||
accessor: 'favorites.food'
|
||||
} {
|
||||
header: 'Actor',
|
||||
accessor: 'favorites.actor'
|
||||
}]
|
||||
}]
|
||||
```
|
||||
|
||||
## Contributing
|
||||
To suggest a feature, create an issue if it does not already exist.
|
||||
If you would like to help develop a suggested feature follow these steps:
|
||||
|
||||
- Fork this repo
|
||||
- Run `npm install`
|
||||
- Run `npm watch`
|
||||
- `npm install`
|
||||
- `npm watch`
|
||||
- Implement your changes to files in the `src/` directory
|
||||
- Submit PR for review
|
||||
|
||||
If you would like to preview your changes, you can utilize the example like so:
|
||||
If you would like to preview your changes, you can link and utilize the example like so:
|
||||
|
||||
- `npm link`
|
||||
- `cd example`
|
||||
- Run `npm install`
|
||||
- Run `npm watch`
|
||||
- `npm install`
|
||||
- `npm link react-table`
|
||||
- `npm watch`
|
||||
- Make changes to the example in `src/screens/index.js` if needed
|
||||
- View changes at `localhost:8000`
|
||||
|
||||
Vendored
BIN
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
Vendored
+18
-9
@@ -100,12 +100,7 @@ html {
|
||||
min-height: 100vh;
|
||||
}
|
||||
body {
|
||||
background: #003952;
|
||||
background: -webkit-radial-gradient(ellipse at center, #005275 0%, #003952 100%);
|
||||
background: -moz-radial-gradient(ellipse at center, #005275 0%, #003952 100%);
|
||||
background: -o-radial-gradient(ellipse at center, #005275 0%, #003952 100%);
|
||||
background: -ms-radial-gradient(ellipse at center, #005275 0%, #003952 100%);
|
||||
background: radial-gradient(ellipse at center, #005275 0%, #003952 100%);
|
||||
background: #fff;
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
font-weight: 300;
|
||||
padding-bottom: 50px;
|
||||
@@ -115,12 +110,16 @@ h1 {
|
||||
color: #fff;
|
||||
}
|
||||
a {
|
||||
color: #fff;
|
||||
color: #02bfe6;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
}
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
.logo {
|
||||
width: 400px;
|
||||
}
|
||||
.container {
|
||||
display: -webkit-box;
|
||||
display: -moz-box;
|
||||
@@ -151,12 +150,22 @@ strong {
|
||||
}
|
||||
.container .github-addon {
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
padding: 10px;
|
||||
}
|
||||
.container .table-wrap {
|
||||
background: #fff;
|
||||
width: 700px;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
-webkit-box-shadow: 0 0 20px 0 rgba(0,0,0,0.2);
|
||||
box-shadow: 0 0 20px 0 rgba(0,0,0,0.2);
|
||||
}
|
||||
.ReactTable thead th.-sort-asc,
|
||||
.ReactTable thead td.-sort-asc {
|
||||
-webkit-box-shadow: inset 0 3px 0 0 rgba(0,0,0,0.6);
|
||||
box-shadow: inset 0 3px 0 0 rgba(0,0,0,0.6);
|
||||
}
|
||||
.ReactTable thead th.-sort-desc,
|
||||
.ReactTable thead td.-sort-desc {
|
||||
-webkit-box-shadow: inset 0 -3px 0 0 rgba(0,0,0,0.6);
|
||||
box-shadow: inset 0 -3px 0 0 rgba(0,0,0,0.6);
|
||||
}
|
||||
|
||||
Vendored
+661
-23
File diff suppressed because one or more lines are too long
+17
-8
@@ -18,9 +18,7 @@ global-reset()
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
$fnt-open-sans = 'Open Sans', sans-serif
|
||||
$clr-jumpsuit1 = #003952
|
||||
$clr-jumpsuit2 = #005275
|
||||
$clr-jumpsuit3 = #0082bb
|
||||
$react = #25d8fd
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// styles
|
||||
@@ -33,8 +31,7 @@ html
|
||||
min-height 100vh
|
||||
|
||||
body
|
||||
background: $clr-jumpsuit1
|
||||
background: radial-gradient(ellipse at center, $clr-jumpsuit2 0%, $clr-jumpsuit1 100%)
|
||||
background: white
|
||||
font-family: $fnt-open-sans
|
||||
font-weight: 300
|
||||
padding-bottom: 50px
|
||||
@@ -44,12 +41,16 @@ h1
|
||||
color: white
|
||||
|
||||
a
|
||||
color: white
|
||||
color: darken($react, 20%)
|
||||
font-weight: bold
|
||||
text-decoration: none
|
||||
|
||||
strong
|
||||
font-weight: bold
|
||||
|
||||
.logo
|
||||
width: 400px
|
||||
|
||||
.container
|
||||
display: flex
|
||||
flex-direction: column
|
||||
@@ -60,11 +61,19 @@ strong
|
||||
|
||||
.github-addon
|
||||
font-size: 20px
|
||||
color:white
|
||||
padding: 10px
|
||||
|
||||
.table-wrap
|
||||
background: white
|
||||
width: 700px
|
||||
padding: 10px
|
||||
border-radius: 5px
|
||||
box-shadow: 0 0 20px 0 alpha(black, .2)
|
||||
|
||||
.ReactTable
|
||||
thead
|
||||
th
|
||||
td
|
||||
&.-sort-asc
|
||||
box-shadow:inset 0 3px 0 0 alpha(black, .6)
|
||||
&.-sort-desc
|
||||
box-shadow:inset 0 -3px 0 0 alpha(black, .6)
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
@@ -34,14 +34,18 @@ export default Component({
|
||||
return (
|
||||
<div className='container'>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<h1>react-table <strong>demo</strong></h1>
|
||||
<h1>
|
||||
<span style={{position: 'absolute', textIndent: '-9999em'}}>
|
||||
react-table <strong>demo</strong>
|
||||
</span>
|
||||
<img src='/Banner.png' className='logo' />
|
||||
</h1>
|
||||
<br />
|
||||
<div>
|
||||
<a
|
||||
className='github-button'
|
||||
href='https://github.com/tannerlinsley/react-table'
|
||||
target='_blank'
|
||||
data-icon='octicon-star'
|
||||
data-style='mega'
|
||||
data-count-href='/tannerlinsley/react-table/stargazers'
|
||||
data-count-api='/repos/tannerlinsley/react-table#stargazers_count'
|
||||
@@ -50,6 +54,7 @@ export default Component({
|
||||
Star
|
||||
</a>
|
||||
</div>
|
||||
<br />
|
||||
<div className='github-addon'>
|
||||
<a
|
||||
target='_blank'
|
||||
@@ -66,9 +71,9 @@ export default Component({
|
||||
columns={columns}
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center', color: 'white'}}>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<br />
|
||||
<em>Tip: Hold shift when sorting for multi-sort!</em>
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
+709
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
Binary file not shown.
+18
-7
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-table",
|
||||
"version": "2.0.1",
|
||||
"version": "2.2.0",
|
||||
"description": "A fast, lightweight, opinionated table and datagrid built on React",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/tannerlinsley/react-table#readme",
|
||||
@@ -14,16 +14,20 @@
|
||||
"react-table",
|
||||
"datagrid"
|
||||
],
|
||||
"main": "react-table.js",
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
"build:js": "rm -rf react-table.js && browserify src/index.js -s reactTable -u react -t babelify -g uglifyify -o react-table.js",
|
||||
"build:node": "babel src --out-dir lib --source-maps inline",
|
||||
"build:css": "rm -rf react-table.css && stylus src/index.styl --use ./node_modules/nib/lib/nib.js --compress -o react-table.css",
|
||||
"watch": "onchange 'src/**' -i -- npm-run-all build:*",
|
||||
"prepublish": "npm-run-all build:*"
|
||||
"test": "standard",
|
||||
"umd": "rm -rf react-table.js && browserify lib/index.js -s reactTable -x react -t babelify -g uglifyify -o react-table.js",
|
||||
"prepublish": "npm-run-all build:* && npm run umd",
|
||||
"postpublish": "git push --tags"
|
||||
},
|
||||
"dependencies": {
|
||||
"classnames": "^2.2.5",
|
||||
"lodash": "^4.16.4",
|
||||
"classnames": "^2.2.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^15.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -34,16 +38,23 @@
|
||||
"babel-preset-stage-2": "6.13.0",
|
||||
"babelify": "^7.3.0",
|
||||
"browserify": "13.1.0",
|
||||
"nib": "^1.1.2",
|
||||
"npm-run-all": "^3.1.1",
|
||||
"onchange": "^3.0.2",
|
||||
"react": "15.3.1",
|
||||
"standard": "8.0.0",
|
||||
"stylus": "^0.54.5",
|
||||
"uglifyify": "3.0.3"
|
||||
},
|
||||
"browserify-shim": {
|
||||
"react": "global:React"
|
||||
},
|
||||
"standard": {
|
||||
"parser": "babel-eslint",
|
||||
"ignore": [
|
||||
"node_modules",
|
||||
"dist",
|
||||
"lib",
|
||||
"example",
|
||||
"react-table.js"
|
||||
]
|
||||
},
|
||||
|
||||
Vendored
+4
-4
File diff suppressed because one or more lines are too long
+168
-70
@@ -16,19 +16,58 @@ const defaultButton = (props) => (
|
||||
)
|
||||
|
||||
export const ReactTableDefaults = {
|
||||
// Classes
|
||||
className: '-striped -highlight',
|
||||
tableClassName: '',
|
||||
theadClassName: '',
|
||||
tbodyClassName: '',
|
||||
trClassName: '',
|
||||
trClassCallback: d => null,
|
||||
thClassName: '',
|
||||
thGroupClassName: '',
|
||||
tdClassName: '',
|
||||
paginationClassName: '',
|
||||
// Styles
|
||||
style: {},
|
||||
tableStyle: {},
|
||||
theadStyle: {},
|
||||
tbodyStyle: {},
|
||||
trStyle: {},
|
||||
trStyleCallback: d => {},
|
||||
thStyle: {},
|
||||
tdStyle: {},
|
||||
paginationStyle: {},
|
||||
//
|
||||
pageSize: 20,
|
||||
minRows: 0,
|
||||
data: [],
|
||||
previousComponent: defaultButton,
|
||||
nextComponent: defaultButton,
|
||||
previousText: 'Previous',
|
||||
nextText: 'Next',
|
||||
loadingComponent: <span>Loading...</span>,
|
||||
// Global Column Defaults
|
||||
column: {
|
||||
sortable: true,
|
||||
show: true
|
||||
}
|
||||
show: true,
|
||||
className: '',
|
||||
style: {},
|
||||
innerClassName: '',
|
||||
innerStyle: {},
|
||||
headerClassName: '',
|
||||
headerStyle: {},
|
||||
headerInnerClassName: '',
|
||||
headerInnerStyle: {}
|
||||
},
|
||||
// Text
|
||||
previousText: 'Previous',
|
||||
nextText: 'Next',
|
||||
loadingText: 'Loading...',
|
||||
// Components
|
||||
tableComponent: (props) => <table {...props}>{props.children}</table>,
|
||||
theadComponent: (props) => <thead {...props}>{props.children}</thead>,
|
||||
tbodyComponent: (props) => <tbody {...props}>{props.children}</tbody>,
|
||||
trComponent: (props) => <tr {...props}>{props.children}</tr>,
|
||||
thComponent: (props) => <th {...props}>{props.children}</th>,
|
||||
tdComponent: (props) => <td {...props}>{props.children}</td>,
|
||||
previousComponent: null,
|
||||
nextComponent: null,
|
||||
// Unlisted
|
||||
data: []
|
||||
}
|
||||
|
||||
export default React.createClass({
|
||||
@@ -79,17 +118,20 @@ export default React.createClass({
|
||||
}
|
||||
const makeDecoratedColumn = (column) => {
|
||||
const dcol = Object.assign({}, this.props.column, column)
|
||||
|
||||
if (typeof dcol.accessor === 'string') {
|
||||
dcol.id = dcol.id || dcol.accessor
|
||||
const accessorString = dcol.accessor
|
||||
dcol.accessor = row => _.get(row, accessorString)
|
||||
return dcol
|
||||
}
|
||||
if (!dcol.id) {
|
||||
console.warn('No column ID found for column: ', dcol)
|
||||
}
|
||||
if (!dcol.accessor) {
|
||||
console.warn('No column accessor found for column: ', dcol)
|
||||
|
||||
if (dcol.accessor && !dcol.id) {
|
||||
console.warn(dcol)
|
||||
throw new Error('A column id is required if using a non-string accessor for column above.')
|
||||
}
|
||||
|
||||
dcol.accessor = d => undefined
|
||||
return dcol
|
||||
}
|
||||
|
||||
@@ -179,9 +221,10 @@ export default React.createClass({
|
||||
}
|
||||
},
|
||||
accessData (data) {
|
||||
return data.map((d) => {
|
||||
return data.map((d, i) => {
|
||||
const row = {
|
||||
__original: d
|
||||
__original: d,
|
||||
__index: i
|
||||
}
|
||||
this.decoratedColumns.forEach(column => {
|
||||
row[column.id] = column.accessor(d)
|
||||
@@ -223,22 +266,46 @@ export default React.createClass({
|
||||
const canPrevious = this.state.page > 0
|
||||
const canNext = this.state.page + 1 < pagesLength
|
||||
|
||||
const PreviousComponent = this.props.previousComponent
|
||||
const NextComponent = this.props.previousComponent
|
||||
const TableComponent = this.props.tableComponent
|
||||
const TheadComponent = this.props.theadComponent
|
||||
const TbodyComponent = this.props.tbodyComponent
|
||||
const TrComponent = this.props.trComponent
|
||||
const ThComponent = this.props.thComponent
|
||||
const TdComponent = this.props.tdComponent
|
||||
|
||||
const PreviousComponent = this.props.previousComponent || defaultButton
|
||||
const NextComponent = this.props.nextComponent || defaultButton
|
||||
|
||||
return (
|
||||
<div className={classnames(this.props.className, 'ReactTable')}>
|
||||
<table>
|
||||
<div
|
||||
className={classnames(this.props.className, 'ReactTable')}
|
||||
style={this.props.style}
|
||||
>
|
||||
<TableComponent
|
||||
className={classnames(this.props.tableClassName)}
|
||||
style={this.props.tableStyle}
|
||||
>
|
||||
{this.hasHeaderGroups && (
|
||||
<thead className='-headerGroups'>
|
||||
<tr>
|
||||
<TheadComponent
|
||||
className={classnames(this.props.theadGroupClassName, '-headerGroups')}
|
||||
style={this.props.theadStyle}
|
||||
>
|
||||
<TrComponent
|
||||
className={this.props.trClassName}
|
||||
style={this.props.trStyle}
|
||||
>
|
||||
{this.headerGroups.map((column, i) => {
|
||||
return (
|
||||
<th
|
||||
<ThComponent
|
||||
key={i}
|
||||
colSpan={column.columns.length}>
|
||||
colSpan={column.columns.length}
|
||||
className={classnames(this.props.thClassname, column.headerClassName)}
|
||||
style={Object.assign({}, this.props.thStyle, column.headerStyle)}
|
||||
>
|
||||
<div
|
||||
className='-th-inner'>
|
||||
className={classnames(column.headerInnerClassName, '-th-inner')}
|
||||
style={Object.assign({}, this.props.thInnerStyle, column.headerInnerStyle)}
|
||||
>
|
||||
{typeof column.header === 'function' ? (
|
||||
<column.header
|
||||
data={this.props.data}
|
||||
@@ -246,36 +313,46 @@ export default React.createClass({
|
||||
/>
|
||||
) : column.header}
|
||||
</div>
|
||||
</th>
|
||||
</ThComponent>
|
||||
)
|
||||
})}
|
||||
</tr>
|
||||
</thead>
|
||||
</TrComponent>
|
||||
</TheadComponent>
|
||||
)}
|
||||
<thead>
|
||||
<tr>
|
||||
<TheadComponent
|
||||
className={classnames(this.props.theadClassName)}
|
||||
style={this.props.theadStyle}
|
||||
>
|
||||
<TrComponent
|
||||
className={this.props.trClassName}
|
||||
style={this.props.trStyle}
|
||||
>
|
||||
{this.decoratedColumns.map((column, i) => {
|
||||
const sort = this.state.sorting.find(d => d.id === column.id)
|
||||
const show = typeof column.show === 'function' ? column.show() : column.show
|
||||
return (
|
||||
<th
|
||||
<ThComponent
|
||||
key={i}
|
||||
className={classnames(
|
||||
this.props.thClassname,
|
||||
column.headerClassName,
|
||||
sort ? (sort.asc ? '-sort-asc' : '-sort-desc') : '',
|
||||
{
|
||||
'-cursor-pointer': column.sortable,
|
||||
'-hidden': !show
|
||||
}
|
||||
)}
|
||||
style={Object.assign({}, this.props.thStyle, column.headerStyle)}
|
||||
onClick={(e) => {
|
||||
column.sortable && this.sortColumn(column, e.shiftKey)
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className='-th-inner'
|
||||
style={{
|
||||
width: column.width + 'px',
|
||||
className={classnames(column.headerInnerClassName, '-th-inner')}
|
||||
style={Object.assign({}, column.headerInnerStyle, {
|
||||
minWidth: column.minWidth + 'px'
|
||||
}}>
|
||||
})}
|
||||
>
|
||||
{typeof column.header === 'function' ? (
|
||||
<column.header
|
||||
data={this.props.data}
|
||||
@@ -283,72 +360,95 @@ export default React.createClass({
|
||||
/>
|
||||
) : column.header}
|
||||
</div>
|
||||
</th>
|
||||
</ThComponent>
|
||||
)
|
||||
})}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</TrComponent>
|
||||
</TheadComponent>
|
||||
<TbodyComponent
|
||||
className={classnames(this.props.tbodyClassName)}
|
||||
style={classnames(this.props.tbodyStyle)}
|
||||
>
|
||||
{pageRows.map((row, i) => {
|
||||
const rowInfo = {
|
||||
row: row.__original,
|
||||
index: row.__index,
|
||||
viewIndex: i
|
||||
}
|
||||
return (
|
||||
<tr key={i}>
|
||||
<TrComponent
|
||||
key={i}
|
||||
className={classnames(this.props.trClassName, this.props.trClassCallback(rowInfo))}
|
||||
style={Object.assign({}, this.props.trStyle, this.props.trStyleCallback(rowInfo))}
|
||||
>
|
||||
{this.decoratedColumns.map((column, i2) => {
|
||||
const Cell = column.render
|
||||
const show = typeof column.show === 'function' ? column.show() : column.show
|
||||
return (
|
||||
<td
|
||||
className={classnames({hidden: !show})}
|
||||
key={i2}>
|
||||
<TdComponent
|
||||
key={i2}
|
||||
className={classnames(column.className, {hidden: !show})}
|
||||
style={Object.assign({}, this.props.tdStyle, column.style)}
|
||||
>
|
||||
<div
|
||||
className='-td-inner'
|
||||
style={{
|
||||
width: column.width + 'px',
|
||||
className={classnames(column.innerClassName, '-td-inner')}
|
||||
style={Object.assign({}, column.innerStyle, {
|
||||
minWidth: column.minWidth + 'px'
|
||||
}}>
|
||||
})}
|
||||
>
|
||||
{typeof Cell === 'function' ? (
|
||||
<Cell
|
||||
value={row[column.id]}
|
||||
row={row.__original}
|
||||
index={i}
|
||||
{...rowInfo}
|
||||
/>
|
||||
) : typeof Cell !== 'undefined' ? Cell
|
||||
: row[column.id]}
|
||||
</div>
|
||||
</td>
|
||||
</TdComponent>
|
||||
)
|
||||
})}
|
||||
</tr>
|
||||
</TrComponent>
|
||||
)
|
||||
})}
|
||||
{padRows.map((row, i) => {
|
||||
return (
|
||||
<tr key={i}>
|
||||
<TrComponent
|
||||
key={i}
|
||||
className={classnames(this.props.trClassName, '-padRow')}
|
||||
style={this.props.trStyle}
|
||||
>
|
||||
{this.decoratedColumns.map((column, i2) => {
|
||||
const show = typeof column.show === 'function' ? column.show() : column.show
|
||||
return (
|
||||
<td
|
||||
className={classnames({hidden: !show})}
|
||||
key={i2}>
|
||||
<TdComponent
|
||||
key={i2}
|
||||
className={classnames(column.className, {hidden: !show})}
|
||||
style={Object.assign({}, this.props.tdStyle, column.style)}
|
||||
>
|
||||
<div
|
||||
className='-td-inner'
|
||||
style={{
|
||||
width: column.width + 'px',
|
||||
className={classnames(column.innerClassName, '-td-inner')}
|
||||
style={Object.assign({}, column.innerStyle, {
|
||||
minWidth: column.minWidth + 'px'
|
||||
}}> </div>
|
||||
</td>
|
||||
})}
|
||||
> </div>
|
||||
</TdComponent>
|
||||
)
|
||||
})}
|
||||
</tr>
|
||||
</TrComponent>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</TbodyComponent>
|
||||
</TableComponent>
|
||||
{pagesLength > 1 && (
|
||||
<div className='-pagination'>
|
||||
<div
|
||||
className={classnames(this.props.paginationClassName, '-pagination')}
|
||||
style={this.props.paginationStyle}
|
||||
>
|
||||
<div className='-left'>
|
||||
<PreviousComponent
|
||||
onClick={canPrevious && ((e) => this.previousPage(e))}
|
||||
disabled={!canPrevious}>
|
||||
disabled={!canPrevious}
|
||||
>
|
||||
{this.props.previousText}
|
||||
</PreviousComponent>
|
||||
</div>
|
||||
@@ -358,7 +458,8 @@ export default React.createClass({
|
||||
<div className='-right'>
|
||||
<NextComponent
|
||||
onClick={canNext && ((e) => this.nextPage(e))}
|
||||
disabled={!canNext}>
|
||||
disabled={!canNext}
|
||||
>
|
||||
{this.props.nextText}
|
||||
</NextComponent>
|
||||
</div>
|
||||
@@ -366,7 +467,7 @@ export default React.createClass({
|
||||
)}
|
||||
<div className={classnames('-loading', {'-active': this.state.loading})}>
|
||||
<div className='-loading-inner'>
|
||||
{this.props.loadingComponent}
|
||||
{this.props.loadingText}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -417,13 +518,10 @@ export default React.createClass({
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
// ########################################################################
|
||||
// Utils
|
||||
// ########################################################################
|
||||
|
||||
|
||||
function remove (a, b) {
|
||||
return a.filter(function (o, i) {
|
||||
var r = b(o)
|
||||
|
||||
Reference in New Issue
Block a user