mirror of
https://github.com/gosticks/react-table.git
synced 2026-08-19 16:30:21 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa48ef57ee | ||
|
|
22f79fcd28 | ||
|
|
ff8e24760a | ||
|
|
f1511bd27e | ||
|
|
4733997c26 | ||
|
|
c3a6e236ae | ||
|
|
83200d4e4c | ||
|
|
5e16c2cb24 | ||
|
|
66cee186a3 | ||
|
|
55bbf4bf37 | ||
|
|
10ce93344c | ||
|
|
114621a359 | ||
|
|
8de0fa420b | ||
|
|
aa77193810 | ||
|
|
92c33de7ac | ||
|
|
c3fb084550 | ||
|
|
04c71f17a8 | ||
|
|
34fa57c4d3 | ||
|
|
de1c8a6156 |
+10
-2
@@ -12,12 +12,16 @@ 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'
|
||||
//
|
||||
configure(() => {
|
||||
storiesOf('1. Docs')
|
||||
@@ -35,10 +39,14 @@ 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)
|
||||
}, module)
|
||||
|
||||
@@ -43,21 +43,28 @@
|
||||
- [Data](#data)
|
||||
- [Props](#props)
|
||||
- [Columns](#columns)
|
||||
- [Column Header Groups](#column-header-groups)
|
||||
- [Custom Cell & Header Rendering](#custom-cell--and-header-rendering)
|
||||
- [Styles](#styles)
|
||||
- [Header Groups](#header-groups)
|
||||
- [Custom Props](#custom-props)
|
||||
- [Pivoting & Aggregation](#pivoting--aggregation)
|
||||
- [Sub Tables & Sub Components](#sub-tables--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
|
||||
@@ -120,55 +127,87 @@ 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,
|
||||
|
||||
// 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: () => ({}),
|
||||
|
||||
// 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',
|
||||
|
||||
// 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 +223,7 @@ Object.assign(ReactTableDefaults, {
|
||||
})
|
||||
```
|
||||
|
||||
Or just define them on the component per-instance
|
||||
Or just define them as props
|
||||
|
||||
```javascript
|
||||
<ReactTable
|
||||
@@ -205,13 +244,18 @@ Or just define them on the component per-instance
|
||||
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 +273,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,6 +292,148 @@ const columns = [{
|
||||
}]
|
||||
```
|
||||
|
||||
## 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
|
||||
- `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 & 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.
|
||||
@@ -376,6 +555,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.2dea77e688032cb54b25.bundle.js"></script>
|
||||
<script src="static/preview.ee446fa2bd3fbfe7e38a.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.f127c5ae855df8d8558a.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.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.2dea77e688032cb54b25.bundle.js","sources":["webpack:///static/preview.2dea77e688032cb54b25.bundle.js"],"mappings":"AAAA;AAwxDA;AA45DA;AA4rDA;AAgjFA;AAy+FA;AAomJA;AAloHA;AAgsWA;AAm0DA;AA4kEA;AA+nDA;AAw8CA;AAkjEA;AA0oDA;AAq8CA;AAqoDA;AAksEA;AAwrDA;AAiuCA;AAopDA;AA0kDA;AAyqEA;AAu2DA;AAgpDA;AAwkDA;AAm5EA;AA0mHA;AAmrDA;AA6/BA;AAw9CA;AA6ZA;AAw8CA","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":""}
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-table",
|
||||
"version": "4.2.8",
|
||||
"version": "5.0.2",
|
||||
"description": "A fast, lightweight, opinionated table and datagrid built on React",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/tannerlinsley/react-table#readme",
|
||||
@@ -60,6 +60,7 @@
|
||||
"postcss-cli": "^2.6.0",
|
||||
"react": "^15.4.2",
|
||||
"react-dom": "^15.4.2",
|
||||
"react-json-tree": "^0.10.1",
|
||||
"standard": "^8.0.0",
|
||||
"stylus": "^0.54.5",
|
||||
"uglifyify": "3.0.3"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,405 @@
|
||||
import _ from './utils'
|
||||
|
||||
export default {
|
||||
getDataModel (nextProps, nextState) {
|
||||
const {
|
||||
columns,
|
||||
pivotBy = [],
|
||||
data,
|
||||
pivotIDKey,
|
||||
pivotValKey,
|
||||
subRowsKey,
|
||||
expanderColumnWidth,
|
||||
SubComponent
|
||||
} = 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)
|
||||
}
|
||||
|
||||
return {
|
||||
resolvedData,
|
||||
pivotColumn,
|
||||
allVisibleColumns,
|
||||
headerGroups,
|
||||
allDecoratedColumns,
|
||||
hasHeaderGroups
|
||||
}
|
||||
},
|
||||
getSortedData (nextProps, nextState) {
|
||||
const {
|
||||
manual,
|
||||
sorting,
|
||||
allDecoratedColumns,
|
||||
resolvedData
|
||||
} = this.getResolvedState(nextProps, nextState)
|
||||
|
||||
const resolvedSorting = sorting.length ? sorting : this.getInitSorting(allDecoratedColumns)
|
||||
|
||||
// Resolve the data from either manual data or sorted data
|
||||
return {
|
||||
resolvedSorting,
|
||||
sortedData: manual ? resolvedData : this.sortData(resolvedData, resolvedSorting)
|
||||
}
|
||||
},
|
||||
|
||||
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])
|
||||
},
|
||||
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) {
|
||||
return -Infinity
|
||||
}
|
||||
return typeof row[sort.id] === 'string' ? row[sort.id].toLowerCase() : row[sort.id]
|
||||
}
|
||||
}), sorting.map(d => d.asc ? 'asc' : '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 || [])
|
||||
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.asc) {
|
||||
existing.asc = false
|
||||
if (!additive) {
|
||||
newSorting = [existing]
|
||||
}
|
||||
} else {
|
||||
if (additive) {
|
||||
newSorting.splice(existingIndex, 1)
|
||||
} else {
|
||||
existing.asc = true
|
||||
newSorting = [existing]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (additive) {
|
||||
newSorting.push({
|
||||
id: column.id,
|
||||
asc: true
|
||||
})
|
||||
} else {
|
||||
newSorting = [{
|
||||
id: column.id,
|
||||
asc: true
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
this.setStateWithData({
|
||||
page: ((!sorting.length && newSorting.length) || !additive) ? 0 : this.state.page,
|
||||
sorting: newSorting
|
||||
}, () => {
|
||||
this.fireOnChange()
|
||||
})
|
||||
}
|
||||
}
|
||||
+509
-642
File diff suppressed because it is too large
Load Diff
+15
-9
@@ -6,16 +6,16 @@ export default {
|
||||
set,
|
||||
takeRight,
|
||||
last,
|
||||
sortBy,
|
||||
orderBy,
|
||||
range,
|
||||
remove,
|
||||
clone,
|
||||
getFirstDefined,
|
||||
sum,
|
||||
makeTemplateComponent,
|
||||
prefixAll,
|
||||
groupBy,
|
||||
isArray
|
||||
isArray,
|
||||
splitProps
|
||||
}
|
||||
|
||||
function get (obj, path, def) {
|
||||
@@ -61,7 +61,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 +75,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 +130,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 +165,11 @@ function flattenDeep (arr, newArr = []) {
|
||||
}
|
||||
return newArr
|
||||
}
|
||||
|
||||
function splitProps ({className, style, ...rest}) {
|
||||
return {
|
||||
className,
|
||||
style,
|
||||
rest
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
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}
|
||||
/>
|
||||
</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}
|
||||
/>
|
||||
)
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
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
|
||||
}]
|
||||
}, {
|
||||
expander: true
|
||||
}, {
|
||||
header: 'Info',
|
||||
columns: [{
|
||||
header: 'Age',
|
||||
accessor: 'age',
|
||||
aggregate: vals => _.round(_.mean(vals)),
|
||||
render: row => {
|
||||
return <span>{row.aggregated ? \`$\{row.value} (avg)\` : row.value}</span>
|
||||
}
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
SubComponent={() => <span>Hello</span>}
|
||||
pivotBy={['lastName']}
|
||||
/>
|
||||
)
|
||||
`
|
||||
}
|
||||
@@ -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,87 @@
|
||||
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',
|
||||
sort: 'desc'
|
||||
}]
|
||||
}]
|
||||
|
||||
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}
|
||||
/>
|
||||
)
|
||||
`
|
||||
}
|
||||
@@ -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>
|
||||
)
|
||||
`
|
||||
}
|
||||
@@ -181,6 +181,10 @@ align-text@^0.1.1, align-text@^0.1.3:
|
||||
longest "^1.0.1"
|
||||
repeat-string "^1.5.2"
|
||||
|
||||
almost-equal@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/almost-equal/-/almost-equal-1.1.0.tgz#f851c631138757994276aa2efbe8dfa3066cccdd"
|
||||
|
||||
alphanum-sort@^1.0.1, alphanum-sort@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
|
||||
@@ -348,26 +352,7 @@ asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
|
||||
autoprefixer-stylus@^0.13.0:
|
||||
version "0.13.0"
|
||||
resolved "https://registry.yarnpkg.com/autoprefixer-stylus/-/autoprefixer-stylus-0.13.0.tgz#cc2a864e121fad691421c82d9f3e4328137b7df4"
|
||||
dependencies:
|
||||
autoprefixer "6.6.1"
|
||||
multi-stage-sourcemap "0.2.1"
|
||||
postcss "5.2.8"
|
||||
|
||||
autoprefixer@6.6.1, autoprefixer@^6.3.1, autoprefixer@^6.3.7:
|
||||
version "6.6.1"
|
||||
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.6.1.tgz#11a4077abb4b313253ec2f6e1adb91ad84253519"
|
||||
dependencies:
|
||||
browserslist "~1.5.1"
|
||||
caniuse-db "^1.0.30000604"
|
||||
normalize-range "^0.1.2"
|
||||
num2fraction "^1.2.2"
|
||||
postcss "^5.2.8"
|
||||
postcss-value-parser "^3.2.3"
|
||||
|
||||
autoprefixer@^6.7.0:
|
||||
autoprefixer@^6.3.1, autoprefixer@^6.3.7, autoprefixer@^6.7.0:
|
||||
version "6.7.0"
|
||||
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.0.tgz#88992cf04df141e7b8293550f2ee716c565d1cae"
|
||||
dependencies:
|
||||
@@ -1190,7 +1175,7 @@ babel-runtime@6.11.6:
|
||||
core-js "^2.4.0"
|
||||
regenerator-runtime "^0.9.5"
|
||||
|
||||
babel-runtime@6.x.x, babel-runtime@^6.0.0, babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.5.0, babel-runtime@^6.9.0, babel-runtime@^6.9.1, babel-runtime@^6.9.2:
|
||||
babel-runtime@6.x.x, babel-runtime@^6.0.0, babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.5.0, babel-runtime@^6.6.1, babel-runtime@^6.9.0, babel-runtime@^6.9.1, babel-runtime@^6.9.2:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.22.0.tgz#1cf8b4ac67c77a4ddb0db2ae1f74de52ac4ca611"
|
||||
dependencies:
|
||||
@@ -1249,6 +1234,10 @@ balanced-match@^0.4.1, balanced-match@^0.4.2:
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
|
||||
|
||||
base16@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/base16/-/base16-1.0.0.tgz#e297f60d7ec1014a7a971a39ebc8a98c0b681e70"
|
||||
|
||||
base64-js@^1.0.2:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1"
|
||||
@@ -1441,13 +1430,7 @@ browserify@13.1.0:
|
||||
vm-browserify "~0.0.1"
|
||||
xtend "^4.0.0"
|
||||
|
||||
browserslist@^1.0.1, browserslist@^1.4.0, browserslist@^1.5.2, browserslist@~1.5.1:
|
||||
version "1.5.2"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.5.2.tgz#1c82fde0ee8693e6d15c49b7bff209dc06298c56"
|
||||
dependencies:
|
||||
caniuse-db "^1.0.30000604"
|
||||
|
||||
browserslist@~1.6.0:
|
||||
browserslist@^1.0.1, browserslist@^1.4.0, browserslist@^1.5.2, browserslist@~1.6.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.6.0.tgz#85fb7c993540d3fda31c282baf7f5aee698ac9ee"
|
||||
dependencies:
|
||||
@@ -1528,7 +1511,7 @@ caniuse-api@^1.5.2:
|
||||
lodash.uniq "^4.3.0"
|
||||
shelljs "^0.7.0"
|
||||
|
||||
caniuse-db@^1.0.30000346, caniuse-db@^1.0.30000604, caniuse-db@^1.0.30000613:
|
||||
caniuse-db@^1.0.30000346, caniuse-db@^1.0.30000613:
|
||||
version "1.0.30000617"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000617.tgz#9b7fd81f58a35526315c83e60cb5f076f0beb392"
|
||||
|
||||
@@ -1662,6 +1645,13 @@ color-name@^1.0.0, color-name@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689"
|
||||
|
||||
color-space@^1.14.3:
|
||||
version "1.14.7"
|
||||
resolved "https://registry.yarnpkg.com/color-space/-/color-space-1.14.7.tgz#b7f5a31779427bb25f9927a69410d80c2eaaa71b"
|
||||
dependencies:
|
||||
husl "^5.0.0"
|
||||
mumath "^3.0.0"
|
||||
|
||||
color-string@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/color-string/-/color-string-0.3.0.tgz#27d46fb67025c5c2fa25993bfbf579e47841b991"
|
||||
@@ -2962,6 +2952,10 @@ https-browserify@0.0.1, https-browserify@~0.0.0:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82"
|
||||
|
||||
husl@^5.0.0:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.yarnpkg.com/husl/-/husl-5.0.3.tgz#ee272aaff1bebe40df3588ed007b70de7e679788"
|
||||
|
||||
iconv-lite@0.4.13:
|
||||
version "0.4.13"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2"
|
||||
@@ -3468,6 +3462,14 @@ lodash.camelcase@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
|
||||
|
||||
lodash.curry@^4.0.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.curry/-/lodash.curry-4.1.1.tgz#248e36072ede906501d75966200a86dab8b23170"
|
||||
|
||||
lodash.flow@^3.3.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a"
|
||||
|
||||
lodash.indexof@^4.0.5:
|
||||
version "4.0.5"
|
||||
resolved "https://registry.yarnpkg.com/lodash.indexof/-/lodash.indexof-4.0.5.tgz#53714adc2cddd6ed87638f893aa9b6c24e31ef3c"
|
||||
@@ -3732,11 +3734,11 @@ ms@0.7.2:
|
||||
version "0.7.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765"
|
||||
|
||||
multi-stage-sourcemap@0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/multi-stage-sourcemap/-/multi-stage-sourcemap-0.2.1.tgz#b09fc8586eaa17f81d575c4ad02e0f7a3f6b1105"
|
||||
mumath@^3.0.0:
|
||||
version "3.3.3"
|
||||
resolved "https://registry.yarnpkg.com/mumath/-/mumath-3.3.3.tgz#262e10fcc10699f7050dc707575d39db5c903181"
|
||||
dependencies:
|
||||
source-map "^0.1.34"
|
||||
almost-equal "^1.1.0"
|
||||
|
||||
mute-stream@0.0.5:
|
||||
version "0.0.5"
|
||||
@@ -4449,16 +4451,7 @@ postcss-zindex@^2.0.1:
|
||||
postcss "^5.0.4"
|
||||
uniqs "^2.0.0"
|
||||
|
||||
postcss@5.2.8, postcss@^5.0.0, postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.2.5, postcss@^5.2.8:
|
||||
version "5.2.8"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.8.tgz#05720c49df23c79bda51fd01daeb1e9222e94390"
|
||||
dependencies:
|
||||
chalk "^1.1.3"
|
||||
js-base64 "^2.1.9"
|
||||
source-map "^0.5.6"
|
||||
supports-color "^3.1.2"
|
||||
|
||||
postcss@^5.2.11:
|
||||
postcss@^5.0.0, postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.2.11, postcss@^5.2.5:
|
||||
version "5.2.11"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.11.tgz#ff29bcd6d2efb98bfe08a022055ec599bbe7b761"
|
||||
dependencies:
|
||||
@@ -4540,6 +4533,10 @@ punycode@^1.2.4, punycode@^1.3.2, punycode@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
|
||||
|
||||
pure-color@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/pure-color/-/pure-color-1.2.0.tgz#702d2f2819dd545b1fde5116fca5f0c2dad2d18d"
|
||||
|
||||
q@^1.1.2:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e"
|
||||
@@ -4591,6 +4588,16 @@ rc@~1.1.6:
|
||||
minimist "^1.2.0"
|
||||
strip-json-comments "~1.0.4"
|
||||
|
||||
react-base16-styling@^0.4.1:
|
||||
version "0.4.6"
|
||||
resolved "https://registry.yarnpkg.com/react-base16-styling/-/react-base16-styling-0.4.6.tgz#ac23cb19b278974d965003b88f06a038d790bc80"
|
||||
dependencies:
|
||||
base16 "^1.0.0"
|
||||
color-space "^1.14.3"
|
||||
lodash.curry "^4.0.1"
|
||||
lodash.flow "^3.3.0"
|
||||
pure-color "^1.2.0"
|
||||
|
||||
react-docgen@^2.12.1:
|
||||
version "2.13.0"
|
||||
resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-2.13.0.tgz#7fcc4a3104ea8d4fd428383ba38df11166837be9"
|
||||
@@ -4626,6 +4633,14 @@ react-inspector@^1.1.0:
|
||||
babel-runtime "^6.9.2"
|
||||
is-dom "^1.0.5"
|
||||
|
||||
react-json-tree@^0.10.1:
|
||||
version "0.10.1"
|
||||
resolved "https://registry.yarnpkg.com/react-json-tree/-/react-json-tree-0.10.1.tgz#7f9eab36abf8adf329c7e5ad4091f5987bcbd5de"
|
||||
dependencies:
|
||||
babel-runtime "^6.6.1"
|
||||
react-base16-styling "^0.4.1"
|
||||
react-pure-render "^1.0.2"
|
||||
|
||||
react-komposer@^1.9.0:
|
||||
version "1.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react-komposer/-/react-komposer-1.13.1.tgz#4b8ac4bcc71323bd7413dcab95c831197f50eed0"
|
||||
@@ -4654,6 +4669,10 @@ react-modal@^1.2.0, react-modal@^1.2.1:
|
||||
exenv "1.2.0"
|
||||
lodash.assign "^4.2.0"
|
||||
|
||||
react-pure-render@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-pure-render/-/react-pure-render-1.0.2.tgz#9d8a928c7f2c37513c2d064e57b3e3c356e9fabb"
|
||||
|
||||
react-simple-di@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "http://registry.npmjs.org/react-simple-di/-/react-simple-di-1.2.0.tgz#dde0e5bf689f391ef2ab02c9043b213fe239c6d0"
|
||||
@@ -5141,7 +5160,7 @@ source-map-support@^0.4.2:
|
||||
dependencies:
|
||||
source-map "^0.5.3"
|
||||
|
||||
source-map@0.1.x, source-map@^0.1.34:
|
||||
source-map@0.1.x:
|
||||
version "0.1.43"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346"
|
||||
dependencies:
|
||||
@@ -5366,7 +5385,7 @@ supports-color@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||
|
||||
supports-color@^3.1.0, supports-color@^3.1.2, supports-color@^3.2.3:
|
||||
supports-color@^3.1.0, supports-color@^3.2.3:
|
||||
version "3.2.3"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6"
|
||||
dependencies:
|
||||
|
||||
Reference in New Issue
Block a user