Compare commits

...
36 Commits
Author SHA1 Message Date
Tanner Linsley 0bf363aeaf 4.2.3 2017-01-16 15:52:47 -07:00
Tanner Linsley 517702922e Fix padRows key 2017-01-16 15:52:42 -07:00
Tanner Linsley ba1325336f 4.2.2 2017-01-16 15:01:44 -07:00
Tanner Linsley 7bd30b623c Improved Sorting Performance 2017-01-16 15:01:37 -07:00
Tanner Linsley f72fec3cc2 4.2.1 2017-01-16 14:18:20 -07:00
Tanner Linsley a8a0d1bab8 Fix pageSize bug and 1 Million rows example 2017-01-16 14:18:11 -07:00
Tanner Linsley f06caec053 4.2.0 2017-01-16 13:16:00 -07:00
Tanner Linsley 8fa7975ca5 Pivoting & Aggregation 2017-01-16 13:15:56 -07:00
Tanner Linsley e04a2dee69 Pass standard linting 2017-01-13 10:09:28 -07:00
Tanner Linsley e059ceec75 4.1.1 2017-01-13 09:42:16 -07:00
Tanner Linsley 09f425aeb3 Redux package size to 5kb 2017-01-13 09:42:07 -07:00
Tanner Linsley ca038e9a69 4.1.0 2017-01-12 11:06:20 -07:00
Tanner Linsley 75c31b9354 Fully controlled component props and callbacks + docs 2017-01-12 11:06:09 -07:00
Tanner Linsley 4b2fa4e47d ignore react-storybook in testing 2017-01-11 20:04:32 -07:00
Tanner Linsley 76e92de670 4.0.1 2017-01-11 19:59:03 -07:00
Tanner Linsley 3c5ba2843d Bug fixes and readme updates 2017-01-11 19:58:52 -07:00
Tanner Linsley 1cb280942d Updated Readme 2017-01-11 16:47:56 -07:00
Tanner Linsley c8c650c729 Readme Updates 2017-01-11 16:34:36 -07:00
Tanner Linsley 29eda4dc71 4.0.0 2017-01-11 16:23:52 -07:00
Tanner Linsley e5689bc9d4 New core styling, sub-components, React-Storybook instead of jumpsuit example 2017-01-11 16:23:49 -07:00
Tanner Linsley dd433f7d9c 3.2.1 2017-01-09 13:44:46 -07:00
Tanner Linsley 0daffaf08d Fixed paginationComponent and paginationClassName
Fixes #24 and fixes #25
2017-01-09 13:44:43 -07:00
Tanner Linsley ecd660ef10 3.2.0 2017-01-09 11:57:51 -07:00
DimitryandTanner Linsley be951a3252 onTrClick (#23)
* README: correct watch command

* Add onTrClick handler

* react soften peerDependency: ^15.x.x
2017-01-09 11:38:22 -07:00
Lukas Gisder-DubéandTanner Linsley f195b3243d added props for more pagination customization (#19) 2016-12-15 07:02:25 -07:00
Tanner LinsleyandGitHub 19a0187720 Update README.md 2016-12-08 11:59:46 -07:00
Tanner Linsley d8e5188d94 3.1.4 2016-12-07 13:00:39 -07:00
Tanner Linsley 8c79bf95df Page Size fix 2016-12-07 13:00:27 -07:00
Tanner Linsley 6053c48781 3.1.3 2016-12-07 12:55:10 -07:00
Tanner Linsley 8f1c8774f2 Fixes and use Yarn 2016-12-07 12:55:03 -07:00
Tanner Linsley d5795fb5ac Readme Update 2016-12-06 23:19:00 -07:00
Tanner Linsley 8abbefa680 Readme updates 2016-12-06 13:17:38 -07:00
Tanner Linsley 4db644941a Badges 2016-12-06 13:15:55 -07:00
Pedro Tacla YamadaandTanner Linsley 6905ccae72 Fix typo when overriding pagination components (#17) 2016-11-15 08:56:05 -07:00
Tanner LinsleyandGitHub e832bf52b0 Update README.md 2016-11-07 13:44:31 -07:00
Tanner Linsley 3432fefce2 Example Update 2016-11-02 15:34:00 -06:00
36 changed files with 7939 additions and 934 deletions
+2
View File
@@ -4,3 +4,5 @@ react-table.js
react-table.css
*.log
example/dist/
storybook-static
+40
View File
@@ -0,0 +1,40 @@
import React from 'react'
import { configure, storiesOf } from '@kadira/storybook'
import './reset.css'
import './fonts.css'
import './layout.css'
import '../stories/utils/prism.css'
import 'github-markdown-css/github-markdown.css'
import '../react-table.css'
//
import Readme from '../README.md'
//
import Simple from '../stories/Simple.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'
//
configure(() => {
storiesOf('1. Docs')
.add('Readme', () => {
const ReadmeCmp = React.createClass({
render () {
return <span className='markdown-body' dangerouslySetInnerHTML={{__html: Readme}} />
},
componentDidMount () {
global.Prism.highlightAll()
}
})
return <ReadmeCmp />
})
storiesOf('2. Demos')
.add('Client-side Data', Simple)
.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)
}, module)
+6
View File
@@ -0,0 +1,6 @@
@import url("https://fonts.googleapis.com/css?family=Open+Sans:300,600");
body {
background: #fff;
font-family: 'Open Sans', sans-serif;
font-weight: 300;
}
+3
View File
@@ -0,0 +1,3 @@
body{
padding: 20px;
}
+48
View File
@@ -0,0 +1,48 @@
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
/*ol, ul {
list-style: none;
}*/
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
+27
View File
@@ -0,0 +1,27 @@
const path = require('path')
// load the default config generator.
const genDefaultConfig = require('@kadira/storybook/dist/server/config/defaults/webpack.config.js')
module.exports = (config, env) => {
config = genDefaultConfig(config, env)
Object.assign(config, {
module: Object.assign(config.module, {
loaders: config.module.loaders.concat([{
test: /\.md$/,
loader: 'html!markdown',
include: path.resolve(__dirname, '../')
}, {
test: /\.html$/,
loader: 'html',
query: {
minimize: true
},
include: path.resolve(__dirname, '../')
}])
})
})
return config
}
+147 -52
View File
@@ -1,40 +1,47 @@
![react-table](https://github.com/tannerlinsley/react-table/raw/master/media/Banner.png)
<div align="center">
<a href="https://github.com/tannerlinsley/react-table"><img src="https://github.com/tannerlinsley/react-table/raw/master/media/Banner.png" alt="React Table Logo" style="width:450px;"/></a>
<br />
<br />
# react-table
A fast, lightweight, opinionated table and datagrid built on React
</div>
[![Build Status](https://travis-ci.org/tannerlinsley/react-table.svg?branch=master)](https://travis-ci.org/tannerlinsley/react-table)
[![react-table on Slack](https://img.shields.io/badge/slack-react--table-blue.svg)](https://react-table-slack.herokuapp.com/)
# React Table
`react-table` is a **lightweight, fast and extendable datagrid** built for React
[![Build Status](https://travis-ci.org/tannerlinsley/react-table.svg?branch=master)](https://travis-ci.org/tannerlinsley/react-table) [![npm](https://img.shields.io/npm/dm/react-table.svg)](https://npmjs.com/packag/react-table) [![react-table on Slack](https://img.shields.io/badge/slack-react--table-blue.svg)](https://react-table-slack.herokuapp.com/) [![GitHub stars](https://img.shields.io/github/stars/tannerlinsley/react-table.svg?style=social&label=Star)](https://github.com/tannerlinsley/react-table) [![Twitter Follow](https://img.shields.io/twitter/follow/tannerlinsley.svg?style=social&label=Follow)](https://twitter.com/tannerlinsley)
## Features
- Lightweight at 4kb (and just 2kb more for styles)
- Fully customizable JSX and callbacks for everything
- Supports both Client-side & Server-side pagination and sorting
- Lightweight at 7kb (and just 2kb more for styles)
- Fully customizable JSX templating
- Supports both Client-side & Server-side pagination and multi-sorting
- Column Pivoting & Aggregation
- Minimal design & easily themeable
- ["Why I wrote React Table and the problems it has solved for Nozzle.io"](https://medium.com/@tannerlinsley/why-i-wrote-react-table-and-the-problems-it-has-solved-for-nozzle-others-445c4e93d4a8#.axza4ixba) by Tanner Linsley
- Fully controllable via optional props and callbacks
- <a href="https://medium.com/@tannerlinsley/why-i-wrote-react-table-and-the-problems-it-has-solved-for-nozzle-others-445c4e93d4a8#.axza4ixba" target="\_blank">"Why I wrote React Table and the problems it has solved for Nozzle.io</a> by Tanner Linsley
## [Demo](http://react-table.zabapps.com)
## <a href="http://react-table.zabapps.com/?selectedKind=2.%20Demos&selectedStory=Client-side%20Data&full=0&down=1&left=1&panelRight=0&downPanel=kadirahq%2Fstorybook-addon-actions%2Factions-panel" target="\_blank">Demo</a>
## Table of Contents
- [Installation](#nstallation)
- [Installation](#installation)
- [Example](#example)
- [Data](#data)
- [Default Props](#default-props)
- [Props](#props)
- [Columns](#columns)
- [Styles](#styles)
- [Header Groups](#header-groups)
- [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)
- [Component Overrides](#component-overrides)
<a name="installation"></a>
## Installation
```bash
$ npm install react-table
```
<a name="example"></a>
## Example
```javascript
import ReactTable from 'react-table'
@@ -71,30 +78,34 @@ const columns = [{
/>
```
<a name="data"></a>
## Data
Simply pass the `data` prop anything that resembles an array or object. Client-side filtering and pagination is built in, and your table will update gracefully as you change any props. [Server-side data](#server-side-data) is also supported!
Simply pass the `data` prop anything that resembles an array or object. Client-side sorting and pagination are built in, and your table will update gracefully as you change any props. [Server-side data](#server-side-data) is also supported!
<a name="default-props"></a>
## Default Props
These are the default props for the main react component `<ReactTable />`
## Props
These are all of the available props (and their default values) for the main `<ReactTable />` component.
```javascript
{
// General
loading: false, // Whether to show the loading overlay or not
pageSize: 20, // The default page size (this can be changed by the user if `showPageSizeOptions` is enabled)
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
// 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
// Text
previousText: 'Previous',
nextText: 'Next'
nextText: 'Next',
pageText: 'Page',
ofText: 'of',
rowsText: 'rows',
// Classes
className: '-striped -highlight', // The most top level className for the component
@@ -104,6 +115,7 @@ These are the default props for the main react component `<ReactTable />`
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
@@ -114,6 +126,16 @@ These are the default props for the main react component `<ReactTable />`
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,
}
```
@@ -123,7 +145,7 @@ You can easily override the core defaults like so:
import { ReactTableDefaults } from 'react-table'
Object.assign(ReactTableDefaults, {
pageSize: 10,
defaultPageSize: 10,
minRows: 3,
// etc...
})
@@ -133,15 +155,14 @@ Or just define them on the component per-instance
```javascript
<ReactTable
pageSize={10}
defaultPageSize={10}
minRows={3}
// etc...
/>
/>
```
<a name="columns"></a>
## Columns
`<ReactTable/>` requires a `columns` prop, which is an array of objects with the following properties
`<ReactTable/>` requires a `columns` prop, which is an array of objects containing the following properties
```javascript
[{
@@ -151,13 +172,11 @@ 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
minWidth: Number // Allows the column to flex above this minimum amount
minWidth: 100 // A minimum width for this column. If there is room, columns will flex to fill available space
// Cell Options
className: '', // Set the classname of the `td` element of the column
style: {}, // Set the style of the `td` element of the column
innerClassName: '', // Set the classname of the `.-td-inner` element of the column
innerStyle: {}, // Set the style of the `.-td-inner` element of the column
render: JSX eg. ({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
@@ -169,8 +188,6 @@ Or just define them on the component per-instance
header: 'Header Name' or JSX eg. ({data, column}) => <div>Header Name</div>,
headerClassName: '', // Set the classname of the `th` element of the column
headerStyle: {}, // Set the style of the `th` element of the column
headerInnerClassName: '', // Set the classname of the `.-th-inner` element of the column
headerInnerStyle: {}, // Set the style of the `.th-inner` element of the column
// Header Groups only
columns: [...] // See Header Groups section below
@@ -178,11 +195,9 @@ Or just define them on the component per-instance
}]
```
<a name="styles"></a>
## Styles
React-table is built to be dropped into existing applications or styled from the ground up, but if you'd like a decent starting point, you can optionally include our default theme `react-table.css`. We think it looks great, honestly :)
<a name="header-groups"></a>
## Header Groups
To group columns with another header column, just nest your columns in a header column like so:
```javascript
@@ -201,7 +216,54 @@ const columns = [{
}]
```
<a name="server-side-data"></a>
## Pivoting & Aggregation
Pivoting the table will group records together based on their accessed values and allow the rows in that group to be expanded underneath it.
To pivot, pass an array of `columnID`'s to `pivotBy`. Remember, a column's `id` is either the one that you assign it (when using a custom accessors) or its `accessor` string.
```javascript
<ReactTable
...
pivotBy={['lastName', 'age']}
/>
```
Naturally when grouping rows together, you may want to aggregate the rows inside it into the grouped column. No aggregation is done by default, however, it is very simple to aggregate any pivoted columns:
```javascript
// In this example, we use lodash to sum and average the values, but you can use whatever you want to aggregate.
const columns = [{
header: 'Age',
accessor: 'age',
aggregate: (values, rows) => _.round(_.mean(values)),
render: row => {
// You can even render the cell differently if it's an aggregated cell
return <span>{row.aggregated ? `${row.value} (avg)` : row.value}</span>
}
}, {
header: 'Visits',
accessor: 'visits',
aggregate: (values, rows) => _.sum(values)
}]
```
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
By adding a `SubComponent` props, you can easily add an expansion level to all root-level rows:
```javascript
<ReactTable
data={data}
columns={columns}
defaultPageSize={10}
SubComponent={(row) => {
return (
<div>
You can put any component you want here, even another React Table! You even have access to the row-level data if you need! Spark-charts, drill-throughs, infographics... the possibilities are endless!
</div>
)
}}
/>
```
## Server-side Data
If you want to handle pagination, and sorting on the server, `react-table` makes it easy on you.
@@ -242,38 +304,71 @@ If you want to handle pagination, and sorting on the server, `react-table` makes
For a detailed example, take a peek at our [async table mockup](https://github.com/tannerlinsley/react-table/blob/master/example/src/screens/async.js)
<a name="multi-sort"></a>
## Fully Controlled Component
React Table by default works fantastically out of the box, but you can achieve even more control and customization if you choose to maintain the state yourself. It is very easy to do, even if you only want to manage *parts* of the state.
Here are the props and their corresponding callbacks that control the state of the a table:
```javascript
<ReactTable
// Props
page={0} // the index of the page you wish to display
pageSize={20} // the number of rows per page to be displayed
sorting={[{
id: 'lastName',
asc: true
}, {
id: 'firstName',
asc: true
}]} // the sorting model for the table
expandedRows={{
1: true,
4: true,
5: {
2: true,
3: true
}
}} // The nested row indexes on the current page that should appear expanded
// Callbacks
onPageChange={(pageIndex) => {...}} // Called when the page index is changed by the user
onPageSizeChange={(pageSize, pageIndex) => {...}} // Called when the pageSize is changed by the user. The resolve page is also sent to maintain approximate position in the data
onSortingChange={(column, shiftKey) => {...}} // Called when a sortable column header is clicked with the column itself and if the shiftkey was held. If the column is a pivoted column, `column` will be an array of columns
onExpandRow={(index, event) => {...}} // Called when an expander is clicked. Use this to manage `expandedRows`
/>
```
## 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!
<a name="component-overrides"></a>
## Component Overrides
Though we wouldn't suggest it, `react-table` has the ability to change the core componentry it used to render it's table. You can do so by assigning a react component to it's corresponding global prop, or on a one-off basis like so:
Though we confidently stand by the markup and architecture behind it, `react-table` does offer the ability to change the core componentry it uses to render everything. You can extend or override these internal components by passing a react component to it's corresponding prop on either the global props or on a one-off basis like so:
```javascript
// Change the global default
import { ReactTableDefaults } from 'react-table'
Object.assign(ReactTableDefaults, {
tableComponent: Component,
theadComponent: Component,
tbodyComponent: Component,
trComponent: Component,
thComponent: Component,
tdComponent: Component,
paginationComponent: Component,
previousComponent: Component,
nextComponent: Component,
loadingComponent: Component
TableComponent: Component,
TheadComponent: Component,
TbodyComponent: Component,
TrGroupComponent: Component,
TrComponent: Component,
ThComponent: Component,
TdComponent: Component,
PaginationComponent: Component,
PreviousComponent: Component,
NextComponent: Component,
LoadingComponent: Component,
ExpanderComponent: Component
})
// Or change per instance
<ReactTable
tableComponent={Component},
theadComponent={Component},
TableComponent={Component},
TheadComponent={Component},
// etc...
/>
```
If you choose to change the core components React-Table uses to render, you must make sure your components support and utilized all of the neeeded features for that component to work properly. For a broad reference on how to do this, investigate [the source](https://github.com/tannerlinsley/react-table/blob/master/src/index.js) for the component you wish to replace.
If you choose to change the core components React-Table uses to render, you must make sure your replacement components consume and utilize all of the supplied and inherited props that are needed for that component to function properly. We would suggest investigating [the source](https://github.com/tannerlinsley/react-table/blob/master/src/index.js) for the component you wish to replace.
## Contributing
@@ -282,7 +377,7 @@ If you would like to help develop a suggested feature follow these steps:
- Fork this repo
- `npm install`
- `npm watch`
- `npm run watch`
- Implement your changes to files in the `src/` directory
- Submit PR for review
@@ -292,7 +387,7 @@ If you would like to preview your changes, you can link and utilize the example
- `cd example`
- `npm install`
- `npm link react-table`
- `npm watch`
- `npm run watch`
- Make changes to the example in `src/screens/index.js` if needed
- View changes at `localhost:8000`
-1
View File
@@ -1 +0,0 @@
# Jumpsuit Getting Started
-28
View File
@@ -1,28 +0,0 @@
var fs = require('fs')
var path = require('path')
var stylus = require('stylus')
var nib = require('nib')
var stylusEntry = path.resolve('src/app.styl')
module.exports = {
styles: {
extensions: ['.css', '.styl'],
action: buildStyles
}
}
function buildStyles () {
return new Promise(function (resolve, reject) {
stylus.render(fs.readFileSync(stylusEntry, 'utf8'), {
'include css': true,
'hoist atrules': true,
compress: process.env.NODE_ENV === 'production',
paths: [path.resolve('src')],
use: nib()
}, function (err, css) {
if (err) reject(err)
else resolve(css)
})
})
}
-28
View File
@@ -1,28 +0,0 @@
{
"name": "react-table-example",
"version": "0.0.1",
"description": "Jumpsuit getting started example",
"license": "MIT",
"private": true,
"repository": {
"type": "git",
"url": "git+https://github.com/jumpsuit/jumpsuit.git"
},
"scripts": {
"watch": "jumpsuit watch",
"build": "jumpsuit build",
"deploy": "jumpsuit build && zab deploy"
},
"devDependencies": {
"nib": "^1.1.0",
"standard": "^8.4.0",
"stylus": "^0.54.5"
},
"dependencies": {
"jumpsuit": "^0.7.5",
"lodash": "^4.16.4",
"namor": "^0.3.0",
"react-syntax-highlighter": "^3.0.0",
"react-table": "^2.0.0"
}
}
-17
View File
@@ -1,17 +0,0 @@
import { Render, Router, Route, IndexRoute } from 'jumpsuit'
//
import Layout from 'components/layout'
import Simple from 'screens/simple'
import ServerSide from 'screens/serverSide'
Render(null, (
<Router>
<Route path='/' component={Layout}>
<IndexRoute component={Simple} />
<Route path='simple' component={Simple} />
<Route path='server-side' component={ServerSide} />
</Route>
</Router>
), {
useHash: false
})
-112
View File
@@ -1,112 +0,0 @@
// -----------------------------------------------------------------------------
// Globals
// -----------------------------------------------------------------------------
@import url('https://fonts.googleapis.com/css?family=Open+Sans:300,600')
@import 'nib'
global-reset()
// -----------------------------------------------------------------------------
// vendor styles
// -----------------------------------------------------------------------------
@import '../../src/index'
// -----------------------------------------------------------------------------
// variables
// -----------------------------------------------------------------------------
$fnt-open-sans = 'Open Sans', sans-serif
$react = #25d8fd
// -----------------------------------------------------------------------------
// styles
// -----------------------------------------------------------------------------
*
box-sizing border-box
html
min-height 100vh
body
background: white
font-family: $fnt-open-sans
font-weight: 300
h1
font-size: 2.5em
color: white
a
color: darken($react, 20%)
font-weight: bold
text-decoration: none
strong
font-weight: bold
.logo
width: 400px
max-width: 100%
.container
display: flex
flex-direction: column
align-items: center
justify-content: center
min-height: 100vh
padding-top: 20px
.github-addon
font-size: 20px
padding: 10px
.viewport
width:100%
.table-wrap
width: 90%
margin: auto
padding: 10px
border-radius: 5px
box-shadow: 0 0 20px 0 alpha(black, .2)
.menu
display:block
margin: 0 10px 20px
ul
display:block
li
display:inline-block
a
display:block
padding: 10px
margin: 5px
background: alpha(black, .7)
color: white
border-radius: 3px
transition: all .2s ease-out
&.active
&:hover
background: alpha(black, .9)
.ReactTable
thead
th
td
&.-sort-asc
box-shadow:inset 0 3px 0 0 alpha(black, .6)
&.-sort-desc
box-shadow:inset 0 -3px 0 0 alpha(black, .6)
pre
display:block
font-family: monospace
font-size: 15px
line-height: 20px
border-radius: 5px
margin: 20px auto
max-width: 90%
padding: 0 20px !important
Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

-14
View File
@@ -1,14 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>React-Table Demo</title>
<link rel="stylesheet" href="/app.css" charset="utf-8">
</head>
<body>
<div id="app"></div>
<script src="/app.js"></script>
<script async defer src="https://buttons.github.io/buttons.js"></script>
</body>
</html>
-11
View File
@@ -1,11 +0,0 @@
import { Component } from 'jumpsuit'
import SyntaxHighlighter from 'react-syntax-highlighter'
import atomOneDark from '../../node_modules/react-syntax-highlighter/dist/styles/atom-one-dark'
export default Component({
render () {
return (
<SyntaxHighlighter language='javascript' style={atomOneDark}>{this.props.children}</SyntaxHighlighter>
)
}
})
-59
View File
@@ -1,59 +0,0 @@
import { Component, Link } from 'jumpsuit'
export default Component({
render () {
return (
<div className='container'>
<div style={{textAlign: 'center'}}>
<h1>
<span style={{position: 'absolute', textIndent: '-9999em'}}>
react-table
</span>
<img src='/Banner.png' className='logo' />
</h1>
<br />
<div>
<a
className='github-button'
href='https://github.com/tannerlinsley/react-table'
target='_blank'
data-style='mega'
data-count-href='/tannerlinsley/react-table/stargazers'
data-count-api='/repos/tannerlinsley/react-table#stargazers_count'
data-count-aria-label='# stargazers on GitHub'
aria-label='Star tannerlinsley/react-table on GitHub'>
Star
</a>
</div>
<br />
<div className='github-addon'>
<a
target='_blank'
href='https://github.com/tannerlinsley/react-table'>
View on Github
</a>
</div>
<br />
<br />
</div>
<div className='menu'>
<ul>
<li>
<Link to='/simple' activeClassName='active'>
Simple
</Link>
</li>
<li>
<Link to='/server-side' activeClassName='active'>
Server-Side
</Link>
</li>
</ul>
</div>
<div className='viewport'>
{this.props.children}
</div>
</div>
)
}
})
-103
View File
@@ -1,103 +0,0 @@
import { Component } from 'jumpsuit'
import _ from 'lodash'
import namor from 'namor'
import CodeHighlight from 'components/codeHighlight'
import ReactTable from '../../../lib/index.js'
export default Component({
render () {
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
data={data}
columns={columns}
pageSize={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'
// To help us mock some data
import namor from 'namor'
import _ from 'lodash'
export default () => {
// Mock some data
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)
}
})
// 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}
pageSize={10}
/>
)
})
`
}
+17 -5
View File
@@ -1,6 +1,6 @@
{
"name": "react-table",
"version": "3.1.2",
"version": "4.2.3",
"description": "A fast, lightweight, opinionated table and datagrid built on React",
"license": "MIT",
"homepage": "https://github.com/tannerlinsley/react-table#readme",
@@ -16,6 +16,7 @@
],
"main": "lib/index.js",
"files": [
"src/",
"lib/",
"react-table.js",
"react-table.css",
@@ -24,19 +25,23 @@
"scripts": {
"build:node": "babel src --out-dir lib --source-maps inline",
"build:css": "rm -rf react-table.css && stylus src/index.styl --use ./node_modules/nib/lib/nib.js --compress -o react-table.css",
"watch": "onchange 'src/**' -i -- npm-run-all build:*",
"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",
"test": "standard",
"umd": "rm -rf react-table.js && browserify lib/index.js -s reactTable -x react -t babelify -g uglifyify -o react-table.js",
"prepublish": "npm-run-all build:* && npm run umd",
"postpublish": "git push --tags"
"storybook": "start-storybook -p 8000 -c .storybook",
"deploy": "build-storybook && zab deploy"
},
"dependencies": {
"classnames": "^2.2.5"
},
"peerDependencies": {
"react": "^15.3.1"
"react": "^15.x.x"
},
"devDependencies": {
"@kadira/storybook": "^2.35.1",
"babel-cli": "6.14.0",
"babel-eslint": "6.1.2",
"babel-preset-es2015": "6.14.0",
@@ -44,9 +49,15 @@
"babel-preset-stage-2": "6.13.0",
"babelify": "^7.3.0",
"browserify": "13.1.0",
"github-markdown-css": "^2.4.1",
"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",
"react": "^15.4.2",
"react-dom": "^15.4.2",
"standard": "^8.0.0",
"stylus": "^0.54.5",
"uglifyify": "3.0.3"
@@ -61,7 +72,8 @@
"dist",
"lib",
"example",
"react-table.js"
"react-table.js",
"stories"
]
},
"babel": {
Binary file not shown.
Binary file not shown.
+830 -343
View File
File diff suppressed because it is too large Load Diff
+86 -95
View File
@@ -2,90 +2,37 @@
$easeOutQuad = cubic-bezier(0.250, 0.460, 0.450, 0.940)
$easeOutBack = cubic-bezier(0.175, 0.885, 0.320, 1.275)
$expandSize = 7px
.ReactTable
position:relative
table
border: 1px solid alpha(black, .1)
*
box-sizing: border-box
.rt-table
display: flex
flex-direction: column
align-items: stretch
width: 100%
border-collapse: collapse
border: 1px solid alpha(black, .1)
display: block
overflow-x: auto
.-td
.-th
&-inner
white-space: nowrap
text-overflow: ellipsis
padding: 7px 5px
overflow: hidden
z-index:0
transition: .3s ease
transition-property: width, min-width, padding, opacity
th
td
&:hover
.-td
.-th
&-inner
position:relative
overflow:visible
z-index:1
text-shadow:
0 0 1px white,
0 0 2px white,
1px 0 3px white,
1px 0 4px white,
2px 0 5px white,
2px 0 6px white,
3px 0 7px white,
3px 0 8px white,
4px 0 9px white,
4px 0 10px white,
5px 0 11px white,
5px 0 12px white,
6px 0 13px white,
6px 0 14px white,
7px 0 15px white,
7px 0 16px white,
8px 0 17px white,
8px 0 18px white,
9px 0 19px white,
9px 0 20px white
> *
text-shadow: none
&.-hidden
border:0 !important
opacity: 0 !important
.-th-inner
.-td-inner
width: 0 !important
min-width: 0 !important
padding: 0 !important
thead
box-shadow: 0px 5px 20px 0 alpha(black, .1)
z-index: 0
overflow: auto
.rt-thead
display: flex
flex-direction: column
&.-headerGroups
background: alpha(black, .03)
border-bottom: 1px solid alpha(black, .05)
th
td
background: alpha(black, .03)
&.-header
box-shadow: 0 2px 15px 0px alpha(black, .15)
tr
.rt-tr
text-align:center
th
td
width: 1%
background: white
font-weight:500
color: $darkColor
.rt-th
.rt-td
color: black
border-right: 1px solid alpha(black, .05)
transition box-shadow .3s $easeOutBack
box-shadow:inset 0 0 0 0 transparent
@@ -95,40 +42,89 @@ $easeOutBack = cubic-bezier(0.175, 0.885, 0.320, 1.275)
box-shadow:inset 0 -3px 0 0 alpha(black, .6)
&.-cursor-pointer
cursor: pointer
tbody
z-index:0
tr
&:last-child
border-right: 0
.rt-tbody
display: flex
flex-direction: column
// z-index:0
.rt-tr-group
border-bottom: solid 1px alpha(black, .05)
&:last-child
border-bottom: 0
&:first-child td
box-shadow: inset 0 20px 20px -20px alpha(black, .2)
td
.rt-td
border-right:1px solid alpha(black, .02)
&:last-child
border-right:0
.rt-pivot
cursor: pointer
.rt-tr-group
display: flex
flex-direction: column
align-items: stretch
.rt-tr
display: inline-flex
.rt-th
.rt-td
flex: 1 0 0px
white-space: nowrap
text-overflow: ellipsis
padding: 7px 5px
overflow: hidden
transition: .3s ease
transition-property: width, min-width, padding, opacity
&.striped
tbody tr:nth-child(even)
&.-hidden
width: 0 !important
min-width: 0 !important
padding: 0 !important
border:0 !important
opacity: 0 !important
.rt-expander
display: inline-block
position:relative
margin: 0
color: transparent
margin: 0 10px
&:after
content: ''
position: absolute
width: 0
height: 0
top:50%
left:50%
transform: translate(-50%, -50%) rotate(-90deg)
border-left: ($expandSize * .72) solid transparent
border-right: ($expandSize * .72) solid transparent
border-top: $expandSize solid alpha(black, .8)
transition: all .3s $easeOutBack
cursor: pointer
&.-open:after
transform: translate(-50%, -50%) rotate(0deg)
&.-striped
.rt-tr.-odd
background: alpha(black, .03)
&.highlight
tbody tr:hover
background: alpha(black, .05)
&.-highlight
.rt-tbody
.rt-tr:not(.-padRow):hover
background: alpha(black, .05)
.-pagination
width:100%
z-index: 1
display:flex
justify-content: space-between
align-items: center
align-items: stretch
flex-wrap: wrap
padding-top:3px
padding: 3px
box-shadow: 0 0px 15px 0px alpha(black, .1)
.-btn
appearance:none
display:block
width:100%
height: 100%
border: 0
border-radius: 3px
padding: 6px
@@ -147,11 +143,6 @@ $easeOutBack = cubic-bezier(0.175, 0.885, 0.320, 1.275)
background: alpha(black, .3)
color: white
.-previous
.-center
.-next
margin:3px 0
.-previous
.-next
flex: 1
@@ -169,7 +160,7 @@ $easeOutBack = cubic-bezier(0.175, 0.885, 0.320, 1.275)
.-pageInfo
display: inline-block
margin: 0 10px 3px
margin: 3px 10px
white-space: nowrap
.-pageJump
@@ -179,7 +170,7 @@ $easeOutBack = cubic-bezier(0.175, 0.885, 0.320, 1.275)
text-align:center
.-pageSizeOptions
margin:0 10px 3px
margin: 3px 10px
.-loading
+21 -19
View File
@@ -10,51 +10,53 @@ const defaultButton = (props) => (
export default React.createClass({
getInitialState () {
return {
page: this.props.currentPage
page: this.props.page
}
},
componentWillReceiveProps (nextProps) {
this.setState({page: nextProps.currentPage})
this.setState({page: nextProps.page})
},
getSafePage (page) {
return Math.min(Math.max(page, 0), this.props.pagesLength - 1)
return Math.min(Math.max(page, 0), this.props.pages - 1)
},
changePage (page) {
page = this.getSafePage(page)
this.setState({page})
this.props.onChange(page)
this.props.onPageChange(page)
},
applyPage (e) {
e && e.preventDefault()
const page = this.state.page
this.changePage(page === '' ? this.props.currentPage : page)
this.changePage(page === '' ? this.props.page : page)
},
render () {
const {
currentPage,
pagesLength,
// Computed
pages,
// Props
page,
showPageSizeOptions,
pageSizeOptions,
pageSize,
showPageJump,
canPrevious,
canNext,
onPageSizeChange
onPageSizeChange,
className,
PreviousComponent = defaultButton,
NextComponent = defaultButton
} = this.props
const PreviousComponent = this.props.PreviousComponent || defaultButton
const NextComponent = this.props.NextComponent || defaultButton
return (
<div
className={classnames(this.props.paginationClassName, '-pagination')}
className={classnames(className, '-pagination')}
style={this.props.paginationStyle}
>
<div className='-previous'>
<PreviousComponent
onClick={(e) => {
if (!canPrevious) return
this.changePage(currentPage - 1)
this.changePage(page - 1)
}}
disabled={!canPrevious}
>
@@ -63,7 +65,7 @@ export default React.createClass({
</div>
<div className='-center'>
<span className='-pageInfo'>
Page {showPageJump ? (
{this.props.pageText} {showPageJump ? (
<form className='-pageJump'
onSubmit={this.applyPage}
>
@@ -81,9 +83,9 @@ export default React.createClass({
onBlur={this.applyPage}
/>
</form>
) : (
<span className='-currentPage'>{currentPage + 1}</span>
)} of <span className='-totalPages'>{pagesLength}</span>
) : (
<span className='-currentPage'>{page + 1}</span>
)} {this.props.ofText} <span className='-totalPages'>{pages}</span>
</span>
{showPageSizeOptions && (
<span className='select-wrap -pageSizeOptions'>
@@ -96,7 +98,7 @@ export default React.createClass({
<option
key={i}
value={option}>
{option} rows
{option} {this.props.rowsText}
</option>
)
})}
@@ -108,7 +110,7 @@ export default React.createClass({
<NextComponent
onClick={(e) => {
if (!canNext) return
this.changePage(currentPage + 1)
this.changePage(page + 1)
}}
disabled={!canNext}
>
+112 -38
View File
@@ -1,37 +1,47 @@
import React from 'react'
import classnames from 'classnames'
//
export default {
get,
set,
takeRight,
last,
orderBy,
sortBy,
range,
clone,
remove,
getFirstDefined
clone,
getFirstDefined,
sum,
makeTemplateComponent,
prefixAll,
groupBy,
isArray
}
function remove (a, b) {
return a.filter(function (o, i) {
var r = b(o)
if (r) {
a.splice(i, 1)
return true
}
return false
})
}
function get (a, b) {
if (isArray(b)) {
b = b.join('.')
function get (obj, path, def) {
if (!path) {
return obj
}
return b
.replace('[', '.').replace(']', '')
.split('.')
.reduce(
function (obj, property) {
return obj[property]
}, a
)
const pathObj = makePathArray(path)
let val
try {
val = pathObj.reduce((current, pathPart) => current[pathPart], obj)
} catch (e) {}
return typeof val !== 'undefined' ? val : def
}
function set (obj = {}, path, value) {
const keys = makePathArray(path)
let keyPart
let cursor = obj
while ((keyPart = keys.shift()) && keys.length) {
if (!cursor[keyPart]) {
cursor[keyPart] = {}
}
cursor = cursor[keyPart]
}
cursor[keyPart] = value
return obj
}
function takeRight (arr, n) {
@@ -51,7 +61,7 @@ function range (n) {
return arr
}
function orderBy (arr, funcs, dirs) {
function sortBy (arr, funcs, dirs) {
return arr.sort((a, b) => {
for (let i = 0; i < funcs.length; i++) {
const comp = funcs[i]
@@ -69,21 +79,28 @@ function orderBy (arr, funcs, dirs) {
})
}
function clone (a) {
return JSON.parse(JSON.stringify(a, function (key, value) {
if (typeof value === 'function') {
return value.toString()
function remove (a, b) {
return a.filter(function (o, i) {
var r = b(o)
if (r) {
a.splice(i, 1)
return true
}
return value
}))
return false
})
}
// ########################################################################
// Helpers
// ########################################################################
function isArray (a) {
return Array.isArray(a)
function clone (a) {
try {
return JSON.parse(JSON.stringify(a, (key, value) => {
if (typeof value === 'function') {
return value.toString()
}
return value
}))
} catch (e) {
return a
}
}
function getFirstDefined (...args) {
@@ -93,3 +110,60 @@ function getFirstDefined (...args) {
}
}
}
function sum (arr) {
return arr.reduce((a, b) => {
return a + b
}, 0)
}
function makeTemplateComponent (compClass) {
return ({children, className, ...rest}) => (
<div
className={classnames(compClass, className)}
{...rest}
>
{children}
</div>
)
}
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]
rv[resKey] = rv[resKey] || []
rv[resKey].push(x)
return rv
}, {})
}
function isArray (a) {
return Array.isArray(a)
}
// ########################################################################
// Non-exported Helpers
// ########################################################################
function makePathArray (obj) {
return flattenDeep(obj)
.join('.')
.replace('[', '.')
.replace(']', '')
.split('.')
}
function flattenDeep (arr, newArr = []) {
if (!isArray(arr)) {
newArr.push(arr)
} else {
for (var i = 0; i < arr.length; i++) {
flattenDeep(arr[i], newArr)
}
}
return newArr
}
+138
View File
@@ -0,0 +1,138 @@
import React from 'react'
import _ from 'lodash'
import namor from 'namor'
import CodeHighlight from './components/codeHighlight'
import ReactTable from '../lib/index'
export default () => {
const data = _.map(_.range(100000), d => {
return {
firstName: namor.generate({ words: 1, numLen: 0 }),
lastName: namor.generate({ words: 1, numLen: 0 }),
age: Math.floor(Math.random() * 30),
visits: Math.floor(Math.random() * 100)
}
})
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',
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)
}]
}]
return (
<div>
<div className='table-wrap'>
<ReactTable
data={data}
columns={columns}
defaultPageSize={10}
pivotBy={['firstName', 'lastName']}
SubComponent={(row) => {
return (
<div style={{padding: '20px'}}>
<em>You can put any component you want here, even another React Table!</em>
<br />
<br />
<ReactTable
data={data}
columns={columns}
defaultPageSize={3}
showPagination={false}
SubComponent={(row) => {
return (
<div style={{padding: '20px'}}>
<em>It even has access to the row data: </em>
<CodeHighlight>{() => JSON.stringify(row, null, 2)}</CodeHighlight>
</div>
)
}}
/>
</div>
)
}}
/>
</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'
}]
}]
export default (
<ReactTable
data={data}
columns={columns}
defaultPageSize={10}
pivotBy={['firstName', 'lastName']}
SubComponent={(row) => {
return (
<div style={{padding: '20px'}}>
<em>You can put any component you want here, even another React Table!</em>
<br />
<br />
<ReactTable
data={data}
columns={columns}
defaultPageSize={3}
showPagination={false}
SubComponent={(row) => {
return (
<div style={{padding: '20px'}}>
<em>It even has access to the row data: </em>
<CodeHighlight>{() => JSON.stringify(row, null, 2)}</CodeHighlight>
</div>
)
}}
/>
</div>
)
}}
/>
)
`
}
+120
View File
@@ -0,0 +1,120 @@
import React from 'react'
import _ from 'lodash'
import namor from 'namor'
import CodeHighlight from './components/codeHighlight'
import ReactTable from '../lib/index'
export default () => {
const data = _.map(_.range(10000), d => {
return {
firstName: namor.generate({ words: 1, numLen: 0 }),
lastName: namor.generate({ words: 1, numLen: 0 }),
age: Math.floor(Math.random() * 30),
visits: Math.floor(Math.random() * 100)
}
})
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',
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)
}]
}]
return (
<div>
<div className='table-wrap'>
<ReactTable
data={data}
columns={columns}
defaultPageSize={10}
pivotBy={['firstName', 'lastName']}
// expandedRows={{
// 2: true,
// 3: {
// 2: 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'
}]
}]
export default (
<ReactTable
data={data}
columns={columns}
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>
)
}}
/>
)
`
}
+138
View File
@@ -0,0 +1,138 @@
import React from 'react'
import _ from 'lodash'
import namor from 'namor'
import CodeHighlight from './components/codeHighlight'
import ReactTable from '../lib/index'
export default () => {
const data = _.map(_.range(1000), d => {
return {
firstName: namor.generate({ words: 1, numLen: 0 }),
lastName: namor.generate({ words: 1, numLen: 0 }),
age: Math.floor(Math.random() * 30),
visits: Math.floor(Math.random() * 100)
}
})
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',
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)
}]
}]
return (
<div>
<div className='table-wrap'>
<ReactTable
data={data}
columns={columns}
defaultPageSize={10}
pivotBy={['firstName', 'lastName']}
SubComponent={(row) => {
return (
<div style={{padding: '20px'}}>
<em>You can put any component you want here, even another React Table!</em>
<br />
<br />
<ReactTable
data={data}
columns={columns}
defaultPageSize={3}
showPagination={false}
SubComponent={(row) => {
return (
<div style={{padding: '20px'}}>
<em>It even has access to the row data: </em>
<CodeHighlight>{() => JSON.stringify(row, null, 2)}</CodeHighlight>
</div>
)
}}
/>
</div>
)
}}
/>
</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'
}]
}]
export default (
<ReactTable
data={data}
columns={columns}
defaultPageSize={10}
pivotBy={['firstName', 'lastName']}
SubComponent={(row) => {
return (
<div style={{padding: '20px'}}>
<em>You can put any component you want here, even another React Table!</em>
<br />
<br />
<ReactTable
data={data}
columns={columns}
defaultPageSize={3}
showPagination={false}
SubComponent={(row) => {
return (
<div style={{padding: '20px'}}>
<em>It even has access to the row data: </em>
<CodeHighlight>{() => JSON.stringify(row, null, 2)}</CodeHighlight>
</div>
)
}}
/>
</div>
)
}}
/>
)
`
}
@@ -1,11 +1,10 @@
import { Component } from 'jumpsuit'
import React from 'react'
import _ from 'lodash'
import namor from 'namor'
import CodeHighlight from 'components/codeHighlight'
import ReactTable from '../../../lib/index.js'
import CodeHighlight from './components/codeHighlight'
import ReactTable from '../lib/index'
// Let's mock some data to play around with
const rawData = _.map(_.range(3424), d => {
return {
firstName: namor.generate({ words: 1, numLen: 0 }),
@@ -39,7 +38,7 @@ const requestData = (pageSize, page, sorting) => {
})
}
export default Component({
const ServerSide = React.createClass({
getInitialState () {
// To handle our data server-side, we need a few things in the state to help us out:
return {
@@ -49,6 +48,7 @@ export default Component({
}
},
fetchData (state, instance) {
console.log(state, instance)
// Whenever the table model changes, or the user sorts or changes pages, this method gets called and passed the current table model.
// You can set the `loading` prop of the table to true to use the built-in one or show you're own loading bar if you want.
this.setState({loading: true})
@@ -86,7 +86,7 @@ export default Component({
}]
}]}
manual // Forces table not to paginate or sort automatically, so we can handle it server-side
pageSize={10}
defaultPageSize={10}
data={this.state.data} // Set the rows to be displayed
pages={this.state.pages} // Display the total number of pages
loading={this.state.loading} // Display the loading overlay when we need it
@@ -97,18 +97,22 @@ export default Component({
<br />
<em>Tip: Hold shift when sorting to multi-sort!</em>
</div>
<CodeHighlight>{getCode()}</CodeHighlight>
<CodeHighlight>{() => getCode()}</CodeHighlight>
</div>
)
}
})
export default () => (
<ServerSide />
)
function getCode () {
return `
import ReactTable from 'react-table'
import Axios from 'axios'
export default React.creatClass({
export default React.createClass({
getInitialState () {
// To handle our data server-side, we need to keep track of our table state
return {
+85
View File
@@ -0,0 +1,85 @@
import React from 'react'
import _ from 'lodash'
import namor from 'namor'
import CodeHighlight from './components/codeHighlight'
import ReactTable from '../lib/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
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}
/>
)
`
}
+127
View File
@@ -0,0 +1,127 @@
import React from 'react'
import _ from 'lodash'
import namor from 'namor'
import CodeHighlight from './components/codeHighlight'
import ReactTable from '../lib/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
data={data}
columns={columns}
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>
)
}}
/>
</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'
}]
}]
export default (
<ReactTable
data={data}
columns={columns}
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>
)
}}
/>
)
`
}
+14
View File
@@ -0,0 +1,14 @@
import React from 'react'
import banner from '../../media/Banner.png'
export default () => (
<div>
<div style={{textAlign: 'center'}}>
<a href='https://github.com/tannerlinsley/react-table' target='_blank'>
<img src={banner} className='logo' />
</a>
<br />
<br />
</div>
</div>
)
+21
View File
@@ -0,0 +1,21 @@
import React from 'react'
import '../utils/prism'
export default React.createClass({
render () {
const { language, children } = this.props
return (
<pre>
<code className={'language-' + (language || 'jsx')}>
{children()}
</code>
</pre>
)
},
componentDidMount () {
window.Prism.highlightAll()
},
componentDidUpdate () {
window.Prism.highlightAll()
}
})
+138
View File
@@ -0,0 +1,138 @@
/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
code[class*="language-"]::selection, code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #a67f59;
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
File diff suppressed because one or more lines are too long
+5797
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "react-table",
"root": "dist",
"root": "storybook-static",
"routes": [{
"src": "/**",
"dest": "index.html"