mirror of
https://github.com/gosticks/react-table.git
synced 2026-08-19 16:30:21 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62cff3d6bc | ||
|
|
057a815337 |
@@ -22,8 +22,6 @@ import PivotingSubComponents from '../stories/PivotingSubComponents.js'
|
||||
import OneHundredKRows from '../stories/OneHundredKRows.js'
|
||||
import FunctionalRendering from '../stories/FunctionalRendering.js'
|
||||
import CustomExpanderPosition from '../stories/CustomExpanderPosition.js'
|
||||
import NoDataText from '../stories/NoDataText.js'
|
||||
import Footers from '../stories/Footers.js'
|
||||
//
|
||||
configure(() => {
|
||||
storiesOf('1. Docs')
|
||||
@@ -51,6 +49,4 @@ configure(() => {
|
||||
.add('100k Rows w/ Pivoting & Sub Components', OneHundredKRows)
|
||||
.add('Functional Rendering', FunctionalRendering)
|
||||
.add('Custom Expander Position', CustomExpanderPosition)
|
||||
.add('Custom "No Data" Text', NoDataText)
|
||||
.add('Footers', Footers)
|
||||
}, module)
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
body{
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
@@ -24,9 +24,6 @@
|
||||
<a href="https://twitter.com/tannerlinsley" target="\_parent">
|
||||
<img alt="" src="https://img.shields.io/twitter/follow/tannerlinsley.svg?style=social&label=Follow" />
|
||||
</a>
|
||||
<a href="https://cash.me/$tannerlinsley" target="\_parent">
|
||||
<img alt="" src="https://img.shields.io/badge/%24-Donate-brightgreen.svg" />
|
||||
</a>
|
||||
|
||||
## Features
|
||||
|
||||
@@ -47,11 +44,11 @@
|
||||
- [Props](#props)
|
||||
- [Columns](#columns)
|
||||
- [Column Header Groups](#column-header-groups)
|
||||
- [Custom Cell and Header Rendering](#custom-cell-and-header-rendering)
|
||||
- [Custom Cell & Header Rendering](#custom-cell--and-header-rendering)
|
||||
- [Styles](#styles)
|
||||
- [Custom Props](#custom-props)
|
||||
- [Pivoting and Aggregation](#pivoting-and-aggregation)
|
||||
- [Sub Tables and Sub Components](#sub-tables-and-sub-components)
|
||||
- [Pivoting & Aggregation](#pivoting--aggregation)
|
||||
- [Sub Tables & Sub Components](#sub-tables--sub-components)
|
||||
- [Server-side Data](#server-side-data)
|
||||
- [Fully Controlled Component](#fully-controlled-component)
|
||||
- [Functional Rendering](#functional-rendering)
|
||||
@@ -102,11 +99,11 @@ const data = [{
|
||||
|
||||
const columns = [{
|
||||
header: 'Name',
|
||||
accessor: 'name' // String-based value accessors!
|
||||
accessor: 'name' // String-based value accessors !
|
||||
}, {
|
||||
header: 'Age',
|
||||
accessor: 'age',
|
||||
render: props => <span className='number'>{props.value}</span> // Custom cell components!
|
||||
render: props => <span className='number'>props.value</span> // Custom cell components!
|
||||
}, {
|
||||
header: 'Friend Name',
|
||||
accessor: d => d.friend.name // Custom value accessors!
|
||||
@@ -138,10 +135,6 @@ These are all of the available props (and their default values) for the main `<R
|
||||
defaultPageSize: 20,
|
||||
showPageJump: true,
|
||||
expanderColumnWidth: 35,
|
||||
collapseOnSortingChange: false,
|
||||
collapseOnPageChange: true,
|
||||
freezeWhenExpanded: false,
|
||||
defaultSorting: [],
|
||||
|
||||
// Controlled State Overrides (see Fully Controlled Component section)
|
||||
page: undefined,
|
||||
@@ -188,12 +181,8 @@ These are all of the available props (and their default values) for the main `<R
|
||||
getTrProps: () => ({}),
|
||||
getThProps: () => ({}),
|
||||
getTdProps: () => ({}),
|
||||
getTfootProps: () => ({}),
|
||||
getTfootTrProps: () => ({}),
|
||||
getTfootThProps: () => ({}),
|
||||
getPaginationProps: () => ({}),
|
||||
getLoadingProps: () => ({}),
|
||||
getNoDataProps: () => ({}),
|
||||
|
||||
// Global Column Defaults
|
||||
column: {
|
||||
@@ -210,18 +199,12 @@ These are all of the available props (and their default values) for the main `<R
|
||||
headerClassName: '',
|
||||
headerStyle: {},
|
||||
getHeaderProps: () => ({})
|
||||
// Footers only
|
||||
footer: undefined,
|
||||
footerClassName: '',
|
||||
footerStyle: {},
|
||||
getFooterProps: () => ({})
|
||||
},
|
||||
|
||||
// Text
|
||||
previousText: 'Previous',
|
||||
nextText: 'Next',
|
||||
loadingText: 'Loading...',
|
||||
noDataText: 'No rows found',
|
||||
pageText: 'Page',
|
||||
ofText: 'of',
|
||||
rowsText: 'rows',
|
||||
@@ -256,9 +239,10 @@ 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,
|
||||
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', // used to determine the column sorting on init
|
||||
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)
|
||||
@@ -279,45 +263,16 @@ Or just define them as props
|
||||
// viewIndex == the index of the row in the current page
|
||||
|
||||
// Header & HeaderGroup Options
|
||||
header: 'Header Name', a function that returns a primitive, or JSX / React Component eg. ({data, column}) => <div>Header Name</div>,
|
||||
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
|
||||
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
|
||||
|
||||
// Footer
|
||||
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
|
||||
|
||||
}]
|
||||
```
|
||||
|
||||
## Accessors
|
||||
Accessors are functions that return the value to populate the row's value for the column.
|
||||
This lets the render function not have to worry about accessing the correct data, the value is automatically populated in it's props.
|
||||
|
||||
If a `string` or `array` is passed the default accessor is used.
|
||||
The default accessor will parse the input into an array and recursively flatten it.
|
||||
Any values that contain a dot (`.`) will be split.
|
||||
Any values that contain bracket (`[]`) will be split.
|
||||
This array is then used as the path to the value to return.
|
||||
|
||||
("$" is the placeholder value that would be returned by the default accessor)
|
||||
| value | path | data |
|
||||
|--------------|-----------------|------------------------|
|
||||
| "a" | ["a"] | {"a": $} |
|
||||
| "a.b" | ["a", "b"] | {"a": {"b": $}} |
|
||||
| "a[0]" | ["a", "0"] | {"a": [$]} |
|
||||
| ["a.b", "c"] | ["a", "b", "c"] | {"a": {"b": {"c": $}}} |
|
||||
|
||||
*NOTE*
|
||||
If your data has a field/key with a dot (`.`) you will need to supply a custom accessor.
|
||||
|
||||
|
||||
## Column Header Groups
|
||||
To group columns with another header column, just nest your columns in a header column. Header columns utilize the same header properties as regular columns.
|
||||
```javascript
|
||||
@@ -337,8 +292,8 @@ const columns = [{
|
||||
}]
|
||||
```
|
||||
|
||||
## Custom Cell, Header and Footer Rendering
|
||||
You can use any react component or JSX to display content in column headers, cells and footers. Any component you use will be passed the following props (if available):
|
||||
## Custom Cell & Header Rendering
|
||||
You can use any react component or JSX to display column headers or cells. Any component you use will be passed the following props:
|
||||
- `row` - Original row from your data
|
||||
- `rowValues` - The post-accessed values from the original row
|
||||
- `index` - The index of the row
|
||||
@@ -380,19 +335,17 @@ const columns = [{
|
||||
```
|
||||
|
||||
## Styles
|
||||
- React-table ships with a minimal and clean stylesheet to get you on your feet quickly.
|
||||
- The stylesheet is located at `react-table/react-table.css`.
|
||||
- There are countless ways to import a stylesheet. If you have questions on how to do so, consult the documentation of your build system.
|
||||
React-table ships with a minimal and clean stylesheet to get you on your feet quickly. It's located at `react-table/react-table.css`.
|
||||
|
||||
#### Classes
|
||||
#### Built-in Styles
|
||||
- Adding a `-striped` className to ReactTable will slightly color odd numbered rows for legibility
|
||||
- Adding a `-highlight` className to ReactTable will highlight any row as you hover over it
|
||||
|
||||
#### CSS
|
||||
#### CSS Styles
|
||||
We think the default styles looks great! But, if you prefer a more custom look, all of the included styles are easily overridable. Every single component contains a unique class that makes it super easy to customize. Just go for it!
|
||||
|
||||
#### JS Styles
|
||||
Every single react-table element and `get[ComponentName]Props` callback supports `classname` and `style` props.
|
||||
Every single react-table element and `get[ComponentName]Props` callback support classes (powered by `classname` and js styles.
|
||||
|
||||
## Custom Props
|
||||
|
||||
@@ -481,7 +434,7 @@ const columns = [{
|
||||
}]
|
||||
```
|
||||
|
||||
## Pivoting and Aggregation
|
||||
## Pivoting & Aggregation
|
||||
Pivoting the table will group records together based on their accessed values and allow the rows in that group to be expanded underneath it.
|
||||
To pivot, pass an array of `columnID`'s to `pivotBy`. Remember, a column's `id` is either the one that you assign it (when using a custom accessors) or its `accessor` string.
|
||||
```javascript
|
||||
@@ -511,7 +464,7 @@ const columns = [{
|
||||
|
||||
Pivoted columns can be sorted just like regular columns, but not independently of each other. For instance, if you click to sort the pivot column in ascending order, it will sort by each pivot recursively in ascending order together.
|
||||
|
||||
## Sub Tables and Sub Components
|
||||
## Sub Tables & Sub Components
|
||||
By adding a `SubComponent` props, you can easily add an expansion level to all root-level rows:
|
||||
```javascript
|
||||
<ReactTable
|
||||
@@ -603,42 +556,51 @@ Here are the props and their corresponding callbacks that control the state of t
|
||||
```
|
||||
|
||||
## Functional Rendering
|
||||
Possibly one of the coolest features of React-Table is its ability to expose internal components and state for custom render logic. The easiest way to do this is to pass a function as the child of `<ReactTable />`.
|
||||
Possibly one of the coolest features of React-Table is its ability to expose internal state for custom render logic. The easiest way to do this is to optionally pass a function as a child of `<ReactTable />`.
|
||||
|
||||
The function you pass will be called with the following items:
|
||||
- Fully-resolved state of the table
|
||||
- A function that returns the standard table component
|
||||
- The standard table generator
|
||||
- The instance of the component
|
||||
|
||||
You can then return any JSX or react you want! This turns out to be perfect for:
|
||||
- Accessing the internal state of the table without a `ref`
|
||||
- Decorating the table or extending it with your own UI
|
||||
- Building your own custom display logic
|
||||
- Accessing the internal state of the table before rendering the table
|
||||
- Decorating the table with more UI
|
||||
- Building your own 100% custom display logic, while utilizing the state and methods of the table component
|
||||
|
||||
Accessing internal state and wrapping with more UI:
|
||||
Example:
|
||||
```javascript
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
data={data}
|
||||
...
|
||||
>
|
||||
{(state, makeTable, instance) => {
|
||||
// Now you have full access to the state of the table!
|
||||
state.decoratedColumns === [...] // all of the columns (with id's and meta)
|
||||
state.visibleColumns === [...] // all of the columns (with id's and meta)
|
||||
state.visibleColumns === [...] // all of the columns (with id's and meta)
|
||||
// etc.
|
||||
|
||||
// `makeTable` is a function that returns the standard table markup
|
||||
return makeTable()
|
||||
|
||||
// So add some decoration!
|
||||
return (
|
||||
<div style={{
|
||||
background: '#ffcf00',
|
||||
borderRadius: '5px',
|
||||
overflow: 'hidden',
|
||||
padding: '5px'
|
||||
}}>
|
||||
<pre><code>state.allVisibleColumns === {JSON.stringify(state.allVisibleColumns, null, 4)}</code></pre>
|
||||
<div>
|
||||
<customPivotBySelect />
|
||||
<customColumnHideShow />
|
||||
<customAnything />
|
||||
{makeTable()}
|
||||
</div>
|
||||
)
|
||||
|
||||
// The possibilities are endless!!!
|
||||
|
||||
}}
|
||||
</ReactTable>
|
||||
```
|
||||
|
||||
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!
|
||||
|
||||
@@ -648,20 +610,18 @@ Though we confidently stand by the markup and architecture behind it, `react-tab
|
||||
// Change the global default
|
||||
import { ReactTableDefaults } from 'react-table'
|
||||
Object.assign(ReactTableDefaults, {
|
||||
TableComponent: component,
|
||||
TheadComponent: component,
|
||||
TbodyComponent: component,
|
||||
TrGroupComponent: component,
|
||||
TrComponent: component,
|
||||
ThComponent: component
|
||||
TdComponent: component,
|
||||
TfootComponent: component,
|
||||
ExpanderComponent: component,
|
||||
PaginationComponent: component,
|
||||
PreviousComponent: undefined,
|
||||
NextComponent: undefined,
|
||||
LoadingComponent: component,
|
||||
NoDataComponent: component,
|
||||
TableComponent: Component,
|
||||
TheadComponent: Component,
|
||||
TbodyComponent: Component,
|
||||
TrGroupComponent: Component,
|
||||
TrComponent: Component,
|
||||
ThComponent: Component,
|
||||
TdComponent: Component,
|
||||
PaginationComponent: Component,
|
||||
PreviousComponent: Component,
|
||||
NextComponent: Component,
|
||||
LoadingComponent: Component,
|
||||
ExpanderComponent: Component
|
||||
})
|
||||
|
||||
// Or change per instance
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<div id="error-display"></div>
|
||||
<script src="static/preview.437e4f72f80621de5f68.bundle.js"></script>
|
||||
<script src="static/preview.ee446fa2bd3fbfe7e38a.bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@
|
||||
</head>
|
||||
<body style="margin: 0;">
|
||||
<div id="root"></div>
|
||||
<script src="static/manager.3f690da6fe3fd9729ee0.bundle.js"></script>
|
||||
<script src="static/manager.f127c5ae855df8d8558a.bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"static/manager.3f690da6fe3fd9729ee0.bundle.js","sources":["webpack:///static/manager.3f690da6fe3fd9729ee0.bundle.js"],"mappings":"AAAA;AAkuDA;AA84DA;AA28DA;AA00DA;AAsyEA;AA89CA;AA+rDA;AAsiDA;AAg6DA;AA2nDA;AA++CA;AAkvDA;AAsnEA;AA2oDA;AAivCA;AA+nDA;AAkpDA;AA6lEA;AAs4DA;AAquDA;AA+pDA;AAoxDA;AAsrDA;AA4yDA;AA88GA;AAj6CA;AAopGA;AAsuFA;AA+zEA;AAtMA;AAizEA","sourceRoot":""}
|
||||
+27
-27
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"static/manager.f127c5ae855df8d8558a.bundle.js","sources":["webpack:///static/manager.f127c5ae855df8d8558a.bundle.js"],"mappings":"AAAA;AAkuDA;AA84DA;AA28DA;AA00DA;AAsyEA;AA89CA;AA8rDA;AAsiDA;AAg6DA;AA2nDA;AA++CA;AAkvDA;AAsnEA;AA2oDA;AAivCA;AA+nDA;AAkpDA;AA6lEA;AAs4DA;AAquDA;AA+pDA;AAqxDA;AAsrDA;AAwyDA;AA88GA;AAj6CA;AAopGA;AAsuFA;AA+zEA;AAtMA;AAizEA","sourceRoot":""}
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"static/preview.437e4f72f80621de5f68.bundle.js","sources":["webpack:///static/preview.437e4f72f80621de5f68.bundle.js"],"mappings":"AAAA;AAkuDA;AAq5DA;AA8xFA;AA2+EA;AA++NA;AA06GA;AAgsDA;AA8/DA;AA4xDA;AAigEA;AAmjDA;AA4sDA;AAk8CA;AAu/DA;AA8lDA;AA09CA;AAqoDA;AAywEA;AAokDA;AAsvCA;AA2mDA;AA4tDA;AAqjEA;AAs2DA;AAmyDA;AAsnDA;AAszFA;AA65FA;AA4/CA;AAwzCA;AAmlCA;AAotDA;AAyrBA;AAkPA;AA84EA","sourceRoot":""}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"static/preview.ee446fa2bd3fbfe7e38a.bundle.js","sources":["webpack:///static/preview.ee446fa2bd3fbfe7e38a.bundle.js"],"mappings":"AAAA;AAkuDA;AAiwDA;AAs1EA;AA+gGA;AAo4IA;AAt5NA;AA4udA;AA2hEA;AA2uDA;AA29DA;AA2gDA;AAosDA;AAuhDA;AA+6DA;AAioDA;AA4+CA;AAwpDA;AAisEA;AAqoDA;AAqwCA;AA2oDA;AAowDA;AAokEA;AA0vDA;AA2rDA;AA8nDA;AAwrFA;AAyiGA;AA0/CA;AAqyCA;AA22CA;AAu/CA;AAyGA;AA+jFA","sourceRoot":""}
|
||||
+1
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-table",
|
||||
"version": "5.3.1",
|
||||
"version": "5.0.3",
|
||||
"description": "A fast, lightweight, opinionated table and datagrid built on React",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/tannerlinsley/react-table#readme",
|
||||
@@ -62,7 +62,6 @@
|
||||
"react-dom": "^15.4.2",
|
||||
"react-json-tree": "^0.10.1",
|
||||
"standard": "^8.0.0",
|
||||
"storybook": "^0.0.0",
|
||||
"stylus": "^0.54.5",
|
||||
"uglifyify": "3.0.3"
|
||||
},
|
||||
|
||||
Binary file not shown.
@@ -12,7 +12,6 @@ export default {
|
||||
expanderColumnWidth,
|
||||
SubComponent,
|
||||
page,
|
||||
pages,
|
||||
pageSize
|
||||
} = this.getResolvedState(nextProps, nextState)
|
||||
|
||||
@@ -215,8 +214,7 @@ export default {
|
||||
resolvedData = groupRecursively(resolvedData, pivotBy)
|
||||
}
|
||||
|
||||
const newPages = _.getFirstDefined(pages, Math.ceil(resolvedData.length / pageSize))
|
||||
const newPage = page > newPages ? newPage - 1 : page
|
||||
const newPages = Math.ceil(resolvedData.length / pageSize)
|
||||
|
||||
return {
|
||||
resolvedData,
|
||||
@@ -225,19 +223,23 @@ export default {
|
||||
headerGroups,
|
||||
allDecoratedColumns,
|
||||
hasHeaderGroups,
|
||||
page: Math.max(newPage, 0)
|
||||
page: (page + 1) > newPages ? newPages - 1 : page
|
||||
}
|
||||
},
|
||||
getSortedData (resolvedState) {
|
||||
getSortedData (nextProps, nextState) {
|
||||
const {
|
||||
manual,
|
||||
sorting,
|
||||
allDecoratedColumns,
|
||||
resolvedData
|
||||
} = resolvedState
|
||||
} = this.getResolvedState(nextProps, nextState)
|
||||
|
||||
const resolvedSorting = sorting.length ? sorting : this.getInitSorting(allDecoratedColumns)
|
||||
|
||||
// Resolve the data from either manual data or sorted data
|
||||
return {
|
||||
sortedData: manual ? resolvedData : this.sortData(resolvedData, sorting)
|
||||
resolvedSorting,
|
||||
sortedData: manual ? resolvedData : this.sortData(resolvedData, resolvedSorting)
|
||||
}
|
||||
},
|
||||
|
||||
@@ -250,10 +252,27 @@ export default {
|
||||
getStateOrProp (key) {
|
||||
return _.getFirstDefined(this.state[key], this.props[key])
|
||||
},
|
||||
sortData (data, sorting) {
|
||||
if (!sorting.length) {
|
||||
return data
|
||||
getInitSorting (columns) {
|
||||
if (!columns) {
|
||||
return []
|
||||
}
|
||||
const initSorting = columns.filter(d => {
|
||||
return typeof d.sort !== 'undefined'
|
||||
}).map(d => {
|
||||
return {
|
||||
id: d.id,
|
||||
asc: d.sort === 'asc'
|
||||
}
|
||||
})
|
||||
|
||||
return initSorting
|
||||
|
||||
// return initSorting.length ? initSorting : [{
|
||||
// id: columns.find(d => d.id).id,
|
||||
// asc: true
|
||||
// }]
|
||||
},
|
||||
sortData (data, sorting) {
|
||||
const sorted = _.orderBy(data, sorting.map(sort => {
|
||||
return row => {
|
||||
if (row[sort.id] === null || row[sort.id] === undefined) {
|
||||
@@ -261,7 +280,7 @@ export default {
|
||||
}
|
||||
return typeof row[sort.id] === 'string' ? row[sort.id].toLowerCase() : row[sort.id]
|
||||
}
|
||||
}), sorting.map(d => !d.desc))
|
||||
}), sorting.map(d => d.asc ? 'asc' : 'desc'))
|
||||
|
||||
return sorted.map(row => {
|
||||
if (!row[this.props.subRowsKey]) {
|
||||
@@ -316,25 +335,54 @@ export default {
|
||||
if (onSortingChange) {
|
||||
return onSortingChange(column, additive)
|
||||
}
|
||||
let newSorting = _.clone(sorting || []).map(d => {
|
||||
d.desc = _.isSortingDesc(d)
|
||||
return d
|
||||
})
|
||||
if (!_.isArray(column)) {
|
||||
// Single-Sort
|
||||
let newSorting = _.clone(sorting || [])
|
||||
if (_.isArray(column)) {
|
||||
const existingIndex = newSorting.findIndex(d => d.id === column[0].id)
|
||||
if (existingIndex > -1) {
|
||||
const existing = newSorting[existingIndex]
|
||||
if (existing.asc) {
|
||||
column.forEach((d, i) => {
|
||||
newSorting[existingIndex + i].asc = false
|
||||
})
|
||||
} else {
|
||||
if (additive) {
|
||||
newSorting.splice(existingIndex, column.length)
|
||||
} else {
|
||||
column.forEach((d, i) => {
|
||||
newSorting[existingIndex + i].asc = true
|
||||
})
|
||||
}
|
||||
}
|
||||
if (!additive) {
|
||||
newSorting = newSorting.slice(existingIndex, column.length)
|
||||
}
|
||||
} else {
|
||||
if (additive) {
|
||||
newSorting = newSorting.concat(column.map(d => ({
|
||||
id: d.id,
|
||||
asc: true
|
||||
})))
|
||||
} else {
|
||||
newSorting = column.map(d => ({
|
||||
id: d.id,
|
||||
asc: true
|
||||
}))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const existingIndex = newSorting.findIndex(d => d.id === column.id)
|
||||
if (existingIndex > -1) {
|
||||
const existing = newSorting[existingIndex]
|
||||
if (existing.desc) {
|
||||
if (additive) {
|
||||
newSorting.splice(existingIndex, 1)
|
||||
} else {
|
||||
existing.desc = false
|
||||
if (existing.asc) {
|
||||
existing.asc = false
|
||||
if (!additive) {
|
||||
newSorting = [existing]
|
||||
}
|
||||
} else {
|
||||
existing.desc = true
|
||||
if (!additive) {
|
||||
if (additive) {
|
||||
newSorting.splice(existingIndex, 1)
|
||||
} else {
|
||||
existing.asc = true
|
||||
newSorting = [existing]
|
||||
}
|
||||
}
|
||||
@@ -342,51 +390,15 @@ export default {
|
||||
if (additive) {
|
||||
newSorting.push({
|
||||
id: column.id,
|
||||
desc: false
|
||||
asc: true
|
||||
})
|
||||
} else {
|
||||
newSorting = [{
|
||||
id: column.id,
|
||||
desc: false
|
||||
asc: true
|
||||
}]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Multi-Sort
|
||||
const existingIndex = newSorting.findIndex(d => d.id === column[0].id)
|
||||
// Existing Sorted Column
|
||||
if (existingIndex > -1) {
|
||||
const existing = newSorting[existingIndex]
|
||||
if (existing.desc) {
|
||||
if (additive) {
|
||||
newSorting.splice(existingIndex, column.length)
|
||||
} else {
|
||||
column.forEach((d, i) => {
|
||||
newSorting[existingIndex + i].desc = false
|
||||
})
|
||||
}
|
||||
} else {
|
||||
column.forEach((d, i) => {
|
||||
newSorting[existingIndex + i].desc = true
|
||||
})
|
||||
}
|
||||
if (!additive) {
|
||||
newSorting = newSorting.slice(existingIndex, column.length)
|
||||
}
|
||||
} else {
|
||||
// New Sort Column
|
||||
if (additive) {
|
||||
newSorting = newSorting.concat(column.map(d => ({
|
||||
id: d.id,
|
||||
desc: false
|
||||
})))
|
||||
} else {
|
||||
newSorting = column.map(d => ({
|
||||
id: d.id,
|
||||
desc: false
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
this.setStateWithData({
|
||||
page: ((!sorting.length && newSorting.length) || !additive) ? 0 : this.state.page,
|
||||
@@ -1,152 +0,0 @@
|
||||
import React from 'react'
|
||||
import classnames from 'classnames'
|
||||
//
|
||||
import _ from './utils'
|
||||
import Pagination from './pagination'
|
||||
|
||||
const emptyObj = () => ({})
|
||||
|
||||
export default {
|
||||
// General
|
||||
data: [],
|
||||
loading: false,
|
||||
showPagination: true,
|
||||
showPageSizeOptions: true,
|
||||
pageSizeOptions: [5, 10, 20, 25, 50, 100],
|
||||
defaultPageSize: 20,
|
||||
showPageJump: true,
|
||||
expanderColumnWidth: 35,
|
||||
collapseOnSortingChange: false,
|
||||
collapseOnPageChange: true,
|
||||
freezeWhenExpanded: false,
|
||||
defaultSorting: [],
|
||||
|
||||
// Controlled State Overrides
|
||||
// page: undefined,
|
||||
// pageSize: undefined,
|
||||
// sorting: undefined,
|
||||
|
||||
// Controlled State Callbacks
|
||||
onExpandSubComponent: undefined,
|
||||
onPageChange: undefined,
|
||||
onPageSizeChange: undefined,
|
||||
onSortingChange: undefined,
|
||||
|
||||
// Pivoting
|
||||
pivotBy: undefined,
|
||||
pivotColumnWidth: 200,
|
||||
pivotValKey: '_pivotVal',
|
||||
pivotIDKey: '_pivotID',
|
||||
subRowsKey: '_subRows',
|
||||
|
||||
// Pivoting State Overrides
|
||||
// expandedRows: {},
|
||||
|
||||
// Pivoting State Callbacks
|
||||
onExpandRow: undefined,
|
||||
|
||||
// General Callbacks
|
||||
onChange: () => null,
|
||||
|
||||
// Classes
|
||||
className: '',
|
||||
style: {},
|
||||
|
||||
// Component decorators
|
||||
getProps: emptyObj,
|
||||
getTableProps: emptyObj,
|
||||
getTheadGroupProps: emptyObj,
|
||||
getTheadGroupTrProps: emptyObj,
|
||||
getTheadGroupThProps: emptyObj,
|
||||
getTheadProps: emptyObj,
|
||||
getTheadTrProps: emptyObj,
|
||||
getTheadThProps: emptyObj,
|
||||
getTbodyProps: emptyObj,
|
||||
getTrGroupProps: emptyObj,
|
||||
getTrProps: emptyObj,
|
||||
getTdProps: emptyObj,
|
||||
getTfootProps: emptyObj,
|
||||
getTfootTrProps: emptyObj,
|
||||
getTfootTdProps: emptyObj,
|
||||
getPaginationProps: emptyObj,
|
||||
getLoadingProps: emptyObj,
|
||||
getNoDataProps: emptyObj,
|
||||
|
||||
// Global Column Defaults
|
||||
column: {
|
||||
sortable: true,
|
||||
show: true,
|
||||
minWidth: 100,
|
||||
// Cells only
|
||||
render: undefined,
|
||||
className: '',
|
||||
style: {},
|
||||
getProps: emptyObj,
|
||||
// Headers only
|
||||
header: undefined,
|
||||
headerClassName: '',
|
||||
headerStyle: {},
|
||||
getHeaderProps: emptyObj,
|
||||
// Footers only
|
||||
footer: undefined,
|
||||
footerClassName: '',
|
||||
footerStyle: {},
|
||||
getFooterProps: emptyObj
|
||||
},
|
||||
|
||||
// Text
|
||||
previousText: 'Previous',
|
||||
nextText: 'Next',
|
||||
loadingText: 'Loading...',
|
||||
noDataText: 'No rows found',
|
||||
pageText: 'Page',
|
||||
ofText: 'of',
|
||||
rowsText: 'rows',
|
||||
|
||||
// Components
|
||||
TableComponent: _.makeTemplateComponent('rt-table'),
|
||||
TheadComponent: _.makeTemplateComponent('rt-thead'),
|
||||
TbodyComponent: _.makeTemplateComponent('rt-tbody'),
|
||||
TrGroupComponent: _.makeTemplateComponent('rt-tr-group'),
|
||||
TrComponent: _.makeTemplateComponent('rt-tr'),
|
||||
ThComponent: ({toggleSort, className, children, ...rest}) => {
|
||||
return (
|
||||
<div
|
||||
className={classnames(className, 'rt-th')}
|
||||
onClick={e => {
|
||||
toggleSort && toggleSort(e)
|
||||
}}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
},
|
||||
TdComponent: _.makeTemplateComponent('rt-td'),
|
||||
TfootComponent: _.makeTemplateComponent('rt-tfoot'),
|
||||
ExpanderComponent: ({isExpanded, ...rest}) => {
|
||||
return (
|
||||
<div
|
||||
className={classnames('rt-expander', isExpanded && '-open')}
|
||||
{...rest}
|
||||
>•</div>
|
||||
)
|
||||
},
|
||||
PaginationComponent: Pagination,
|
||||
PreviousComponent: undefined,
|
||||
NextComponent: undefined,
|
||||
LoadingComponent: ({className, loading, loadingText, ...rest}) => (
|
||||
<div className={classnames(
|
||||
'-loading',
|
||||
{'-active': loading},
|
||||
className
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
<div className='-loading-inner'>
|
||||
{loadingText}
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
NoDataComponent: _.makeTemplateComponent('rt-noData')
|
||||
}
|
||||
+306
-211
@@ -2,12 +2,218 @@ import React from 'react'
|
||||
import classnames from 'classnames'
|
||||
//
|
||||
import _ from './utils'
|
||||
import lifecycle from './lifecycle'
|
||||
import methods from './methods'
|
||||
|
||||
import componentMethods from './componentMethods'
|
||||
import Pagination from './pagination'
|
||||
|
||||
const emptyObj = () => ({})
|
||||
|
||||
export const ReactTableDefaults = {
|
||||
// General
|
||||
data: [],
|
||||
loading: false,
|
||||
showPagination: true,
|
||||
showPageSizeOptions: true,
|
||||
pageSizeOptions: [5, 10, 20, 25, 50, 100],
|
||||
defaultPageSize: 20,
|
||||
showPageJump: true,
|
||||
expanderColumnWidth: 35,
|
||||
|
||||
// Controlled State Overrides
|
||||
// page: undefined,
|
||||
// pageSize: undefined,
|
||||
// sorting: undefined,
|
||||
|
||||
// Controlled State Callbacks
|
||||
onExpandSubComponent: undefined,
|
||||
onPageChange: undefined,
|
||||
onPageSizeChange: undefined,
|
||||
onSortingChange: undefined,
|
||||
|
||||
// Pivoting
|
||||
pivotBy: undefined,
|
||||
pivotColumnWidth: 200,
|
||||
pivotValKey: '_pivotVal',
|
||||
pivotIDKey: '_pivotID',
|
||||
subRowsKey: '_subRows',
|
||||
|
||||
// Pivoting State Overrides
|
||||
// expandedRows: {},
|
||||
|
||||
// Pivoting State Callbacks
|
||||
onExpandRow: undefined,
|
||||
|
||||
// General Callbacks
|
||||
onChange: () => null,
|
||||
|
||||
// Classes
|
||||
className: '',
|
||||
style: {},
|
||||
|
||||
// Component decorators
|
||||
getProps: emptyObj,
|
||||
getTableProps: emptyObj,
|
||||
getTheadGroupProps: emptyObj,
|
||||
getTheadGroupTrProps: emptyObj,
|
||||
getTheadGroupThProps: emptyObj,
|
||||
getTheadProps: emptyObj,
|
||||
getTheadTrProps: emptyObj,
|
||||
getTheadThProps: emptyObj,
|
||||
getTbodyProps: emptyObj,
|
||||
getTrGroupProps: emptyObj,
|
||||
getTrProps: emptyObj,
|
||||
getThProps: emptyObj,
|
||||
getTdProps: emptyObj,
|
||||
getPaginationProps: emptyObj,
|
||||
getLoadingProps: emptyObj,
|
||||
|
||||
// Global Column Defaults
|
||||
column: {
|
||||
sortable: true,
|
||||
show: true,
|
||||
minWidth: 100,
|
||||
// Cells only
|
||||
render: undefined,
|
||||
className: '',
|
||||
style: {},
|
||||
getProps: () => ({}),
|
||||
// Headers only
|
||||
header: undefined,
|
||||
headerClassName: '',
|
||||
headerStyle: {},
|
||||
getHeaderProps: () => ({})
|
||||
},
|
||||
|
||||
// Text
|
||||
previousText: 'Previous',
|
||||
nextText: 'Next',
|
||||
loadingText: 'Loading...',
|
||||
pageText: 'Page',
|
||||
ofText: 'of',
|
||||
rowsText: 'rows',
|
||||
|
||||
// Components
|
||||
TableComponent: _.makeTemplateComponent('rt-table'),
|
||||
TheadComponent: _.makeTemplateComponent('rt-thead'),
|
||||
TbodyComponent: _.makeTemplateComponent('rt-tbody'),
|
||||
TrGroupComponent: _.makeTemplateComponent('rt-tr-group'),
|
||||
TrComponent: _.makeTemplateComponent('rt-tr'),
|
||||
ThComponent: ({toggleSort, className, children, ...rest}) => {
|
||||
return (
|
||||
<div
|
||||
className={classnames(className, 'rt-th')}
|
||||
onClick={e => {
|
||||
toggleSort && toggleSort(e)
|
||||
}}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
},
|
||||
TdComponent: _.makeTemplateComponent('rt-td'),
|
||||
ExpanderComponent: ({isExpanded, ...rest}) => {
|
||||
return (
|
||||
<div
|
||||
className={classnames('rt-expander', isExpanded && '-open')}
|
||||
{...rest}
|
||||
>•</div>
|
||||
)
|
||||
},
|
||||
PaginationComponent: Pagination,
|
||||
PreviousComponent: undefined,
|
||||
NextComponent: undefined,
|
||||
LoadingComponent: ({className, loading, loadingText, ...rest}) => (
|
||||
<div className={classnames(
|
||||
'-loading',
|
||||
{'-active': loading},
|
||||
className
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
<div className='-loading-inner'>
|
||||
{loadingText}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.createClass({
|
||||
...lifecycle,
|
||||
...methods,
|
||||
getDefaultProps () {
|
||||
return ReactTableDefaults
|
||||
},
|
||||
|
||||
getInitialState () {
|
||||
return {
|
||||
page: 0,
|
||||
pageSize: this.props.defaultPageSize || 10,
|
||||
sorting: [],
|
||||
expandedRows: {}
|
||||
}
|
||||
},
|
||||
|
||||
getResolvedState (props, state) {
|
||||
const resolvedState = {
|
||||
...this.state,
|
||||
...state,
|
||||
...this.props,
|
||||
...props
|
||||
}
|
||||
return resolvedState
|
||||
},
|
||||
|
||||
componentWillMount () {
|
||||
this.setStateWithData(this.getDataModel())
|
||||
},
|
||||
|
||||
componentDidMount () {
|
||||
this.fireOnChange()
|
||||
},
|
||||
|
||||
componentWillReceiveProps (nextProps, nextState) {
|
||||
const oldState = this.getResolvedState()
|
||||
const newState = this.getResolvedState(nextProps, nextState)
|
||||
// Props that trigger a data update
|
||||
if (
|
||||
oldState.data !== newState.data ||
|
||||
oldState.columns !== newState.columns ||
|
||||
oldState.pivotBy !== newState.pivotBy ||
|
||||
oldState.sorting !== newState.sorting
|
||||
) {
|
||||
this.setStateWithData(this.getDataModel(nextProps, nextState))
|
||||
}
|
||||
},
|
||||
|
||||
setStateWithData (newState, cb) {
|
||||
const oldState = this.getResolvedState()
|
||||
const newResolvedState = this.getResolvedState({}, newState)
|
||||
if (
|
||||
oldState.resolvedData !== newResolvedState.resolvedData ||
|
||||
oldState.sorting !== newResolvedState.sorting
|
||||
) {
|
||||
Object.assign(newState, this.getSortedData({}, newState))
|
||||
}
|
||||
// Calculate pageSize all the time
|
||||
if (newResolvedState.resolvedData) {
|
||||
newState.pages = newResolvedState.manual ? newResolvedState.pages : Math.ceil(newResolvedState.resolvedData.length / newResolvedState.pageSize)
|
||||
}
|
||||
return this.setState(newState, cb)
|
||||
},
|
||||
|
||||
shouldComponentUpdate (nextProps, nextState) {
|
||||
const oldState = this.getResolvedState()
|
||||
const newState = this.getResolvedState(nextProps, nextState)
|
||||
// State changes that trigger a render
|
||||
if (
|
||||
oldState.sortedData !== newState.sortedData ||
|
||||
oldState.page !== newState.page ||
|
||||
oldState.pageSize !== newState.pageSize ||
|
||||
oldState.expandedRows !== newState.expandedRows
|
||||
) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
|
||||
render () {
|
||||
const resolvedState = this.getResolvedState()
|
||||
@@ -26,23 +232,19 @@ export default React.createClass({
|
||||
getTbodyProps,
|
||||
getTrGroupProps,
|
||||
getTrProps,
|
||||
getThProps,
|
||||
getTdProps,
|
||||
getTfootProps,
|
||||
getTfootTrProps,
|
||||
getTfootTdProps,
|
||||
getPaginationProps,
|
||||
getLoadingProps,
|
||||
getNoDataProps,
|
||||
showPagination,
|
||||
expanderColumnWidth,
|
||||
manual,
|
||||
loadingText,
|
||||
noDataText,
|
||||
// State
|
||||
loading,
|
||||
pageSize,
|
||||
page,
|
||||
sorting,
|
||||
resolvedSorting,
|
||||
pages,
|
||||
// Pivoting State
|
||||
pivotValKey,
|
||||
@@ -57,12 +259,10 @@ export default React.createClass({
|
||||
TrComponent,
|
||||
ThComponent,
|
||||
TdComponent,
|
||||
TfootComponent,
|
||||
ExpanderComponent,
|
||||
PaginationComponent,
|
||||
LoadingComponent,
|
||||
SubComponent,
|
||||
NoDataComponent,
|
||||
// Data model
|
||||
resolvedData,
|
||||
allVisibleColumns,
|
||||
@@ -72,6 +272,9 @@ export default React.createClass({
|
||||
sortedData
|
||||
} = resolvedState
|
||||
|
||||
// Determine the flex percentage for each column
|
||||
// const columnPercentage = 100 / allVisibleColumns.length
|
||||
|
||||
// Pagination
|
||||
const startRow = pageSize * page
|
||||
const endRow = startRow + pageSize
|
||||
@@ -81,8 +284,6 @@ export default React.createClass({
|
||||
: minRows ? _.range(Math.max(minRows - pageRows.length, 0))
|
||||
: []
|
||||
|
||||
const hasColumnFooter = allVisibleColumns.some(d => d.footer)
|
||||
|
||||
const recurseRowsViewIndex = (rows, path = [], index = -1) => {
|
||||
rows.forEach((row, i) => {
|
||||
index++
|
||||
@@ -111,7 +312,6 @@ export default React.createClass({
|
||||
pageRows,
|
||||
minRows,
|
||||
padRows,
|
||||
hasColumnFooter,
|
||||
canPrevious,
|
||||
canNext,
|
||||
rowMinWidth
|
||||
@@ -176,7 +376,6 @@ export default React.createClass({
|
||||
if (column.pivotColumns) {
|
||||
return (
|
||||
<ThComponent
|
||||
key={i}
|
||||
className={classnames(
|
||||
'rt-pivot-header',
|
||||
classes
|
||||
@@ -191,7 +390,6 @@ export default React.createClass({
|
||||
}
|
||||
return (
|
||||
<ThComponent
|
||||
key={i}
|
||||
className={classnames(
|
||||
'rt-expander-header',
|
||||
classes
|
||||
@@ -217,10 +415,12 @@ export default React.createClass({
|
||||
}}
|
||||
{...rest}
|
||||
>
|
||||
{_.normalizeComponent(column.header, {
|
||||
data: sortedData,
|
||||
column: column
|
||||
})}
|
||||
{typeof column.header === 'function' ? (
|
||||
<column.header
|
||||
data={sortedData}
|
||||
column={column}
|
||||
/>
|
||||
) : column.header}
|
||||
</ThComponent>
|
||||
)
|
||||
}
|
||||
@@ -249,7 +449,7 @@ export default React.createClass({
|
||||
}
|
||||
|
||||
const makeHeader = (column, i) => {
|
||||
const sort = sorting.find(d => d.id === column.id)
|
||||
const sort = resolvedSorting.find(d => d.id === column.id)
|
||||
const show = typeof column.show === 'function' ? column.show() : column.show
|
||||
const width = _.getFirstDefined(column.width, column.minWidth)
|
||||
const maxWidth = _.getFirstDefined(column.width, column.maxWidth)
|
||||
@@ -275,7 +475,7 @@ export default React.createClass({
|
||||
|
||||
if (column.expander) {
|
||||
if (column.pivotColumns) {
|
||||
const pivotSort = sorting.find(d => d.id === column.id)
|
||||
const pivotSort = resolvedSorting.find(d => d.id === column.id)
|
||||
return (
|
||||
<ThComponent
|
||||
key={i}
|
||||
@@ -283,7 +483,7 @@ export default React.createClass({
|
||||
'rt-pivot-header',
|
||||
column.sortable && '-cursor-pointer',
|
||||
classes,
|
||||
pivotSort ? (pivotSort.desc ? '-sort-asc' : '-sort-desc') : ''
|
||||
pivotSort ? (pivotSort.asc ? '-sort-asc' : '-sort-desc') : ''
|
||||
)}
|
||||
style={{
|
||||
...styles,
|
||||
@@ -299,10 +499,12 @@ export default React.createClass({
|
||||
{column.pivotColumns.map((pivotColumn, i) => {
|
||||
return (
|
||||
<span key={pivotColumn.id}>
|
||||
{_.normalizeComponent(pivotColumn.header, {
|
||||
data: sortedData,
|
||||
column: column
|
||||
})}
|
||||
{typeof pivotColumn.header === 'function' ? (
|
||||
<pivotColumn.header
|
||||
data={sortedData}
|
||||
column={pivotColumn}
|
||||
/>
|
||||
) : pivotColumn.header}
|
||||
{i < column.pivotColumns.length - 1 && (
|
||||
<ExpanderComponent />
|
||||
)}
|
||||
@@ -334,7 +536,7 @@ export default React.createClass({
|
||||
key={i}
|
||||
className={classnames(
|
||||
classes,
|
||||
sort ? (sort.desc ? '-sort-asc' : '-sort-desc') : '',
|
||||
sort ? (sort.asc ? '-sort-asc' : '-sort-desc') : '',
|
||||
column.sortable && '-cursor-pointer',
|
||||
!show && '-hidden',
|
||||
)}
|
||||
@@ -349,10 +551,12 @@ export default React.createClass({
|
||||
}}
|
||||
{...rest}
|
||||
>
|
||||
{_.normalizeComponent(column.header, {
|
||||
data: sortedData,
|
||||
column: column
|
||||
})}
|
||||
{typeof column.header === 'function' ? (
|
||||
<column.header
|
||||
data={sortedData}
|
||||
column={column}
|
||||
/>
|
||||
) : column.header}
|
||||
</ThComponent>
|
||||
)
|
||||
}
|
||||
@@ -385,6 +589,7 @@ export default React.createClass({
|
||||
{...trProps.rest}
|
||||
>
|
||||
{allVisibleColumns.map((column, i2) => {
|
||||
const Cell = column.render
|
||||
const show = typeof column.show === 'function' ? column.show() : column.show
|
||||
const width = _.getFirstDefined(column.width, column.minWidth)
|
||||
const maxWidth = _.getFirstDefined(column.width, column.maxWidth)
|
||||
@@ -424,7 +629,6 @@ export default React.createClass({
|
||||
const PivotCell = column.pivotRender
|
||||
return (
|
||||
<TdComponent
|
||||
key={i2}
|
||||
className={classnames(
|
||||
'rt-pivot',
|
||||
classes
|
||||
@@ -465,7 +669,6 @@ export default React.createClass({
|
||||
// Return the regular expander cell
|
||||
return (
|
||||
<TdComponent
|
||||
key={i2}
|
||||
className={classnames(
|
||||
classes,
|
||||
{hidden: !show}
|
||||
@@ -502,10 +705,13 @@ export default React.createClass({
|
||||
}}
|
||||
{...tdProps.rest}
|
||||
>
|
||||
{_.normalizeComponent(column.render, {
|
||||
...rowInfo,
|
||||
value: rowInfo.rowValues[column.id]
|
||||
}, rowInfo.rowValues[column.id])}
|
||||
{typeof Cell === 'function' ? (
|
||||
<Cell
|
||||
{...rowInfo}
|
||||
value={rowInfo.rowValues[column.id]}
|
||||
/>
|
||||
) : typeof Cell !== 'undefined' ? Cell
|
||||
: rowInfo.rowValues[column.id]}
|
||||
</TdComponent>
|
||||
)
|
||||
})}
|
||||
@@ -523,7 +729,7 @@ export default React.createClass({
|
||||
const makePadRow = (row, i) => {
|
||||
const trGroupProps = getTrGroupProps(finalState, undefined, undefined, this)
|
||||
const trProps = _.splitProps(getTrProps(finalState, undefined, undefined, this))
|
||||
const tdProps = _.splitProps(getTdProps(finalState, undefined, undefined, this))
|
||||
const thProps = _.splitProps(getThProps(finalState, undefined, undefined, this))
|
||||
return (
|
||||
<TrGroupComponent
|
||||
key={i}
|
||||
@@ -540,14 +746,14 @@ export default React.createClass({
|
||||
<ThComponent
|
||||
className={classnames(
|
||||
'rt-expander-header',
|
||||
tdProps.className
|
||||
thProps.className
|
||||
)}
|
||||
style={{
|
||||
...tdProps.style,
|
||||
...thProps.style,
|
||||
flex: `0 0 auto`,
|
||||
width: `${expanderColumnWidth}px`
|
||||
}}
|
||||
{...tdProps.rest}
|
||||
{...thProps.rest}
|
||||
/>
|
||||
)}
|
||||
{allVisibleColumns.map((column, i2) => {
|
||||
@@ -593,182 +799,71 @@ export default React.createClass({
|
||||
)
|
||||
}
|
||||
|
||||
const makeColumnFooters = () => {
|
||||
const tFootProps = getTfootProps(finalState, undefined, undefined, this)
|
||||
const tFootTrProps = _.splitProps(getTfootTrProps(finalState, undefined, undefined, this))
|
||||
const makeTable = () => {
|
||||
const rootProps = _.splitProps(getProps(finalState, undefined, undefined, this))
|
||||
const tableProps = _.splitProps(getTableProps(finalState, undefined, undefined, this))
|
||||
const tBodyProps = _.splitProps(getTbodyProps(finalState, undefined, undefined, this))
|
||||
const paginationProps = _.splitProps(getPaginationProps(finalState, undefined, undefined, this))
|
||||
const loadingProps = getLoadingProps(finalState, undefined, undefined, this)
|
||||
return (
|
||||
<TfootComponent
|
||||
className={tFootProps.className}
|
||||
<div
|
||||
className={classnames(
|
||||
'ReactTable',
|
||||
className,
|
||||
rootProps.className
|
||||
)}
|
||||
style={{
|
||||
...tFootProps.style,
|
||||
minWidth: `${rowMinWidth}px`
|
||||
...style,
|
||||
...rootProps.style
|
||||
}}
|
||||
{...tFootProps.rest}
|
||||
{...rootProps.rest}
|
||||
>
|
||||
<TrComponent
|
||||
className={classnames(
|
||||
tFootTrProps.className
|
||||
)}
|
||||
style={tFootTrProps.style}
|
||||
{...tFootTrProps.rest}
|
||||
<TableComponent
|
||||
className={classnames(tableProps.className)}
|
||||
style={tableProps.style}
|
||||
{...tableProps.rest}
|
||||
>
|
||||
{allVisibleColumns.map((column, i2) => {
|
||||
const show = typeof column.show === 'function' ? column.show() : column.show
|
||||
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))
|
||||
|
||||
const classes = [
|
||||
tFootTdProps.className,
|
||||
column.className,
|
||||
columnProps.className,
|
||||
columnFooterProps.className
|
||||
]
|
||||
|
||||
const styles = {
|
||||
...tFootTdProps.style,
|
||||
...column.style,
|
||||
...columnProps.style,
|
||||
...columnFooterProps.style
|
||||
}
|
||||
|
||||
if (column.expander) {
|
||||
if (column.pivotColumns) {
|
||||
return (
|
||||
<TdComponent
|
||||
key={i2}
|
||||
className={classnames(
|
||||
'rt-pivot',
|
||||
classes
|
||||
)}
|
||||
style={{
|
||||
...styles,
|
||||
flex: `${width} 0 auto`,
|
||||
width: `${width}px`,
|
||||
maxWidth: `${maxWidth}px`
|
||||
}}
|
||||
{...columnProps.rest}
|
||||
{...tFootTdProps.rest}
|
||||
{...columnFooterProps.rest}
|
||||
>
|
||||
{_.normalizeComponent(column.footer)}
|
||||
</TdComponent>
|
||||
)
|
||||
}
|
||||
|
||||
// Return the regular expander cell
|
||||
return (
|
||||
<TdComponent
|
||||
key={i2}
|
||||
className={classnames(
|
||||
classes,
|
||||
{hidden: !show}
|
||||
)}
|
||||
style={{
|
||||
...styles,
|
||||
flex: `0 0 auto`,
|
||||
width: `${expanderColumnWidth}px`
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
// Return regular cell
|
||||
return (
|
||||
<TdComponent
|
||||
key={i2}
|
||||
className={classnames(
|
||||
classes,
|
||||
!show && 'hidden'
|
||||
)}
|
||||
style={{
|
||||
...styles,
|
||||
flex: `${width} 0 auto`,
|
||||
width: `${width}px`,
|
||||
maxWidth: `${maxWidth}px`
|
||||
}}
|
||||
{...columnProps.rest}
|
||||
{...tFootTdProps.rest}
|
||||
{...columnFooterProps.rest}
|
||||
>
|
||||
{_.normalizeComponent(column.footer)}
|
||||
</TdComponent>
|
||||
)
|
||||
})}
|
||||
</TrComponent>
|
||||
</TfootComponent>
|
||||
{hasHeaderGroups && makeHeaderGroups()}
|
||||
{makeHeaders()}
|
||||
<TbodyComponent
|
||||
className={classnames(tBodyProps.className)}
|
||||
style={{
|
||||
...tBodyProps.style,
|
||||
minWidth: `${rowMinWidth}px`
|
||||
}}
|
||||
{...tBodyProps.rest}
|
||||
>
|
||||
{pageRows.map((d, i) => makePageRow(d, i))}
|
||||
{padRows.map(makePadRow)}
|
||||
</TbodyComponent>
|
||||
</TableComponent>
|
||||
{showPagination && (
|
||||
<PaginationComponent
|
||||
{...resolvedState}
|
||||
pages={pages}
|
||||
canPrevious={canPrevious}
|
||||
canNext={canNext}
|
||||
onPageChange={this.onPageChange}
|
||||
onPageSizeChange={this.onPageSizeChange}
|
||||
className={paginationProps.className}
|
||||
style={paginationProps.style}
|
||||
{...paginationProps.rest}
|
||||
/>
|
||||
)}
|
||||
<LoadingComponent
|
||||
loading={loading}
|
||||
loadingText={loadingText}
|
||||
{...loadingProps}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const rootProps = _.splitProps(getProps(finalState, undefined, undefined, this))
|
||||
const tableProps = _.splitProps(getTableProps(finalState, undefined, undefined, this))
|
||||
const tBodyProps = _.splitProps(getTbodyProps(finalState, undefined, undefined, this))
|
||||
const paginationProps = _.splitProps(getPaginationProps(finalState, undefined, undefined, this))
|
||||
const loadingProps = getLoadingProps(finalState, undefined, undefined, this)
|
||||
const noDataProps = getNoDataProps(finalState, undefined, undefined, this)
|
||||
|
||||
const makeTable = () => (
|
||||
<div
|
||||
className={classnames(
|
||||
'ReactTable',
|
||||
className,
|
||||
rootProps.className
|
||||
)}
|
||||
style={{
|
||||
...style,
|
||||
...rootProps.style
|
||||
}}
|
||||
{...rootProps.rest}
|
||||
>
|
||||
<TableComponent
|
||||
className={classnames(tableProps.className)}
|
||||
style={tableProps.style}
|
||||
{...tableProps.rest}
|
||||
>
|
||||
{hasHeaderGroups ? makeHeaderGroups() : null}
|
||||
{makeHeaders()}
|
||||
<TbodyComponent
|
||||
className={classnames(tBodyProps.className)}
|
||||
style={{
|
||||
...tBodyProps.style,
|
||||
minWidth: `${rowMinWidth}px`
|
||||
}}
|
||||
{...tBodyProps.rest}
|
||||
>
|
||||
{pageRows.map((d, i) => makePageRow(d, i))}
|
||||
{padRows.map(makePadRow)}
|
||||
</TbodyComponent>
|
||||
{hasColumnFooter ? makeColumnFooters() : null}
|
||||
</TableComponent>
|
||||
{showPagination ? (
|
||||
<PaginationComponent
|
||||
{...resolvedState}
|
||||
pages={pages}
|
||||
canPrevious={canPrevious}
|
||||
canNext={canNext}
|
||||
onPageChange={this.onPageChange}
|
||||
onPageSizeChange={this.onPageSizeChange}
|
||||
className={paginationProps.className}
|
||||
style={paginationProps.style}
|
||||
{...paginationProps.rest}
|
||||
/>
|
||||
) : null}
|
||||
<NoDataComponent
|
||||
{...noDataProps}
|
||||
>
|
||||
{_.normalizeComponent(noDataText)}
|
||||
</NoDataComponent>
|
||||
<LoadingComponent
|
||||
loading={loading}
|
||||
loadingText={loadingText}
|
||||
{...loadingProps}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
// childProps are optionally passed to a function-as-a-child
|
||||
return children ? children(finalState, makeTable, this) : makeTable()
|
||||
}
|
||||
},
|
||||
|
||||
// Helpers
|
||||
...componentMethods
|
||||
|
||||
})
|
||||
|
||||
+1
-22
@@ -30,6 +30,7 @@ $expandSize = 7px
|
||||
|
||||
.rt-th
|
||||
.rt-td
|
||||
color: black
|
||||
border-right: 1px solid alpha(black, .05)
|
||||
transition box-shadow .3s $easeOutBack
|
||||
box-shadow:inset 0 0 0 0 transparent
|
||||
@@ -99,15 +100,6 @@ $expandSize = 7px
|
||||
cursor: pointer
|
||||
&.-open:after
|
||||
transform: translate(-50%, -50%) rotate(0deg)
|
||||
.rt-tfoot
|
||||
display: flex
|
||||
flex-direction: column
|
||||
box-shadow: 0 0px 15px 0px alpha(black, .15)
|
||||
|
||||
.rt-td
|
||||
border-right:1px solid alpha(black, .05)
|
||||
&:last-child
|
||||
border-right:0
|
||||
|
||||
&.-striped
|
||||
.rt-tr.-odd
|
||||
@@ -125,7 +117,6 @@ $expandSize = 7px
|
||||
flex-wrap: wrap
|
||||
padding: 3px
|
||||
box-shadow: 0 0px 15px 0px alpha(black, .1)
|
||||
border-top: 2px solid alpha(black, .1)
|
||||
|
||||
.-btn
|
||||
appearance:none
|
||||
@@ -179,18 +170,6 @@ $expandSize = 7px
|
||||
.-pageSizeOptions
|
||||
margin: 3px 10px
|
||||
|
||||
.rt-noData
|
||||
display:block
|
||||
position:absolute
|
||||
left:50%
|
||||
top:50%
|
||||
transform: translate(-50%, -50%)
|
||||
background: alpha(white, .8)
|
||||
transition: all .3s ease
|
||||
z-index: 1
|
||||
pointer-events: none
|
||||
padding: 20px
|
||||
color: alpha(black, .5)
|
||||
|
||||
.-loading
|
||||
display:block
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
import _ from './utils'
|
||||
import defaultProps from './defaultProps'
|
||||
|
||||
export default {
|
||||
getDefaultProps () {
|
||||
return defaultProps
|
||||
},
|
||||
|
||||
getInitialState () {
|
||||
return {
|
||||
page: 0,
|
||||
pageSize: this.props.defaultPageSize || 10,
|
||||
sorting: this.props.defaultSorting,
|
||||
expandedRows: {}
|
||||
}
|
||||
},
|
||||
|
||||
getResolvedState (props, state) {
|
||||
const resolvedState = {
|
||||
..._.compactObject(this.state),
|
||||
..._.compactObject(state),
|
||||
..._.compactObject(this.props),
|
||||
..._.compactObject(props)
|
||||
}
|
||||
return resolvedState
|
||||
},
|
||||
|
||||
componentWillMount () {
|
||||
this.setStateWithData(this.getDataModel())
|
||||
},
|
||||
|
||||
componentDidMount () {
|
||||
this.fireOnChange()
|
||||
},
|
||||
|
||||
componentWillReceiveProps (nextProps, nextState) {
|
||||
const oldState = this.getResolvedState()
|
||||
const newState = this.getResolvedState(nextProps, nextState)
|
||||
|
||||
// Props that trigger a data update
|
||||
if (
|
||||
oldState.data !== newState.data ||
|
||||
oldState.columns !== newState.columns ||
|
||||
oldState.pivotBy !== newState.pivotBy ||
|
||||
oldState.sorting !== newState.sorting
|
||||
) {
|
||||
this.setStateWithData(this.getDataModel(nextProps, nextState))
|
||||
}
|
||||
},
|
||||
|
||||
setStateWithData (newState, cb) {
|
||||
const oldState = this.getResolvedState()
|
||||
const newResolvedState = this.getResolvedState({}, newState)
|
||||
const { freezeWhenExpanded } = newResolvedState
|
||||
|
||||
// Default to unfrozen state
|
||||
newResolvedState.frozen = false
|
||||
|
||||
// If freezeWhenExpanded is set, check for frozen conditions
|
||||
if (freezeWhenExpanded) {
|
||||
// if any rows are expanded, freeze the existing data and sorting
|
||||
const keys = Object.keys(newResolvedState.expandedRows)
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
if (newResolvedState.expandedRows[keys[i]]) {
|
||||
newResolvedState.frozen = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the data isn't frozen and either the data or
|
||||
// sorting model has changed, update the data
|
||||
if (
|
||||
(oldState.frozen && !newResolvedState.frozen) ||
|
||||
oldState.sorting !== newResolvedState.sorting ||
|
||||
(!newResolvedState.frozen && oldState.resolvedData !== newResolvedState.resolvedData)
|
||||
) {
|
||||
// Handle collapseOnSortingChange & collapseOnPageChange
|
||||
if (
|
||||
(oldState.sorting !== newResolvedState.sorting && this.props.collapseOnSortingChange) ||
|
||||
(!newResolvedState.frozen && oldState.resolvedData !== newResolvedState.resolvedData && this.props.collapseOnPageChange)
|
||||
) {
|
||||
newResolvedState.expandedRows = {}
|
||||
}
|
||||
|
||||
Object.assign(newResolvedState, this.getSortedData(newResolvedState))
|
||||
}
|
||||
|
||||
// Calculate pageSize all the time
|
||||
if (newResolvedState.resolvedData) {
|
||||
newResolvedState.pages = newResolvedState.manual ? newResolvedState.pages : Math.ceil(newResolvedState.resolvedData.length / newResolvedState.pageSize)
|
||||
}
|
||||
|
||||
return this.setState(newResolvedState, cb)
|
||||
}
|
||||
}
|
||||
+1
-28
@@ -15,10 +15,7 @@ export default {
|
||||
makeTemplateComponent,
|
||||
groupBy,
|
||||
isArray,
|
||||
splitProps,
|
||||
compactObject,
|
||||
isSortingDesc,
|
||||
normalizeComponent
|
||||
splitProps
|
||||
}
|
||||
|
||||
function get (obj, path, def) {
|
||||
@@ -176,27 +173,3 @@ function splitProps ({className, style, ...rest}) {
|
||||
rest
|
||||
}
|
||||
}
|
||||
|
||||
function compactObject (obj) {
|
||||
const newObj = {}
|
||||
for (var key in obj) {
|
||||
if (obj.hasOwnProperty(key) && obj[key] !== undefined && typeof obj[key] !== 'undefined') {
|
||||
newObj[key] = obj[key]
|
||||
}
|
||||
}
|
||||
return newObj
|
||||
}
|
||||
|
||||
function isSortingDesc (d) {
|
||||
return !!(d.sort === 'desc' || d.desc === true || d.asc === false)
|
||||
}
|
||||
|
||||
function normalizeComponent (Comp, params = {}, fallback = Comp) {
|
||||
return typeof Comp === 'function' ? (
|
||||
Comp.prototype.isReactComponent ? (
|
||||
<Comp
|
||||
{...params}
|
||||
/>
|
||||
) : Comp(params)
|
||||
) : fallback
|
||||
}
|
||||
|
||||
@@ -34,24 +34,12 @@ export default () => {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<strong>Hey!</strong> Open your console! :)
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
getTdProps={(state, rowInfo, column, instance) => {
|
||||
return {
|
||||
onMouseEnter: e => console.log('Cell - onMouseEnter', {
|
||||
state,
|
||||
rowInfo,
|
||||
column,
|
||||
instance,
|
||||
event: e
|
||||
})
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
@@ -65,6 +53,9 @@ export default () => {
|
||||
|
||||
function getCode () {
|
||||
return `
|
||||
import ReactTable from 'react-table'
|
||||
|
||||
// Create some column definitions
|
||||
const columns = [{
|
||||
header: 'Name',
|
||||
columns: [{
|
||||
@@ -83,23 +74,12 @@ const columns = [{
|
||||
}]
|
||||
}]
|
||||
|
||||
// Display your table!
|
||||
return (
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
getTdProps={(state, rowInfo, column, instance) => {
|
||||
return {
|
||||
onMouseEnter: e => console.log('Cell - onMouseEnter', {
|
||||
state,
|
||||
rowInfo,
|
||||
column,
|
||||
instance,
|
||||
event: e
|
||||
})
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
`
|
||||
|
||||
@@ -79,6 +79,8 @@ const columns = [{
|
||||
id: 'lastName',
|
||||
accessor: d => d.lastName
|
||||
}]
|
||||
}, {
|
||||
expander: true
|
||||
}, {
|
||||
header: 'Info',
|
||||
columns: [{
|
||||
@@ -89,8 +91,6 @@ const columns = [{
|
||||
return <span>{row.aggregated ? \`$\{row.value} (avg)\` : row.value}</span>
|
||||
}
|
||||
}]
|
||||
}, {
|
||||
expander: true
|
||||
}]
|
||||
|
||||
return (
|
||||
@@ -100,6 +100,7 @@ return (
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
SubComponent={() => <span>Hello</span>}
|
||||
pivotBy={['lastName']}
|
||||
/>
|
||||
)
|
||||
`
|
||||
|
||||
+30
-34
@@ -28,7 +28,8 @@ export default () => {
|
||||
header: 'Info',
|
||||
columns: [{
|
||||
header: 'Age',
|
||||
accessor: 'age'
|
||||
accessor: 'age',
|
||||
sort: 'desc'
|
||||
}]
|
||||
}]
|
||||
|
||||
@@ -40,10 +41,6 @@ export default () => {
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
defaultSorting={[{
|
||||
id: 'age',
|
||||
desc: true
|
||||
}]}
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
@@ -57,35 +54,34 @@ export default () => {
|
||||
|
||||
function getCode () {
|
||||
return `
|
||||
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'
|
||||
}]
|
||||
}]
|
||||
import ReactTable from 'react-table'
|
||||
|
||||
return (
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
defaultSorting={[{
|
||||
id: 'age',
|
||||
desc: true
|
||||
}]}
|
||||
/>
|
||||
)
|
||||
// Create some column definitions
|
||||
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'
|
||||
}]
|
||||
}]
|
||||
|
||||
// Display your table!
|
||||
return (
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
/>
|
||||
)
|
||||
`
|
||||
}
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
|
||||
import CodeHighlight from './components/codeHighlight'
|
||||
import ReactTable from '../src/index'
|
||||
|
||||
export default () => {
|
||||
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',
|
||||
footer: (
|
||||
<span><strong>Popular:</strong> {
|
||||
_.first(
|
||||
_.reduce(
|
||||
_.map(
|
||||
_.groupBy(
|
||||
data, d => d.firstName
|
||||
)
|
||||
),
|
||||
(a, b) => a.length > b.length ? a : b
|
||||
)
|
||||
).firstName}
|
||||
</span>
|
||||
)
|
||||
}, {
|
||||
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>
|
||||
)
|
||||
}]
|
||||
}, {
|
||||
header: 'Info',
|
||||
columns: [{
|
||||
header: 'Age',
|
||||
accessor: 'age',
|
||||
footer: <span><strong>Average:</strong> {_.round(_.mean(_.map(data, d => d.age)))}</span>
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<br />
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>
|
||||
<CodeHighlight>{() => getCode()}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function getCode () {
|
||||
return `
|
||||
import ReactTable from 'react-table'
|
||||
|
||||
// Create some column definitions
|
||||
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'
|
||||
}]
|
||||
}]
|
||||
|
||||
// Display your table!
|
||||
return (
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
/>
|
||||
)
|
||||
`
|
||||
}
|
||||
@@ -40,89 +40,22 @@ export default () => {
|
||||
header: 'Name',
|
||||
columns: [{
|
||||
header: 'First Name',
|
||||
accessor: 'firstName',
|
||||
footer: 'Footer'
|
||||
accessor: 'firstName'
|
||||
}, {
|
||||
header: 'Last Name',
|
||||
id: 'lastName',
|
||||
accessor: d => d.lastName,
|
||||
footer: 'Footer'
|
||||
accessor: d => d.lastName
|
||||
}]
|
||||
}, {
|
||||
header: 'Info',
|
||||
columns: [{
|
||||
header: 'Age',
|
||||
accessor: 'age',
|
||||
footer: 'Footer'
|
||||
accessor: 'age'
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<strong>Functional rendering</strong> simply means that you have all of the building blocks to render your own React Table however you'd like.
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<strong>Decorating the standard table output</strong>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
>
|
||||
{(state, makeTable, instance) => {
|
||||
return (
|
||||
<div style={{
|
||||
background: '#ffcf00',
|
||||
borderRadius: '5px',
|
||||
overflow: 'hidden',
|
||||
padding: '5px'
|
||||
}}>
|
||||
<pre><code>state.allVisibleColumns === {JSON.stringify(state.allVisibleColumns, null, 4)}</code></pre>
|
||||
{makeTable()}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
</ReactTable>
|
||||
</div>
|
||||
|
||||
<CodeHighlight>{() => `
|
||||
import ReactTable from 'react-table'
|
||||
|
||||
return (
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
>
|
||||
{(state, Table, instance) => {
|
||||
return (
|
||||
<div style={{
|
||||
background: '#ffcf00',
|
||||
borderRadius: '5px',
|
||||
overflow: 'hidden',
|
||||
padding: '5px'
|
||||
}}>
|
||||
<pre><code>state.allVisibleColumns === {JSON.stringify(state.allVisibleColumns, null, 4)}</code></pre>
|
||||
<Table />
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
</ReactTable>
|
||||
)
|
||||
`}</CodeHighlight>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<strong>Need more control? This is the entire table state and component instance at your disposal!</strong>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
@@ -130,23 +63,54 @@ return (
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
>
|
||||
{(state, StandardTable, instance) => {
|
||||
{(state, makeTable, instance) => {
|
||||
console.log(state)
|
||||
return (
|
||||
<div>
|
||||
Look! This is the entire table state and component instance at your disposal!
|
||||
<JSONTree
|
||||
data={Object.assign({}, state, {children: 'function () {...}'})}
|
||||
theme={JSONtheme}
|
||||
invertTheme
|
||||
/>
|
||||
<br />
|
||||
<br />
|
||||
{makeTable()}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
</ReactTable>
|
||||
</div>
|
||||
<br />
|
||||
<CodeHighlight>{() => `
|
||||
<CodeHighlight>{() => getCode()}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function getCode () {
|
||||
return `
|
||||
import ReactTable from 'react-table'
|
||||
|
||||
// Create some column definitions
|
||||
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'
|
||||
}]
|
||||
}]
|
||||
|
||||
// Display your table!
|
||||
return (
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
@@ -154,20 +118,23 @@ return (
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
>
|
||||
{(state, StandardTable, instance) => {
|
||||
{(state, makeTable, instance) => {
|
||||
console.log(state)
|
||||
return (
|
||||
<div>
|
||||
Look! This is the entire table state and component instance at your disposal!
|
||||
<JSONTree
|
||||
data={Object.assign({}, state, {children: 'function () {...}'})}
|
||||
theme={JSONtheme}
|
||||
invertTheme
|
||||
/>
|
||||
<br />
|
||||
<br />
|
||||
{makeTable()}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
</ReactTable>
|
||||
)
|
||||
`}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
`
|
||||
}
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
|
||||
import CodeHighlight from './components/codeHighlight'
|
||||
import ReactTable from '../src/index'
|
||||
|
||||
export default () => {
|
||||
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'
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={[]}
|
||||
noDataText='Oh Noes!'
|
||||
// noDataText={() => 'Oh Noes!'} // Supports functions
|
||||
// noDataText={() => <span>Oh Noes!</span>} // Supports JSX / React Components
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<br />
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>
|
||||
<CodeHighlight>{() => getCode()}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function getCode () {
|
||||
return `
|
||||
import ReactTable from 'react-table'
|
||||
|
||||
// Create some column definitions
|
||||
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'
|
||||
}]
|
||||
}]
|
||||
|
||||
// Display your table!
|
||||
return (
|
||||
<ReactTable
|
||||
data={[]}
|
||||
noDataText='Oh Noes!'
|
||||
// noDataText={() => 'Oh Noes!'} // Supports functions
|
||||
// noDataText={() => <span>Oh Noes!</span>} // Supports JSX / React Components
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
/>
|
||||
)
|
||||
`
|
||||
}
|
||||
@@ -100,24 +100,15 @@ const columns = [{
|
||||
header: 'Info',
|
||||
columns: [{
|
||||
header: 'Age',
|
||||
accessor: 'age',
|
||||
aggregate: vals => _.round(_.mean(vals)),
|
||||
render: row => {
|
||||
return <span>{row.aggregated ? \`\${row.value} (avg)\` : row.value}</span>
|
||||
}
|
||||
}, {
|
||||
header: 'Visits',
|
||||
accessor: 'visits',
|
||||
aggregate: vals => _.sum(vals)
|
||||
accessor: 'age'
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
export default (
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
className='-striped -highlight'
|
||||
pivotBy={['firstName', 'lastName']}
|
||||
SubComponent={(row) => {
|
||||
return (
|
||||
|
||||
+31
-12
@@ -50,6 +50,12 @@ export default () => {
|
||||
className='-striped -highlight'
|
||||
defaultPageSize={10}
|
||||
pivotBy={['firstName', 'lastName']}
|
||||
// expandedRows={{
|
||||
// 2: true,
|
||||
// 3: {
|
||||
// 2: true
|
||||
// }
|
||||
// }}
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
@@ -77,25 +83,38 @@ const columns = [{
|
||||
header: 'Info',
|
||||
columns: [{
|
||||
header: 'Age',
|
||||
accessor: 'age',
|
||||
aggregate: vals => _.round(_.mean(vals)),
|
||||
render: row => {
|
||||
return <span>{row.aggregated ? \`\${row.value} (avg)\` : row.value}</span>
|
||||
}
|
||||
}, {
|
||||
header: 'Visits',
|
||||
accessor: 'visits',
|
||||
aggregate: vals => _.sum(vals)
|
||||
accessor: 'age'
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
export default (
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
className='-striped -highlight'
|
||||
defaultPageSize={10}
|
||||
pivotBy={['firstName', 'lastName']}
|
||||
SubComponent={(row) => {
|
||||
return (
|
||||
<div style={{padding: '20px'}}>
|
||||
<em>You can put any component you want here, even another React Table!</em>
|
||||
<br />
|
||||
<br />
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={3}
|
||||
showPagination={false}
|
||||
SubComponent={(row) => {
|
||||
return (
|
||||
<div style={{padding: '20px'}}>
|
||||
<em>It even has access to the row data: </em>
|
||||
<CodeHighlight>{() => JSON.stringify(row, null, 2)}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
`
|
||||
|
||||
@@ -100,24 +100,15 @@ const columns = [{
|
||||
header: 'Info',
|
||||
columns: [{
|
||||
header: 'Age',
|
||||
accessor: 'age',
|
||||
aggregate: vals => _.round(_.mean(vals)),
|
||||
render: row => {
|
||||
return <span>{row.aggregated ? \`\${row.value} (avg)\` : row.value}</span>
|
||||
}
|
||||
}, {
|
||||
header: 'Visits',
|
||||
accessor: 'visits',
|
||||
aggregate: vals => _.sum(vals)
|
||||
accessor: 'age'
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
export default (
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
className='-striped -highlight'
|
||||
pivotBy={['firstName', 'lastName']}
|
||||
SubComponent={(row) => {
|
||||
return (
|
||||
|
||||
@@ -125,4 +125,4 @@ export default (
|
||||
/>
|
||||
)
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2998,7 +2998,7 @@ indexof@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d"
|
||||
|
||||
inflight@^1.0.4, inflight@^1.0.6:
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
dependencies:
|
||||
@@ -5248,10 +5248,6 @@ standard@^8.0.0:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e"
|
||||
|
||||
storybook@^0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/storybook/-/storybook-0.0.0.tgz#b3b9508fb99fd83615674917583cfe9e1532931d"
|
||||
|
||||
stream-browserify@^2.0.0, stream-browserify@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db"
|
||||
|
||||
Reference in New Issue
Block a user