mirror of
https://github.com/gosticks/react-table.git
synced 2026-08-19 08:20:30 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d5207eb4e | ||
|
|
0d397e0c29 | ||
|
|
b15f3ac3b0 | ||
|
|
48ea0df09d | ||
|
|
403fb7a708 | ||
|
|
ecd5658e4b | ||
|
|
3852227bdd | ||
|
|
1fec9b882f | ||
|
|
46c4c6fdb2 | ||
|
|
e702fc80ca | ||
|
|
beaa748187 | ||
|
|
cce77d24f2 | ||
|
|
3984a540c1 | ||
|
|
726fd52753 | ||
|
|
6a6d373526 | ||
|
|
e11fdab457 | ||
|
|
1e4f838326 | ||
|
|
aa48ef57ee | ||
|
|
22f79fcd28 | ||
|
|
ff8e24760a | ||
|
|
f1511bd27e | ||
|
|
4733997c26 | ||
|
|
c3a6e236ae | ||
|
|
83200d4e4c | ||
|
|
5e16c2cb24 | ||
|
|
66cee186a3 | ||
|
|
55bbf4bf37 | ||
|
|
10ce93344c | ||
|
|
114621a359 | ||
|
|
8de0fa420b | ||
|
|
aa77193810 | ||
|
|
92c33de7ac | ||
|
|
c3fb084550 | ||
|
|
04c71f17a8 | ||
|
|
34fa57c4d3 | ||
|
|
de1c8a6156 | ||
|
|
ab9d67d2d9 |
+12
-2
@@ -12,12 +12,17 @@ import Readme from '../README.md'
|
||||
//
|
||||
import Simple from '../stories/Simple.js'
|
||||
import CellRenderers from '../stories/CellRenderers.js'
|
||||
import MaxWidths from '../stories/MaxWidths.js'
|
||||
import DefaultSorting from '../stories/DefaultSorting.js'
|
||||
import CustomWidths from '../stories/CustomWidths.js'
|
||||
import CustomComponentProps from '../stories/CustomComponentProps.js'
|
||||
import ServerSide from '../stories/ServerSide.js'
|
||||
import SubComponents from '../stories/SubComponents.js'
|
||||
import Pivoting from '../stories/Pivoting.js'
|
||||
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'
|
||||
//
|
||||
configure(() => {
|
||||
storiesOf('1. Docs')
|
||||
@@ -35,10 +40,15 @@ configure(() => {
|
||||
storiesOf('2. Demos')
|
||||
.add('Simple Table', Simple)
|
||||
.add('Cell Renderers & Custom Components', CellRenderers)
|
||||
.add('Max Widths', MaxWidths)
|
||||
.add('Default Sorting', DefaultSorting)
|
||||
.add('Custom Column Widths', CustomWidths)
|
||||
.add('Custom Component Props', CustomComponentProps)
|
||||
.add('Server-side Data', ServerSide)
|
||||
.add('Sub Components', SubComponents)
|
||||
.add('Pivoting & Aggregation', Pivoting)
|
||||
.add('Pivoting & Aggregation w/ Sub Components', PivotingSubComponents)
|
||||
.add('100k Rows w/ Pivoting & Sub Components', OneHundredKRows)
|
||||
.add('Functional Rendering', FunctionalRendering)
|
||||
.add('Custom Expander Position', CustomExpanderPosition)
|
||||
.add('Custom "No Data" Text', NoDataText)
|
||||
}, module)
|
||||
|
||||
@@ -43,21 +43,28 @@
|
||||
- [Data](#data)
|
||||
- [Props](#props)
|
||||
- [Columns](#columns)
|
||||
- [Column Header Groups](#column-header-groups)
|
||||
- [Custom Cell and Header Rendering](#custom-cell-and-header-rendering)
|
||||
- [Styles](#styles)
|
||||
- [Header Groups](#header-groups)
|
||||
- [Pivoting & Aggregation](#pivoting--aggregation)
|
||||
- [Sub Tables & Sub Components](#sub-tables--sub-components)
|
||||
- [Custom Props](#custom-props)
|
||||
- [Pivoting and Aggregation](#pivoting-and-aggregation)
|
||||
- [Sub Tables and Sub Components](#sub-tables-and-sub-components)
|
||||
- [Server-side Data](#server-side-data)
|
||||
- [Fully Controlled Component](#fully-controlled-component)
|
||||
- [Multi-sort](#multi-sort)
|
||||
- [Functional Rendering](#functional-rendering)
|
||||
- [Multi-Sort](#multi-sort)
|
||||
- [Component Overrides](#component-overrides)
|
||||
- [Contributing](#contributing)
|
||||
- [Scripts](#scripts)
|
||||
- [Used By](#used-by)
|
||||
|
||||
|
||||
## Installation
|
||||
1. Install React Table as a dependency
|
||||
```bash
|
||||
$ npm install react-table
|
||||
# or
|
||||
$ yarn react-table
|
||||
$ yarn add react-table
|
||||
```
|
||||
2. Import the `react-table` module
|
||||
```javascript
|
||||
@@ -96,7 +103,7 @@ const columns = [{
|
||||
}, {
|
||||
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!
|
||||
@@ -120,55 +127,93 @@ These are all of the available props (and their default values) for the main `<R
|
||||
```javascript
|
||||
{
|
||||
// General
|
||||
loading: false, // Whether to show the loading overlay or not
|
||||
defaultPageSize: 20, // The default page size (this can be changed by the user if `showPageSizeOptions` is enabled)
|
||||
minRows: 0, // Ensure this many rows are always rendered, regardless of rows on page
|
||||
showPagination: true, // Shows or hides the pagination component
|
||||
showPageJump: true, // Shows or hides the pagination number input
|
||||
showPageSizeOptions: true, // Enables the user to change the page size
|
||||
pageSizeOptions: [5, 10, 20, 25, 50, 100], // The available page size options
|
||||
expanderColumnWidth: 30, // default columnWidth for the expander column
|
||||
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: [],
|
||||
|
||||
// Callbacks
|
||||
onChange: (state, instance) => null, // Anytime the internal state of the table changes, this will fire
|
||||
onTrClick: (row, event) => null, // Handler for row click events
|
||||
// Controlled State Overrides (see Fully Controlled Component section)
|
||||
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 (see Fully Controlled Component section)
|
||||
expandedRows: {},
|
||||
|
||||
// Pivoting State Callbacks
|
||||
onExpandRow: undefined,
|
||||
|
||||
// General Callbacks
|
||||
onChange: () => null,
|
||||
|
||||
// Classes
|
||||
className: '',
|
||||
style: {},
|
||||
|
||||
// Component decorators
|
||||
getProps: () => ({}),
|
||||
getTableProps: () => ({}),
|
||||
getTheadGroupProps: () => ({}),
|
||||
getTheadGroupTrProps: () => ({}),
|
||||
getTheadGroupThProps: () => ({}),
|
||||
getTheadProps: () => ({}),
|
||||
getTheadTrProps: () => ({}),
|
||||
getTheadThProps: () => ({}),
|
||||
getTbodyProps: () => ({}),
|
||||
getTrGroupProps: () => ({}),
|
||||
getTrProps: () => ({}),
|
||||
getThProps: () => ({}),
|
||||
getTdProps: () => ({}),
|
||||
getPaginationProps: () => ({}),
|
||||
getLoadingProps: () => ({}),
|
||||
getNoDataProps: () => ({}),
|
||||
|
||||
// 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...',
|
||||
noDataText: 'No rows found',
|
||||
pageText: 'Page',
|
||||
ofText: 'of',
|
||||
rowsText: 'rows',
|
||||
|
||||
// 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
|
||||
|
||||
// Controlled Props (see Using as a Fully Controlled Component below)
|
||||
page: undefined,
|
||||
pageSize: undefined,
|
||||
sorting: undefined,
|
||||
expandedRows: undefined,
|
||||
// Controlled Callbacks
|
||||
onExpandRow: undefined,
|
||||
onPageChange: undefined,
|
||||
onPageSizeChange: undefined,
|
||||
}
|
||||
```
|
||||
|
||||
@@ -184,7 +229,7 @@ Object.assign(ReactTableDefaults, {
|
||||
})
|
||||
```
|
||||
|
||||
Or just define them on the component per-instance
|
||||
Or just define them as props
|
||||
|
||||
```javascript
|
||||
<ReactTable
|
||||
@@ -203,15 +248,19 @@ Or just define them on the component per-instance
|
||||
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)
|
||||
maxWidth: undefined // A maximum width for this column.
|
||||
|
||||
// Special
|
||||
expander: false // This option will override all data-related options and designates the column to be used
|
||||
// for pivoting and sub-component expansion
|
||||
|
||||
// Cell Options
|
||||
className: '', // Set the classname of the `td` element of the column
|
||||
style: {}, // Set the style of the `td` element of the column
|
||||
render: JSX eg. ({value, rowValues, row, 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
|
||||
render: JSX eg. (rowInfo: {value, rowValues, row, 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
|
||||
// value == the accessed value of the column
|
||||
// rowValues == an object of all of the accessed values for the row
|
||||
// row == the original row of data supplied to the table
|
||||
@@ -229,19 +278,12 @@ Or just define them on the component per-instance
|
||||
}]
|
||||
```
|
||||
|
||||
## Styles
|
||||
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`.
|
||||
|
||||
- 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
|
||||
|
||||
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!
|
||||
|
||||
## Header Groups
|
||||
To group columns with another header column, just nest your columns in a header column like so:
|
||||
## 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
|
||||
const columns = [{
|
||||
header: 'Favorites',
|
||||
headerClassName: 'my-favorites-column-header-group'
|
||||
columns: [{
|
||||
header: 'Color',
|
||||
accessor: 'favorites.color'
|
||||
@@ -255,7 +297,149 @@ const columns = [{
|
||||
}]
|
||||
```
|
||||
|
||||
## Pivoting & Aggregation
|
||||
## Custom Cell and 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
|
||||
- `viewIndex` - the index of the row relative to the current page
|
||||
- `level` - The nesting depth (zero-indexed)
|
||||
- `nestingPath` - The nesting path of the row
|
||||
- `aggregated` - A boolean stating if the row is an aggregation row
|
||||
- `subRows` - An array of any expandable sub-rows contained in this row
|
||||
|
||||
```javascript
|
||||
// This column uses a stateless component to produce a different colored bar depending on the value
|
||||
// You can also use stateful components or any other function that returns JSX
|
||||
const columns = [{
|
||||
header: () => <span><i className='fa-tasks' /> Progress</span>,
|
||||
accessor: 'progress',
|
||||
render: row => (
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
backgroundColor: '#dadada',
|
||||
borderRadius: '2px'
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: `${row.value}%`,
|
||||
height: '100%',
|
||||
backgroundColor: row.value > 66 ? '#85cc00'
|
||||
: row.value > 33 ? '#ffbf00'
|
||||
: '#ff2e00',
|
||||
borderRadius: '2px',
|
||||
transition: 'all .2s ease-out'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}]
|
||||
```
|
||||
|
||||
## Styles
|
||||
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`.
|
||||
|
||||
#### 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 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 support classes (powered by `classname` and js styles.
|
||||
|
||||
## Custom Props
|
||||
|
||||
#### Built-in Components
|
||||
Every single built-in component's props can be dynamically extended using any one of these prop-callbacks:
|
||||
```javascript
|
||||
<ReactTable
|
||||
getProps={fn}
|
||||
getTableProps={fn}
|
||||
getTheadGroupProps={fn}
|
||||
getTheadGroupTrProps={fn}
|
||||
getTheadGroupThProps={fn}
|
||||
getTheadProps={fn}
|
||||
getTheadTrProps={fn}
|
||||
getTheadThProps={fn}
|
||||
getTbodyProps={fn}
|
||||
getTrGroupProps={fn}
|
||||
getTrProps={fn}
|
||||
getThProps={fn}
|
||||
getTdProps={fn}
|
||||
getPaginationProps={fn}
|
||||
getLoadingProps={fn}
|
||||
/>
|
||||
```
|
||||
|
||||
These callbacks are executed with each render of the element with three parameters:
|
||||
1. Table State
|
||||
1. RowInfo (undefined if not applicable)
|
||||
1. Column (undefined if not applicable)
|
||||
1. React Table Instance
|
||||
|
||||
This makes it extremely easy to add, say... a row click callback!
|
||||
```javascript
|
||||
// When any Td element is clicked, we'll log out some information
|
||||
<ReactTable
|
||||
getTdProps={(state, rowInfo, column, instance) => {
|
||||
return {
|
||||
onClick: e => {
|
||||
console.log('A Td Element was clicked!')
|
||||
console.log('it produced this event:', e)
|
||||
console.log('It was in this column:', column)
|
||||
console.log('It was in this row:', rowInfo)
|
||||
console.log('It was in this table instance:', instance)
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
You can use these callbacks for dynamic styling as well!
|
||||
```javascript
|
||||
// Any Tr element will be green if its (row.age > 20)
|
||||
<ReactTable
|
||||
getTrProps={(state, rowInfo, column) => {
|
||||
return {
|
||||
style: {
|
||||
background: rowInfo.age > 20 ? 'green' : 'red'
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
#### Column Components
|
||||
Just as core components can have dynamic props, columns and column headers can too!
|
||||
|
||||
You can utilize either of these prop callbacks on columns:
|
||||
```javascript
|
||||
const columns = [{
|
||||
getHeaderProps: () => (...),
|
||||
getProps: () => (...)
|
||||
}]
|
||||
```
|
||||
|
||||
In a similar fashion these can be used to dynamically style just about anything!
|
||||
```javascript
|
||||
// This columns cells will be red if (row.name === Santa Clause)
|
||||
const columns = [{
|
||||
getProps: (state, rowInfo, column) => {
|
||||
return {
|
||||
style: {
|
||||
background: rowInfo.name === 'Santa Clause' ? 'red' : null
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
```
|
||||
|
||||
## Pivoting and 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
|
||||
@@ -285,7 +469,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 & Sub Components
|
||||
## Sub Tables and Sub Components
|
||||
By adding a `SubComponent` props, you can easily add an expansion level to all root-level rows:
|
||||
```javascript
|
||||
<ReactTable
|
||||
@@ -376,6 +560,52 @@ 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 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
|
||||
- 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 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
|
||||
|
||||
Example:
|
||||
```javascript
|
||||
<ReactTable
|
||||
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>
|
||||
<customPivotBySelect />
|
||||
<customColumnHideShow />
|
||||
<customAnything />
|
||||
{makeTable()}
|
||||
</div>
|
||||
)
|
||||
|
||||
// The possibilities are endless!!!
|
||||
|
||||
}}
|
||||
</ReactTable>
|
||||
```
|
||||
|
||||
## 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!
|
||||
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<div id="error-display"></div>
|
||||
<script src="static/preview.254c6d60467ce3c21d01.bundle.js"></script>
|
||||
<script src="static/preview.1dfdb2ebd0085aa535c8.bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="storybook-version" content="2.35.2">
|
||||
<meta name="storybook-version" content="2.35.3">
|
||||
<title>React Storybook</title>
|
||||
<style>
|
||||
/*
|
||||
@@ -38,7 +38,7 @@
|
||||
</head>
|
||||
<body style="margin: 0;">
|
||||
<div id="root"></div>
|
||||
<script src="static/manager.6358a4421928765ac21b.bundle.js"></script>
|
||||
<script src="static/manager.d3baea6e6f08c3c0279c.bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"static/manager.6358a4421928765ac21b.bundle.js","sources":["webpack:///static/manager.6358a4421928765ac21b.bundle.js"],"mappings":"AAAA;AA4zDA;AAg4DA;AA4gEA;AAiiEA;AAk0EA;AA67CA;AA0qDA;AAy4DA;AA8lDA;AA4hDA;AA62DA;AA+/DA;AA6mDA;AAsyCA;AA2gDA;AA+2DA;AA+jEA;AAixDA;AA6lDA;AA+nDA;AA0qEA;AAinDA;AAw3DA;AA80GA;AAhvCA;AAuqGA;AAuqEA;AA6wEA;AAleA;AA+gEA;AA+mCA","sourceRoot":""}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"static/manager.d3baea6e6f08c3c0279c.bundle.js","sources":["webpack:///static/manager.d3baea6e6f08c3c0279c.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;AAyyDA;AA88GA;AAj6CA;AAopGA;AAsuFA;AA+zEA;AAtMA;AAizEA","sourceRoot":""}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"static/preview.1dfdb2ebd0085aa535c8.bundle.js","sources":["webpack:///static/preview.1dfdb2ebd0085aa535c8.bundle.js"],"mappings":"AAAA;AAkuDA;AAu+CA;AA0+FA;AAmpFA;AAkxLA;AA7sBA;AAojOA;AAkjEA;AAivDA;AAy7DA;AAqlDA;AAmvDA;AAu8CA;AA6+DA;AAwlDA;AA2+CA;AAimDA;AA29DA;AA04DA;AAsxCA;AAynDA;AAurDA;AAgiEA;AA03DA;AAwwCA;AA8tDA;AA02FA;AA+tGA;AAy+CA;AAuzCA;AAkuCA;AAikDA;AA8dA;AA+jFA","sourceRoot":""}
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"static/preview.254c6d60467ce3c21d01.bundle.js","sources":["webpack:///static/preview.254c6d60467ce3c21d01.bundle.js"],"mappings":"AAAA;AAwxDA;AA45DA;AA6rDA;AAokFA;AAy9FA;AA4nJA;AA1pHA;AAgsWA;AAm0DA;AA0kEA;AA6nDA;AAi9CA;AA8iEA;AAipDA;AAy8CA;AAmoDA;AAktEA;AA6pDA;AAwuCA;AA8oDA;AA6kDA;AA8pEA;AAu2DA;AAgpDA;AAwkDA;AAm5EA;AA0mHA;AA6rDA;AAugCA;AAs8CA;AA6WA;AA+9CA","sourceRoot":""}
|
||||
+7
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-table",
|
||||
"version": "4.2.7",
|
||||
"version": "5.2.0",
|
||||
"description": "A fast, lightweight, opinionated table and datagrid built on React",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/tannerlinsley/react-table#readme",
|
||||
@@ -24,7 +24,8 @@
|
||||
],
|
||||
"scripts": {
|
||||
"build:node": "babel src --out-dir lib --source-maps inline",
|
||||
"build:css": "rm -rf react-table.css && stylus src/index.styl --use autoprefixer-stylus --compress -o react-table.css",
|
||||
"build:css": "rm -rf react-table.css && stylus src/index.styl --compress -o react-table.css && yarn run css:autoprefix",
|
||||
"css:autoprefix": "postcss --use autoprefixer react-table.css -r",
|
||||
"watch": "npm-run-all --parallel watch:*",
|
||||
"watch:node": "onchange 'src/**/*.js' -i -- npm run build:node",
|
||||
"watch:css": "onchange 'src/**/*.styl' -i -- npm run build:css",
|
||||
@@ -42,7 +43,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@kadira/storybook": "^2.35.1",
|
||||
"autoprefixer-stylus": "^0.13.0",
|
||||
"autoprefixer": "^6.7.0",
|
||||
"babel-cli": "6.14.0",
|
||||
"babel-eslint": "6.1.2",
|
||||
"babel-preset-es2015": "6.14.0",
|
||||
@@ -54,12 +55,14 @@
|
||||
"html-loader": "^0.4.4",
|
||||
"markdown-loader": "^0.1.7",
|
||||
"namor": "^0.3.0",
|
||||
"nib": "^1.1.2",
|
||||
"npm-run-all": "^3.1.1",
|
||||
"onchange": "^3.0.2",
|
||||
"postcss-cli": "^2.6.0",
|
||||
"react": "^15.4.2",
|
||||
"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.
Binary file not shown.
@@ -0,0 +1,398 @@
|
||||
import _ from './utils'
|
||||
|
||||
export default {
|
||||
getDataModel (nextProps, nextState) {
|
||||
const {
|
||||
columns,
|
||||
pivotBy = [],
|
||||
data,
|
||||
pivotIDKey,
|
||||
pivotValKey,
|
||||
subRowsKey,
|
||||
expanderColumnWidth,
|
||||
SubComponent,
|
||||
page,
|
||||
pages,
|
||||
pageSize
|
||||
} = this.getResolvedState(nextProps, nextState)
|
||||
|
||||
// Determine Header Groups
|
||||
let hasHeaderGroups = false
|
||||
columns.forEach(column => {
|
||||
if (column.columns) {
|
||||
hasHeaderGroups = true
|
||||
}
|
||||
})
|
||||
|
||||
// Build Header Groups
|
||||
const headerGroups = []
|
||||
let currentSpan = []
|
||||
|
||||
// A convenience function to add a header and reset the currentSpan
|
||||
const addHeader = (columns, column = columns[0]) => {
|
||||
headerGroups.push({
|
||||
...this.props.column,
|
||||
...column,
|
||||
columns: columns
|
||||
})
|
||||
currentSpan = []
|
||||
}
|
||||
|
||||
const noSubExpanderColumns = columns.map(col => {
|
||||
return {
|
||||
...col,
|
||||
columns: col.columns ? col.columns.filter(d => !d.expander) : undefined
|
||||
}
|
||||
})
|
||||
|
||||
let expanderColumnIndex = columns.findIndex(col => col.expander)
|
||||
const needsExpander = (SubComponent || pivotBy.length) && expanderColumnIndex === -1
|
||||
const columnsWithExpander = needsExpander ? [{expander: true}, ...noSubExpanderColumns] : noSubExpanderColumns
|
||||
if (needsExpander) {
|
||||
expanderColumnIndex = 0
|
||||
}
|
||||
|
||||
const makeDecoratedColumn = (column) => {
|
||||
const dcol = {
|
||||
...this.props.column,
|
||||
...column
|
||||
}
|
||||
|
||||
if (dcol.expander) {
|
||||
dcol.width = expanderColumnWidth
|
||||
return dcol
|
||||
}
|
||||
|
||||
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.accessor && !dcol.id) {
|
||||
console.warn(dcol)
|
||||
throw new Error('A column id is required if using a non-string accessor for column above.')
|
||||
}
|
||||
|
||||
if (!dcol.accessor) {
|
||||
dcol.accessor = d => undefined
|
||||
}
|
||||
|
||||
// Ensure minWidth is not greater than maxWidth if set
|
||||
if (dcol.maxWidth < dcol.minWidth) {
|
||||
dcol.minWidth = dcol.maxWidth
|
||||
}
|
||||
|
||||
return dcol
|
||||
}
|
||||
|
||||
// Decorate the columns
|
||||
const decorateAndAddToAll = (col) => {
|
||||
const decoratedColumn = makeDecoratedColumn(col)
|
||||
allDecoratedColumns.push(decoratedColumn)
|
||||
return decoratedColumn
|
||||
}
|
||||
let allDecoratedColumns = []
|
||||
const decoratedColumns = columnsWithExpander.map((column, i) => {
|
||||
if (column.columns) {
|
||||
return {
|
||||
...column,
|
||||
columns: column.columns.map(decorateAndAddToAll)
|
||||
}
|
||||
} else {
|
||||
return decorateAndAddToAll(column)
|
||||
}
|
||||
})
|
||||
|
||||
// Build the visible columns, headers and flat column list
|
||||
let visibleColumns = decoratedColumns.slice()
|
||||
let allVisibleColumns = []
|
||||
|
||||
visibleColumns = visibleColumns.map((column, i) => {
|
||||
if (column.columns) {
|
||||
const visibleSubColumns = column.columns.filter(d => pivotBy.indexOf(d.id) > -1 ? false : _.getFirstDefined(d.show, true))
|
||||
return {
|
||||
...column,
|
||||
columns: visibleSubColumns
|
||||
}
|
||||
}
|
||||
return column
|
||||
})
|
||||
|
||||
visibleColumns = visibleColumns.filter(column => {
|
||||
return column.columns ? column.columns.length : pivotBy.indexOf(column.id) > -1 ? false : _.getFirstDefined(column.show, true)
|
||||
})
|
||||
|
||||
// Move the pivot columns into a single column if needed
|
||||
if (pivotBy.length) {
|
||||
const pivotColumns = []
|
||||
for (var i = 0; i < allDecoratedColumns.length; i++) {
|
||||
if (pivotBy.indexOf(allDecoratedColumns[i].id) > -1) {
|
||||
pivotColumns.push(allDecoratedColumns[i])
|
||||
}
|
||||
}
|
||||
const pivotColumn = {
|
||||
...pivotColumns[0],
|
||||
pivotColumns,
|
||||
expander: true
|
||||
}
|
||||
visibleColumns[expanderColumnIndex] = pivotColumn
|
||||
}
|
||||
|
||||
// Build flast list of allVisibleColumns and HeaderGroups
|
||||
visibleColumns.forEach((column, i) => {
|
||||
if (column.columns) {
|
||||
allVisibleColumns = allVisibleColumns.concat(column.columns)
|
||||
if (currentSpan.length > 0) {
|
||||
addHeader(currentSpan)
|
||||
}
|
||||
addHeader(column.columns, column)
|
||||
return
|
||||
}
|
||||
allVisibleColumns.push(column)
|
||||
currentSpan.push(column)
|
||||
})
|
||||
if (hasHeaderGroups && currentSpan.length > 0) {
|
||||
addHeader(currentSpan)
|
||||
}
|
||||
|
||||
// Access the data
|
||||
let resolvedData = data.map((d, i) => {
|
||||
const row = {
|
||||
__original: d,
|
||||
__index: i
|
||||
}
|
||||
allDecoratedColumns.forEach(column => {
|
||||
if (column.expander) return
|
||||
row[column.id] = column.accessor(d)
|
||||
})
|
||||
return row
|
||||
})
|
||||
|
||||
// If pivoting, recursively group the data
|
||||
const aggregate = (rows) => {
|
||||
const aggregationValues = {}
|
||||
aggregatingColumns.forEach(column => {
|
||||
const values = rows.map(d => d[column.id])
|
||||
aggregationValues[column.id] = column.aggregate(values, rows)
|
||||
})
|
||||
return aggregationValues
|
||||
}
|
||||
let standardColumns = pivotBy.length ? allVisibleColumns.slice(1) : allVisibleColumns
|
||||
const aggregatingColumns = standardColumns.filter(d => d.aggregate)
|
||||
let pivotColumn
|
||||
if (pivotBy.length) {
|
||||
pivotColumn = allVisibleColumns[0]
|
||||
const groupRecursively = (rows, keys, i = 0) => {
|
||||
// This is the last level, just return the rows
|
||||
if (i === keys.length) {
|
||||
return rows
|
||||
}
|
||||
// Group the rows together for this level
|
||||
let groupedRows = Object.entries(
|
||||
_.groupBy(rows, keys[i]))
|
||||
.map(([key, value]) => {
|
||||
return {
|
||||
[pivotIDKey]: keys[i],
|
||||
[pivotValKey]: key,
|
||||
[keys[i]]: key,
|
||||
[subRowsKey]: value
|
||||
}
|
||||
}
|
||||
)
|
||||
// Recurse into the subRows
|
||||
groupedRows = groupedRows.map(rowGroup => {
|
||||
let subRows = groupRecursively(rowGroup[subRowsKey], keys, i + 1)
|
||||
return {
|
||||
...rowGroup,
|
||||
[subRowsKey]: subRows,
|
||||
...aggregate(subRows)
|
||||
}
|
||||
})
|
||||
return groupedRows
|
||||
}
|
||||
resolvedData = groupRecursively(resolvedData, pivotBy)
|
||||
}
|
||||
|
||||
const newPages = _.getFirstDefined(pages, Math.ceil(resolvedData.length / pageSize))
|
||||
const newPage = page > newPages ? newPage - 1 : page
|
||||
|
||||
return {
|
||||
resolvedData,
|
||||
pivotColumn,
|
||||
allVisibleColumns,
|
||||
headerGroups,
|
||||
allDecoratedColumns,
|
||||
hasHeaderGroups,
|
||||
page: Math.max(newPage, 0)
|
||||
}
|
||||
},
|
||||
getSortedData (resolvedState) {
|
||||
const {
|
||||
manual,
|
||||
sorting,
|
||||
resolvedData
|
||||
} = resolvedState
|
||||
|
||||
// Resolve the data from either manual data or sorted data
|
||||
return {
|
||||
sortedData: manual ? resolvedData : this.sortData(resolvedData, sorting)
|
||||
}
|
||||
},
|
||||
|
||||
fireOnChange () {
|
||||
this.props.onChange(this.getResolvedState(), this)
|
||||
},
|
||||
getPropOrState (key) {
|
||||
return _.getFirstDefined(this.props[key], this.state[key])
|
||||
},
|
||||
getStateOrProp (key) {
|
||||
return _.getFirstDefined(this.state[key], this.props[key])
|
||||
},
|
||||
sortData (data, sorting) {
|
||||
if (!sorting.length) {
|
||||
return data
|
||||
}
|
||||
const sorted = _.orderBy(data, sorting.map(sort => {
|
||||
return row => {
|
||||
if (row[sort.id] === null || row[sort.id] === undefined) {
|
||||
return -Infinity
|
||||
}
|
||||
return typeof row[sort.id] === 'string' ? row[sort.id].toLowerCase() : row[sort.id]
|
||||
}
|
||||
}), sorting.map(d => !d.desc))
|
||||
|
||||
return sorted.map(row => {
|
||||
if (!row[this.props.subRowsKey]) {
|
||||
return row
|
||||
}
|
||||
return {
|
||||
...row,
|
||||
[this.props.subRowsKey]: this.sortData(row[this.props.subRowsKey], sorting)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getMinRows () {
|
||||
return _.getFirstDefined(this.props.minRows, this.getStateOrProp('pageSize'))
|
||||
},
|
||||
|
||||
// User actions
|
||||
onPageChange (page) {
|
||||
const { onPageChange } = this.props
|
||||
if (onPageChange) {
|
||||
return onPageChange(page)
|
||||
}
|
||||
this.setStateWithData({
|
||||
expandedRows: {},
|
||||
page
|
||||
}, () => {
|
||||
this.fireOnChange()
|
||||
})
|
||||
},
|
||||
onPageSizeChange (newPageSize) {
|
||||
const { onPageSizeChange } = this.props
|
||||
const { pageSize, page } = this.getResolvedState()
|
||||
|
||||
// Normalize the page to display
|
||||
const currentRow = pageSize * page
|
||||
const newPage = Math.floor(currentRow / newPageSize)
|
||||
|
||||
if (onPageSizeChange) {
|
||||
return onPageSizeChange(newPageSize, newPage)
|
||||
}
|
||||
|
||||
this.setStateWithData({
|
||||
pageSize: newPageSize,
|
||||
page: newPage
|
||||
}, () => {
|
||||
this.fireOnChange()
|
||||
})
|
||||
},
|
||||
sortColumn (column, additive) {
|
||||
const { sorting } = this.getResolvedState()
|
||||
const { onSortingChange } = this.props
|
||||
if (onSortingChange) {
|
||||
return onSortingChange(column, additive)
|
||||
}
|
||||
let newSorting = _.clone(sorting || []).map(d => {
|
||||
d.desc = _.isSortingDesc(d)
|
||||
return d
|
||||
})
|
||||
if (!_.isArray(column)) {
|
||||
// Single-Sort
|
||||
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
|
||||
newSorting = [existing]
|
||||
}
|
||||
} else {
|
||||
existing.desc = true
|
||||
if (!additive) {
|
||||
newSorting = [existing]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (additive) {
|
||||
newSorting.push({
|
||||
id: column.id,
|
||||
desc: false
|
||||
})
|
||||
} else {
|
||||
newSorting = [{
|
||||
id: column.id,
|
||||
desc: false
|
||||
}]
|
||||
}
|
||||
}
|
||||
} 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,
|
||||
sorting: newSorting
|
||||
}, () => {
|
||||
this.fireOnChange()
|
||||
})
|
||||
}
|
||||
}
|
||||
+578
-667
File diff suppressed because it is too large
Load Diff
@@ -170,6 +170,18 @@ $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
|
||||
|
||||
+42
-9
@@ -6,16 +6,19 @@ export default {
|
||||
set,
|
||||
takeRight,
|
||||
last,
|
||||
sortBy,
|
||||
orderBy,
|
||||
range,
|
||||
remove,
|
||||
clone,
|
||||
getFirstDefined,
|
||||
sum,
|
||||
makeTemplateComponent,
|
||||
prefixAll,
|
||||
groupBy,
|
||||
isArray
|
||||
isArray,
|
||||
splitProps,
|
||||
compactObject,
|
||||
isSortingDesc,
|
||||
normalizeComponent
|
||||
}
|
||||
|
||||
function get (obj, path, def) {
|
||||
@@ -61,7 +64,7 @@ function range (n) {
|
||||
return arr
|
||||
}
|
||||
|
||||
function sortBy (arr, funcs, dirs) {
|
||||
function orderBy (arr, funcs, dirs) {
|
||||
return arr.sort((a, b) => {
|
||||
for (let i = 0; i < funcs.length; i++) {
|
||||
const comp = funcs[i]
|
||||
@@ -75,7 +78,9 @@ function sortBy (arr, funcs, dirs) {
|
||||
return desc ? 1 : -1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
return dirs[0]
|
||||
? a.__index - b.__index
|
||||
: b.__index - b.__index
|
||||
})
|
||||
}
|
||||
|
||||
@@ -128,10 +133,6 @@ function makeTemplateComponent (compClass) {
|
||||
)
|
||||
}
|
||||
|
||||
function prefixAll (obj) {
|
||||
return obj
|
||||
}
|
||||
|
||||
function groupBy (xs, key) {
|
||||
return xs.reduce((rv, x, i) => {
|
||||
const resKey = typeof key === 'function' ? key(x, i) : x[key]
|
||||
@@ -167,3 +168,35 @@ function flattenDeep (arr, newArr = []) {
|
||||
}
|
||||
return newArr
|
||||
}
|
||||
|
||||
function splitProps ({className, style, ...rest}) {
|
||||
return {
|
||||
className,
|
||||
style,
|
||||
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
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
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>
|
||||
<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'}}>
|
||||
<br />
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>
|
||||
<CodeHighlight>{() => getCode()}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
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'
|
||||
}]
|
||||
}]
|
||||
|
||||
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
|
||||
})
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
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',
|
||||
render: row => {
|
||||
return <span>{row.aggregated ? '...' : row.value}</span>
|
||||
}
|
||||
}, {
|
||||
header: 'Last Name',
|
||||
id: 'lastName',
|
||||
accessor: d => d.lastName
|
||||
}]
|
||||
}, {
|
||||
header: 'Info',
|
||||
columns: [{
|
||||
header: 'Age',
|
||||
accessor: 'age',
|
||||
aggregate: vals => _.round(_.mean(vals)),
|
||||
render: row => {
|
||||
return <span>{row.aggregated ? `${row.value} (avg)` : row.value}</span>
|
||||
}
|
||||
}]
|
||||
}, {
|
||||
expander: true
|
||||
}]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
SubComponent={() => <span>Hello</span>}
|
||||
/>
|
||||
</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',
|
||||
render: row => {
|
||||
return <span>{row.aggregated ? '...' : row.value}</span>
|
||||
}
|
||||
}, {
|
||||
header: 'Last Name',
|
||||
id: 'lastName',
|
||||
accessor: d => d.lastName
|
||||
}]
|
||||
}, {
|
||||
header: 'Info',
|
||||
columns: [{
|
||||
header: 'Age',
|
||||
accessor: 'age',
|
||||
aggregate: vals => _.round(_.mean(vals)),
|
||||
render: row => {
|
||||
return <span>{row.aggregated ? \`$\{row.value} (avg)\` : row.value}</span>
|
||||
}
|
||||
}]
|
||||
}, {
|
||||
expander: true
|
||||
}]
|
||||
|
||||
return (
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
SubComponent={() => <span>Hello</span>}
|
||||
/>
|
||||
)
|
||||
`
|
||||
}
|
||||
@@ -24,14 +24,14 @@ export default () => {
|
||||
header: 'Last Name',
|
||||
id: 'lastName',
|
||||
accessor: d => d.lastName,
|
||||
maxWidth: 400
|
||||
width: 300
|
||||
}]
|
||||
}, {
|
||||
header: 'Info',
|
||||
columns: [{
|
||||
header: 'Age',
|
||||
accessor: 'age',
|
||||
maxWidth: 60
|
||||
minWidth: 400
|
||||
}]
|
||||
}]
|
||||
|
||||
@@ -68,14 +68,14 @@ const columns = [{
|
||||
header: 'Last Name',
|
||||
id: 'lastName',
|
||||
accessor: d => d.lastName,
|
||||
maxWidth: 400
|
||||
width: 300
|
||||
}]
|
||||
}, {
|
||||
header: 'Info',
|
||||
columns: [{
|
||||
header: 'Age',
|
||||
accessor: 'age',
|
||||
maxWidth: 60
|
||||
minWidth: 400
|
||||
}]
|
||||
}]
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
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={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
defaultSorting={[{
|
||||
id: 'age',
|
||||
desc: true
|
||||
}]}
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<br />
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>
|
||||
<CodeHighlight>{() => getCode()}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
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'
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
defaultSorting={[{
|
||||
id: 'age',
|
||||
desc: true
|
||||
}]}
|
||||
/>
|
||||
)
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
import JSONTree from 'react-json-tree'
|
||||
|
||||
import CodeHighlight from './components/codeHighlight'
|
||||
import ReactTable from '../src/index'
|
||||
|
||||
const JSONtheme = {
|
||||
scheme: 'monokai',
|
||||
author: 'wimer hazenberg (http://www.monokai.nl)',
|
||||
base00: '#272822',
|
||||
base01: '#383830',
|
||||
base02: '#49483e',
|
||||
base03: '#75715e',
|
||||
base04: '#a59f85',
|
||||
base05: '#f8f8f2',
|
||||
base06: '#f5f4f1',
|
||||
base07: '#f9f8f5',
|
||||
base08: '#f92672',
|
||||
base09: '#fd971f',
|
||||
base0A: '#f4bf75',
|
||||
base0B: '#a6e22e',
|
||||
base0C: '#a1efe4',
|
||||
base0D: '#66d9ef',
|
||||
base0E: '#ae81ff',
|
||||
base0F: '#cc6633'
|
||||
}
|
||||
|
||||
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={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
>
|
||||
{(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>{() => 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'
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
>
|
||||
{(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>
|
||||
)
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
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,15 +100,24 @@ const columns = [{
|
||||
header: 'Info',
|
||||
columns: [{
|
||||
header: 'Age',
|
||||
accessor: '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)
|
||||
}]
|
||||
}]
|
||||
|
||||
export default (
|
||||
return (
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
className='-striped -highlight'
|
||||
pivotBy={['firstName', 'lastName']}
|
||||
SubComponent={(row) => {
|
||||
return (
|
||||
|
||||
+12
-31
@@ -50,12 +50,6 @@ export default () => {
|
||||
className='-striped -highlight'
|
||||
defaultPageSize={10}
|
||||
pivotBy={['firstName', 'lastName']}
|
||||
// expandedRows={{
|
||||
// 2: true,
|
||||
// 3: {
|
||||
// 2: true
|
||||
// }
|
||||
// }}
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
@@ -83,38 +77,25 @@ const columns = [{
|
||||
header: 'Info',
|
||||
columns: [{
|
||||
header: 'Age',
|
||||
accessor: '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)
|
||||
}]
|
||||
}]
|
||||
|
||||
export default (
|
||||
return (
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
className='-striped -highlight'
|
||||
defaultPageSize={10}
|
||||
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>
|
||||
)
|
||||
}}
|
||||
pivotBy={['firstName', 'lastName']}
|
||||
/>
|
||||
)
|
||||
`
|
||||
|
||||
@@ -100,15 +100,24 @@ const columns = [{
|
||||
header: 'Info',
|
||||
columns: [{
|
||||
header: 'Age',
|
||||
accessor: '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)
|
||||
}]
|
||||
}]
|
||||
|
||||
export default (
|
||||
return (
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
className='-striped -highlight'
|
||||
pivotBy={['firstName', 'lastName']}
|
||||
SubComponent={(row) => {
|
||||
return (
|
||||
|
||||
@@ -125,4 +125,4 @@ export default (
|
||||
/>
|
||||
)
|
||||
`
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user