Compare commits

..
2 Commits
Author SHA1 Message Date
Tanner Linsley 2fe97f921f 3.0.0 2016-10-31 01:44:13 -06:00
Tanner Linsley 9a0369ee33 Major changes for server-side data 2016-10-31 01:44:07 -06:00
34 changed files with 59875 additions and 7031 deletions
-3
View File
@@ -3,6 +3,3 @@ lib/
react-table.js
react-table.css
*.log
example/dist/
storybook-static
-34
View File
@@ -1,34 +0,0 @@
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'
//
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)
}, module)
-6
View File
@@ -1,6 +0,0 @@
@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
@@ -1,3 +0,0 @@
body{
padding: 20px;
}
-48
View File
@@ -1,48 +0,0 @@
/* 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
@@ -1,27 +0,0 @@
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
}
+27 -73
View File
@@ -1,24 +1,19 @@
<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](https://github.com/tannerlinsley/react-table/raw/master/media/Banner.png)
</div>
# react-table
A fast, lightweight, opinionated table and datagrid built on React
# 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)
[![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/)
## Features
- Lightweight at 4kb (and just 2kb more for styles)
- Lightweight at 3kb (and just 2kb more for styles)
- Fully customizable JSX and callbacks for everything
- Supports both Client-side & Server-side pagination and sorting
- Minimal design & easily themeable
- <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
## <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>
## [Demo](http://react-table.zabapps.com)
## Table of Contents
- [Installation](#nstallation)
@@ -28,7 +23,6 @@
- [Columns](#columns)
- [Styles](#styles)
- [Header Groups](#header-groups)
- [Sub Tables & Components](#sub-tables--components)
- [Server-side Data](#server-side-data)
- [Multi-sort](#multi-sort)
- [Component Overrides](#component-overrides)
@@ -57,28 +51,27 @@ const data = [{
const columns = [{
header: 'Name',
accessor: 'name' // String-based value accessors !
accessor: 'name',
}, {
header: 'Age',
accessor: 'age',
render: props => <span className='number'>props.value</span> // Custom cell components!
accessor: 'age'
}, {
header: 'Friend Name',
accessor: d => d.friend.name // Custom value accessors!
accessor: d => d.friend.name
}, {
header: props => <span>Friend Age</span>, // Custom header components!
header: 'Friend Age',
accessor: 'friend.age'
}]
<ReactTable
data={data}
data=[data]
columns={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!
Every React-Table instance requires you to set the `data` prop. To use client-side data, simply pass the `data` prop anything that resembles an array or object. Client-side filtering and pagination is built in, and your table will update gracefully if you change any props. [Server-side data](#server-side-data) is also supported.
<a name="default-props"></a>
@@ -87,25 +80,12 @@ These are the default props for the main react component `<ReactTable />`
```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)
pageSize: 20,
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',
pageText: 'Page',
ofText: 'of',
rowsText: 'rows',
nextText: 'Next'
// Classes
className: '-striped -highlight', // The most top level className for the component
@@ -152,7 +132,7 @@ Or just define them on the component per-instance
<a name="columns"></a>
## Columns
`<ReactTable/>` requires a `columns` prop, which is an array of objects with the following properties
Every React-Table instance requires a `columns` prop, which is an array of objects containing the following properties
```javascript
[{
@@ -160,13 +140,15 @@ Or just define them on the component per-instance
accessor: 'propertyName' or Accessor eg. (row) => row.propertyName,
id: 'myProperty', // Conditional - A unique ID is required if the accessor is not a string or if you would like to override the column name used in server-side calls
sortable: true,
sort: 'asc' or 'desc', // used to determine the column sorting on init
show: true, // can be used to hide a column
minWidth: 100 // A minimum width for this column. If there is room, columns will flex to fill
sort: 'asc' or 'desc',
show: true,
minWidth: Number // Allows the column to flex above this minimum amount
// Cell Options
className: '', // Set the classname of the `td` element of the column
style: {}, // Set the style of the `td` element of the column
innerClassName: '', // Set the classname of the `.-td-inner` element of the column
innerStyle: {}, // Set the style of the `.-td-inner` element of the column
render: JSX eg. ({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
@@ -178,6 +160,8 @@ 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
@@ -208,31 +192,13 @@ const columns = [{
}]
```
## Sub Tables & Components
By adding a `subComponent` props, you can easily add an expansion level to all root-level rows:
```javascript
<ReactTable
data={data}
columns={columns}
pageSize={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>
)
}}
/>
```
<a name="server-side-data"></a>
## Server-side Data
If you want to handle pagination, and sorting on the server, `react-table` makes it easy on you.
1. Feed React Table `data` from somewhere dynamic. eg. `state`, a redux store, etc...
1. Add `manual` as a prop. This informs React Table that you'll be handling sorting and pagination server-side
1. Subscribe to the `onChange` prop. This function is called at `compomentDidMount` and any time sorting or pagination is changed by the user
1. Subscribe to the `onChange` prop. This function is called any time sorting or pagination is changed by the user
1. In the `onChange` callback, request your data using the provided information in the params of the function (state and instance)
1. Update your data with the rows to be displayed
1. Optionally set how many pages there are total
@@ -242,23 +208,17 @@ If you want to handle pagination, and sorting on the server, `react-table` makes
...
data={this.state.data} // should default to []
pages={this.state.pages} // should default to -1 (which means we don't know how many pages we have)
loading={this.state.loading}
manual // informs React Table that you'll be handling sorting and pagination server-side
onChange={(state, instance) => {
// show the loading overlay
this.setState({loading: true})
// fetch your data
Axios.post('mysite.com/data', {
page: state.page,
pageSize: state.pageSize,
sorting: state.sorting
})
.then((res) => {
// Update react-table
this.setState({
data: res.data.rows,
pages: res.data.pages,
loading: false
pages: res.data.pages
})
})
}}
@@ -307,7 +267,7 @@ If you would like to help develop a suggested feature follow these steps:
- Fork this repo
- `npm install`
- `npm run watch`
- `npm watch`
- Implement your changes to files in the `src/` directory
- Submit PR for review
@@ -317,12 +277,6 @@ If you would like to preview your changes, you can link and utilize the example
- `cd example`
- `npm install`
- `npm link react-table`
- `npm run watch`
- `npm watch`
- Make changes to the example in `src/screens/index.js` if needed
- View changes at `localhost:8000`
## Used By
<a href='https://nozzle.io'>
<img src='https://nozzle.io/img/logo-blue.png' alt='Nozzle Logo' style='width:300px;'/>
</a>
+1
View File
@@ -0,0 +1 @@
# Jumpsuit Getting Started
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

+171
View File
File diff suppressed because one or more lines are too long
+59138
View File
File diff suppressed because one or more lines are too long
+13
View File
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<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>
+28
View File
@@ -0,0 +1,28 @@
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)
})
})
}
+26
View File
@@ -0,0 +1,26 @@
{
"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"
},
"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-table": "^2.0.0"
}
}
+5
View File
@@ -0,0 +1,5 @@
import { Render } from 'jumpsuit'
// import App from 'screens/async'
import App from 'screens/index'
Render(null, <App />)
+79
View File
@@ -0,0 +1,79 @@
// -----------------------------------------------------------------------------
// Globals
// -----------------------------------------------------------------------------
@import url('https://fonts.googleapis.com/css?family=Open+Sans:300,600')
@import 'nib'
global-reset()
// -----------------------------------------------------------------------------
// vendor styles
// -----------------------------------------------------------------------------
@import '../node_modules/react-table/react-table.css'
// -----------------------------------------------------------------------------
// 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
padding-bottom: 50px
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
.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
.table-wrap
width: 700px
padding: 10px
border-radius: 5px
box-shadow: 0 0 20px 0 alpha(black, .2)
.ReactTable
thead
th
td
&.-sort-asc
box-shadow:inset 0 3px 0 0 alpha(black, .6)
&.-sort-desc
box-shadow:inset 0 -3px 0 0 alpha(black, .6)
Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

+13
View File
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<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>
@@ -1,11 +1,11 @@
import React from 'react'
import { Component } from 'jumpsuit'
import _ from 'lodash'
import namor from 'namor'
import CodeHighlight from './components/codeHighlight'
import ReactTable from '../lib/index'
import ReactTable from 'react-table'
const rawData = _.map(_.range(3424), d => {
// Let's mock some data to play around with
const rawData = _.map(_.range(1000), d => {
return {
firstName: namor.generate({ words: 1, numLen: 0 }),
lastName: namor.generate({ words: 1, numLen: 0 }),
@@ -38,7 +38,7 @@ const requestData = (pageSize, page, sorting) => {
})
}
const ServerSide = React.createClass({
export default Component({
getInitialState () {
// To handle our data server-side, we need a few things in the state to help us out:
return {
@@ -64,7 +64,39 @@ const ServerSide = React.createClass({
},
render () {
return (
<div>
<div className='container'>
<div style={{textAlign: 'center'}}>
<h1>
<span style={{position: 'absolute', textIndent: '-9999em'}}>
react-table <strong>server-side demo</strong>
</span>
<img src='/Banner.png' className='logo' />
</h1>
<br />
<div>
<a
className='github-button'
href='https://github.com/tannerlinsley/react-table'
target='_blank'
data-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='table-wrap'>
<ReactTable
columns={[{
@@ -85,7 +117,7 @@ const ServerSide = React.createClass({
}]
}]}
manual // Forces table not to paginate or sort automatically, so we can handle it server-side
pageSize={10}
pageSize={5}
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
@@ -96,79 +128,7 @@ const ServerSide = React.createClass({
<br />
<em>Tip: Hold shift when sorting to multi-sort!</em>
</div>
<CodeHighlight>{() => getCode()}</CodeHighlight>
</div>
)
}
})
export default () => (
<ServerSide />
)
function getCode () {
return `
import ReactTable from 'react-table'
import Axios from 'axios'
export default React.creatClass({
getInitialState () {
// To handle our data server-side, we need to keep track of our table state
return {
data: [],
pages: null,
loading: true
}
},
fetchData (state, instance) {
// Whenever the table model changes (sorting, pagination, etc), 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 loading notice, or show you're own loading bar if you want.
this.setState({loading: true})
// Request the data from a server however you want! Be sure to send the bits of the table model that it may neeed.
Axios.post('mysite.com/data', {
pageSize: state.pageSize,
page: state.page,
sorting: state.sorting
})
.then((res) => {
// Now update your state!
this.setState({
data: res.rows,
pages: res.pages,
loading: false
})
})
},
render () {
const columns = [{
header: 'Name',
columns: [{
header: 'First Name',
accessor: 'firstName'
}, {
header: 'Last Name',
id: 'lastName',
accessor: d => d.lastName
}]
}, {
header: 'Info',
columns: [{
header: 'Age',
accessor: 'age'
}]
}]
return (
<ReactTable
columns={columns}
manual // This forces table not to paginate or sort automatically, so we can handle things server-side
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
onChange={this.fetchData} // Request new data when things change
/>
)
}
})
`
}
+82
View File
@@ -0,0 +1,82 @@
import { Component } from 'jumpsuit'
import _ from 'lodash'
import namor from 'namor'
import ReactTable from 'react-table'
export default Component({
render () {
const data = _.map(_.range(5000), 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 className='container'>
<div style={{textAlign: 'center'}}>
<h1>
<span style={{position: 'absolute', textIndent: '-9999em'}}>
react-table <strong>demo</strong>
</span>
<img src='/Banner.png' className='logo' />
</h1>
<br />
<div>
<a
className='github-button'
href='https://github.com/tannerlinsley/react-table'
target='_blank'
data-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='table-wrap'>
<ReactTable
data={data}
columns={columns}
/>
</div>
<div style={{textAlign: 'center'}}>
<br />
<em>Tip: Hold shift when sorting to multi-sort!</em>
</div>
</div>
)
}
})
+4
View File
@@ -0,0 +1,4 @@
{
"name": "react-table",
"root": "dist"
}
+5 -17
View File
@@ -1,6 +1,6 @@
{
"name": "react-table",
"version": "4.0.0",
"version": "3.0.0",
"description": "A fast, lightweight, opinionated table and datagrid built on React",
"license": "MIT",
"homepage": "https://github.com/tannerlinsley/react-table#readme",
@@ -16,7 +16,6 @@
],
"main": "lib/index.js",
"files": [
"src/",
"lib/",
"react-table.js",
"react-table.css",
@@ -25,24 +24,19 @@
"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": "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",
"watch": "onchange 'src/**' -i -- npm-run-all build:*",
"test": "standard",
"umd": "rm -rf react-table.js && browserify lib/index.js -s reactTable -x react -t babelify -g uglifyify -o react-table.js",
"prepublish": "npm-run-all build:* && npm run umd",
"storybook": "start-storybook -p 8000 -c .storybook",
"deploy": "build-storybook && zab deploy"
"postpublish": "git push --tags"
},
"dependencies": {
"classnames": "^2.2.5",
"inline-style-prefixer": "^2.0.5"
"classnames": "^2.2.5"
},
"peerDependencies": {
"react": "^15.x.x"
"react": "^15.3.1"
},
"devDependencies": {
"@kadira/storybook": "^2.35.1",
"babel-cli": "6.14.0",
"babel-eslint": "6.1.2",
"babel-preset-es2015": "6.14.0",
@@ -50,15 +44,9 @@
"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"
+146 -292
View File
@@ -1,33 +1,22 @@
import React from 'react'
import classnames from 'classnames'
import prefixAll from 'inline-style-prefixer/static'
//
import _ from './utils'
import Pagination from './pagination'
const makeTemplateComponent = (compClass) => ({children, className, ...rest}) => (
<div
className={classnames(compClass, className)}
{...rest}
>
{children}
</div>
const defaultButton = (props) => (
<button {...props} className='-btn'>{props.children}</button>
)
export const ReactTableDefaults = {
// General
// State
data: [],
loading: false,
pageSize: 20,
showPagination: true,
showPageSizeOptions: true,
pageSizeOptions: [5, 10, 20, 25, 50, 100],
showPageJump: true,
expanderColumnWidth: 30,
minRows: 0,
// Callbacks
onChange: () => null,
onTrClick: () => null,
onPageChange: () => null,
onSort: () => null,
// Classes
className: '-striped -highlight',
tableClassName: '',
@@ -55,57 +44,26 @@ export const ReactTableDefaults = {
show: true,
className: '',
style: {},
innerClassName: '',
innerStyle: {},
headerClassName: '',
headerStyle: {},
headerInnerClassName: '',
headerInnerStyle: {},
minWidth: 100
headerInnerStyle: {}
},
// Text
previousText: 'Previous',
nextText: 'Next',
loadingText: 'Loading...',
pageText: 'Page',
ofText: 'of',
rowsText: 'rows',
// Components
tableComponent: makeTemplateComponent('rt-table'),
theadComponent: makeTemplateComponent('rt-thead'),
tbodyComponent: makeTemplateComponent('rt-tbody'),
trGroupComponent: makeTemplateComponent('rt-tr-group'),
trComponent: makeTemplateComponent('rt-tr'),
thComponent: ({toggleSort, className, children, ...rest}) => {
return (
<div
className={classnames(className, 'rt-th')}
onClick={e => {
toggleSort && toggleSort(e)
}}
{...rest}
>
{children}
</div>
)
},
tdComponent: makeTemplateComponent('rt-td'),
expanderComponent: ({isOpen, toggle, ...rest}) => {
return (
<div
className={classnames('rt-expander', isOpen && '-open')}
{...rest}
/>
)
},
paginationComponent: Pagination,
tableComponent: (props) => <table {...props}>{props.children}</table>,
theadComponent: (props) => <thead {...props}>{props.children}</thead>,
tbodyComponent: (props) => <tbody {...props}>{props.children}</tbody>,
trComponent: (props) => <tr {...props}>{props.children}</tr>,
thComponent: (props) => <th {...props}>{props.children}</th>,
tdComponent: (props) => <td {...props}>{props.children}</td>,
previousComponent: null,
nextComponent: null,
loadingComponent: props => (
<div className={classnames('-loading', {'-active': props.loading})}>
<div className='-loading-inner'>
{props.loadingText}
</div>
</div>
)
nextComponent: null
}
export default React.createClass({
@@ -115,8 +73,8 @@ export default React.createClass({
getInitialState () {
return {
page: 0,
sorting: false,
visibleSubComponents: {}
pages: -1,
sorting: false
}
},
componentDidMount () {
@@ -124,18 +82,12 @@ export default React.createClass({
},
fireOnChange () {
this.props.onChange({
page: this.getPropOrState('page'),
pageSize: this.getStateOrProp('pageSize'),
pages: this.getPagesLength(),
page: _.getFirstDefined(this.props.page, this.state.page),
pageSize: this.props.pageSize,
pages: this.props.pages,
sorting: this.getSorting()
}, 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 []
@@ -188,47 +140,7 @@ export default React.createClass({
getSorting (columns) {
return this.props.sorting || (this.state.sorting && this.state.sorting.length ? this.state.sorting : this.getInitSorting(columns))
},
getPagesLength () {
return this.props.manual ? this.props.pages
: Math.ceil(this.props.data.length / this.getStateOrProp('pageSize'))
},
getMinRows () {
return _.getFirstDefined(this.props.minRows, this.getStateOrProp('pageSize'))
},
render () {
const {visibleSubComponents} = this.state
const {
className,
style,
tableClassName,
tableStyle,
theadGroupClassName,
theadStyle,
trClassName,
trStyle,
thClassname,
thStyle,
data,
theadClassName,
tbodyClassName,
tbodyStyle,
onTrClick,
trClassCallback,
trStyleCallback,
tdStyle,
showPagination,
showPageSizeOptions,
pageSizeOptions,
showPageJump,
previousText,
nextText,
pageText,
ofText,
rowsText,
paginationClassName,
expanderColumnWidth
} = this.props
// Build Columns
const decoratedColumns = []
const headerGroups = []
@@ -271,8 +183,6 @@ export default React.createClass({
}
})
const columnPercentage = 100 / decoratedColumns.length
if (hasHeaderGroups && currentSpan.length > 0) {
addHeader(currentSpan)
}
@@ -288,86 +198,67 @@ export default React.createClass({
})
return row
})
const resolvedData = this.props.manual ? accessedData : this.sortData(accessedData, sorting)
// Normalize state
const currentPage = this.getPropOrState('page')
const pageSize = this.getStateOrProp('pageSize')
const pagesLength = this.getPagesLength()
const data = this.props.manual ? accessedData : this.sortData(accessedData, sorting)
// Pagination
const startRow = pageSize * currentPage
const endRow = startRow + pageSize
const pageRows = this.props.manual ? resolvedData : resolvedData.slice(startRow, endRow)
const minRows = this.getMinRows()
const padRows = pagesLength > 1 ? _.range(pageSize - pageRows.length)
: minRows ? _.range(Math.max(minRows - pageRows.length, 0))
const pagesLength = this.props.manual ? this.props.pages : Math.ceil(data.length / this.props.pageSize)
const startRow = this.props.pageSize * this.state.page
const endRow = startRow + this.props.pageSize
const pageRows = this.props.manual ? data : data.slice(startRow, endRow)
const padRows = pagesLength > 1 ? _.range(this.props.pageSize - pageRows.length)
: this.props.minRows ? _.range(Math.max(this.props.minRows - pageRows.length, 0))
: []
const canPrevious = currentPage > 0
const canNext = currentPage + 1 < pagesLength
const canPrevious = this.state.page > 0
const canNext = this.state.page + 1 < pagesLength
const TableComponent = this.props.tableComponent
const TheadComponent = this.props.theadComponent
const TbodyComponent = this.props.tbodyComponent
const TrGroupComponent = this.props.trGroupComponent
const TrComponent = this.props.trComponent
const ThComponent = this.props.thComponent
const TdComponent = this.props.tdComponent
const ExpanderComponent = this.props.expanderComponent
const PaginationComponent = this.props.paginationComponent
const PreviousComponent = this.props.previousComponent
const NextComponent = this.props.nextComponent
const LoadingComponent = this.props.loadingComponent
const SubComponent = this.props.subComponent
const rowWidth = (SubComponent ? expanderColumnWidth : 0) + _.sum(decoratedColumns.map(d => d.minWidth))
const PreviousComponent = this.props.previousComponent || defaultButton
const NextComponent = this.props.nextComponent || defaultButton
return (
<div
className={classnames(className, 'ReactTable')}
style={style}
className={classnames(this.props.className, 'ReactTable')}
style={this.props.style}
>
<TableComponent
className={classnames(tableClassName)}
style={tableStyle}
className={classnames(this.props.tableClassName)}
style={this.props.tableStyle}
>
{hasHeaderGroups && (
<TheadComponent
className={classnames(theadGroupClassName, '-headerGroups')}
style={Object.assign({}, theadStyle, {
minWidth: `${rowWidth}px`
})}
className={classnames(this.props.theadGroupClassName, '-headerGroups')}
style={this.props.theadStyle}
>
<TrComponent
className={trClassName}
style={trStyle}
className={this.props.trClassName}
style={this.props.trStyle}
>
{SubComponent && (
<ThComponent
className={classnames(thClassname, 'rt-expander-header')}
style={prefixAll({
flex: `0 0 auto`,
width: `${expanderColumnWidth}px`
})}
/>
)}
{headerGroups.map((column, i) => {
return (
<ThComponent
key={i}
className={classnames(thClassname, column.headerClassName)}
style={Object.assign({}, thStyle, column.headerStyle, prefixAll({
flex: `${column.columns.length * columnPercentage} 0 auto`,
width: `${_.sum(column.columns.map(d => d.minWidth))}px`
}))}
colSpan={column.columns.length}
className={classnames(this.props.thClassname, column.headerClassName)}
style={Object.assign({}, this.props.thStyle, column.headerStyle)}
>
{typeof column.header === 'function' ? (
<column.header
data={resolvedData}
column={column}
/>
) : column.header}
<div
className={classnames(column.headerInnerClassName, '-th-inner')}
style={Object.assign({}, this.props.thInnerStyle, column.headerInnerStyle)}
>
{typeof column.header === 'function' ? (
<column.header
data={this.props.data}
column={column}
/>
) : column.header}
</div>
</ThComponent>
)
})}
@@ -375,24 +266,13 @@ export default React.createClass({
</TheadComponent>
)}
<TheadComponent
className={classnames(theadClassName, '-header')}
style={Object.assign({}, theadStyle, {
minWidth: `${rowWidth}px`
})}
className={classnames(this.props.theadClassName)}
style={this.props.theadStyle}
>
<TrComponent
className={trClassName}
style={trStyle}
className={this.props.trClassName}
style={this.props.trStyle}
>
{SubComponent && (
<ThComponent
className={classnames(thClassname, 'rt-expander-header')}
style={prefixAll({
flex: `0 0 auto`,
width: `${expanderColumnWidth}px`
})}
/>
)}
{decoratedColumns.map((column, i) => {
const sort = sorting.find(d => d.id === column.id)
const show = typeof column.show === 'function' ? column.show() : column.show
@@ -400,7 +280,7 @@ export default React.createClass({
<ThComponent
key={i}
className={classnames(
thClassname,
this.props.thClassname,
column.headerClassName,
sort ? (sort.asc ? '-sort-asc' : '-sort-desc') : '',
{
@@ -408,30 +288,32 @@ export default React.createClass({
'-hidden': !show
}
)}
style={Object.assign({}, thStyle, column.headerStyle, prefixAll({
flex: `${columnPercentage} 0 auto`,
width: `${column.minWidth}px`
}))}
toggleSort={(e) => {
style={Object.assign({}, this.props.thStyle, column.headerStyle)}
onClick={(e) => {
column.sortable && this.sortColumn(column, e.shiftKey)
}}
>
{typeof column.header === 'function' ? (
<column.header
data={resolvedData}
column={column}
/>
) : column.header}
<div
className={classnames(column.headerInnerClassName, '-th-inner')}
style={Object.assign({}, column.headerInnerStyle, {
minWidth: column.minWidth + 'px'
})}
>
{typeof column.header === 'function' ? (
<column.header
data={this.props.data}
column={column}
/>
) : column.header}
</div>
</ThComponent>
)
})}
</TrComponent>
</TheadComponent>
<TbodyComponent
className={classnames(tbodyClassName)}
style={Object.assign({}, tbodyStyle, {
minWidth: `${rowWidth}px`
})}
className={classnames(this.props.tbodyClassName)}
style={this.props.tbodyStyle}
>
{pageRows.map((row, i) => {
const rowInfo = {
@@ -441,90 +323,61 @@ export default React.createClass({
viewIndex: i
}
return (
<TrGroupComponent key={i}>
<TrComponent
onClick={event => onTrClick(rowInfo.row, event)}
className={classnames(trClassName, trClassCallback(rowInfo))}
style={Object.assign({}, trStyle, trStyleCallback(rowInfo))}
>
{SubComponent && (
<ThComponent
className={classnames(thClassname, 'rt-expander-wrap')}
style={prefixAll({
flex: `0 0 auto`,
width: `${expanderColumnWidth}px`
})}
onClick={() => {
this.setState({
visibleSubComponents: {
...visibleSubComponents,
[i]: !visibleSubComponents[i]
}
})
}}
<TrComponent
key={i}
className={classnames(this.props.trClassName, this.props.trClassCallback(rowInfo))}
style={Object.assign({}, this.props.trStyle, this.props.trStyleCallback(rowInfo))}
>
{decoratedColumns.map((column, i2) => {
const Cell = column.render
const show = typeof column.show === 'function' ? column.show() : column.show
return (
<TdComponent
key={i2}
className={classnames(column.className, {hidden: !show})}
style={Object.assign({}, this.props.tdStyle, column.style)}
>
<ExpanderComponent
isOpen={visibleSubComponents[i]}
/>
</ThComponent>
)}
{decoratedColumns.map((column, i2) => {
const Cell = column.render
const show = typeof column.show === 'function' ? column.show() : column.show
return (
<TdComponent
key={i2}
className={classnames(column.className, {hidden: !show})}
style={Object.assign({}, tdStyle, column.style, prefixAll({
flex: `${columnPercentage} 0 auto`,
width: `${column.minWidth}px`
}))}
<div
className={classnames(column.innerClassName, '-td-inner')}
style={Object.assign({}, column.innerStyle, {
minWidth: column.minWidth + 'px'
})}
>
{typeof Cell === 'function' ? (
<Cell
{...rowInfo}
value={rowInfo.rowValues[column.id]}
/>
) : typeof Cell !== 'undefined' ? Cell
) : typeof Cell !== 'undefined' ? Cell
: rowInfo.rowValues[column.id]}
</TdComponent>
)
})}
</TrComponent>
{SubComponent && visibleSubComponents[i] ? (
SubComponent(rowInfo)
) : null}
</TrGroupComponent>
</div>
</TdComponent>
)
})}
</TrComponent>
)
})}
{padRows.map((row, i) => {
return (
<TrComponent
key={i}
className={classnames(trClassName, '-padRow')}
style={trStyle}
className={classnames(this.props.trClassName, '-padRow')}
style={this.props.trStyle}
>
{SubComponent && (
<ThComponent
className={classnames(thClassname, 'rt-expander-header')}
style={prefixAll({
flex: `0 0 auto`,
width: `${expanderColumnWidth}px`
})}
/>
)}
{decoratedColumns.map((column, i2) => {
const show = typeof column.show === 'function' ? column.show() : column.show
return (
<TdComponent
key={i2}
className={classnames(column.className, {hidden: !show})}
style={Object.assign({}, tdStyle, column.style, {
flex: `${columnPercentage} 0 auto`,
width: `${column.minWidth}px`
})}
style={Object.assign({}, this.props.tdStyle, column.style)}
>
&nbsp;
<div
className={classnames(column.innerClassName, '-td-inner')}
style={Object.assign({}, column.innerStyle, {
minWidth: column.minWidth + 'px'
})}
>&nbsp;</div>
</TdComponent>
)
})}
@@ -533,54 +386,55 @@ export default React.createClass({
})}
</TbodyComponent>
</TableComponent>
{showPagination && (
<PaginationComponent
currentPage={currentPage}
pagesLength={pagesLength}
pageSize={pageSize}
showPageSizeOptions={showPageSizeOptions}
pageSizeOptions={pageSizeOptions}
showPageJump={showPageJump}
canPrevious={canPrevious}
canNext={canNext}
previousText={previousText}
nextText={nextText}
pageText={pageText}
ofText={ofText}
rowsText={rowsText}
previousComponent={PreviousComponent}
nextComponent={NextComponent}
//
onChange={this.setPage}
onPageSizeChange={this.setPageSize}
//
className={paginationClassName}
/>
{pagesLength > 1 && (
<div
className={classnames(this.props.paginationClassName, '-pagination')}
style={this.props.paginationStyle}
>
<div className='-left'>
<PreviousComponent
onClick={canPrevious && ((e) => this.previousPage(e))}
disabled={!canPrevious}
>
{this.props.previousText}
</PreviousComponent>
</div>
<div className='-center'>
Page {this.state.page + 1} of {pagesLength}
</div>
<div className='-right'>
<NextComponent
onClick={canNext && ((e) => this.nextPage(e))}
disabled={!canNext}
>
{this.props.nextText}
</NextComponent>
</div>
</div>
)}
<LoadingComponent {...this.props} />
<div className={classnames('-loading', {'-active': this.props.loading})}>
<div className='-loading-inner'>
{this.props.loadingText}
</div>
</div>
</div>
)
},
// User actions
setPage (page) {
this.setState({
visibleSubComponents: {},
page
}, () => {
this.fireOnChange()
})
},
setPageSize (pageSize) {
const currentPageSize = this.getStateOrProp('pageSize')
const currentPage = this.getPropOrState('page')
const currentRow = currentPageSize * currentPage
const page = Math.floor(currentRow / pageSize)
this.setState({
pageSize,
page
}, () => {
this.fireOnChange()
})
nextPage (e) {
e.preventDefault()
this.setPage(this.state.page + 1)
},
previousPage (e) {
e.preventDefault()
this.setPage(this.state.page - 1)
},
sortColumn (column, additive) {
const existingSorting = this.getSorting()
+97 -125
View File
@@ -2,37 +2,90 @@
$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
border: 1px solid alpha(black, .1)
*
box-sizing: border-box
.rt-table
display: flex
flex-direction: column
align-items: stretch
table
width: 100%
border-collapse: collapse
overflow: auto
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
.rt-thead
display: flex
flex-direction: column
&.-headerGroups
background: alpha(black, .03)
border-bottom: 1px solid alpha(black, .05)
&.-header
box-shadow: 0 2px 15px 0px alpha(black, .15)
th
td
background: alpha(black, .03)
.rt-tr
tr
text-align:center
.rt-th
.rt-td
color: black
th
td
width: 1%
background: white
font-weight:500
color: $darkColor
border-right: 1px solid alpha(black, .05)
transition box-shadow .3s $easeOutBack
box-shadow:inset 0 0 0 0 transparent
@@ -42,81 +95,40 @@ $expandSize = 7px
box-shadow:inset 0 -3px 0 0 alpha(black, .6)
&.-cursor-pointer
cursor: pointer
&:last-child
border-right: 0
.rt-tbody
display: flex
flex-direction: column
// z-index:0
.rt-tr-group
tbody
z-index:0
tr
border-bottom: solid 1px alpha(black, .05)
&:last-child
border-bottom: 0
.rt-td
&:first-child td
box-shadow: inset 0 20px 20px -20px alpha(black, .2)
td
border-right:1px solid alpha(black, .02)
&:last-child
border-right:0
.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
&.-hidden
width: 0 !important
min-width: 0 !important
padding: 0 !important
border:0 !important
opacity: 0 !important
.rt-expander-wrap
display:flex
align-items: center
justify-content: center
cursor: pointer
.rt-expander
width: 0
height: 0
border-left: ($expandSize * .72) solid transparent
border-right: ($expandSize * .72) solid transparent
border-top: $expandSize solid alpha(black, .8)
transition: all .3s $easeOutBack
transform: rotate(-90deg)
&.-open
transform: rotate(0deg)
&.-striped
.rt-tr-group:nth-child(even)
&.striped
tbody tr:nth-child(even)
background: alpha(black, .03)
&.-highlight
.rt-tr-group:hover
&.highlight
tbody tr:hover
background: alpha(black, .05)
.-pagination
z-index: 1
width:100%
display:flex
margin-top:5px
justify-content: space-between
align-items: stretch
align-items: center
flex-wrap: wrap
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
@@ -135,34 +147,21 @@ $expandSize = 7px
background: alpha(black, .3)
color: white
.-previous
.-next
.-left
.-center
.-right
flex: 1
// min-width:150px
margin-bottom:5px
.-left
.-right
text-align: center
.-center
flex: 1.5
text-align:center
margin-bottom:0
display: flex
flex-direction: row
flex-wrap: wrap
align-items: center
justify-content: space-around
.-pageInfo
display: inline-block
margin: 3px 10px
white-space: nowrap
.-pageJump
display:inline-block
input
width: 70px
text-align:center
.-pageSizeOptions
margin: 3px 10px
padding: 0 5px
.-loading
@@ -195,30 +194,3 @@ $expandSize = 7px
pointer-events: all
> div
transform: translateY(50%)
input
select
appearance: none
border: 1px solid rgba(0,0,0,0.1)
background: white
padding: 5px 7px
font-size: inherit
border-radius: 3px
font-weight: normal
outline:none
.select-wrap
position:relative
display:inline-block
select
padding: 5px 15px 5px 7px
min-width:100px
&:after
content: ''
position: absolute
right: 8px
top: 50%
transform: translate(0, -50%)
border-color: #999 transparent transparent
border-style: solid
border-width: 5px 5px 2.5px
-122
View File
@@ -1,122 +0,0 @@
import React from 'react'
import classnames from 'classnames'
//
// import _ from './utils'
const defaultButton = (props) => (
<button {...props} className='-btn'>{props.children}</button>
)
export default React.createClass({
getInitialState () {
return {
page: this.props.currentPage
}
},
componentWillReceiveProps (nextProps) {
this.setState({page: nextProps.currentPage})
},
getSafePage (page) {
return Math.min(Math.max(page, 0), this.props.pagesLength - 1)
},
changePage (page) {
page = this.getSafePage(page)
this.setState({page})
this.props.onChange(page)
},
applyPage (e) {
e && e.preventDefault()
const page = this.state.page
this.changePage(page === '' ? this.props.currentPage : page)
},
render () {
const {
currentPage,
pagesLength,
showPageSizeOptions,
pageSizeOptions,
pageSize,
showPageJump,
canPrevious,
canNext,
onPageSizeChange,
className
} = this.props
const PreviousComponent = this.props.previousComponent || defaultButton
const NextComponent = this.props.nextComponent || defaultButton
return (
<div
className={classnames(className, '-pagination')}
style={this.props.paginationStyle}
>
<div className='-previous'>
<PreviousComponent
onClick={(e) => {
if (!canPrevious) return
this.changePage(currentPage - 1)
}}
disabled={!canPrevious}
>
{this.props.previousText}
</PreviousComponent>
</div>
<div className='-center'>
<span className='-pageInfo'>
{this.props.pageText} {showPageJump ? (
<form className='-pageJump'
onSubmit={this.applyPage}
>
<input
type={this.state.page === '' ? 'text' : 'number'}
onChange={e => {
const val = e.target.value
const page = val - 1
if (val === '') {
return this.setState({page: val})
}
this.setState({page: this.getSafePage(page)})
}}
value={this.state.page === '' ? '' : this.state.page + 1}
onBlur={this.applyPage}
/>
</form>
) : (
<span className='-currentPage'>{currentPage + 1}</span>
)} {this.props.ofText} <span className='-totalPages'>{pagesLength}</span>
</span>
{showPageSizeOptions && (
<span className='select-wrap -pageSizeOptions'>
<select
onChange={(e) => onPageSizeChange(Number(e.target.value))}
value={pageSize}
>
{pageSizeOptions.map((option, i) => {
return (
<option
key={i}
value={option}>
{option} {this.props.rowsText}
</option>
)
})}
</select>
</span>
)}
</div>
<div className='-next'>
<NextComponent
onClick={(e) => {
if (!canNext) return
this.changePage(currentPage + 1)
}}
disabled={!canNext}
>
{this.props.nextText}
</NextComponent>
</div>
</div>
)
}
})
+1 -8
View File
@@ -6,8 +6,7 @@ export default {
range,
clone,
remove,
getFirstDefined,
sum
getFirstDefined
}
function remove (a, b) {
@@ -94,9 +93,3 @@ function getFirstDefined (...args) {
}
}
}
function sum (arr) {
return arr.reduce((a, b) => {
return a + b
}, 0)
}
-85
View File
@@ -1,85 +0,0 @@
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}
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'
// 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}
/>
)
`
}
-107
View File
@@ -1,107 +0,0 @@
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}
pageSize={10}
subComponent={(row) => {
return (
<div style={{padding: '20px'}}>
<em>You can put any component you want here, even another React Table!. It has access to the row data: </em>
<CodeHighlight>{() => JSON.stringify(row, null, 2)}</CodeHighlight>
<ReactTable
data={data}
columns={columns}
pageSize={10}
subComponent={(row) => {
return (
<div style={{padding: '20px'}}>
<em>You can put any component you want here, even another React Table! 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}
pageSize={10}
subComponent={(row) => {
return (
<code><pre>{JSON.stringify(row, null, 2)}</pre></code>
)
}}
/>
)
`
}
-14
View File
@@ -1,14 +0,0 @@
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
@@ -1,21 +0,0 @@
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
@@ -1,138 +0,0 @@
/* 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
-5812
View File
File diff suppressed because it is too large Load Diff
-8
View File
@@ -1,8 +0,0 @@
{
"name": "react-table",
"root": "storybook-static",
"routes": [{
"src": "/**",
"dest": "index.html"
}]
}