mirror of
https://github.com/gosticks/react-table.git
synced 2026-08-19 08:20:30 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
652a366efc | ||
|
|
476bddfcad | ||
|
|
249bf509b5 | ||
|
|
f8563affb5 | ||
|
|
22c703391c | ||
|
|
3107517226 | ||
|
|
f2e62a13f2 | ||
|
|
fb134462ff | ||
|
|
da5e9d7d27 | ||
|
|
3e464faf8c | ||
|
|
0fde1ed8d6 | ||
|
|
e1690ea151 | ||
|
|
6584dbdad2 | ||
|
|
e4d1b8ac47 | ||
|
|
9b2fc7680a | ||
|
|
6bc2389ab3 | ||
|
|
872304da17 | ||
|
|
5875f80089 | ||
|
|
d05e54dee8 | ||
|
|
ab12816799 | ||
|
|
8ea48576b8 | ||
|
|
5730544d35 | ||
|
|
e2f03ef2f2 | ||
|
|
7a38d1fdb3 | ||
|
|
36666e19d2 | ||
|
|
50b03b7ec6 | ||
|
|
79ba413db2 | ||
|
|
4c68975cf0 | ||
|
|
0070d60d42 | ||
|
|
1621bcb0c3 | ||
|
|
4a4d2245fd | ||
|
|
2c2d2aa092 | ||
|
|
92321b6d0a | ||
|
|
0c15308d7a | ||
|
|
8cde0cafbf | ||
|
|
afab8a34cc | ||
|
|
969407254f | ||
|
|
a5a49709d4 | ||
|
|
71c25f571b | ||
|
|
b75055ef38 | ||
|
|
1079914996 | ||
|
|
5301355192 | ||
|
|
4c7e493f41 | ||
|
|
928233713e | ||
|
|
feda66196e | ||
|
|
c1b399d603 | ||
|
|
d59d7e4fba | ||
|
|
168a8e3f93 | ||
|
|
221164484f | ||
|
|
c7d2c36454 | ||
|
|
26961d0994 | ||
|
|
de6389cafc | ||
|
|
e0f9d98819 | ||
|
|
0365057446 | ||
|
|
ec25bfbb5a | ||
|
|
0a1c12faca | ||
|
|
1fddb1b97d | ||
|
|
1e04377de7 | ||
|
|
555c4fae9d | ||
|
|
0d8ca53b76 | ||
|
|
64db8e09d4 | ||
|
|
c5233c4404 | ||
|
|
d0d862f1e8 | ||
|
|
dd3f30b099 | ||
|
|
d5fc894dd7 | ||
|
|
dc771ff25f | ||
|
|
d38021d4b0 | ||
|
|
06648b2577 | ||
|
|
836f256031 | ||
|
|
188fc51336 | ||
|
|
474244ce41 | ||
|
|
b6074a9ab1 | ||
|
|
3278e1b05e | ||
|
|
2352cac4b8 | ||
|
|
d94f59a5fa | ||
|
|
7876a3876c | ||
|
|
02e65b4388 | ||
|
|
d9d49fa3de | ||
|
|
41784cd52d | ||
|
|
9048835bcc | ||
|
|
b12fc8fc88 | ||
|
|
76fde77b0f | ||
|
|
f50b0a47cf | ||
|
|
ac8b497671 | ||
|
|
c79806090a | ||
|
|
f55ce62041 | ||
|
|
4c9b44ab48 | ||
|
|
48869a65e7 | ||
|
|
3246336120 | ||
|
|
b12238d535 | ||
|
|
1f92ed8d4f | ||
|
|
cf59c644b4 | ||
|
|
a7e8e26c00 | ||
|
|
dd4c1e2df6 | ||
|
|
621c3bf092 | ||
|
|
72afabbd03 | ||
|
|
4aa07c33da | ||
|
|
d430d51888 | ||
|
|
4824b4c8cc | ||
|
|
60766cf261 | ||
|
|
fcdc3d88bc | ||
|
|
24a9efd670 | ||
|
|
bdb7d44438 | ||
|
|
7a6ed50b81 | ||
|
|
8f062550aa | ||
|
|
4e9eec3578 | ||
|
|
35b92567b5 | ||
|
|
a1f5b462d5 | ||
|
|
9e479e4d4c | ||
|
|
9fe806d8a7 | ||
|
|
083534149c | ||
|
|
8bd3daafcb | ||
|
|
6649b21abe | ||
|
|
3a8a037ee6 | ||
|
|
9e0361e511 | ||
|
|
0a62d86e5e | ||
|
|
3ff988861e | ||
|
|
f4067b86dd | ||
|
|
f70d453caa | ||
|
|
54f3cc791c | ||
|
|
05c56f0da4 | ||
|
|
ddf877bcac | ||
|
|
928ad11a07 | ||
|
|
0783837786 | ||
|
|
cf0f8bb729 | ||
|
|
1e849df999 | ||
|
|
62da8880e6 | ||
|
|
656522eb71 | ||
|
|
b0c50509ee | ||
|
|
01ca4518fc | ||
|
|
cdf806b3f6 | ||
|
|
0443644ccd | ||
|
|
f74ba3cc16 | ||
|
|
2e8596618a | ||
|
|
b2db31c9bd | ||
|
|
6a5400b247 | ||
|
|
ed6dd5af4c | ||
|
|
80aa2ea7f4 | ||
|
|
b310a2ebc4 | ||
|
|
bcfa658257 | ||
|
|
ad151b5ff0 | ||
|
|
3f1b0d36ed | ||
|
|
a6036004af | ||
|
|
913d214e94 | ||
|
|
2fbd0d49db | ||
|
|
fc47d4f258 | ||
|
|
6df336215d | ||
|
|
feec96359b | ||
|
|
33252adfab | ||
|
|
1cf9e49952 | ||
|
|
b585c4b8db | ||
|
|
710891f0c0 | ||
|
|
cb0000e588 | ||
|
|
d0bd56729b | ||
|
|
e4c819039f | ||
|
|
adc07de817 | ||
|
|
e94e88849a | ||
|
|
2dcfef884f | ||
|
|
d798584208 | ||
|
|
5759885983 | ||
|
|
e59ddc1f8d | ||
|
|
35e8636fd1 | ||
|
|
bb2f969db9 | ||
|
|
cd0222fcd2 | ||
|
|
93ceffbf26 | ||
|
|
879a6ac273 | ||
|
|
b285288849 | ||
|
|
05f4aaef2e | ||
|
|
2b9c546132 | ||
|
|
55ef8a9e7d | ||
|
|
189ee436f9 | ||
|
|
225a74770b | ||
|
|
fa425a162a | ||
|
|
e42b7bbd7d | ||
|
|
9efee144a8 | ||
|
|
56b721c185 | ||
|
|
e91bb91ea1 | ||
|
|
dadfcc121c | ||
|
|
8cec156d13 | ||
|
|
5c531095a9 | ||
|
|
8d4deb3496 | ||
|
|
646b701f93 | ||
|
|
3043cbe4b4 | ||
|
|
fcb82694bb | ||
|
|
e8c557d70e | ||
|
|
ff95c21440 | ||
|
|
2630161222 | ||
|
|
e67072edae | ||
|
|
fb569ad592 | ||
|
|
b957503612 | ||
|
|
3d9b7b1186 | ||
|
|
e3528fef38 | ||
|
|
6b192bd363 | ||
|
|
0725f2159d | ||
|
|
5d2deda246 | ||
|
|
2961eb8a18 | ||
|
|
d170adb6a7 | ||
|
|
d8aec06496 | ||
|
|
8efeef3b8b | ||
|
|
8004e7a85f | ||
|
|
84af88916a | ||
|
|
9846bf1905 | ||
|
|
bf88dda5dc | ||
|
|
7f5779a833 | ||
|
|
8792bd95a0 | ||
|
|
098b1fec51 | ||
|
|
750cfe3ac4 | ||
|
|
370f443347 | ||
|
|
67f8c9adf1 | ||
|
|
867cc25899 | ||
|
|
639630946c | ||
|
|
688afd2947 | ||
|
|
bbebf02a55 | ||
|
|
f4d3c2d7bb | ||
|
|
f8634e771e | ||
|
|
ba74ab3ce8 | ||
|
|
30ed0c82fc | ||
|
|
62f19aecf0 | ||
|
|
8dc4caff45 | ||
|
|
c2e935d75b | ||
|
|
f9a1cfae1e | ||
|
|
5ac2c1779d | ||
|
|
3b2432f535 | ||
|
|
7aa98887ef | ||
|
|
d26d82ecfb | ||
|
|
b76f9c956d | ||
|
|
2e3743b75f | ||
|
|
fdb3e77b00 | ||
|
|
d9248cef2b | ||
|
|
f4704b146c | ||
|
|
004186af24 | ||
|
|
0d0e239baa | ||
|
|
f61b19cb8a | ||
|
|
e1a46fb77e | ||
|
|
a9db5b1ac6 | ||
|
|
846fc0d84d | ||
|
|
87610c83fa | ||
|
|
a58f5c4de2 | ||
|
|
1995bba652 | ||
|
|
680747d1d0 |
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
extends: 'react-tools',
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
* text=auto
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Codesandbox!**
|
||||
Use a new [react-table codesandbox](codesandbox.io/s/X6npLXPRW) to reproduce the issue.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
name: Questions, Support & Help
|
||||
about: Looking for help? Need a question answered?
|
||||
|
||||
---
|
||||
|
||||
STOP!!!
|
||||
|
||||
Github issues is no place for general support. We encourage you to use our public support forum at https://spectrum.chat/react-table.
|
||||
|
||||
NOTE: If a support/help/question issue is opened, it will be closed immediately and be redirected to the forum. Thanks for helping us keep our issues clean and productive!
|
||||
@@ -1,8 +1,12 @@
|
||||
node_modules/
|
||||
lib/
|
||||
es/
|
||||
docs/build
|
||||
react-table.js
|
||||
react-table.min.js
|
||||
react-table.css
|
||||
*.log
|
||||
.idea
|
||||
.DS_Store
|
||||
.history
|
||||
.vscode
|
||||
@@ -1 +0,0 @@
|
||||
react-table.js.org
|
||||
@@ -1,18 +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;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 15px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 15px;
|
||||
line-height: 22px;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
body{
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: bold
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
+151
-1
@@ -1,6 +1,156 @@
|
||||
## 6.10.3
|
||||
|
||||
- Further improve `normalizeComponent` function
|
||||
|
||||
## 6.10.2
|
||||
|
||||
- Fixed regression found in `normalizeComponent` function fix
|
||||
|
||||
## 6.10.1
|
||||
|
||||
- Fixed issues with `normalizeComponent` function
|
||||
|
||||
## 6.10.0
|
||||
|
||||
- Rebased volatile commits out of 6.9.0
|
||||
- Merged (hopefully) non-breaking fixes after rebasing and reverting.
|
||||
|
||||
## 6.9.0
|
||||
|
||||
This version has been reverted due to some major bugs that were introduced with it.
|
||||
|
||||
## 6.8.6
|
||||
|
||||
#### Fixes & Optimizations
|
||||
|
||||
- Since `resolveData` is now capable of materializing data on it's own, the `data` prop is no longer required as a prop-type.
|
||||
|
||||
## 6.8.4
|
||||
|
||||
#### Fixes & Optimizations
|
||||
|
||||
- Only run `resolveData` prop when `data` prop has changed, not any others.
|
||||
|
||||
## 6.8.3
|
||||
|
||||
#### Fixes & Optimizations
|
||||
|
||||
- Allow the `resolveData` prop to alter or materialize new data when the `data` prop changes.
|
||||
|
||||
## 6.8.1
|
||||
|
||||
#### Fixes & Optimizations
|
||||
|
||||
- Updated eslint and code formatting
|
||||
|
||||
## 6.7.5
|
||||
|
||||
#### Fixes & Optimizations
|
||||
|
||||
- Now passes `column` to `getResizerProps` (#667)
|
||||
- NOTE: `getResizerProps` is now only called if the column is resizable
|
||||
- Fixes the `className` ordering in defaultProps for ThComponent (#673)
|
||||
- NOTE: user supplied classNames now come at the end so they can extend the defaults
|
||||
|
||||
## 6.7.4
|
||||
|
||||
#### Fixes & Optimizations
|
||||
|
||||
- Fix Prop types for columns
|
||||
|
||||
## 6.7.3
|
||||
|
||||
#### Fixes & Optimizations
|
||||
|
||||
- Fix the rest of the proptypes
|
||||
|
||||
## 6.7.2
|
||||
|
||||
#### Fixes & Optimizations
|
||||
|
||||
- `getPropTypes` proptype check
|
||||
|
||||
## 6.7.1
|
||||
|
||||
#### Fixes & Optimizations
|
||||
|
||||
- `eslint-config` moved to dev deps
|
||||
|
||||
## 6.7.0
|
||||
|
||||
## 6.7.0-alpha-0
|
||||
|
||||
#### New Features
|
||||
|
||||
- Expose page/pageSize to rows/cells
|
||||
- Supply sort direction to custom sort methods
|
||||
|
||||
#### Fixes & Optimizations
|
||||
|
||||
- README updates
|
||||
- Linter cleanup
|
||||
- Added PropTypes node module
|
||||
- Deps, linting and style upgrades
|
||||
|
||||
## 6.6.0
|
||||
|
||||
#### Fixes & Optimizations
|
||||
|
||||
- moved repo to react-tools
|
||||
- Doc examples moved to codesandbox.io
|
||||
- README updates
|
||||
- CSS refacting for rt-tfoot to match rt-thead
|
||||
- CSS more specific for input and select
|
||||
|
||||
## 6.5.3
|
||||
|
||||
#### Fixes & Optimizations
|
||||
|
||||
- `onClick` proxying and eslint
|
||||
|
||||
## 6.5.2
|
||||
|
||||
#### New Features
|
||||
|
||||
- Provide onClick handleOriginal function - #406
|
||||
|
||||
#### Fixes & Optimizations
|
||||
|
||||
- README updates
|
||||
- `makePathArray` in utils - #326
|
||||
- Various fixes: #294, #376, #398, #415,
|
||||
|
||||
## 6.5.1
|
||||
|
||||
#### Fixes & Optimizations
|
||||
|
||||
- `defaultExpanded` now works correctly - #372
|
||||
- `column.getProps().rest` props are now applied correctly
|
||||
- `makeTemplateComponent` now supports `displayName` - #289
|
||||
|
||||
## 6.5.0
|
||||
|
||||
##### New Features
|
||||
|
||||
- `column.filterAll` - defaults to `false`, but when set to `true` will provide the entire array of rows to `filterMethod` as opposed to one row at a time. This allows for more fine-grained filtering using any method you can dream up. See the [Custom Filtering example](https://react-table.js.org/#/story/custom-filtering) for more info.
|
||||
|
||||
## 6.4.0
|
||||
|
||||
##### New Features
|
||||
|
||||
- `PadRowComponent` - the content rendered inside of a padding row. Defaults to a react component that renders ` `
|
||||
|
||||
## 6.3.0
|
||||
|
||||
##### New Features
|
||||
|
||||
- `defaultSortDesc` - allows you to set the default sorting direction for all columns to descending.
|
||||
- `column.defaultSortDesc` - allows you to set the default sorting direction for a specific column. Falls back to the global `defaultSortDesc` when not set at all.
|
||||
|
||||
## 6.0.0
|
||||
|
||||
##### New Features
|
||||
|
||||
- New Renderers:
|
||||
- `Aggregated` - Custom renderer for aggregated cells
|
||||
- `Pivot` - Custom renderer for Pivoted Cells (utilizes `Expander` and `PivotValue`)
|
||||
@@ -16,8 +166,8 @@
|
||||
- Prevent transitions while column resizing for a smoother resize effect.
|
||||
- Disable text selection while resizing columns.
|
||||
|
||||
|
||||
##### Breaking API Changes
|
||||
|
||||
- New Renderers:
|
||||
- `Cell` - deprecates and replaces `render`
|
||||
- `Header` - deprecates and replaces `header`
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
## Problem Description
|
||||
include a detailed explanation of the problem here...
|
||||
|
||||
## Code Snippet(s) or Codepen (http://codepen.io/tannerlinsley/pen/QpeZBa?editors=0010)
|
||||
|
||||
## Steps to Reproduce
|
||||
1. list the steps
|
||||
2. to reproduce the issue
|
||||
|
||||
## System Information
|
||||
* **Browser & Browser Version:**
|
||||
* **Node Version:**
|
||||
* **OS Version:**
|
||||
* **NPM Version:**
|
||||
* **Yarn Version:**
|
||||
@@ -0,0 +1,77 @@
|
||||
module.exports = {
|
||||
parserOptions: {
|
||||
ecmaVersion: 8,
|
||||
ecmaFeatures: {
|
||||
experimentalObjectRestSpread: true,
|
||||
jsx: true,
|
||||
node: false,
|
||||
classes: true
|
||||
},
|
||||
sourceType: 'module'
|
||||
},
|
||||
|
||||
parser: 'babel-eslint',
|
||||
|
||||
extends: ['standard'],
|
||||
|
||||
plugins: ['react'],
|
||||
|
||||
rules: {
|
||||
// Nozzle
|
||||
'jsx-quotes': [2, 'prefer-single'],
|
||||
'comma-dangle': [2, 'always-multiline'],
|
||||
|
||||
// // React
|
||||
'react/jsx-boolean-value': 2,
|
||||
'react/jsx-curly-spacing': [2, 'never'],
|
||||
'react/jsx-equals-spacing': [2, 'never'],
|
||||
// 'react/jsx-indent': 2,
|
||||
'react/jsx-indent-props': [2, 2],
|
||||
'react/jsx-no-duplicate-props': 2,
|
||||
'react/jsx-no-undef': 2,
|
||||
'react/jsx-tag-spacing': [
|
||||
2,
|
||||
{
|
||||
closingSlash: 'never',
|
||||
beforeSelfClosing: 'always',
|
||||
afterOpening: 'never'
|
||||
}
|
||||
],
|
||||
'react/jsx-uses-react': 2,
|
||||
'react/jsx-uses-vars': 2,
|
||||
'react/self-closing-comp': 2,
|
||||
'react/jsx-no-bind': [
|
||||
2,
|
||||
{
|
||||
allowArrowFunctions: true,
|
||||
allowBind: false,
|
||||
ignoreRefs: true
|
||||
}
|
||||
],
|
||||
'react/no-did-update-set-state': 2,
|
||||
'react/no-unknown-property': 2,
|
||||
'react/react-in-jsx-scope': 2,
|
||||
'react/jsx-closing-bracket-location': [0, 'tag-aligned'],
|
||||
'react/jsx-tag-spacing': [2, { beforeSelfClosing: 'always' }],
|
||||
'react/jsx-wrap-multilines': 2,
|
||||
'react/self-closing-comp': 2,
|
||||
'react/jsx-key': 2,
|
||||
'react/jsx-no-comment-textnodes': 2,
|
||||
'react/jsx-no-duplicate-props': 2,
|
||||
'react/jsx-no-target-blank': 2,
|
||||
'react/jsx-no-undef': 2,
|
||||
'react/jsx-uses-react': 2,
|
||||
'react/jsx-uses-vars': 2,
|
||||
'react/no-danger-with-children': 2,
|
||||
'react/no-deprecated': 2,
|
||||
'react/no-direct-mutation-state': 2,
|
||||
'react/no-find-dom-node': 2,
|
||||
'react/no-is-mounted': 2,
|
||||
'react/no-render-return-value': 2,
|
||||
'react/no-string-refs': 2,
|
||||
'react/no-unknown-property': 2,
|
||||
'react/react-in-jsx-scope': 2,
|
||||
'react/require-render-return': 2
|
||||
// 'react/jsx-max-props-per-line': [2, { maximum: 1 }]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
react-table.js.org
|
||||
+197
-192
@@ -5,83 +5,83 @@ You can find the most recent version of this guide [here](https://github.com/fac
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Updating to New Releases](#updating-to-new-releases)
|
||||
- [Sending Feedback](#sending-feedback)
|
||||
- [Folder Structure](#folder-structure)
|
||||
- [Available Scripts](#available-scripts)
|
||||
- [npm start](#npm-start)
|
||||
- [npm test](#npm-test)
|
||||
- [npm run build](#npm-run-build)
|
||||
- [npm run eject](#npm-run-eject)
|
||||
- [Supported Language Features and Polyfills](#supported-language-features-and-polyfills)
|
||||
- [Syntax Highlighting in the Editor](#syntax-highlighting-in-the-editor)
|
||||
- [Displaying Lint Output in the Editor](#displaying-lint-output-in-the-editor)
|
||||
- [Debugging in the Editor](#debugging-in-the-editor)
|
||||
- [Changing the Page `<title>`](#changing-the-page-title)
|
||||
- [Installing a Dependency](#installing-a-dependency)
|
||||
- [Importing a Component](#importing-a-component)
|
||||
- [Adding a Stylesheet](#adding-a-stylesheet)
|
||||
- [Post-Processing CSS](#post-processing-css)
|
||||
- [Adding a CSS Preprocessor (Sass, Less etc.)](#adding-a-css-preprocessor-sass-less-etc)
|
||||
- [Adding Images and Fonts](#adding-images-and-fonts)
|
||||
- [Using the `public` Folder](#using-the-public-folder)
|
||||
- [Changing the HTML](#changing-the-html)
|
||||
- [Adding Assets Outside of the Module System](#adding-assets-outside-of-the-module-system)
|
||||
- [When to Use the `public` Folder](#when-to-use-the-public-folder)
|
||||
- [Using Global Variables](#using-global-variables)
|
||||
- [Adding Bootstrap](#adding-bootstrap)
|
||||
- [Using a Custom Theme](#using-a-custom-theme)
|
||||
- [Adding Flow](#adding-flow)
|
||||
- [Adding Custom Environment Variables](#adding-custom-environment-variables)
|
||||
- [Referencing Environment Variables in the HTML](#referencing-environment-variables-in-the-html)
|
||||
- [Adding Temporary Environment Variables In Your Shell](#adding-temporary-environment-variables-in-your-shell)
|
||||
- [Adding Development Environment Variables In `.env`](#adding-development-environment-variables-in-env)
|
||||
- [Can I Use Decorators?](#can-i-use-decorators)
|
||||
- [Integrating with an API Backend](#integrating-with-an-api-backend)
|
||||
- [Node](#node)
|
||||
- [Ruby on Rails](#ruby-on-rails)
|
||||
- [Proxying API Requests in Development](#proxying-api-requests-in-development)
|
||||
- [Using HTTPS in Development](#using-https-in-development)
|
||||
- [Generating Dynamic `<meta>` Tags on the Server](#generating-dynamic-meta-tags-on-the-server)
|
||||
- [Pre-Rendering into Static HTML Files](#pre-rendering-into-static-html-files)
|
||||
- [Injecting Data from the Server into the Page](#injecting-data-from-the-server-into-the-page)
|
||||
- [Running Tests](#running-tests)
|
||||
- [Filename Conventions](#filename-conventions)
|
||||
- [Command Line Interface](#command-line-interface)
|
||||
- [Version Control Integration](#version-control-integration)
|
||||
- [Writing Tests](#writing-tests)
|
||||
- [Testing Components](#testing-components)
|
||||
- [Using Third Party Assertion Libraries](#using-third-party-assertion-libraries)
|
||||
- [Initializing Test Environment](#initializing-test-environment)
|
||||
- [Focusing and Excluding Tests](#focusing-and-excluding-tests)
|
||||
- [Coverage Reporting](#coverage-reporting)
|
||||
- [Continuous Integration](#continuous-integration)
|
||||
- [Disabling jsdom](#disabling-jsdom)
|
||||
- [Snapshot Testing](#snapshot-testing)
|
||||
- [Editor Integration](#editor-integration)
|
||||
- [Developing Components in Isolation](#developing-components-in-isolation)
|
||||
- [Making a Progressive Web App](#making-a-progressive-web-app)
|
||||
- [Deployment](#deployment)
|
||||
- [Static Server](#static-server)
|
||||
- [Other Solutions](#other-solutions)
|
||||
- [Serving Apps with Client-Side Routing](#serving-apps-with-client-side-routing)
|
||||
- [Building for Relative Paths](#building-for-relative-paths)
|
||||
- [Azure](#azure)
|
||||
- [Firebase](#firebase)
|
||||
- [GitHub Pages](#github-pages)
|
||||
- [Heroku](#heroku)
|
||||
- [Modulus](#modulus)
|
||||
- [Netlify](#netlify)
|
||||
- [Now](#now)
|
||||
- [S3 and CloudFront](#s3-and-cloudfront)
|
||||
- [Surge](#surge)
|
||||
- [Advanced Configuration](#advanced-configuration)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [`npm start` doesn’t detect changes](#npm-start-doesnt-detect-changes)
|
||||
- [`npm test` hangs on macOS Sierra](#npm-test-hangs-on-macos-sierra)
|
||||
- [`npm run build` silently fails](#npm-run-build-silently-fails)
|
||||
- [`npm run build` fails on Heroku](#npm-run-build-fails-on-heroku)
|
||||
- [Something Missing?](#something-missing)
|
||||
* [Updating to New Releases](#updating-to-new-releases)
|
||||
* [Sending Feedback](#sending-feedback)
|
||||
* [Folder Structure](#folder-structure)
|
||||
* [Available Scripts](#available-scripts)
|
||||
* [npm start](#npm-start)
|
||||
* [npm test](#npm-test)
|
||||
* [npm run build](#npm-run-build)
|
||||
* [npm run eject](#npm-run-eject)
|
||||
* [Supported Language Features and Polyfills](#supported-language-features-and-polyfills)
|
||||
* [Syntax Highlighting in the Editor](#syntax-highlighting-in-the-editor)
|
||||
* [Displaying Lint Output in the Editor](#displaying-lint-output-in-the-editor)
|
||||
* [Debugging in the Editor](#debugging-in-the-editor)
|
||||
* [Changing the Page `<title>`](#changing-the-page-title)
|
||||
* [Installing a Dependency](#installing-a-dependency)
|
||||
* [Importing a Component](#importing-a-component)
|
||||
* [Adding a Stylesheet](#adding-a-stylesheet)
|
||||
* [Post-Processing CSS](#post-processing-css)
|
||||
* [Adding a CSS Preprocessor (Sass, Less etc.)](#adding-a-css-preprocessor-sass-less-etc)
|
||||
* [Adding Images and Fonts](#adding-images-and-fonts)
|
||||
* [Using the `public` Folder](#using-the-public-folder)
|
||||
* [Changing the HTML](#changing-the-html)
|
||||
* [Adding Assets Outside of the Module System](#adding-assets-outside-of-the-module-system)
|
||||
* [When to Use the `public` Folder](#when-to-use-the-public-folder)
|
||||
* [Using Global Variables](#using-global-variables)
|
||||
* [Adding Bootstrap](#adding-bootstrap)
|
||||
* [Using a Custom Theme](#using-a-custom-theme)
|
||||
* [Adding Flow](#adding-flow)
|
||||
* [Adding Custom Environment Variables](#adding-custom-environment-variables)
|
||||
* [Referencing Environment Variables in the HTML](#referencing-environment-variables-in-the-html)
|
||||
* [Adding Temporary Environment Variables In Your Shell](#adding-temporary-environment-variables-in-your-shell)
|
||||
* [Adding Development Environment Variables In `.env`](#adding-development-environment-variables-in-env)
|
||||
* [Can I Use Decorators?](#can-i-use-decorators)
|
||||
* [Integrating with an API Backend](#integrating-with-an-api-backend)
|
||||
* [Node](#node)
|
||||
* [Ruby on Rails](#ruby-on-rails)
|
||||
* [Proxying API Requests in Development](#proxying-api-requests-in-development)
|
||||
* [Using HTTPS in Development](#using-https-in-development)
|
||||
* [Generating Dynamic `<meta>` Tags on the Server](#generating-dynamic-meta-tags-on-the-server)
|
||||
* [Pre-Rendering into Static HTML Files](#pre-rendering-into-static-html-files)
|
||||
* [Injecting Data from the Server into the Page](#injecting-data-from-the-server-into-the-page)
|
||||
* [Running Tests](#running-tests)
|
||||
* [Filename Conventions](#filename-conventions)
|
||||
* [Command Line Interface](#command-line-interface)
|
||||
* [Version Control Integration](#version-control-integration)
|
||||
* [Writing Tests](#writing-tests)
|
||||
* [Testing Components](#testing-components)
|
||||
* [Using Third Party Assertion Libraries](#using-third-party-assertion-libraries)
|
||||
* [Initializing Test Environment](#initializing-test-environment)
|
||||
* [Focusing and Excluding Tests](#focusing-and-excluding-tests)
|
||||
* [Coverage Reporting](#coverage-reporting)
|
||||
* [Continuous Integration](#continuous-integration)
|
||||
* [Disabling jsdom](#disabling-jsdom)
|
||||
* [Snapshot Testing](#snapshot-testing)
|
||||
* [Editor Integration](#editor-integration)
|
||||
* [Developing Components in Isolation](#developing-components-in-isolation)
|
||||
* [Making a Progressive Web App](#making-a-progressive-web-app)
|
||||
* [Deployment](#deployment)
|
||||
* [Static Server](#static-server)
|
||||
* [Other Solutions](#other-solutions)
|
||||
* [Serving Apps with Client-Side Routing](#serving-apps-with-client-side-routing)
|
||||
* [Building for Relative Paths](#building-for-relative-paths)
|
||||
* [Azure](#azure)
|
||||
* [Firebase](#firebase)
|
||||
* [GitHub Pages](#github-pages)
|
||||
* [Heroku](#heroku)
|
||||
* [Modulus](#modulus)
|
||||
* [Netlify](#netlify)
|
||||
* [Now](#now)
|
||||
* [S3 and CloudFront](#s3-and-cloudfront)
|
||||
* [Surge](#surge)
|
||||
* [Advanced Configuration](#advanced-configuration)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
* [`npm start` doesn’t detect changes](#npm-start-doesnt-detect-changes)
|
||||
* [`npm test` hangs on macOS Sierra](#npm-test-hangs-on-macos-sierra)
|
||||
* [`npm run build` silently fails](#npm-run-build-silently-fails)
|
||||
* [`npm run build` fails on Heroku](#npm-run-build-fails-on-heroku)
|
||||
* [Something Missing?](#something-missing)
|
||||
|
||||
## Updating to New Releases
|
||||
|
||||
@@ -207,7 +207,7 @@ To configure the syntax highlighting in your favorite text editor, head to the [
|
||||
|
||||
## Displaying Lint Output in the Editor
|
||||
|
||||
>Note: this feature is available with `react-scripts@0.2.0` and higher.
|
||||
> Note: this feature is available with `react-scripts@0.2.0` and higher.
|
||||
|
||||
Some editors, including Sublime Text, Atom, and Visual Studio Code, provide plugins for ESLint.
|
||||
|
||||
@@ -215,24 +215,24 @@ They are not required for linting. You should see the linter output right in you
|
||||
|
||||
You would need to install an ESLint plugin for your editor first.
|
||||
|
||||
>**A note for Atom `linter-eslint` users**
|
||||
> **A note for Atom `linter-eslint` users**
|
||||
|
||||
>If you are using the Atom `linter-eslint` plugin, make sure that **Use global ESLint installation** option is checked:
|
||||
> If you are using the Atom `linter-eslint` plugin, make sure that **Use global ESLint installation** option is checked:
|
||||
|
||||
><img src="http://i.imgur.com/yVNNHJM.png" width="300">
|
||||
> <img src="http://i.imgur.com/yVNNHJM.png" width="300">
|
||||
|
||||
> **For Visual Studio Code users**
|
||||
|
||||
>**For Visual Studio Code users**
|
||||
> VS Code ESLint plugin automatically detects Create React App's configuration file. So you do not need to create `eslintrc.json` at the root directory, except when you want to add your own rules. In that case, you should include CRA's config by adding this line:
|
||||
|
||||
>VS Code ESLint plugin automatically detects Create React App's configuration file. So you do not need to create `eslintrc.json` at the root directory, except when you want to add your own rules. In that case, you should include CRA's config by adding this line:
|
||||
|
||||
>```js
|
||||
{
|
||||
// ...
|
||||
"extends": "react-app"
|
||||
}
|
||||
```
|
||||
> ```js
|
||||
> {
|
||||
> // ...
|
||||
> "extends": "react-app"
|
||||
> }
|
||||
> ```
|
||||
|
||||
````
|
||||
Then add this block to the `package.json` file of your project:
|
||||
|
||||
```js
|
||||
@@ -242,9 +242,9 @@ Then add this block to the `package.json` file of your project:
|
||||
"extends": "react-app"
|
||||
}
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
Finally, you will need to install some packages *globally*:
|
||||
Finally, you will need to install some packages _globally_:
|
||||
|
||||
```sh
|
||||
npm install -g eslint-config-react-app@0.3.0 eslint@3.8.1 babel-eslint@7.0.0 eslint-plugin-react@6.4.1 eslint-plugin-import@2.0.1 eslint-plugin-jsx-a11y@4.0.0 eslint-plugin-flowtype@2.21.0
|
||||
@@ -265,17 +265,19 @@ Then add the block below to your `launch.json` file and put it inside the `.vsco
|
||||
```json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [{
|
||||
"name": "Chrome",
|
||||
"type": "chrome",
|
||||
"request": "launch",
|
||||
"url": "http://localhost:3000",
|
||||
"webRoot": "${workspaceRoot}/src",
|
||||
"userDataDir": "${workspaceRoot}/.vscode/chrome",
|
||||
"sourceMapPathOverrides": {
|
||||
"webpack:///src/*": "${webRoot}/*"
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Chrome",
|
||||
"type": "chrome",
|
||||
"request": "launch",
|
||||
"url": "http://localhost:3000",
|
||||
"webRoot": "${workspaceRoot}/src",
|
||||
"userDataDir": "${workspaceRoot}/.vscode/chrome",
|
||||
"sourceMapPathOverrides": {
|
||||
"webpack:///src/*": "${webRoot}/*"
|
||||
}
|
||||
}
|
||||
}]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -309,7 +311,7 @@ For example:
|
||||
### `Button.js`
|
||||
|
||||
```js
|
||||
import React, { Component } from 'react';
|
||||
import React, { Component } from "react";
|
||||
|
||||
class Button extends Component {
|
||||
render() {
|
||||
@@ -322,10 +324,9 @@ export default Button; // Don’t forget to use export default!
|
||||
|
||||
### `DangerButton.js`
|
||||
|
||||
|
||||
```js
|
||||
import React, { Component } from 'react';
|
||||
import Button from './Button'; // Import a component from another file
|
||||
import React, { Component } from "react";
|
||||
import Button from "./Button"; // Import a component from another file
|
||||
|
||||
class DangerButton extends Component {
|
||||
render() {
|
||||
@@ -363,8 +364,8 @@ This project setup uses [Webpack](https://webpack.github.io/) for handling all a
|
||||
### `Button.js`
|
||||
|
||||
```js
|
||||
import React, { Component } from 'react';
|
||||
import './Button.css'; // Tell Webpack that Button.js uses these styles
|
||||
import React, { Component } from "react";
|
||||
import "./Button.css"; // Tell Webpack that Button.js uses these styles
|
||||
|
||||
class Button extends Component {
|
||||
render() {
|
||||
@@ -403,11 +404,11 @@ becomes this:
|
||||
display: flex;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -436,7 +437,7 @@ Then in `package.json`, add the following lines to `scripts`:
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
```
|
||||
|
||||
>Note: To use a different preprocessor, replace `build-css` and `watch-css` commands according to your preprocessor’s documentation.
|
||||
> Note: To use a different preprocessor, replace `build-css` and `watch-css` commands according to your preprocessor’s documentation.
|
||||
|
||||
Now you can rename `src/App.css` to `src/App.scss` and run `npm run watch-css`. The watcher will find every Sass file in `src` subdirectories, and create a corresponding CSS file next to it, in our case overwriting `src/App.css`. Since `src/App.js` still imports `src/App.css`, the styles become a part of your application. You can now edit `src/App.scss`, and `src/App.css` will be regenerated.
|
||||
|
||||
@@ -477,8 +478,8 @@ You can **`import` an image right in a JavaScript module**. This tells Webpack t
|
||||
Here is an example:
|
||||
|
||||
```js
|
||||
import React from 'react';
|
||||
import logo from './logo.png'; // Tell Webpack this JS file uses this image
|
||||
import React from "react";
|
||||
import logo from "./logo.png"; // Tell Webpack this JS file uses this image
|
||||
|
||||
console.log(logo); // /logo.84287d09.png
|
||||
|
||||
@@ -509,7 +510,7 @@ An alternative way of handling static assets is described in the next section.
|
||||
|
||||
## Using the `public` Folder
|
||||
|
||||
>Note: this feature is available with `react-scripts@0.5.0` and higher.
|
||||
> Note: this feature is available with `react-scripts@0.5.0` and higher.
|
||||
|
||||
### Changing the HTML
|
||||
|
||||
@@ -530,7 +531,7 @@ This mechanism provides a number of benefits:
|
||||
|
||||
However there is an **escape hatch** that you can use to add an asset outside of the module system.
|
||||
|
||||
If you put a file into the `public` folder, it will **not** be processed by Webpack. Instead it will be copied into the build folder untouched. To reference assets in the `public` folder, you need to use a special variable called `PUBLIC_URL`.
|
||||
If you put a file into the `public` folder, it will **not** be processed by Webpack. Instead it will be copied into the build folder untouched. To reference assets in the `public` folder, you need to use a special variable called `PUBLIC_URL`.
|
||||
|
||||
Inside `index.html`, you can use it like this:
|
||||
|
||||
@@ -596,19 +597,19 @@ npm install react-bootstrap --save
|
||||
npm install bootstrap@3 --save
|
||||
```
|
||||
|
||||
Import Bootstrap CSS and optionally Bootstrap theme CSS in the beginning of your ```src/index.js``` file:
|
||||
Import Bootstrap CSS and optionally Bootstrap theme CSS in the beginning of your `src/index.js` file:
|
||||
|
||||
```js
|
||||
import 'bootstrap/dist/css/bootstrap.css';
|
||||
import 'bootstrap/dist/css/bootstrap-theme.css';
|
||||
import "bootstrap/dist/css/bootstrap.css";
|
||||
import "bootstrap/dist/css/bootstrap-theme.css";
|
||||
// Put any other imports below so that CSS from your
|
||||
// components takes precedence over default styles.
|
||||
```
|
||||
|
||||
Import required React Bootstrap components within ```src/App.js``` file or your custom component files:
|
||||
Import required React Bootstrap components within `src/App.js` file or your custom component files:
|
||||
|
||||
```js
|
||||
import { Navbar, Jumbotron, Button } from 'react-bootstrap';
|
||||
import { Navbar, Jumbotron, Button } from "react-bootstrap";
|
||||
```
|
||||
|
||||
Now you are ready to use the imported React Bootstrap components within your component hierarchy defined in the render method. Here is an example [`App.js`](https://gist.githubusercontent.com/gaearon/85d8c067f6af1e56277c82d19fd4da7b/raw/6158dd991b67284e9fc8d70b9d973efe87659d72/App.js) redone using React Bootstrap.
|
||||
@@ -632,10 +633,10 @@ Recent versions of [Flow](http://flowtype.org/) work with Create React App proje
|
||||
|
||||
To add Flow to a Create React App project, follow these steps:
|
||||
|
||||
1. Run `npm install --save-dev flow-bin` (or `yarn add --dev flow-bin`).
|
||||
2. Add `"flow": "flow"` to the `scripts` section of your `package.json`.
|
||||
3. Run `npm run flow -- init` (or `yarn flow -- init`) to create a [`.flowconfig` file](https://flowtype.org/docs/advanced-configuration.html) in the root directory.
|
||||
4. Add `// @flow` to any files you want to type check (for example, to `src/App.js`).
|
||||
1. Run `npm install --save-dev flow-bin` (or `yarn add --dev flow-bin`).
|
||||
2. Add `"flow": "flow"` to the `scripts` section of your `package.json`.
|
||||
3. Run `npm run flow -- init` (or `yarn flow -- init`) to create a [`.flowconfig` file](https://flowtype.org/docs/advanced-configuration.html) in the root directory.
|
||||
4. Add `// @flow` to any files you want to type check (for example, to `src/App.js`).
|
||||
|
||||
Now you can run `npm run flow` (or `yarn flow`) to check the files for type errors.
|
||||
You can optionally use an IDE like [Nuclide](https://nuclide.io/docs/languages/flow/) for a better integrated experience.
|
||||
@@ -645,7 +646,7 @@ To learn more about Flow, check out [its documentation](https://flowtype.org/).
|
||||
|
||||
## Adding Custom Environment Variables
|
||||
|
||||
>Note: this feature is available with `react-scripts@0.2.3` and higher.
|
||||
> Note: this feature is available with `react-scripts@0.2.3` and higher.
|
||||
|
||||
Your project can consume variables declared in your environment as if they were declared locally in your JS files. By
|
||||
default you will have `NODE_ENV` defined for you, and any other environment variables starting with
|
||||
@@ -653,7 +654,7 @@ default you will have `NODE_ENV` defined for you, and any other environment vari
|
||||
|
||||
**The environment variables are embedded during the build time**. Since Create React App produces a static HTML/CSS/JS bundle, it can’t possibly read them at runtime. To read them at runtime, you would need to load HTML into memory on the server and replace placeholders in runtime, just like [described here](#injecting-data-from-the-server-into-the-page). Alternatively you can rebuild the app on the server anytime you change them.
|
||||
|
||||
>Note: You must create custom environment variables beginning with `REACT_APP_`. Any other variables except `NODE_ENV` will be ignored to avoid accidentally [exposing a private key on the machine that could have the same name](https://github.com/facebookincubator/create-react-app/issues/865#issuecomment-252199527). Changing any environment variables will require you to restart the development server if it is running.
|
||||
> Note: You must create custom environment variables beginning with `REACT_APP_`. Any other variables except `NODE_ENV` will be ignored to avoid accidentally [exposing a private key on the machine that could have the same name](https://github.com/facebookincubator/create-react-app/issues/865#issuecomment-252199527). Changing any environment variables will require you to restart the development server if it is running.
|
||||
|
||||
These environment variables will be defined for you on `process.env`. For example, having an environment
|
||||
variable named `REACT_APP_SECRET_CODE` will be exposed in your JS as `process.env.REACT_APP_SECRET_CODE`.
|
||||
@@ -699,7 +700,7 @@ a `.env` file. Both of these ways are described in the next few sections.
|
||||
Having access to the `NODE_ENV` is also useful for performing actions conditionally:
|
||||
|
||||
```js
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
analytics.disable();
|
||||
}
|
||||
```
|
||||
@@ -708,7 +709,7 @@ When you compile the app with `npm run build`, the minification step will strip
|
||||
|
||||
### Referencing Environment Variables in the HTML
|
||||
|
||||
>Note: this feature is available with `react-scripts@0.9.0` and higher.
|
||||
> Note: this feature is available with `react-scripts@0.9.0` and higher.
|
||||
|
||||
You can also access the environment variables starting with `REACT_APP_` in the `public/index.html`. For example:
|
||||
|
||||
@@ -742,7 +743,7 @@ REACT_APP_SECRET_CODE=abcdef npm start
|
||||
|
||||
### Adding Development Environment Variables In `.env`
|
||||
|
||||
>Note: this feature is available with `react-scripts@0.5.0` and higher.
|
||||
> Note: this feature is available with `react-scripts@0.5.0` and higher.
|
||||
|
||||
To define permanent environment variables, create a file called `.env` in the root of your project:
|
||||
|
||||
@@ -753,8 +754,8 @@ REACT_APP_SECRET_CODE=abcdef
|
||||
These variables will act as the defaults if the machine does not explicitly set them.<br>
|
||||
Please refer to the [dotenv documentation](https://github.com/motdotla/dotenv) for more details.
|
||||
|
||||
>Note: If you are defining environment variables for development, your CI and/or hosting platform will most likely need
|
||||
these defined as well. Consult their documentation how to do this. For example, see the documentation for [Travis CI](https://docs.travis-ci.com/user/environment-variables/) or [Heroku](https://devcenter.heroku.com/articles/config-vars).
|
||||
> Note: If you are defining environment variables for development, your CI and/or hosting platform will most likely need
|
||||
> these defined as well. Consult their documentation how to do this. For example, see the documentation for [Travis CI](https://docs.travis-ci.com/user/environment-variables/) or [Heroku](https://devcenter.heroku.com/articles/config-vars).
|
||||
|
||||
## Can I Use Decorators?
|
||||
|
||||
@@ -779,6 +780,7 @@ These tutorials will help you to integrate your app with an API backend running
|
||||
using `fetch()` to access it.
|
||||
|
||||
### Node
|
||||
|
||||
Check out [this tutorial](https://www.fullstackreact.com/articles/using-create-react-app-with-a-server/).
|
||||
You can find the companion GitHub repository [here](https://github.com/fullstackreact/food-lookup-demo).
|
||||
|
||||
@@ -789,7 +791,7 @@ You can find the companion GitHub repository [here](https://github.com/fullstack
|
||||
|
||||
## Proxying API Requests in Development
|
||||
|
||||
>Note: this feature is available with `react-scripts@0.2.3` and higher.
|
||||
> Note: this feature is available with `react-scripts@0.2.3` and higher.
|
||||
|
||||
People often serve the front-end React app from the same host and port as their backend implementation.<br>
|
||||
For example, a production setup might look like this after the app is deployed:
|
||||
@@ -826,7 +828,7 @@ If the `proxy` option is **not** flexible enough for you, alternatively you can:
|
||||
|
||||
## Using HTTPS in Development
|
||||
|
||||
>Note: this feature is available with `react-scripts@0.4.0` and higher.
|
||||
> Note: this feature is available with `react-scripts@0.4.0` and higher.
|
||||
|
||||
You may require the dev server to serve pages over HTTPS. One particular case where this could be useful is when using [the "proxy" feature](#proxying-api-requests-in-development) to proxy requests to an API server when that API server is itself serving HTTPS.
|
||||
|
||||
@@ -891,8 +893,7 @@ Then, on the server, you can replace `__SERVER_DATA__` with a JSON of real data
|
||||
|
||||
## Running Tests
|
||||
|
||||
>Note: this feature is available with `react-scripts@0.3.0` and higher.<br>
|
||||
>[Read the migration guide to learn how to enable it in older projects!](https://github.com/facebookincubator/create-react-app/blob/master/CHANGELOG.md#migrating-from-023-to-030)
|
||||
> Note: this feature is available with `react-scripts@0.3.0` and higher.<br> >[Read the migration guide to learn how to enable it in older projects!](https://github.com/facebookincubator/create-react-app/blob/master/CHANGELOG.md#migrating-from-023-to-030)
|
||||
|
||||
Create React App uses [Jest](https://facebook.github.io/jest/) as its test runner. To prepare for this integration, we did a [major revamp](https://facebook.github.io/jest/blog/2016/09/01/jest-15.html) of Jest so if you heard bad things about it years ago, give it another try.
|
||||
|
||||
@@ -937,9 +938,9 @@ To create tests, add `it()` (or `test()`) blocks with the name of the test and i
|
||||
Jest provides a built-in `expect()` global function for making assertions. A basic test could look like this:
|
||||
|
||||
```js
|
||||
import sum from './sum';
|
||||
import sum from "./sum";
|
||||
|
||||
it('sums numbers', () => {
|
||||
it("sums numbers", () => {
|
||||
expect(sum(1, 2)).toEqual(3);
|
||||
expect(sum(2, 2)).toEqual(4);
|
||||
});
|
||||
@@ -955,12 +956,12 @@ There is a broad spectrum of component testing techniques. They range from a “
|
||||
Different projects choose different testing tradeoffs based on how often components change, and how much logic they contain. If you haven’t decided on a testing strategy yet, we recommend that you start with creating simple smoke tests for your components:
|
||||
|
||||
```js
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import App from './App';
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import App from "./App";
|
||||
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
it("renders without crashing", () => {
|
||||
const div = document.createElement("div");
|
||||
ReactDOM.render(<App />, div);
|
||||
});
|
||||
```
|
||||
@@ -976,11 +977,11 @@ npm install --save-dev enzyme react-addons-test-utils
|
||||
```
|
||||
|
||||
```js
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import App from './App';
|
||||
import React from "react";
|
||||
import { shallow } from "enzyme";
|
||||
import App from "./App";
|
||||
|
||||
it('renders without crashing', () => {
|
||||
it("renders without crashing", () => {
|
||||
shallow(<App />);
|
||||
});
|
||||
```
|
||||
@@ -992,11 +993,11 @@ You can read the [Enzyme documentation](http://airbnb.io/enzyme/) for more testi
|
||||
Here is an example from Enzyme documentation that asserts specific output, rewritten to use Jest matchers:
|
||||
|
||||
```js
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import App from './App';
|
||||
import React from "react";
|
||||
import { shallow } from "enzyme";
|
||||
import App from "./App";
|
||||
|
||||
it('renders welcome message', () => {
|
||||
it("renders welcome message", () => {
|
||||
const wrapper = shallow(<App />);
|
||||
const welcome = <h2>Welcome to React</h2>;
|
||||
// expect(wrapper.contains(welcome)).to.equal(true);
|
||||
@@ -1010,7 +1011,7 @@ Nevertheless you can use a third-party assertion library like [Chai](http://chai
|
||||
Additionally, you might find [jest-enzyme](https://github.com/blainekasten/enzyme-matchers) helpful to simplify your tests with readable matchers. The above `contains` code can be written simpler with jest-enzyme.
|
||||
|
||||
```js
|
||||
expect(wrapper).toContainReact(welcome)
|
||||
expect(wrapper).toContainReact(welcome);
|
||||
```
|
||||
|
||||
To setup jest-enzyme with Create React App, follow the instructions for [initializing your test environment](#initializing-test-environment) to import `jest-enzyme`.
|
||||
@@ -1021,10 +1022,9 @@ npm install --save-dev jest-enzyme
|
||||
|
||||
```js
|
||||
// src/setupTests.js
|
||||
import 'jest-enzyme';
|
||||
import "jest-enzyme";
|
||||
```
|
||||
|
||||
|
||||
### Using Third Party Assertion Libraries
|
||||
|
||||
We recommend that you use `expect()` for assertions and `jest.fn()` for spies. If you are having issues with them please [file those against Jest](https://github.com/facebook/jest/issues/new), and we’ll fix them. We intend to keep making them better for React, supporting, for example, [pretty-printing React elements as JSX](https://github.com/facebook/jest/pull/1566).
|
||||
@@ -1032,28 +1032,29 @@ We recommend that you use `expect()` for assertions and `jest.fn()` for spies. I
|
||||
However, if you are used to other libraries, such as [Chai](http://chaijs.com/) and [Sinon](http://sinonjs.org/), or if you have existing code using them that you’d like to port over, you can import them normally like this:
|
||||
|
||||
```js
|
||||
import sinon from 'sinon';
|
||||
import { expect } from 'chai';
|
||||
import sinon from "sinon";
|
||||
import { expect } from "chai";
|
||||
```
|
||||
|
||||
and then use them in your tests like you normally do.
|
||||
|
||||
### Initializing Test Environment
|
||||
|
||||
>Note: this feature is available with `react-scripts@0.4.0` and higher.
|
||||
> Note: this feature is available with `react-scripts@0.4.0` and higher.
|
||||
|
||||
If your app uses a browser API that you need to mock in your tests or if you just need a global setup before running your tests, add a `src/setupTests.js` to your project. It will be automatically executed before running your tests.
|
||||
|
||||
For example:
|
||||
|
||||
#### `src/setupTests.js`
|
||||
|
||||
```js
|
||||
const localStorageMock = {
|
||||
getItem: jest.fn(),
|
||||
setItem: jest.fn(),
|
||||
clear: jest.fn()
|
||||
};
|
||||
global.localStorage = localStorageMock
|
||||
global.localStorage = localStorageMock;
|
||||
```
|
||||
|
||||
### Focusing and Excluding Tests
|
||||
@@ -1079,10 +1080,12 @@ When creating a build of your application with `npm run build` linter warnings a
|
||||
Popular CI servers already set the environment variable `CI` by default but you can do this yourself too:
|
||||
|
||||
### On CI servers
|
||||
|
||||
#### Travis CI
|
||||
|
||||
1. Following the [Travis Getting started](https://docs.travis-ci.com/user/getting-started/) guide for syncing your GitHub repository with Travis. You may need to initialize some settings manually in your [profile](https://travis-ci.org/profile) page.
|
||||
1. Add a `.travis.yml` file to your git repository.
|
||||
1. Following the [Travis Getting started](https://docs.travis-ci.com/user/getting-started/) guide for syncing your GitHub repository with Travis. You may need to initialize some settings manually in your [profile](https://travis-ci.org/profile) page.
|
||||
1. Add a `.travis.yml` file to your git repository.
|
||||
|
||||
```
|
||||
language: node_js
|
||||
node_js:
|
||||
@@ -1095,10 +1098,12 @@ script:
|
||||
- npm test
|
||||
- npm run build
|
||||
```
|
||||
1. Trigger your first build with a git push.
|
||||
1. [Customize your Travis CI Build](https://docs.travis-ci.com/user/customizing-the-build/) if needed.
|
||||
|
||||
1. Trigger your first build with a git push.
|
||||
1. [Customize your Travis CI Build](https://docs.travis-ci.com/user/customizing-the-build/) if needed.
|
||||
|
||||
### On your own environment
|
||||
|
||||
##### Windows (cmd.exe)
|
||||
|
||||
```cmd
|
||||
@@ -1123,7 +1128,7 @@ CI=true npm run build
|
||||
|
||||
The test command will force Jest to run tests once instead of launching the watcher.
|
||||
|
||||
> If you find yourself doing this often in development, please [file an issue](https://github.com/facebookincubator/create-react-app/issues/new) to tell us about your use case because we want to make watcher the best experience and are open to changing how it works to accommodate more workflows.
|
||||
> If you find yourself doing this often in development, please [file an issue](https://github.com/facebookincubator/create-react-app/issues/new) to tell us about your use case because we want to make watcher the best experience and are open to changing how it works to accommodate more workflows.
|
||||
|
||||
The build command will check for linter warnings and fail if any are found.
|
||||
|
||||
@@ -1236,14 +1241,14 @@ You don’t necessarily need a static server in order to run a Create React App
|
||||
Here’s a programmatic example using [Node](https://nodejs.org/) and [Express](http://expressjs.com/):
|
||||
|
||||
```javascript
|
||||
const express = require('express');
|
||||
const path = require('path');
|
||||
const express = require("express");
|
||||
const path = require("path");
|
||||
const app = express();
|
||||
|
||||
app.use(express.static('./build'));
|
||||
app.use(express.static("./build"));
|
||||
|
||||
app.get('/', function (req, res) {
|
||||
res.sendFile(path.join(__dirname, './build', 'index.html'));
|
||||
app.get("/", function(req, res) {
|
||||
res.sendFile(path.join(__dirname, "./build", "index.html"));
|
||||
});
|
||||
|
||||
app.listen(9000);
|
||||
@@ -1296,7 +1301,7 @@ This will let Create React App correctly infer the root path to use in the gener
|
||||
|
||||
#### Serving the Same Build from Different Paths
|
||||
|
||||
>Note: this feature is available with `react-scripts@0.9.0` and higher.
|
||||
> Note: this feature is available with `react-scripts@0.9.0` and higher.
|
||||
|
||||
If you are not using the HTML5 `pushState` history API or not using client-side routing at all, it is unnecessary to specify the URL from which your app will be served. Instead, you can put this in your `package.json`:
|
||||
|
||||
@@ -1373,7 +1378,7 @@ For more information see [Add Firebase to your JavaScript Project](https://fireb
|
||||
|
||||
### GitHub Pages
|
||||
|
||||
>Note: this feature is available with `react-scripts@0.2.0` and higher.
|
||||
> Note: this feature is available with `react-scripts@0.2.0` and higher.
|
||||
|
||||
#### Step 1: Add `homepage` to `package.json`
|
||||
|
||||
@@ -1493,9 +1498,9 @@ Choose `build` as the path to deploy.
|
||||
|
||||
With this setup Netlify will build and deploy when you push to git or open a pull request:
|
||||
|
||||
1. [Start a new netlify project](https://app.netlify.com/signup)
|
||||
2. Pick your Git hosting service and select your repository
|
||||
3. Click `Build your site`
|
||||
1. [Start a new netlify project](https://app.netlify.com/signup)
|
||||
2. Pick your Git hosting service and select your repository
|
||||
3. Click `Build your site`
|
||||
|
||||
**Support for client-side routing:**
|
||||
|
||||
@@ -1511,22 +1516,22 @@ When you build the project, Create React App will place the `public` folder cont
|
||||
|
||||
[now](https://zeit.co/now) offers a zero-configuration single-command deployment.
|
||||
|
||||
1. Install the `now` command-line tool either via the recommended [desktop tool](https://zeit.co/download) or via node with `npm install -g now`.
|
||||
1. Install the `now` command-line tool either via the recommended [desktop tool](https://zeit.co/download) or via node with `npm install -g now`.
|
||||
|
||||
2. Install `serve` by running `npm install --save serve`.
|
||||
2. Install `serve` by running `npm install --save serve`.
|
||||
|
||||
3. Add this line to `scripts` in `package.json`:
|
||||
|
||||
3. Add this line to `scripts` in `package.json`:
|
||||
|
||||
```
|
||||
"now-start": "serve build/",
|
||||
```
|
||||
|
||||
4. Run `now` from your project directory. You will see a **now.sh** URL in your output like this:
|
||||
|
||||
|
||||
4. Run `now` from your project directory. You will see a **now.sh** URL in your output like this:
|
||||
|
||||
```
|
||||
> Ready! https://your-project-dirname-tpspyhtdtk.now.sh (copied to clipboard)
|
||||
```
|
||||
|
||||
|
||||
Paste that URL into your browser when the build is complete, and you will see your deployed app.
|
||||
|
||||
Details are available in [this article.](https://zeit.co/blog/now-static)
|
||||
@@ -1537,7 +1542,7 @@ See this [blog post](https://medium.com/@omgwtfmarc/deploying-create-react-app-t
|
||||
|
||||
### Surge
|
||||
|
||||
Install the Surge CLI if you haven’t already by running `npm install -g surge`. Run the `surge` command and log in you or create a new account. You just need to specify the *build* folder and your custom domain, and you are done.
|
||||
Install the Surge CLI if you haven’t already by running `npm install -g surge`. Run the `surge` command and log in you or create a new account. You just need to specify the _build_ folder and your custom domain, and you are done.
|
||||
|
||||
```sh
|
||||
email: email@domain.com
|
||||
@@ -1560,14 +1565,14 @@ Note that in order to support routers that use HTML5 `pushState` API, you may wa
|
||||
|
||||
You can adjust various development and production settings by setting environment variables in your shell or with [.env](#adding-development-environment-variables-in-env).
|
||||
|
||||
Variable | Development | Production | Usage
|
||||
:--- | :---: | :---: | :---
|
||||
BROWSER | :white_check_mark: | :x: | By default, Create React App will open the default system browser, favoring Chrome on macOS. Specify a [browser](https://github.com/sindresorhus/opn#app) to override this behavior, or set it to `none` to disable it completely.
|
||||
HOST | :white_check_mark: | :x: | By default, the development web server binds to `localhost`. You may use this variable to specify a different host.
|
||||
PORT | :white_check_mark: | :x: | By default, the development web server will attempt to listen on port 3000 or prompt you to attempt the next available port. You may use this variable to specify a different port.
|
||||
HTTPS | :white_check_mark: | :x: | When set to `true`, Create React App will run the development server in `https` mode.
|
||||
PUBLIC_URL | :x: | :white_check_mark: | Create React App assumes your application is hosted at the serving web server's root or a subpath as specified in [`package.json` (`homepage`)](#building-for-relative-paths). Normally, Create React App ignores the hostname. You may use this variable to force assets to be referenced verbatim to the url you provide (hostname included). This may be particularly useful when using a CDN to host your application.
|
||||
CI | :large_orange_diamond: | :white_check_mark: | When set to `true`, Create React App treats warnings as failures in the build. It also makes the test runner non-watching. Most CIs set this flag by default.
|
||||
| Variable | Development | Production | Usage |
|
||||
| :--------- | :--------------------: | :----------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| BROWSER | :white_check_mark: | :x: | By default, Create React App will open the default system browser, favoring Chrome on macOS. Specify a [browser](https://github.com/sindresorhus/opn#app) to override this behavior, or set it to `none` to disable it completely. |
|
||||
| HOST | :white_check_mark: | :x: | By default, the development web server binds to `localhost`. You may use this variable to specify a different host. |
|
||||
| PORT | :white_check_mark: | :x: | By default, the development web server will attempt to listen on port 3000 or prompt you to attempt the next available port. You may use this variable to specify a different port. |
|
||||
| HTTPS | :white_check_mark: | :x: | When set to `true`, Create React App will run the development server in `https` mode. |
|
||||
| PUBLIC_URL | :x: | :white_check_mark: | Create React App assumes your application is hosted at the serving web server's root or a subpath as specified in [`package.json` (`homepage`)](#building-for-relative-paths). Normally, Create React App ignores the hostname. You may use this variable to force assets to be referenced verbatim to the url you provide (hostname included). This may be particularly useful when using a CDN to host your application. |
|
||||
| CI | :large_orange_diamond: | :white_check_mark: | When set to `true`, Create React App treats warnings as failures in the build. It also makes the test runner non-watching. Most CIs set this flag by default. |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
@@ -1607,7 +1612,7 @@ You can find [other installation methods](https://facebook.github.io/watchman/do
|
||||
|
||||
If this still doesn’t help, try running `launchctl unload -F ~/Library/LaunchAgents/com.github.facebook.watchman.plist`.
|
||||
|
||||
There are also reports that *uninstalling* Watchman fixes the issue. So if nothing else helps, remove it from your system and try again.
|
||||
There are also reports that _uninstalling_ Watchman fixes the issue. So if nothing else helps, remove it from your system and try again.
|
||||
|
||||
### `npm run build` silently fails
|
||||
|
||||
|
||||
+33
-3
@@ -3,16 +3,46 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"react-scripts": "0.9.5",
|
||||
"standard": "^10.0.2"
|
||||
"autoprefixer": "^6.7.0",
|
||||
"babel-cli": "6.14.0",
|
||||
"babel-eslint": "6.1.2",
|
||||
"babel-preset-es2015": "6.14.0",
|
||||
"babel-preset-react": "6.11.1",
|
||||
"babel-preset-stage-2": "6.13.0",
|
||||
"eslint": "^4.1.1",
|
||||
"eslint-config-standard": "^10.2.1",
|
||||
"eslint-plugin-class-property": "^1.0.6",
|
||||
"eslint-plugin-import": "^2.8.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.0.2",
|
||||
"eslint-plugin-node": "^5.2.1",
|
||||
"eslint-plugin-promise": "^3.6.0",
|
||||
"eslint-plugin-react": "^7.4.0",
|
||||
"eslint-plugin-standard": "^3.0.1",
|
||||
"html-element-attributes": "^1.3.0",
|
||||
"match-sorter": "^1.8.0",
|
||||
"npm-run-all": "^3.1.1",
|
||||
"onchange": "^3.0.2",
|
||||
"postcss-cli": "^2.6.0",
|
||||
"react": "^15.4.2",
|
||||
"react-dom": "^15.4.2",
|
||||
"react-json-tree": "^0.10.9",
|
||||
"rimraf": "^2.6.1",
|
||||
"standard": "^10.0.2",
|
||||
"stylus": "^0.54.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"eslint-config-react-tools": "^1.0.10",
|
||||
"github-markdown-css": "^2.6.0",
|
||||
"marked": "^0.3.6",
|
||||
"namor": "^1.0.1",
|
||||
"raw-loader": "^0.5.1",
|
||||
"react": "^15.5.4",
|
||||
"react-dom": "^15.5.4",
|
||||
"react-story": "^0.0.6"
|
||||
"react-json-tree": "^0.10.9",
|
||||
"react-script": "^2.0.5",
|
||||
"react-scripts": "^0.9.5",
|
||||
"react-story": "^0.0.10",
|
||||
"shortid": "^2.2.8"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+78
-66
@@ -1,31 +1,73 @@
|
||||
import React from 'react'
|
||||
/* eslint-disable */
|
||||
|
||||
import React from 'react';
|
||||
//
|
||||
import ReactStory, { defaultProps } from 'react-story'
|
||||
import ReactStory, { defaultProps } from 'react-story';
|
||||
import CodeSandbox from './CodeSandbox.js';
|
||||
import './stories/utils/prism.css';
|
||||
import '../../react-table.css';
|
||||
|
||||
import './stories/utils/prism.css'
|
||||
import '../../react-table.css'
|
||||
import Readme from './stories/Readme.js';
|
||||
import HOCReadme from './stories/HOCReadme.js';
|
||||
|
||||
import Readme from './stories/Readme.js'
|
||||
import Simple from './stories/Simple.js'
|
||||
import CellRenderers from './stories/CellRenderers.js'
|
||||
import DefaultSorting from './stories/DefaultSorting.js'
|
||||
import CustomSorting from './stories/CustomSorting.js'
|
||||
import CustomWidths from './stories/CustomWidths.js'
|
||||
import CustomComponentProps from './stories/CustomComponentProps.js'
|
||||
import ServerSide from './stories/ServerSide.js'
|
||||
import SubComponents from './stories/SubComponents.js'
|
||||
import Pivoting from './stories/Pivoting.js'
|
||||
import PivotingSubComponents from './stories/PivotingSubComponents.js'
|
||||
import OneHundredKRows from './stories/OneHundredKRows.js'
|
||||
import FunctionalRendering from './stories/FunctionalRendering.js'
|
||||
import CustomExpanderPosition from './stories/CustomExpanderPosition.js'
|
||||
import NoDataText from './stories/NoDataText.js'
|
||||
import Footers from './stories/Footers.js'
|
||||
import Filtering from './stories/Filtering.js'
|
||||
import ControlledTable from './stories/ControlledTable.js'
|
||||
import PivotingOptions from './stories/PivotingOptions.js'
|
||||
import EditableTable from './stories/EditableTable.js'
|
||||
import FixedHeader from './stories/FixedHeader.js'
|
||||
// import Test from './stories/test.js'
|
||||
|
||||
// import Tester from './examples/expander';
|
||||
|
||||
const stories = [
|
||||
{ name: 'Readme', component: Readme },
|
||||
{ name: 'HOC Readme', component: HOCReadme },
|
||||
|
||||
// { name: 'Tester', component: Test },
|
||||
{ name: 'Simple Table', component: CodeSandbox('X6npLXPRW') },
|
||||
{
|
||||
name: 'Cell Renderers & Custom Components',
|
||||
component: CodeSandbox('OyRL04Z4Y')
|
||||
},
|
||||
{ name: 'Default Sorting', component: CodeSandbox('gLwmmjzA3') },
|
||||
{
|
||||
name: 'Custom Sorting',
|
||||
component: CodeSandbox('VGx67J35')
|
||||
},
|
||||
{ name: 'Custom Column Widths', component: CodeSandbox('o2OORXNXN') },
|
||||
{ name: 'Custom Component Props', component: CodeSandbox('nZW3L0wp4') },
|
||||
{ name: 'Server-side Data', component: CodeSandbox('wjrn8wy3R') },
|
||||
{ name: 'Sub Components', component: CodeSandbox('n2gqAxl7') },
|
||||
{ name: 'Pivoting & Aggregation', component: CodeSandbox('oNY9z8xN') },
|
||||
{
|
||||
name: 'Pivoting & Aggregation w/ Sub Components',
|
||||
component: CodeSandbox('p0kEVBgQ')
|
||||
},
|
||||
{
|
||||
name: '100k Rows w/ Pivoting & Sub Components',
|
||||
component: CodeSandbox('DRmKj0XyK')
|
||||
},
|
||||
{ name: 'Pivoting Options', component: CodeSandbox('kZKmNBK6r') },
|
||||
{ name: 'Functional Rendering', component: CodeSandbox('VPZ0Bzv8X') },
|
||||
{
|
||||
name: 'Custom Expander Position',
|
||||
component: CodeSandbox('1jj2XrPEV')
|
||||
},
|
||||
{ name: 'Custom "No Data" Text', component: CodeSandbox('RgRpRDv80') },
|
||||
{ name: 'Footers', component: CodeSandbox('KOqQXn3p8') },
|
||||
{ name: 'Custom Filtering', component: CodeSandbox('5Eyxxxyx') },
|
||||
{ name: 'Controlled Component', component: CodeSandbox('r7XEZRK2') },
|
||||
{ name: 'Editable Table', component: CodeSandbox('n5r19gzQP') },
|
||||
{
|
||||
name: 'Fixed Header w/ Vertical Scroll',
|
||||
component: CodeSandbox('7LY0gjA8O')
|
||||
},
|
||||
{
|
||||
name: 'Multiple Pagers (Top and Bottom)',
|
||||
component: CodeSandbox('VEZ8OgvX')
|
||||
},
|
||||
|
||||
{ name: 'Tree Table (HOC)', component: CodeSandbox('lxmr4wynzq') },
|
||||
{ name: 'Select Table (HOC)', component: CodeSandbox('7yq5ylw09j') },
|
||||
{ name: 'Select Tree Table (HOC)', component: CodeSandbox('2p7jp4klwp') },
|
||||
{ name: 'Foldable Table (HOC)', component: CodeSandbox('8pkrj5yorl') },
|
||||
{ name: 'Advanced Expand Table (HOC)', component: CodeSandbox('y2m39jz8v1') }
|
||||
];
|
||||
|
||||
export default class App extends React.Component {
|
||||
render() {
|
||||
@@ -40,11 +82,13 @@ export default class App extends React.Component {
|
||||
StoryWrapper={props => (
|
||||
<defaultProps.StoryWrapper
|
||||
css={{
|
||||
padding: 0
|
||||
padding: 0,
|
||||
display: 'flex',
|
||||
flexDirection: 'column'
|
||||
}}
|
||||
>
|
||||
<a
|
||||
href="//github.com/tannerlinsley/react-table"
|
||||
href="//github.com/react-tools/react-table"
|
||||
style={{
|
||||
display: 'block',
|
||||
textAlign: 'center',
|
||||
@@ -52,57 +96,25 @@ export default class App extends React.Component {
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src="//npmcdn.com/react-table/media/Banner.png"
|
||||
src="https://github.com/react-tools/media/raw/master/logo-react-table.png"
|
||||
alt="React Table Logo"
|
||||
style={{
|
||||
width: '100px'
|
||||
width: '150px',
|
||||
padding: '10px'
|
||||
}}
|
||||
/>
|
||||
</a>
|
||||
<div
|
||||
{...props}
|
||||
style={{
|
||||
padding: '10px'
|
||||
flex: '1 0 auto',
|
||||
position: 'relative'
|
||||
}}
|
||||
/>
|
||||
</defaultProps.StoryWrapper>
|
||||
)}
|
||||
stories={[
|
||||
{ name: 'Readme', component: Readme },
|
||||
{ name: 'Simple Table', component: Simple },
|
||||
{
|
||||
name: 'Cell Renderers & Custom Components',
|
||||
component: CellRenderers
|
||||
},
|
||||
{ name: 'Default Sorting', component: DefaultSorting },
|
||||
{ name: 'Custom Sorting', component: CustomSorting },
|
||||
{ name: 'Custom Column Widths', component: CustomWidths },
|
||||
{ name: 'Custom Component Props', component: CustomComponentProps },
|
||||
{ name: 'Server-side Data', component: ServerSide },
|
||||
{ name: 'Sub Components', component: SubComponents },
|
||||
{ name: 'Pivoting & Aggregation', component: Pivoting },
|
||||
{
|
||||
name: 'Pivoting & Aggregation w/ Sub Components',
|
||||
component: PivotingSubComponents
|
||||
},
|
||||
{
|
||||
name: '100k Rows w/ Pivoting & Sub Components',
|
||||
component: OneHundredKRows
|
||||
},
|
||||
{ name: 'Pivoting Options', component: PivotingOptions },
|
||||
{ name: 'Functional Rendering', component: FunctionalRendering },
|
||||
{
|
||||
name: 'Custom Expander Position',
|
||||
component: CustomExpanderPosition
|
||||
},
|
||||
{ name: 'Custom "No Data" Text', component: NoDataText },
|
||||
{ name: 'Footers', component: Footers },
|
||||
{ name: 'Custom Filtering', component: Filtering },
|
||||
{ name: 'Controlled Component', component: ControlledTable },
|
||||
{ name: 'Editable Table', component: EditableTable },
|
||||
{ name: 'Fixed Header w/ Vertical Scroll', component: FixedHeader }
|
||||
]}
|
||||
stories={stories}
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import React from "react";
|
||||
|
||||
export default id => () => {
|
||||
return (
|
||||
<iframe
|
||||
src={`https://codesandbox.io/embed/${id}?autoresize=1&hidenavigation=1&view=${
|
||||
global.innerWidth < 1000 ? "preview" : "split"
|
||||
}`}
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: `100%`,
|
||||
height: `100%`,
|
||||
border: 0,
|
||||
overflow: `hidden`
|
||||
}}
|
||||
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,116 @@
|
||||
import React from 'react';
|
||||
import { render } from 'react-dom';
|
||||
import { makeData, Logo, Tips } from './Utils';
|
||||
import { advancedExpandTableHOC } from '../../../../lib/hoc/advancedExpandTable';
|
||||
|
||||
// Import React Table
|
||||
import ReactTable from 'react-table';
|
||||
import 'react-table/react-table.css';
|
||||
|
||||
const columns = [
|
||||
{
|
||||
Header: 'First Name',
|
||||
accessor: 'firstName',
|
||||
Cell: props => {
|
||||
const {
|
||||
// react table props
|
||||
columnProps: { rest: { showRowSubComponent } },
|
||||
nestingPath
|
||||
} = props;
|
||||
return (
|
||||
<div>
|
||||
<button
|
||||
onClick={e => showRowSubComponent({ nestingPath: nestingPath }, e)}
|
||||
>
|
||||
SHOW SUBCOMPONENT {props.value}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
Header: 'Last Name',
|
||||
id: 'lastName',
|
||||
accessor: d => d.lastName
|
||||
},
|
||||
{
|
||||
Header: 'Info',
|
||||
columns: [
|
||||
{
|
||||
Header: 'Age',
|
||||
accessor: 'age',
|
||||
Cell: props => {
|
||||
const {
|
||||
// react table props
|
||||
columnProps: { rest: { toggleRowSubComponent } },
|
||||
nestingPath
|
||||
} = props;
|
||||
return (
|
||||
<div>
|
||||
<button
|
||||
onClick={e =>
|
||||
toggleRowSubComponent({ nestingPath: nestingPath }, e)
|
||||
}
|
||||
>
|
||||
TOGGLE SUBCOMPONENT {props.value}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
Header: 'Status',
|
||||
accessor: 'status'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
Header: 'Stats',
|
||||
columns: [
|
||||
{
|
||||
Header: 'Visits',
|
||||
accessor: 'visits'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const AdvancedExpandReactTable = advancedExpandTableHOC(ReactTable);
|
||||
|
||||
class App extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
data: makeData()
|
||||
};
|
||||
}
|
||||
render() {
|
||||
const { data } = this.state;
|
||||
return (
|
||||
<div>
|
||||
<AdvancedExpandReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
className='-striped -highlight'
|
||||
SubComponent={({ row, nestingPath, toggleRowSubComponent }) => {
|
||||
return (
|
||||
<div style={{ padding: '20px' }}>
|
||||
<button
|
||||
onClick={e => toggleRowSubComponent({ nestingPath }, e)}
|
||||
>
|
||||
CLOSE SUBCOMPONENT {row.firstName} {row.lastName}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<br />
|
||||
<Tips />
|
||||
<Logo />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
render(<App />, document.getElementById('root'));
|
||||
@@ -0,0 +1,94 @@
|
||||
import React from "react";
|
||||
|
||||
export default Component => {
|
||||
const wrapper = class RTCheckboxTable extends React.Component {
|
||||
// we only need a Component so we can get the 'ref' - pure components can't get a 'ref'
|
||||
|
||||
rowSelector = row => {
|
||||
if (!row || !row.hasOwnProperty(this.props.keyField)) return null;
|
||||
const checked = this.props.isSelected(row[this.props.keyField]);
|
||||
return (
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={checked}
|
||||
onClick={e => {
|
||||
const { shiftKey } = e;
|
||||
e.stopPropagation();
|
||||
this.props.toggleSelection(row[this.props.keyField], shiftKey, row);
|
||||
}}
|
||||
onChange={() => {}}
|
||||
value=""
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
headSelector = row => {
|
||||
const checked = this.props.selectAll;
|
||||
return (
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={checked}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
this.props.toggleAll();
|
||||
}}
|
||||
onChange={() => {}}
|
||||
value=""
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
// this is so we can expose the underlying ReactTable to get at the sortedData for selectAll
|
||||
getWrappedInstance = () => this.wrappedInstance;
|
||||
|
||||
render() {
|
||||
const {
|
||||
columns: originalCols,
|
||||
isSelected,
|
||||
toggleSelection,
|
||||
toggleAll,
|
||||
keyField,
|
||||
selectAll,
|
||||
...rest
|
||||
} = this.props;
|
||||
const { rowSelector, headSelector } = this;
|
||||
const select = {
|
||||
id: "_selector",
|
||||
accessor: () => "x", // this value is not important
|
||||
Header: headSelector,
|
||||
Cell: ci => {
|
||||
return rowSelector(ci.original);
|
||||
},
|
||||
width: 30,
|
||||
filterable: false,
|
||||
sortable: false,
|
||||
resizable: false,
|
||||
style: { textAlign: "center" }
|
||||
};
|
||||
const columns = [select, ...originalCols];
|
||||
const extra = {
|
||||
columns
|
||||
};
|
||||
return (
|
||||
<Component {...rest} {...extra} ref={r => (this.wrappedInstance = r)} />
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
wrapper.displayName = "RTCheckboxTable";
|
||||
wrapper.defaultProps = {
|
||||
keyField: "_id",
|
||||
isSelected: key => {
|
||||
console.log("No isSelected handler provided:", { key });
|
||||
},
|
||||
selectAll: false,
|
||||
toggleSelection: (key, shift, row) => {
|
||||
console.log("No toggleSelection handler provided:", { key, shift, row });
|
||||
},
|
||||
toggleAll: () => {
|
||||
console.log("No toggleAll handler provided.");
|
||||
}
|
||||
};
|
||||
|
||||
return wrapper;
|
||||
};
|
||||
@@ -0,0 +1,148 @@
|
||||
import React from "react";
|
||||
import shortid from "shortid";
|
||||
|
||||
import ReactTable from "../../../../lib/index";
|
||||
import "../../../../react-table.css";
|
||||
|
||||
import checkboxTableHOC from "./checkboxHOC";
|
||||
|
||||
const CheckboxTable = checkboxTableHOC(ReactTable);
|
||||
|
||||
async function getData() {
|
||||
const result = await (await fetch("/au_500_tree.json")).json();
|
||||
// we are adding a unique ID to the data for tracking the selected records
|
||||
return result.map(item => {
|
||||
const _id = shortid.generate();
|
||||
return {
|
||||
_id,
|
||||
...item
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function getColumns(data) {
|
||||
const columns = [];
|
||||
const sample = data[0];
|
||||
for (let key in sample) {
|
||||
if (key === "_id") continue;
|
||||
columns.push({
|
||||
accessor: key,
|
||||
Header: key
|
||||
});
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
export class ComponentTest extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
data: null,
|
||||
columns: null,
|
||||
selection: [],
|
||||
selectAll: false
|
||||
};
|
||||
}
|
||||
componentDidMount() {
|
||||
getData().then(data => {
|
||||
const columns = getColumns(data);
|
||||
this.setState({ data, columns });
|
||||
});
|
||||
}
|
||||
toggleSelection = (key, shift, row) => {
|
||||
/*
|
||||
Implementation of how to manage the selection state is up to the developer.
|
||||
This implementation uses an array stored in the component state.
|
||||
Other implementations could use object keys, a Javascript Set, or Redux... etc.
|
||||
*/
|
||||
// start off with the existing state
|
||||
let selection = [...this.state.selection];
|
||||
const keyIndex = selection.indexOf(key);
|
||||
// check to see if the key exists
|
||||
if (keyIndex >= 0) {
|
||||
// it does exist so we will remove it using destructing
|
||||
selection = [
|
||||
...selection.slice(0, keyIndex),
|
||||
...selection.slice(keyIndex + 1)
|
||||
];
|
||||
} else {
|
||||
// it does not exist so add it
|
||||
selection.push(key);
|
||||
}
|
||||
// update the state
|
||||
this.setState({ selection });
|
||||
};
|
||||
toggleAll = () => {
|
||||
/*
|
||||
'toggleAll' is a tricky concept with any filterable table
|
||||
do you just select ALL the records that are in your data?
|
||||
OR
|
||||
do you only select ALL the records that are in the current filtered data?
|
||||
|
||||
The latter makes more sense because 'selection' is a visual thing for the user.
|
||||
This is especially true if you are going to implement a set of external functions
|
||||
that act on the selected information (you would not want to DELETE the wrong thing!).
|
||||
|
||||
So, to that end, access to the internals of ReactTable are required to get what is
|
||||
currently visible in the table (either on the current page or any other page).
|
||||
|
||||
The HOC provides a method call 'getWrappedInstance' to get a ref to the wrapped
|
||||
ReactTable and then get the internal state and the 'sortedData'.
|
||||
That can then be iterrated to get all the currently visible records and set
|
||||
the selection state.
|
||||
*/
|
||||
const selectAll = this.state.selectAll ? false : true;
|
||||
const selection = [];
|
||||
if (selectAll) {
|
||||
// we need to get at the internals of ReactTable
|
||||
const wrappedInstance = this.checkboxTable.getWrappedInstance();
|
||||
// the 'sortedData' property contains the currently accessible records based on the filter and sort
|
||||
const currentRecords = wrappedInstance.getResolvedState().sortedData;
|
||||
// we just push all the IDs onto the selection array
|
||||
currentRecords.forEach(item => {
|
||||
selection.push(item._original._id);
|
||||
});
|
||||
}
|
||||
this.setState({ selectAll, selection });
|
||||
};
|
||||
isSelected = key => {
|
||||
/*
|
||||
Instead of passing our external selection state we provide an 'isSelected'
|
||||
callback and detect the selection state ourselves. This allows any implementation
|
||||
for selection (either an array, object keys, or even a Javascript Set object).
|
||||
*/
|
||||
return this.state.selection.includes(key);
|
||||
};
|
||||
logSelection = () => {
|
||||
console.log("selection:", this.state.selection);
|
||||
};
|
||||
render() {
|
||||
const { toggleSelection, toggleAll, isSelected, logSelection } = this;
|
||||
const { data, columns, selectAll } = this.state;
|
||||
const extraProps = {
|
||||
selectAll,
|
||||
isSelected,
|
||||
toggleAll,
|
||||
toggleSelection
|
||||
};
|
||||
return (
|
||||
<div style={{ padding: "10px" }}>
|
||||
<h1>react-table - Checkbox Table</h1>
|
||||
<button onClick={logSelection}>Log Selection to Console</button>
|
||||
{` (${this.state.selection.length}) selected`}
|
||||
{data ? (
|
||||
<CheckboxTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
ref={r => (this.checkboxTable = r)}
|
||||
className="-striped -highlight"
|
||||
{...extraProps}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// export default treeTableHOC(ComponentTest);
|
||||
export default ComponentTest;
|
||||
@@ -0,0 +1,60 @@
|
||||
import React from "react";
|
||||
|
||||
export default class ComponentTest extends React.component {
|
||||
render() {
|
||||
return <div>Bozo</div>;
|
||||
}
|
||||
}
|
||||
|
||||
// import ReactTable from '../../../../lib/index'
|
||||
// import '../../../../react-table.css'
|
||||
//
|
||||
// console.log('ReactTable:',ReactTable)
|
||||
//
|
||||
// const data = [
|
||||
// {one:"1.1",two:"1.2"},
|
||||
// {one:"2.1",two:"2.2"},
|
||||
// {one:"3.1",two:"3.2"},
|
||||
// {one:"4.1",two:"4.2"},
|
||||
// ]
|
||||
//
|
||||
// const columns = [
|
||||
// {accessor:'one', Header: 'One'},
|
||||
// {accessor:'two', Header: 'Two'},
|
||||
// ]
|
||||
//
|
||||
// class ExpanderComponent extends React.Component {
|
||||
// render()
|
||||
// {
|
||||
// return (
|
||||
// <div className={`rt-expander ${this.props.isExpanded ? '-open' : ''}`}>
|
||||
// •
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// class SubComponent extends React.Component {
|
||||
// render()
|
||||
// {
|
||||
// return <div>Nothing</div>
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// export default class ComponentTest extends React.Component {
|
||||
// render()
|
||||
// {
|
||||
// const rtProps = {
|
||||
// data,
|
||||
// columns,
|
||||
// // ExpanderComponent: (props, closeExpanded)=><ExpanderComponent {...props, closeExpanded} />,
|
||||
// // SubComponent: (props)=><SubComponent {...props} />,
|
||||
// // multiSort: false,
|
||||
// }
|
||||
// return (
|
||||
// <ReactTable
|
||||
// {...rtProps}
|
||||
// />
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
@@ -0,0 +1,110 @@
|
||||
import React from 'react'
|
||||
import ReactTable from '../../../../lib/index'
|
||||
import FoldableTableHOC from '../../../../lib/hoc/foldableTable'
|
||||
import selectTableHOC from '../../../../lib/hoc/selectTable'
|
||||
|
||||
const FoldableTable = FoldableTableHOC(selectTableHOC(ReactTable))
|
||||
|
||||
export default class FoldableTableCustomState extends React.Component {
|
||||
constructor(props, context) {
|
||||
super(props, context)
|
||||
|
||||
this.state = { folded: {}, seleted: {}, selectedAll: false }
|
||||
}
|
||||
|
||||
getData = () => [{
|
||||
id: 1,
|
||||
first_name: 'Jeanette',
|
||||
'last_name': 'Penddreth',
|
||||
email: 'jpenddreth0@census.gov',
|
||||
'gender': 'Female',
|
||||
ip_address: '26.58.193.2',
|
||||
}, {
|
||||
'id': 2,
|
||||
'first_name': 'Giavani',
|
||||
last_name: 'Frediani',
|
||||
'email': 'gfrediani1@senate.gov',
|
||||
'gender': 'Male',
|
||||
'ip_address': '229.179.4.212',
|
||||
}, {
|
||||
'id': 3,
|
||||
first_name: 'Noell',
|
||||
last_name: 'Bea',
|
||||
'email': 'nbea2@imageshack.us',
|
||||
gender: 'Female',
|
||||
ip_address: '180.66.162.255',
|
||||
}, {
|
||||
'id': 4,
|
||||
'first_name': 'Willard',
|
||||
'last_name': 'Valek',
|
||||
email: 'wvalek3@vk.com',
|
||||
'gender': 'Male',
|
||||
ip_address: '67.76.188.26',
|
||||
}];
|
||||
|
||||
toggleSelection = (key, shift, row) => {
|
||||
const { selected } = this.state
|
||||
let newSelected = Object.assign({}, selected)
|
||||
newSelected[key] = !newSelected[key]
|
||||
this.setState(p => ({ selected: newSelected }))
|
||||
};
|
||||
|
||||
toggleAll = () => {
|
||||
const { selectedAll } = this.state
|
||||
|
||||
if (selectedAll) { this.setState(p => { return { selectedAll: false, seleted: {} } }); }
|
||||
else {
|
||||
const data = this.getData()
|
||||
|
||||
let newSelected = {}
|
||||
data.forEach(d => newSelected[d.id] = true)
|
||||
this.setState(p => ({ selectedAll: true, seleted: newSelected }))
|
||||
}
|
||||
}
|
||||
|
||||
isSelected = key => this.state.seleted[key];
|
||||
|
||||
render() {
|
||||
return (<FoldableTable
|
||||
//SelectTable props
|
||||
keyField='id'
|
||||
toggleSelection={this.toggleSelection}
|
||||
toggleAll={this.toggleAll}
|
||||
isSelected={this.isSelected}
|
||||
selectAll={this.state.selectedAll}
|
||||
selectType='checkbox'
|
||||
|
||||
onFoldChange={newFolded => this.setState(p => { return { folded: newFolded } })}
|
||||
folded={this.state.folded}
|
||||
|
||||
data={this.getData()}
|
||||
columns={[{
|
||||
Header: "Name",
|
||||
foldable: true,
|
||||
columns: [
|
||||
{
|
||||
Header: "First Name",
|
||||
accessor: "first_name"
|
||||
},
|
||||
{
|
||||
Header: "Last Name",
|
||||
accessor: "last_name"
|
||||
}
|
||||
]
|
||||
}, {
|
||||
Header: "Info",
|
||||
foldable: true,
|
||||
columns: [
|
||||
{
|
||||
Header: "Email",
|
||||
accessor: "email"
|
||||
},
|
||||
{
|
||||
Header: "Gender",
|
||||
accessor: "gender"
|
||||
}
|
||||
]
|
||||
}]
|
||||
}></FoldableTable>)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import React from 'react'
|
||||
import ReactTable from '../../../../lib/index'
|
||||
import FoldableTableHOC from '../../../../lib/hoc/foldableTable'
|
||||
|
||||
const FoldableTable = FoldableTableHOC(ReactTable)
|
||||
|
||||
export default class FoldableTableWithHeader extends React.Component {
|
||||
|
||||
getData = () => [{
|
||||
id: 1,
|
||||
first_name: 'Jeanette',
|
||||
last_name: 'Penddreth',
|
||||
'email': 'jpenddreth0@census.gov',
|
||||
gender: 'Female',
|
||||
'ip_address': '26.58.193.2',
|
||||
}, {
|
||||
'id': 2,
|
||||
first_name: 'Giavani',
|
||||
last_name: 'Frediani',
|
||||
email: 'gfrediani1@senate.gov',
|
||||
gender: 'Male',
|
||||
'ip_address': '229.179.4.212',
|
||||
}, {
|
||||
'id': 3,
|
||||
'first_name': 'Noell',
|
||||
last_name: 'Bea',
|
||||
'email': 'nbea2@imageshack.us',
|
||||
'gender': 'Female',
|
||||
ip_address: '180.66.162.255',
|
||||
}, {
|
||||
'id': 4,
|
||||
'first_name': 'Willard',
|
||||
'last_name': 'Valek',
|
||||
email: 'wvalek3@vk.com',
|
||||
'gender': 'Male',
|
||||
ip_address: '67.76.188.26',
|
||||
}];
|
||||
|
||||
render() {
|
||||
return (<FoldableTable
|
||||
data={this.getData()}
|
||||
columns={[{
|
||||
Header: "Name",
|
||||
foldable: true,
|
||||
columns: [
|
||||
{
|
||||
Header: "First Name",
|
||||
accessor: "first_name"
|
||||
},
|
||||
{
|
||||
Header: "Last Name",
|
||||
accessor: "last_name"
|
||||
}
|
||||
]
|
||||
}, {
|
||||
Header: "Info",
|
||||
foldable: true,
|
||||
columns: [
|
||||
{
|
||||
Header: "Email",
|
||||
accessor: "email"
|
||||
},
|
||||
{
|
||||
Header: "Gender",
|
||||
accessor: "gender"
|
||||
}
|
||||
]
|
||||
}]
|
||||
}></FoldableTable>)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import React from 'react';
|
||||
import ReactTable from '../../../../lib/index';
|
||||
import FoldableTableHOC from '../../../../lib/hoc/foldableTable';
|
||||
|
||||
const FoldableTable = FoldableTableHOC(ReactTable);
|
||||
|
||||
export default class FoldableTableWithoutHeader extends React.Component {
|
||||
|
||||
getData = () => [{
|
||||
"id": 1,
|
||||
"first_name": "Jeanette",
|
||||
"last_name": "Penddreth",
|
||||
"email": "jpenddreth0@census.gov",
|
||||
"gender": "Female",
|
||||
"ip_address": "26.58.193.2"
|
||||
}, {
|
||||
"id": 2,
|
||||
"first_name": "Giavani",
|
||||
"last_name": "Frediani",
|
||||
"email": "gfrediani1@senate.gov",
|
||||
"gender": "Male",
|
||||
"ip_address": "229.179.4.212"
|
||||
}, {
|
||||
"id": 3,
|
||||
"first_name": "Noell",
|
||||
"last_name": "Bea",
|
||||
"email": "nbea2@imageshack.us",
|
||||
"gender": "Female",
|
||||
"ip_address": "180.66.162.255"
|
||||
}, {
|
||||
"id": 4,
|
||||
"first_name": "Willard",
|
||||
"last_name": "Valek",
|
||||
"email": "wvalek3@vk.com",
|
||||
"gender": "Male",
|
||||
"ip_address": "67.76.188.26"
|
||||
}];
|
||||
|
||||
render() {
|
||||
return <FoldableTable
|
||||
data={this.getData()}
|
||||
columns={[
|
||||
{
|
||||
Header: "First Name",
|
||||
accessor: "first_name"
|
||||
},
|
||||
{
|
||||
Header: "Last Name",
|
||||
accessor: "last_name",
|
||||
foldable: true,
|
||||
},
|
||||
{
|
||||
Header: "Email",
|
||||
accessor: "email",
|
||||
foldable: true,
|
||||
},
|
||||
{
|
||||
Header: "Gender",
|
||||
accessor: "gender",
|
||||
foldable: true,
|
||||
}
|
||||
]}></FoldableTable>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
import React from 'react'
|
||||
import '../../../../react-table.css'
|
||||
|
||||
import FoldableTableWithHeader from './FoldableTableWithHeader'
|
||||
import FoldableTableWithoutHeader from './FoldableTableWithoutHeader'
|
||||
import FoldableTableCustomState from './FoldableTableCustomState'
|
||||
|
||||
class FaldableComponentTest extends React.Component {
|
||||
render() {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>- Sample With Header Columns</p>
|
||||
<br />
|
||||
<FoldableTableWithHeader />
|
||||
<br /> <br />
|
||||
<p>- Sample With Normal Columns</p>
|
||||
<br />
|
||||
<FoldableTableWithoutHeader />
|
||||
<br /> <br />
|
||||
<p>- Custom State and selectedTable</p>
|
||||
<br />
|
||||
<FoldableTableCustomState />
|
||||
</div >
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default FaldableComponentTest
|
||||
@@ -0,0 +1,13 @@
|
||||
/* eslint-disable */
|
||||
|
||||
import TreeTable from './treetable'
|
||||
import SelectTable from './selecttable'
|
||||
import SelectTreeTable from './selecttreetable'
|
||||
import FoldableTable from './foldabletable';
|
||||
|
||||
export {
|
||||
TreeTable,
|
||||
SelectTable,
|
||||
SelectTreeTable,
|
||||
FoldableTable
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
import React from "react";
|
||||
import shortid from "shortid";
|
||||
|
||||
import ReactTable from "../../../../lib/index";
|
||||
import "../../../../react-table.css";
|
||||
|
||||
import selectTableHOC from "../../../../lib/hoc/selectTable";
|
||||
|
||||
const SelectTable = selectTableHOC(ReactTable);
|
||||
|
||||
async function getData() {
|
||||
const result = await (await fetch("/au_500_tree.json")).json();
|
||||
// we are adding a unique ID to the data for tracking the selected records
|
||||
return result.map(item => {
|
||||
const _id = shortid.generate();
|
||||
return {
|
||||
_id,
|
||||
...item
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function getColumns(data) {
|
||||
const columns = [];
|
||||
const sample = data[0];
|
||||
for (let key in sample) {
|
||||
if (key === "_id") continue;
|
||||
columns.push({
|
||||
accessor: key,
|
||||
Header: key
|
||||
});
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
export class ComponentTest extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
data: null,
|
||||
columns: null,
|
||||
selection: [],
|
||||
selectAll: false,
|
||||
selectType: "checkbox"
|
||||
};
|
||||
}
|
||||
componentDidMount() {
|
||||
getData().then(data => {
|
||||
const columns = getColumns(data);
|
||||
this.setState({ data, columns });
|
||||
});
|
||||
}
|
||||
toggleSelection = (key, shift, row) => {
|
||||
/*
|
||||
Implementation of how to manage the selection state is up to the developer.
|
||||
This implementation uses an array stored in the component state.
|
||||
Other implementations could use object keys, a Javascript Set, or Redux... etc.
|
||||
*/
|
||||
// start off with the existing state
|
||||
if (this.state.selectType === "radio") {
|
||||
let selection = [];
|
||||
if (selection.indexOf(key) < 0) selection.push(key);
|
||||
this.setState({ selection });
|
||||
} else {
|
||||
let selection = [...this.state.selection];
|
||||
const keyIndex = selection.indexOf(key);
|
||||
// check to see if the key exists
|
||||
if (keyIndex >= 0) {
|
||||
// it does exist so we will remove it using destructing
|
||||
selection = [
|
||||
...selection.slice(0, keyIndex),
|
||||
...selection.slice(keyIndex + 1)
|
||||
];
|
||||
} else {
|
||||
// it does not exist so add it
|
||||
selection.push(key);
|
||||
}
|
||||
// update the state
|
||||
this.setState({ selection });
|
||||
}
|
||||
};
|
||||
toggleAll = () => {
|
||||
/*
|
||||
'toggleAll' is a tricky concept with any filterable table
|
||||
do you just select ALL the records that are in your data?
|
||||
OR
|
||||
do you only select ALL the records that are in the current filtered data?
|
||||
|
||||
The latter makes more sense because 'selection' is a visual thing for the user.
|
||||
This is especially true if you are going to implement a set of external functions
|
||||
that act on the selected information (you would not want to DELETE the wrong thing!).
|
||||
|
||||
So, to that end, access to the internals of ReactTable are required to get what is
|
||||
currently visible in the table (either on the current page or any other page).
|
||||
|
||||
The HOC provides a method call 'getWrappedInstance' to get a ref to the wrapped
|
||||
ReactTable and then get the internal state and the 'sortedData'.
|
||||
That can then be iterrated to get all the currently visible records and set
|
||||
the selection state.
|
||||
*/
|
||||
const selectAll = this.state.selectAll ? false : true;
|
||||
const selection = [];
|
||||
if (selectAll) {
|
||||
// we need to get at the internals of ReactTable
|
||||
const wrappedInstance = this.selectTable.getWrappedInstance();
|
||||
// the 'sortedData' property contains the currently accessible records based on the filter and sort
|
||||
const currentRecords = wrappedInstance.getResolvedState().sortedData;
|
||||
// we just push all the IDs onto the selection array
|
||||
currentRecords.forEach(item => {
|
||||
if (item._original) {
|
||||
selection.push(item._original._id);
|
||||
}
|
||||
});
|
||||
}
|
||||
this.setState({ selectAll, selection });
|
||||
};
|
||||
isSelected = key => {
|
||||
/*
|
||||
Instead of passing our external selection state we provide an 'isSelected'
|
||||
callback and detect the selection state ourselves. This allows any implementation
|
||||
for selection (either an array, object keys, or even a Javascript Set object).
|
||||
*/
|
||||
return this.state.selection.includes(key);
|
||||
};
|
||||
logSelection = () => {
|
||||
console.log("selection:", this.state.selection);
|
||||
};
|
||||
toggleType = () => {
|
||||
this.setState({
|
||||
selectType: this.state.selectType === "radio" ? "checkbox" : "radio",
|
||||
selection: [],
|
||||
selectAll: false
|
||||
});
|
||||
};
|
||||
render() {
|
||||
const {
|
||||
toggleSelection,
|
||||
toggleAll,
|
||||
isSelected,
|
||||
logSelection,
|
||||
toggleType
|
||||
} = this;
|
||||
const { data, columns, selectAll, selectType } = this.state;
|
||||
const extraProps = {
|
||||
selectAll,
|
||||
isSelected,
|
||||
toggleAll,
|
||||
toggleSelection,
|
||||
selectType
|
||||
};
|
||||
return (
|
||||
<div style={{ padding: "10px" }}>
|
||||
<h1>react-table - Select Table</h1>
|
||||
<button onClick={toggleType}>
|
||||
Select Type: <strong>{selectType}</strong>
|
||||
</button>
|
||||
<button onClick={logSelection}>Log Selection to Console</button>
|
||||
{` (${this.state.selection.length}) selected`}
|
||||
{data ? (
|
||||
<SelectTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
ref={r => (this.selectTable = r)}
|
||||
className="-striped -highlight"
|
||||
{...extraProps}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ComponentTest;
|
||||
@@ -0,0 +1,238 @@
|
||||
import React from "react";
|
||||
import shortid from "shortid";
|
||||
|
||||
import ReactTable from "../../../../lib/index";
|
||||
import "../../../../react-table.css";
|
||||
|
||||
import selectTableHOC from "../../../../lib/hoc/selectTable";
|
||||
import treeTableHOC from "../../../../lib/hoc/treeTable";
|
||||
|
||||
const SelectTreeTable = selectTableHOC(treeTableHOC(ReactTable));
|
||||
|
||||
async function getData() {
|
||||
const result = await (await fetch("/au_500_tree.json")).json();
|
||||
// we are adding a unique ID to the data for tracking the selected records
|
||||
return result.map(item => {
|
||||
const _id = shortid.generate();
|
||||
return {
|
||||
_id,
|
||||
...item
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function getColumns(data) {
|
||||
const columns = [];
|
||||
const sample = data[0];
|
||||
for (let key in sample) {
|
||||
if (key === "_id") continue;
|
||||
columns.push({
|
||||
accessor: key,
|
||||
Header: key
|
||||
});
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
function getNodes(data, node = []) {
|
||||
data.forEach(item => {
|
||||
if (item.hasOwnProperty("_subRows") && item._subRows) {
|
||||
node = getNodes(item._subRows, node);
|
||||
} else {
|
||||
node.push(item._original);
|
||||
}
|
||||
});
|
||||
return node;
|
||||
}
|
||||
|
||||
export class ComponentTest extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
data: null,
|
||||
columns: null,
|
||||
selection: [],
|
||||
selectAll: false,
|
||||
selectType: "checkbox"
|
||||
};
|
||||
}
|
||||
componentDidMount() {
|
||||
getData().then(data => {
|
||||
const columns = getColumns(data);
|
||||
const pivotBy = ["state", "post"];
|
||||
this.setState({ data, columns, pivotBy });
|
||||
});
|
||||
}
|
||||
toggleSelection = (key, shift, row) => {
|
||||
/*
|
||||
Implementation of how to manage the selection state is up to the developer.
|
||||
This implementation uses an array stored in the component state.
|
||||
Other implementations could use object keys, a Javascript Set, or Redux... etc.
|
||||
*/
|
||||
// start off with the existing state
|
||||
if (this.state.selectType === "radio") {
|
||||
let selection = [];
|
||||
if (selection.indexOf(key) < 0) selection.push(key);
|
||||
this.setState({ selection });
|
||||
} else {
|
||||
let selection = [...this.state.selection];
|
||||
const keyIndex = selection.indexOf(key);
|
||||
// check to see if the key exists
|
||||
if (keyIndex >= 0) {
|
||||
// it does exist so we will remove it using destructing
|
||||
selection = [
|
||||
...selection.slice(0, keyIndex),
|
||||
...selection.slice(keyIndex + 1)
|
||||
];
|
||||
} else {
|
||||
// it does not exist so add it
|
||||
selection.push(key);
|
||||
}
|
||||
// update the state
|
||||
this.setState({ selection });
|
||||
}
|
||||
};
|
||||
toggleAll = () => {
|
||||
/*
|
||||
'toggleAll' is a tricky concept with any filterable table
|
||||
do you just select ALL the records that are in your data?
|
||||
OR
|
||||
do you only select ALL the records that are in the current filtered data?
|
||||
|
||||
The latter makes more sense because 'selection' is a visual thing for the user.
|
||||
This is especially true if you are going to implement a set of external functions
|
||||
that act on the selected information (you would not want to DELETE the wrong thing!).
|
||||
|
||||
So, to that end, access to the internals of ReactTable are required to get what is
|
||||
currently visible in the table (either on the current page or any other page).
|
||||
|
||||
The HOC provides a method call 'getWrappedInstance' to get a ref to the wrapped
|
||||
ReactTable and then get the internal state and the 'sortedData'.
|
||||
That can then be iterrated to get all the currently visible records and set
|
||||
the selection state.
|
||||
*/
|
||||
const selectAll = this.state.selectAll ? false : true;
|
||||
const selection = [];
|
||||
if (selectAll) {
|
||||
// we need to get at the internals of ReactTable
|
||||
const wrappedInstance = this.selectTable.getWrappedInstance();
|
||||
// the 'sortedData' property contains the currently accessible records based on the filter and sort
|
||||
const currentRecords = wrappedInstance.getResolvedState().sortedData;
|
||||
// we need to get all the 'real' (original) records out to get at their IDs
|
||||
const nodes = getNodes(currentRecords);
|
||||
// we just push all the IDs onto the selection array
|
||||
nodes.forEach(item => {
|
||||
selection.push(item._id);
|
||||
});
|
||||
}
|
||||
this.setState({ selectAll, selection });
|
||||
};
|
||||
isSelected = key => {
|
||||
/*
|
||||
Instead of passing our external selection state we provide an 'isSelected'
|
||||
callback and detect the selection state ourselves. This allows any implementation
|
||||
for selection (either an array, object keys, or even a Javascript Set object).
|
||||
*/
|
||||
return this.state.selection.includes(key);
|
||||
};
|
||||
logSelection = () => {
|
||||
console.log("selection:", this.state.selection);
|
||||
};
|
||||
toggleType = () => {
|
||||
this.setState({
|
||||
selectType: this.state.selectType === "radio" ? "checkbox" : "radio",
|
||||
selection: [],
|
||||
selectAll: false
|
||||
});
|
||||
};
|
||||
toggleTree = () => {
|
||||
if (this.state.pivotBy.length) {
|
||||
this.setState({ pivotBy: [], expanded: {} });
|
||||
} else {
|
||||
this.setState({ pivotBy: ["state", "post"], expanded: {} });
|
||||
}
|
||||
};
|
||||
onExpandedChange = expanded => {
|
||||
this.setState({ expanded });
|
||||
};
|
||||
render() {
|
||||
const {
|
||||
toggleSelection,
|
||||
toggleAll,
|
||||
isSelected,
|
||||
logSelection,
|
||||
toggleType,
|
||||
toggleTree,
|
||||
onExpandedChange
|
||||
} = this;
|
||||
const {
|
||||
data,
|
||||
columns,
|
||||
selectAll,
|
||||
selectType,
|
||||
pivotBy,
|
||||
expanded
|
||||
} = this.state;
|
||||
const extraProps = {
|
||||
selectAll,
|
||||
isSelected,
|
||||
toggleAll,
|
||||
toggleSelection,
|
||||
selectType,
|
||||
pivotBy,
|
||||
expanded,
|
||||
onExpandedChange,
|
||||
pageSize: 5
|
||||
};
|
||||
return (
|
||||
<div style={{ padding: "10px" }}>
|
||||
<h1>react-table - Select Tree Table</h1>
|
||||
<p>
|
||||
This example combines two HOCs (the TreeTable and the SelectTable) to
|
||||
make a composite component.
|
||||
</p>
|
||||
<p>We'll call it SelectTreeTable!</p>
|
||||
<p>Here is what the buttons do:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Toggle Tree:</strong> enables or disabled the pivotBy on the
|
||||
table.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Select Type:</strong> changes from 'checkbox' to 'radio' and
|
||||
back again.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Log Selection to Console:</strong> open your console to see
|
||||
what has been selected.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
<strong>NOTE:</strong> the selection is maintained when toggling the
|
||||
tree on and off but is cleared when switching between select types
|
||||
(radio, checkbox).
|
||||
</p>
|
||||
<button onClick={toggleTree}>
|
||||
Toggle Tree [{pivotBy && pivotBy.length ? pivotBy.join(", ") : ""}]
|
||||
</button>
|
||||
<button onClick={toggleType}>
|
||||
Select Type: <strong>{selectType}</strong>
|
||||
</button>
|
||||
<button onClick={logSelection}>Log Selection to Console</button>
|
||||
{` (${this.state.selection.length}) selected`}
|
||||
{data ? (
|
||||
<SelectTreeTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
ref={r => (this.selectTable = r)}
|
||||
className="-striped -highlight"
|
||||
freezeWhenExpanded={true}
|
||||
{...extraProps}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ComponentTest;
|
||||
@@ -0,0 +1,70 @@
|
||||
import React from "react";
|
||||
|
||||
import ReactTable from "../../../../lib/index";
|
||||
import "../../../../react-table.css";
|
||||
|
||||
import treeTableHOC from "../../../../lib/hoc/treeTable";
|
||||
|
||||
async function getData() {
|
||||
const result = await (await fetch("/au_500_tree.json")).json();
|
||||
return result;
|
||||
}
|
||||
|
||||
function getColumns(data, pivotBy) {
|
||||
const columns = [];
|
||||
const sample = data[0];
|
||||
for (let key in sample) {
|
||||
columns.push({
|
||||
accessor: key,
|
||||
Header: key
|
||||
});
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
export class ComponentTest extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
data: null,
|
||||
columns: null,
|
||||
pivotBy: null // ["firstName", "lastName"],
|
||||
};
|
||||
}
|
||||
componentDidMount() {
|
||||
getData().then(data => {
|
||||
// console.log('cwm data:',data);
|
||||
const pivotBy = ["state", "post", "city"];
|
||||
const columns = getColumns(data, pivotBy);
|
||||
// console.log('cwm cols:',columns);
|
||||
this.setState({ data, columns, pivotBy });
|
||||
});
|
||||
}
|
||||
showState = () => {
|
||||
console.log("state:", this.reactTable.getResolvedState());
|
||||
};
|
||||
render() {
|
||||
const { data, columns, pivotBy } = this.state;
|
||||
const extraProps = {
|
||||
data,
|
||||
columns,
|
||||
pivotBy
|
||||
};
|
||||
const TreeTable = treeTableHOC(ReactTable);
|
||||
return (
|
||||
<div style={{ padding: "10px" }}>
|
||||
<h1>react-table - Tree Table</h1>
|
||||
{data ? (
|
||||
<TreeTable
|
||||
ref={r => (this.reactTable = r)}
|
||||
className="-striped -highlight"
|
||||
defaultPageSize={5}
|
||||
{...extraProps}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ComponentTest;
|
||||
@@ -0,0 +1,53 @@
|
||||
import React from "react";
|
||||
|
||||
export default Component => {
|
||||
const wrapper = componentProps => {
|
||||
const TrComponent = props => {
|
||||
const { ri, ...rest } = props;
|
||||
if (ri && ri.groupedByPivot) {
|
||||
const cell = props.children[ri.level];
|
||||
|
||||
cell.props.style.flex = "unset";
|
||||
cell.props.style.width = "100%";
|
||||
cell.props.style.maxWidth = "unset";
|
||||
cell.props.style.paddingLeft = `${componentProps.treeTableIndent *
|
||||
ri.level}px`;
|
||||
cell.props.style.backgroundColor = "#DDD";
|
||||
cell.props.style.borderBottom = "1px solid rgba(128,128,128,0.2)";
|
||||
|
||||
return <div {...rest}>{cell}</div>;
|
||||
}
|
||||
return <Component.defaultProps.TrComponent {...rest} />;
|
||||
};
|
||||
|
||||
const getTrProps = (state, ri, ci, instance) => {
|
||||
return { ri };
|
||||
};
|
||||
|
||||
const { columns, ...rest } = componentProps;
|
||||
const extra = {
|
||||
columns: columns.map(col => {
|
||||
let column = col;
|
||||
if (rest.pivotBy && rest.pivotBy.includes(col.accessor)) {
|
||||
column = {
|
||||
accessor: col.accessor,
|
||||
width: `${componentProps.treeTableIndent}px`,
|
||||
show: false,
|
||||
Header: ""
|
||||
};
|
||||
}
|
||||
return column;
|
||||
}),
|
||||
TrComponent,
|
||||
getTrProps
|
||||
};
|
||||
|
||||
return <Component {...rest} {...extra} />;
|
||||
};
|
||||
wrapper.displayName = "RTTreeTable";
|
||||
wrapper.defaultProps = {
|
||||
treeTableRowBackground: "#EEE",
|
||||
treeTableIndent: 10
|
||||
};
|
||||
return wrapper;
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
import namor from "namor";
|
||||
|
||||
const range = len => {
|
||||
const arr = [];
|
||||
for (let i = 0; i < len; i++) {
|
||||
arr.push(i);
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
const newPerson = () => {
|
||||
const statusChance = Math.random();
|
||||
return {
|
||||
firstName: namor.generate({ words: 1, numbers: 0 }),
|
||||
lastName: namor.generate({ words: 1, numbers: 0 }),
|
||||
age: Math.floor(Math.random() * 30),
|
||||
visits: Math.floor(Math.random() * 100),
|
||||
progress: Math.floor(Math.random() * 100),
|
||||
status:
|
||||
statusChance > 0.66
|
||||
? "relationship"
|
||||
: statusChance > 0.33
|
||||
? "complicated"
|
||||
: "single"
|
||||
};
|
||||
};
|
||||
|
||||
export function makeData(len = 5553) {
|
||||
return range(len).map(d => {
|
||||
return {
|
||||
...newPerson(),
|
||||
children: range(10).map(newPerson)
|
||||
};
|
||||
});
|
||||
}
|
||||
+4
-2
@@ -1,5 +1,7 @@
|
||||
html, body, #root {
|
||||
height: 100%
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
height: 100%;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
|
||||
+5
-8
@@ -1,10 +1,7 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
//
|
||||
import './index.css'
|
||||
import App from './App.js'
|
||||
import "./index.css";
|
||||
import App from "./App.js";
|
||||
|
||||
ReactDOM.render(
|
||||
<App />,
|
||||
document.getElementById('root')
|
||||
)
|
||||
ReactDOM.render(<App />, document.getElementById("root"));
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
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'
|
||||
}]
|
||||
}]
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
constructor () {
|
||||
super()
|
||||
this.state = {
|
||||
sorted: [],
|
||||
page: 0,
|
||||
pageSize: 10,
|
||||
expanded: {},
|
||||
resized: [],
|
||||
filtered: []
|
||||
}
|
||||
}
|
||||
render () {
|
||||
return (
|
||||
<div>
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={data}
|
||||
columns={columns}
|
||||
pivotBy={['lastName']}
|
||||
filterable
|
||||
// Controlled Props
|
||||
sorted={this.state.sorted}
|
||||
page={this.state.page}
|
||||
pageSize={this.state.pageSize}
|
||||
expanded={this.state.expanded}
|
||||
resized={this.state.resized}
|
||||
filtered={this.state.filtered}
|
||||
// Callbacks
|
||||
onSortedChange={sorted => this.setState({sorted})}
|
||||
onPageChange={page => this.setState({page})}
|
||||
onPageSizeChange={(pageSize, page) => this.setState({page, pageSize})}
|
||||
onExpandedChange={expanded => this.setState({expanded})}
|
||||
onResizedChange={resized => this.setState({resized})}
|
||||
onFilteredChange={filtered => this.setState({filtered})}
|
||||
/>
|
||||
</div>
|
||||
<br />
|
||||
<pre><code><strong>this.state ===</strong> {JSON.stringify(this.state, null, 2)}</code></pre>
|
||||
<br />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Source Code
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./ControlledTable')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -1,76 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
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>
|
||||
<strong>Hey!</strong> Open your console! :)
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
getTdProps={(state, rowInfo, column, instance) => {
|
||||
return {
|
||||
onMouseEnter: e => console.log('Cell - onMouseEnter', {
|
||||
state,
|
||||
rowInfo,
|
||||
column,
|
||||
instance,
|
||||
event: e
|
||||
})
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<br />
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Source Code
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./CustomComponentProps')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -1,81 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
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',
|
||||
Footer: () => <div style={{textAlign: 'center'}}>First Name</div>
|
||||
}, {
|
||||
Header: 'Last Name',
|
||||
accessor: 'lastName',
|
||||
Footer: () => <div style={{textAlign: 'center'}}>Last Name</div>
|
||||
}]
|
||||
}, {
|
||||
Header: 'Info',
|
||||
columns: [{
|
||||
Header: 'Age',
|
||||
accessor: 'age',
|
||||
Footer: () => <div style={{textAlign: 'center'}}>Age</div>
|
||||
}]
|
||||
}, {
|
||||
Header: 'Expand',
|
||||
columns: [{
|
||||
expander: true,
|
||||
Header: () => (<strong>More</strong>),
|
||||
width: 65,
|
||||
Expander: ({isExpanded, ...rest}) => (
|
||||
<div>
|
||||
{isExpanded ? <span>⊙</span> : <span>⊕</span>}
|
||||
</div>
|
||||
),
|
||||
style: {cursor: 'pointer', fontSize: 25, padding: '0', textAlign: 'center', userSelect: 'none'},
|
||||
Footer: () => <span>♥</span>
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
SubComponent={() => <span>Hello</span>}
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<br />
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Source Code
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./CustomExpanderPosition')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -1,78 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
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 (Sorted by Length, A-Z)',
|
||||
accessor: 'firstName',
|
||||
sortMethod: (a, b) => {
|
||||
if (a.length === b.length) {
|
||||
return a > b ? 1 : -1
|
||||
}
|
||||
return a.length > b.length ? 1 : -1
|
||||
}
|
||||
}, {
|
||||
Header: 'Last Name (Sorted in reverse, A-Z)',
|
||||
id: 'lastName',
|
||||
accessor: d => d.lastName,
|
||||
sortMethod: (a, b) => {
|
||||
if (a === b) {
|
||||
return 0
|
||||
}
|
||||
const aReverse = a.split('').reverse().join('')
|
||||
const bReverse = b.split('').reverse().join('')
|
||||
return aReverse > bReverse ? 1 : -1
|
||||
}
|
||||
}]
|
||||
}, {
|
||||
Header: 'Info',
|
||||
columns: [{
|
||||
Header: 'Age',
|
||||
accessor: 'age'
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<br />
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Source Code
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./CustomSorting')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -1,67 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
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',
|
||||
maxWidth: 200
|
||||
}, {
|
||||
Header: 'Last Name',
|
||||
id: 'lastName',
|
||||
accessor: d => d.lastName,
|
||||
width: 300
|
||||
}]
|
||||
}, {
|
||||
Header: 'Info',
|
||||
columns: [{
|
||||
Header: 'Age',
|
||||
accessor: 'age',
|
||||
minWidth: 400
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<br />
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Source Code
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./CustomWidths')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -1,68 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
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
|
||||
className='-striped -highlight'
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
defaultSorted={[{
|
||||
id: 'age',
|
||||
desc: true
|
||||
}]}
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<br />
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Source Code
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./DefaultSorting')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -1,70 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
constructor (props, context) {
|
||||
super(props, context)
|
||||
this.renderEditable = this.renderEditable.bind(this)
|
||||
|
||||
this.state = {
|
||||
data: [
|
||||
{ firstName: 'Lucy', lastName: 'Marks' },
|
||||
{ firstName: 'Bejamin', lastName: 'Pike' }
|
||||
]
|
||||
}
|
||||
|
||||
this.columns = [
|
||||
{
|
||||
Header: 'First Name',
|
||||
accessor: 'firstName',
|
||||
Cell: this.renderEditable
|
||||
},
|
||||
{
|
||||
Header: 'Last Name',
|
||||
accessor: 'lastName',
|
||||
Cell: this.renderEditable
|
||||
},
|
||||
{
|
||||
Header: 'Full Name',
|
||||
id: 'full',
|
||||
accessor: d => d.firstName + ' ' + d.lastName
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
renderEditable (cellInfo) {
|
||||
return (<div style={{ backgroundColor: '#fafafa' }} contentEditable suppressContentEditableWarning onBlur={(e) => {
|
||||
const data = [...this.state.data]
|
||||
data[cellInfo.index][cellInfo.column.id] = e.target.textContent
|
||||
this.setState({data: data})
|
||||
}}>{this.state.data[cellInfo.index][cellInfo.column.id]}</div>)
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className='table-wrap' style={{marginBottom: '20px'}}>
|
||||
<p>First two columns are editable just by clicking into them using the <code>contentEditable</code> attribute. Last column (Full Name) is computed from the first two.</p>
|
||||
<ReactTable
|
||||
data={this.state.data}
|
||||
columns={this.columns}
|
||||
defaultPageSize={2}
|
||||
showPageSizeOptions={false}
|
||||
showPagination={false}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Source Code
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./EditableTable')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -1,194 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
|
||||
import CodeHighlight from './components/codeHighlight'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
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)
|
||||
}
|
||||
})
|
||||
|
||||
this.state = {
|
||||
tableOptions: {
|
||||
loading: false,
|
||||
showPagination: true,
|
||||
showPageSizeOptions: true,
|
||||
showPageJump: true,
|
||||
collapseOnSortingChange: true,
|
||||
collapseOnPageChange: true,
|
||||
collapseOnDataChange: true,
|
||||
freezeWhenExpanded: false,
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
resizable: true
|
||||
},
|
||||
data: data
|
||||
}
|
||||
|
||||
this.setTableOption = this.setTableOption.bind(this)
|
||||
}
|
||||
|
||||
render () {
|
||||
const columns = [{
|
||||
Header: 'Name',
|
||||
columns: [{
|
||||
Header: 'First Name',
|
||||
accessor: 'firstName',
|
||||
filterMethod: (filter, row) => (row[filter.id].startsWith(filter.value) && row[filter.id].endsWith(filter.value))
|
||||
}, {
|
||||
Header: 'Last Name',
|
||||
id: 'lastName',
|
||||
accessor: d => d.lastName,
|
||||
filterMethod: (filter, row) => (row[filter.id].includes(filter.value))
|
||||
}]
|
||||
}, {
|
||||
Header: 'Info',
|
||||
columns: [{
|
||||
Header: 'Age',
|
||||
accessor: 'age'
|
||||
}, {
|
||||
Header: 'Over 21',
|
||||
accessor: 'age',
|
||||
id: 'over',
|
||||
Cell: ({value}) => (value >= 21 ? 'Yes' : 'No'),
|
||||
filterMethod: (filter, row) => {
|
||||
if (filter.value === 'all') {
|
||||
return true
|
||||
}
|
||||
if (filter.value === 'true') {
|
||||
return row[filter.id] >= 21
|
||||
}
|
||||
return row[filter.id] < 21
|
||||
},
|
||||
Filter: ({filter, onChange}) => (
|
||||
<select
|
||||
onChange={event => onChange(event.target.value)}
|
||||
style={{width: '100%'}}
|
||||
value={filter ? filter.value : 'all'}
|
||||
>
|
||||
<option value='all' />
|
||||
<option value='true'>Can Drink</option>
|
||||
<option value='false'>Can't Drink</option>
|
||||
</select>
|
||||
)
|
||||
}
|
||||
]
|
||||
}]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
<h1>Table Options</h1>
|
||||
<table>
|
||||
<tbody>
|
||||
{
|
||||
Object.keys(this.state.tableOptions).map(optionKey => {
|
||||
const optionValue = this.state.tableOptions[optionKey]
|
||||
return (
|
||||
<tr key={optionKey}>
|
||||
<td>{optionKey}</td>
|
||||
<td style={{paddingLeft: 10, paddingTop: 5}}>
|
||||
<input type='checkbox'
|
||||
name={optionKey}
|
||||
checked={optionValue}
|
||||
onChange={this.setTableOption}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
})
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={this.state.data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
defaultFilterMethod={(filter, row) => (String(row[filter.id]) === filter.value)}
|
||||
{...this.state.tableOptions}
|
||||
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={this.state.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>
|
||||
<div>
|
||||
<h1>Custom Filters In This Example</h1>
|
||||
<p>The default filter for all columns of a table if it is not specified in the configuration is set to match
|
||||
on values that start with the filter text. Example: age.startsWith("2").</p>
|
||||
<p>This example overrides the default filter behavior by setting
|
||||
the <strong>defaultFilterMethod</strong> table option to match on values that are exactly equal to the
|
||||
filter text. Example: age == "23")</p>
|
||||
<p>Each column can also be customized with the column <strong>filterMethod</strong> option:</p>
|
||||
<p>In this example the firstName column filters on the value starting with and ending with the filter
|
||||
value.</p>
|
||||
<p>In this example the lastName column filters on the value including the filter value anywhere in its
|
||||
text.</p>
|
||||
<p>To completely override the filter that is shown, you can set the <strong>Filter</strong> column
|
||||
option. Using this option you can specify the JSX that is shown. The option is passed
|
||||
an <strong>onChange</strong> method that must be called with the value that you wan't to
|
||||
pass to the <strong>filterMethod</strong> option whenever the filter has changed.</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
setTableOption (event) {
|
||||
const target = event.target
|
||||
const value = target.type === 'checkbox' ? target.checked : target.value
|
||||
const name = target.name
|
||||
this.setState({
|
||||
tableOptions: {
|
||||
...this.state.tableOptions,
|
||||
[name]: value
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Source Code
|
||||
const source = require('!raw!./Filtering')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -1,81 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
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),
|
||||
children: _.map(_.range(10), d => {
|
||||
return {
|
||||
firstName: namor.generate({ words: 1, numLen: 0 }),
|
||||
lastName: namor.generate({ words: 1, numLen: 0 }),
|
||||
age: Math.floor(Math.random() * 30)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const columns = [
|
||||
{
|
||||
Header: 'Name',
|
||||
columns: [
|
||||
{
|
||||
Header: 'First Name',
|
||||
accessor: 'firstName'
|
||||
},
|
||||
{
|
||||
Header: 'Last Name',
|
||||
id: 'lastName',
|
||||
accessor: d => d.lastName
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
Header: 'Info',
|
||||
columns: [
|
||||
{
|
||||
Header: 'Age',
|
||||
accessor: 'age'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="table-wrap">
|
||||
<ReactTable
|
||||
className="-striped -highlight"
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={20}
|
||||
style={{
|
||||
height: '400px' // This will force the table body to overflow and scroll, since there is not enough room
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<br />
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./Simple')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -1,92 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
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',
|
||||
Footer: (
|
||||
<span><strong>Popular:</strong> {
|
||||
_.first(
|
||||
_.reduce(
|
||||
_.map(
|
||||
_.groupBy(
|
||||
data, d => d.firstName
|
||||
)
|
||||
),
|
||||
(a, b) => a.length > b.length ? a : b
|
||||
)
|
||||
).firstName}
|
||||
</span>
|
||||
)
|
||||
}, {
|
||||
Header: 'Last Name',
|
||||
id: 'lastName',
|
||||
accessor: d => d.lastName,
|
||||
Footer: (
|
||||
<span><strong>Longest:</strong> {
|
||||
_.reduce(
|
||||
_.map(
|
||||
_.groupBy(
|
||||
data, d => d.lastName
|
||||
),
|
||||
(d, key) => key
|
||||
),
|
||||
(a, b) => a.length > b.length ? a : b
|
||||
)}
|
||||
</span>
|
||||
)
|
||||
}]
|
||||
}, {
|
||||
Header: 'Info',
|
||||
columns: [{
|
||||
Header: 'Age',
|
||||
accessor: 'age',
|
||||
Footer: <span><strong>Average:</strong> {_.round(_.mean(_.map(data, d => d.age)))}</span>
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<br />
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Source Code
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./Footers')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -1,137 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
import JSONTree from 'react-json-tree'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
const JSONtheme = {
|
||||
scheme: 'monokai',
|
||||
author: 'wimer hazenberg (http://www.monokai.nl)',
|
||||
base00: '#272822',
|
||||
base01: '#383830',
|
||||
base02: '#49483e',
|
||||
base03: '#75715e',
|
||||
base04: '#a59f85',
|
||||
base05: '#f8f8f2',
|
||||
base06: '#f5f4f1',
|
||||
base07: '#f9f8f5',
|
||||
base08: '#f92672',
|
||||
base09: '#fd971f',
|
||||
base0A: '#f4bf75',
|
||||
base0B: '#a6e22e',
|
||||
base0C: '#a1efe4',
|
||||
base0D: '#66d9ef',
|
||||
base0E: '#ae81ff',
|
||||
base0F: '#cc6633'
|
||||
}
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
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',
|
||||
Footer: 'Footer'
|
||||
}, {
|
||||
Header: 'Last Name',
|
||||
id: 'lastName',
|
||||
accessor: d => d.lastName,
|
||||
Footer: 'Footer'
|
||||
}]
|
||||
}, {
|
||||
Header: 'Info',
|
||||
columns: [{
|
||||
Header: 'Age',
|
||||
accessor: 'age',
|
||||
Footer: 'Footer'
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<strong>Functional rendering</strong> simply means that you have all of the building blocks to render your own React Table however you'd like.
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<strong>Decorating the standard table output</strong>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
>
|
||||
{(state, makeTable, instance) => {
|
||||
return (
|
||||
<div style={{
|
||||
background: '#ffcf00',
|
||||
borderRadius: '5px',
|
||||
overflow: 'hidden',
|
||||
padding: '5px'
|
||||
}}>
|
||||
<pre><code>state.allVisibleColumns === {JSON.stringify(state.allVisibleColumns, null, 4)}</code></pre>
|
||||
{makeTable()}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
</ReactTable>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<strong>Need more control? This is the entire table state and component instance at your disposal!</strong>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
>
|
||||
{(state, StandardTable, instance) => {
|
||||
return (
|
||||
<div>
|
||||
<JSONTree
|
||||
data={Object.assign({}, state, {children: 'function () {...}'})}
|
||||
theme={JSONtheme}
|
||||
invertTheme
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
</ReactTable>
|
||||
</div>
|
||||
<br />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Source Code
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./FunctionalRendering')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -0,0 +1,23 @@
|
||||
/* eslint-disable */
|
||||
import React from "react";
|
||||
import marked from "marked";
|
||||
//
|
||||
import HOCReadme from "!raw!../../../src/hoc/README.md";
|
||||
import "github-markdown-css/github-markdown.css";
|
||||
import "./utils/prism.js";
|
||||
|
||||
export default class HOCStory extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div style={{ padding: "10px" }}>
|
||||
<span
|
||||
className="markdown-body"
|
||||
dangerouslySetInnerHTML={{ __html: marked(HOCReadme) }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
componentDidMount() {
|
||||
global.Prism && global.Prism.highlightAll();
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
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 (
|
||||
<div>
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={[]}
|
||||
noDataText='Oh Noes!'
|
||||
// noDataText={() => 'Oh Noes!'} // Supports functions
|
||||
// noDataText={() => <span>Oh Noes!</span>} // Supports JSX / React Components
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<br />
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Source Code
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./NoDataText')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -1,97 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
render () {
|
||||
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)),
|
||||
Aggregated: row => {
|
||||
return <span>{row.value} (avg)</span>
|
||||
}
|
||||
}, {
|
||||
Header: 'Visits',
|
||||
accessor: 'visits',
|
||||
aggregate: vals => _.sum(vals)
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
className='-striped -highlight'
|
||||
defaultPageSize={10}
|
||||
pivotBy={['firstName', 'lastName']}
|
||||
SubComponent={(row) => {
|
||||
return (
|
||||
<div style={{padding: '20px'}}>
|
||||
<em>You can put any component you want here, even another React Table!</em>
|
||||
<br />
|
||||
<br />
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={3}
|
||||
showPagination={false}
|
||||
SubComponent={(row) => {
|
||||
return (
|
||||
<div style={{padding: '20px'}}>
|
||||
<em>It even has access to the row data: </em>
|
||||
<CodeHighlight>{() => JSON.stringify(row, null, 2)}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<br />
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Source Code
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./OneHundredKRows')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -1,74 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
render () {
|
||||
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)),
|
||||
Aggregated: row => {
|
||||
return <span>{row.value} (avg)</span>
|
||||
}
|
||||
}, {
|
||||
Header: 'Visits',
|
||||
accessor: 'visits',
|
||||
aggregate: vals => _.sum(vals)
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
className='-striped -highlight'
|
||||
defaultPageSize={10}
|
||||
pivotBy={['firstName', 'lastName']}
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<br />
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Source Code
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./Pivoting')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -1,132 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
render () {
|
||||
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',
|
||||
PivotValue: ({value}) => <span style={{color: 'darkred'}}>{value}</span>
|
||||
}, {
|
||||
Header: 'Last Name',
|
||||
id: 'lastName',
|
||||
accessor: d => d.lastName,
|
||||
PivotValue: ({value}) => <span style={{color: 'darkblue'}}>{value}</span>,
|
||||
Footer: () => <div style={{textAlign: 'center'}}><strong>Pivot Column Footer</strong></div>
|
||||
}]
|
||||
}, {
|
||||
Header: 'Info',
|
||||
columns: [{
|
||||
Header: 'Age',
|
||||
accessor: 'age',
|
||||
aggregate: vals => {
|
||||
return _.round(_.mean(vals))
|
||||
},
|
||||
Aggregated: row => <span>{row.value} (avg)</span>
|
||||
}, {
|
||||
Header: 'Visits',
|
||||
accessor: 'visits',
|
||||
aggregate: vals => _.sum(vals),
|
||||
filterable: false
|
||||
}]
|
||||
}, {
|
||||
pivot: true,
|
||||
Header: () => <strong>Overridden Pivot Column Header Group</strong>
|
||||
}, {
|
||||
expander: true
|
||||
}]
|
||||
|
||||
const subtableColumns = [{
|
||||
Header: 'Name',
|
||||
columns: [{
|
||||
Header: 'First Name',
|
||||
accessor: 'firstName'
|
||||
}, {
|
||||
Header: 'Last Name',
|
||||
id: 'lastName'
|
||||
}]
|
||||
}, {
|
||||
Header: 'Info',
|
||||
columns: [{
|
||||
Header: 'Age',
|
||||
accessor: 'age'
|
||||
}, {
|
||||
Header: 'Visits',
|
||||
accessor: 'visits'
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
className='-striped -highlight'
|
||||
pivotBy={['firstName', 'lastName']}
|
||||
defaultSorted={[{id: 'firstName', desc: false}, {id: 'lastName', desc: true}]}
|
||||
collapseOnSortingChange={false}
|
||||
filterable
|
||||
ExpanderComponent={({isExpanded, ...rest}) => (
|
||||
isExpanded ? <span> ➘ </span> : <span> ➙ </span>
|
||||
)}
|
||||
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={subtableColumns}
|
||||
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>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Source Code
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./PivotingOptions')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -1,100 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
render () {
|
||||
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)),
|
||||
Aggregated: row => {
|
||||
return <span>{row.value} (avg)</span>
|
||||
},
|
||||
filterMethod: (filter, row) => (filter.value === `${row[filter.id]} (avg)`)
|
||||
}, {
|
||||
Header: 'Visits',
|
||||
accessor: 'visits',
|
||||
aggregate: vals => _.sum(vals),
|
||||
filterable: false
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
className='-striped -highlight'
|
||||
pivotBy={['firstName', 'lastName']}
|
||||
filterable
|
||||
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>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Source Code
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./PivotingSubComponents')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -1,15 +1,23 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import marked from 'marked'
|
||||
import React from "react";
|
||||
import marked from "marked";
|
||||
//
|
||||
import Readme from '!raw!../../../README.md'
|
||||
import 'github-markdown-css/github-markdown.css'
|
||||
import Readme from "!raw!../../../README.md";
|
||||
import "github-markdown-css/github-markdown.css";
|
||||
import "./utils/prism.js";
|
||||
|
||||
export default class Story extends React.Component {
|
||||
render () {
|
||||
return <span className='markdown-body' dangerouslySetInnerHTML={{__html: marked(Readme)}} />
|
||||
render() {
|
||||
return (
|
||||
<div style={{ padding: "10px" }}>
|
||||
<span
|
||||
className="markdown-body"
|
||||
dangerouslySetInnerHTML={{ __html: marked(Readme) }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
componentDidMount () {
|
||||
global.Prism.highlightAll()
|
||||
componentDidMount() {
|
||||
global.Prism && global.Prism.highlightAll();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
const rawData = _.map(_.range(3424), d => {
|
||||
return {
|
||||
firstName: namor.generate({ words: 1, numLen: 0 }),
|
||||
lastName: namor.generate({ words: 1, numLen: 0 }),
|
||||
age: Math.floor(Math.random() * 30)
|
||||
}
|
||||
})
|
||||
|
||||
// Now let's mock the server. It's job is simple: use the table model to sort and return the page data
|
||||
const requestData = (pageSize, page, sorted, filtered) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// On the server, you'll likely use SQL or noSQL or some other query language to do this.
|
||||
// For this mock, we'll just use lodash
|
||||
let filteredData = rawData
|
||||
if (filtered.length) {
|
||||
filteredData = filtered.reduce(
|
||||
(filteredSoFar, nextFilter) => {
|
||||
return filteredSoFar.filter(
|
||||
(row) => {
|
||||
return (row[nextFilter.id] + '').includes(nextFilter.value)
|
||||
})
|
||||
}
|
||||
, filteredData)
|
||||
}
|
||||
const sortedData = _.orderBy(filteredData, sorted.map(sort => {
|
||||
return row => {
|
||||
if (row[sort.id] === null || row[sort.id] === undefined) {
|
||||
return -Infinity
|
||||
}
|
||||
return typeof row[sort.id] === 'string' ? row[sort.id].toLowerCase() : row[sort.id]
|
||||
}
|
||||
}), sorted.map(d => d.desc ? 'desc' : 'asc'))
|
||||
|
||||
// Be sure to send back the rows to be displayed and any other pertinent information, like how many pages there are total.
|
||||
const res = {
|
||||
rows: sortedData.slice(pageSize * page, (pageSize * page) + pageSize),
|
||||
pages: Math.ceil(filteredData.length / pageSize)
|
||||
}
|
||||
|
||||
// Here we'll simulate a server response with 500ms of delay.
|
||||
setTimeout(() => resolve(res), 500)
|
||||
})
|
||||
}
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
constructor () {
|
||||
super()
|
||||
this.state = {
|
||||
data: [],
|
||||
pages: null,
|
||||
loading: true
|
||||
}
|
||||
this.fetchData = this.fetchData.bind(this)
|
||||
}
|
||||
fetchData (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})
|
||||
// Request the data however you want. Here, we'll use our mocked service we created earlier
|
||||
requestData(state.pageSize, state.page, state.sorted, state.filtered)
|
||||
.then((res) => {
|
||||
// Now just get the rows of data to your React Table (and update anything else like total pages or loading)
|
||||
this.setState({
|
||||
data: res.rows,
|
||||
pages: res.pages,
|
||||
loading: false
|
||||
})
|
||||
})
|
||||
}
|
||||
render () {
|
||||
return (
|
||||
<div>
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
columns={[{
|
||||
Header: 'First Name',
|
||||
accessor: 'firstName'
|
||||
}, {
|
||||
Header: 'Last Name',
|
||||
id: 'lastName',
|
||||
accessor: d => d.lastName
|
||||
}, {
|
||||
Header: 'Age',
|
||||
accessor: 'age'
|
||||
}]}
|
||||
manual // Forces table not to paginate or sort automatically, so we can handle it server-side
|
||||
defaultPageSize={10}
|
||||
filterable
|
||||
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
|
||||
onFetchData={this.fetchData} // Request new data when things change
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<br />
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Source Code
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./ServerSide')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -1,70 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
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),
|
||||
children: _.map(_.range(10), d => {
|
||||
return {
|
||||
firstName: namor.generate({ words: 1, numLen: 0 }),
|
||||
lastName: namor.generate({ words: 1, numLen: 0 }),
|
||||
age: Math.floor(Math.random() * 30)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const columns = [{
|
||||
Header: 'Name',
|
||||
columns: [{
|
||||
Header: 'First Name',
|
||||
accessor: 'firstName'
|
||||
}, {
|
||||
Header: 'Last Name',
|
||||
id: 'lastName',
|
||||
accessor: d => d.lastName
|
||||
}]
|
||||
}, {
|
||||
Header: 'Info',
|
||||
columns: [{
|
||||
Header: 'Age',
|
||||
accessor: 'age'
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<br />
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./Simple')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -1,146 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
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)
|
||||
}
|
||||
})
|
||||
|
||||
this.state = {
|
||||
tableOptions: {
|
||||
loading: false,
|
||||
showPagination: true,
|
||||
showPageSizeOptions: true,
|
||||
showPageJump: true,
|
||||
collapseOnSortingChange: true,
|
||||
collapseOnPageChange: true,
|
||||
collapseOnDataChange: true,
|
||||
freezeWhenExpanded: false,
|
||||
filterable: false,
|
||||
sortable: true,
|
||||
resizable: true
|
||||
},
|
||||
data: data
|
||||
}
|
||||
|
||||
this.setTableOption = this.setTableOption.bind(this)
|
||||
}
|
||||
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 (
|
||||
<div>
|
||||
<div>
|
||||
<h1>Table Options</h1>
|
||||
<table>
|
||||
<tbody>
|
||||
{
|
||||
Object.keys(this.state.tableOptions).map(optionKey => {
|
||||
const optionValue = this.state.tableOptions[optionKey]
|
||||
return (
|
||||
<tr key={optionKey}>
|
||||
<td>{optionKey}</td>
|
||||
<td style={{paddingLeft: 10, paddingTop: 5}}>
|
||||
<input type='checkbox'
|
||||
name={optionKey}
|
||||
checked={optionValue}
|
||||
onChange={this.setTableOption}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
})
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={this.state.data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
{...this.state.tableOptions}
|
||||
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={this.state.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>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
setTableOption (event) {
|
||||
const target = event.target
|
||||
const value = target.type === 'checkbox' ? target.checked : target.value
|
||||
const name = target.name
|
||||
this.setState({
|
||||
tableOptions: {
|
||||
...this.state.tableOptions,
|
||||
[name]: value
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Source Code
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./SubComponents')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -1,78 +0,0 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
render () {
|
||||
const data = _.map(_.range(5553), d => {
|
||||
const children = _.map(_.range(10), d => {
|
||||
const grandChildren = _.map(_.range(10), d => {
|
||||
return {
|
||||
age: Math.floor(Math.random() * 30)
|
||||
}
|
||||
})
|
||||
return {
|
||||
firstName: namor.generate({ words: 1, numLen: 0 }),
|
||||
age: Math.floor(Math.random() * 30),
|
||||
children: grandChildren
|
||||
}
|
||||
})
|
||||
return {
|
||||
lastName: namor.generate({ words: 1, numLen: 0 }),
|
||||
firstName: children.map(d => d.firstName),
|
||||
age: Math.floor(Math.random() * 30),
|
||||
children
|
||||
}
|
||||
})
|
||||
|
||||
const columns = [{
|
||||
Header: 'Name',
|
||||
columns: [{
|
||||
Header: 'First Name',
|
||||
accessor: 'firstName',
|
||||
expander: true
|
||||
}, {
|
||||
Header: 'Last Name',
|
||||
accessor: 'lastName'
|
||||
}]
|
||||
}, {
|
||||
Header: 'Info',
|
||||
columns: [{
|
||||
Header: 'Age',
|
||||
accessor: 'age'
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
subRowsKey='children'
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<br />
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Source Code
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./SubRows')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
@@ -1,21 +0,0 @@
|
||||
import React from 'react'
|
||||
import '../utils/prism'
|
||||
|
||||
export default class CodeHighlight extends React.Component {
|
||||
render () {
|
||||
const { language, children } = this.props
|
||||
return (
|
||||
<pre>
|
||||
<code className={'language-' + (language || 'jsx')}>
|
||||
{children()}
|
||||
</code>
|
||||
</pre>
|
||||
)
|
||||
}
|
||||
componentDidMount () {
|
||||
window.Prism.highlightAll()
|
||||
}
|
||||
componentDidUpdate () {
|
||||
window.Prism.highlightAll()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import React from "react";
|
||||
|
||||
import ReactTable from "../../../lib/index";
|
||||
import "../../../react-table.css";
|
||||
|
||||
const data = [
|
||||
{ one: "1.1", two: "1.2" },
|
||||
{ one: "2.1", two: "2.2" },
|
||||
{ one: "3.1", two: "3.2" },
|
||||
{ one: "4.1", two: "4.2" }
|
||||
];
|
||||
|
||||
const columns = [
|
||||
{ accessor: "one", Header: "One" },
|
||||
{ accessor: "two", Header: "Two" }
|
||||
];
|
||||
|
||||
export default class Story extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
Test
|
||||
<ReactTable data={data} columns={columns} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
+1983
-426
File diff suppressed because it is too large
Load Diff
Executable
+21
@@ -0,0 +1,21 @@
|
||||
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
Executable
+1863
File diff suppressed because it is too large
Load Diff
Executable
+23
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "react-table-100k-rows-aggregation",
|
||||
"version": "0.0.7",
|
||||
"description": null,
|
||||
"keywords": [],
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"react-table": "6.5.3",
|
||||
"react-dom": "15.5.3",
|
||||
"react": "15.5.3",
|
||||
"namor": "1.0.1",
|
||||
"lodash": "4.17.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"react-scripts": "1.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
}
|
||||
}
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
+38
@@ -0,0 +1,38 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="theme-color" content="#000000">
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is added to the
|
||||
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"start_url": "./index.html",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"infiniteLoopProtection": false,
|
||||
"hardReloadOnChange": false,
|
||||
"view": "browser"
|
||||
}
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
import React from "react";
|
||||
import namor from "namor";
|
||||
import "./index.css";
|
||||
|
||||
const range = len => {
|
||||
const arr = [];
|
||||
for (let i = 0; i < len; i++) {
|
||||
arr.push(i);
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
const newPerson = () => {
|
||||
const statusChance = Math.random();
|
||||
return {
|
||||
firstName: namor.generate({ words: 1, numbers: 0 }),
|
||||
lastName: namor.generate({ words: 1, numbers: 0 }),
|
||||
age: Math.floor(Math.random() * 30),
|
||||
visits: Math.floor(Math.random() * 100),
|
||||
progress: Math.floor(Math.random() * 100),
|
||||
status:
|
||||
statusChance > 0.66
|
||||
? "relationship"
|
||||
: statusChance > 0.33 ? "complicated" : "single"
|
||||
};
|
||||
};
|
||||
|
||||
export function makeData(len = 5553) {
|
||||
return range(len).map(d => {
|
||||
return {
|
||||
...newPerson(),
|
||||
children: range(10).map(newPerson)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export const Logo = () =>
|
||||
<div style={{ margin: '1rem auto', display: 'flex', flexWrap: 'wrap', alignItems: 'center', justifyContent: 'center'}}>
|
||||
For more examples, visit {''}
|
||||
<br />
|
||||
<a href="https://github.com/react-tools/react-table" target="_blank">
|
||||
<img
|
||||
src="https://github.com/react-tools/media/raw/master/logo-react-table.png"
|
||||
style={{ width: `150px`, margin: ".5em auto .3em" }}
|
||||
/>
|
||||
</a>
|
||||
</div>;
|
||||
|
||||
export const Tips = () =>
|
||||
<div style={{ textAlign: "center" }}>
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>;
|
||||
@@ -0,0 +1,52 @@
|
||||
// In production, we register a service worker to serve assets from local cache.
|
||||
|
||||
// This lets the app load faster on subsequent visits in production, and gives
|
||||
// it offline capabilities. However, it also means that developers (and users)
|
||||
// will only see deployed updates on the "N+1" visit to a page, since previously
|
||||
// cached resources are updated in the background.
|
||||
|
||||
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
|
||||
// This link also includes instructions on opting out of this behavior.
|
||||
|
||||
export default function register() {
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
navigator.serviceWorker
|
||||
.register(swUrl)
|
||||
.then(registration => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the old content will have been purged and
|
||||
// the fresh content will have been added to the cache.
|
||||
// It's the perfect time to display a "New content is
|
||||
// available; please refresh." message in your web app.
|
||||
console.log('New content is available; please refresh.'); // eslint-disable-line no-console
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log('Content is cached for offline use.'); // eslint-disable-line no-console
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error during service worker registration:', error);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister();
|
||||
});
|
||||
}
|
||||
}
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
body {
|
||||
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
|
||||
font-weight: 300;
|
||||
font-size: 14px;
|
||||
}
|
||||
Executable
+85
@@ -0,0 +1,85 @@
|
||||
import React from "react";
|
||||
import { render } from "react-dom";
|
||||
import { makeData, Logo, Tips } from "./Utils";
|
||||
import _ from "lodash";
|
||||
|
||||
// Import React Table
|
||||
import ReactTable from "react-table";
|
||||
import "react-table/react-table.css";
|
||||
|
||||
class App extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
data: makeData(100000)
|
||||
};
|
||||
}
|
||||
render() {
|
||||
const { data } = this.state;
|
||||
return (
|
||||
<div>
|
||||
<br />
|
||||
<strong>Note: Having the console open will slow performance</strong>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<ReactTable
|
||||
data={data}
|
||||
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)),
|
||||
Aggregated: row => {
|
||||
return (
|
||||
<span>
|
||||
{row.value} (avg)
|
||||
</span>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
Header: "Visits",
|
||||
accessor: "visits",
|
||||
aggregate: vals => _.sum(vals)
|
||||
}
|
||||
]
|
||||
}
|
||||
]}
|
||||
pivotBy={["firstName", "lastName"]}
|
||||
defaultPageSize={10}
|
||||
className="-striped -highlight"
|
||||
SubComponent={row => {
|
||||
return (
|
||||
<div style={{ padding: "20px" }}>
|
||||
<em>Sub Component!</em>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<br />
|
||||
<Tips />
|
||||
<Logo />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
render(<App />, document.getElementById("root"));
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "react-table-100k-rows-aggregation",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"keywords": [],
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"react-table": "6.5.3",
|
||||
"react-dom": "15.5.3",
|
||||
"react": "15.5.3",
|
||||
"namor": "1.0.1",
|
||||
"lodash": "4.17.4"
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Executable
+21
@@ -0,0 +1,21 @@
|
||||
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
Executable
+1863
File diff suppressed because it is too large
Load Diff
Executable
+28
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "react-table-cell-renderers",
|
||||
"version": "0.0.12",
|
||||
"description": null,
|
||||
"keywords": [
|
||||
"react",
|
||||
"react-table",
|
||||
"datagrid",
|
||||
"grid",
|
||||
"table"
|
||||
],
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"react-table": "6.5.3",
|
||||
"react-dom": "15.5.3",
|
||||
"react": "15.5.3",
|
||||
"namor": "1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"react-scripts": "1.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
}
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
Executable
+38
@@ -0,0 +1,38 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="theme-color" content="#000000">
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is added to the
|
||||
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"start_url": "./index.html",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
import React from "react";
|
||||
import namor from "namor";
|
||||
import "./index.css";
|
||||
|
||||
const range = len => {
|
||||
const arr = [];
|
||||
for (let i = 0; i < len; i++) {
|
||||
arr.push(i);
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
const newPerson = () => {
|
||||
const statusChance = Math.random();
|
||||
return {
|
||||
firstName: namor.generate({ words: 1, numbers: 0 }),
|
||||
lastName: namor.generate({ words: 1, numbers: 0 }),
|
||||
age: Math.floor(Math.random() * 30),
|
||||
visits: Math.floor(Math.random() * 100),
|
||||
progress: Math.floor(Math.random() * 100),
|
||||
status:
|
||||
statusChance > 0.66
|
||||
? "relationship"
|
||||
: statusChance > 0.33 ? "complicated" : "single"
|
||||
};
|
||||
};
|
||||
|
||||
export function makeData(len = 5553) {
|
||||
return range(len).map(d => {
|
||||
return {
|
||||
...newPerson(),
|
||||
children: range(10).map(newPerson)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export const Logo = () =>
|
||||
<div style={{ margin: '1rem auto', display: 'flex', flexWrap: 'wrap', alignItems: 'center', justifyContent: 'center'}}>
|
||||
For more examples, visit {''}
|
||||
<br />
|
||||
<a href="https://github.com/react-tools/react-table" target="_blank">
|
||||
<img
|
||||
src="https://github.com/react-tools/media/raw/master/logo-react-table.png"
|
||||
style={{ width: `150px`, margin: ".5em auto .3em" }}
|
||||
/>
|
||||
</a>
|
||||
</div>;
|
||||
|
||||
export const Tips = () =>
|
||||
<div style={{ textAlign: "center" }}>
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>;
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
// In production, we register a service worker to serve assets from local cache.
|
||||
|
||||
// This lets the app load faster on subsequent visits in production, and gives
|
||||
// it offline capabilities. However, it also means that developers (and users)
|
||||
// will only see deployed updates on the "N+1" visit to a page, since previously
|
||||
// cached resources are updated in the background.
|
||||
|
||||
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
|
||||
// This link also includes instructions on opting out of this behavior.
|
||||
|
||||
export default function register() {
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
navigator.serviceWorker
|
||||
.register(swUrl)
|
||||
.then(registration => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the old content will have been purged and
|
||||
// the fresh content will have been added to the cache.
|
||||
// It's the perfect time to display a "New content is
|
||||
// available; please refresh." message in your web app.
|
||||
console.log('New content is available; please refresh.'); // eslint-disable-line no-console
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log('Content is cached for offline use.'); // eslint-disable-line no-console
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error during service worker registration:', error);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister();
|
||||
});
|
||||
}
|
||||
}
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
body {
|
||||
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
|
||||
font-weight: 300;
|
||||
font-size: 14px;
|
||||
}
|
||||
Regular → Executable
+29
-47
@@ -1,25 +1,25 @@
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import React from 'react'
|
||||
import _ from 'lodash'
|
||||
import namor from 'namor'
|
||||
import React from "react";
|
||||
import { render } from "react-dom";
|
||||
import { makeData, Logo, Tips } from "./Utils";
|
||||
|
||||
import ReactTable from '../../../lib/index'
|
||||
// Import React Table
|
||||
import ReactTable from "react-table";
|
||||
import "react-table/react-table.css";
|
||||
|
||||
class Story extends React.PureComponent {
|
||||
render () {
|
||||
const data = _.map(_.range(5553), d => {
|
||||
const statusChance = Math.random()
|
||||
return {
|
||||
firstName: namor.generate({ words: 1, numLen: 0 }),
|
||||
lastName: namor.generate({ words: 1, numLen: 0 }),
|
||||
progress: Math.floor(Math.random() * 100),
|
||||
status: statusChance > 0.66 ? 'relationship'
|
||||
: statusChance > 0.33 ? 'complicated'
|
||||
: 'single'
|
||||
}
|
||||
})
|
||||
|
||||
const columns = [{
|
||||
class App extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
data: makeData()
|
||||
};
|
||||
}
|
||||
render() {
|
||||
const { data } = this.state;
|
||||
return (
|
||||
<div>
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={[{
|
||||
Header: 'Name',
|
||||
columns: [{
|
||||
Header: 'First Name',
|
||||
@@ -76,34 +76,16 @@ class Story extends React.PureComponent {
|
||||
</span>
|
||||
)
|
||||
}]
|
||||
}]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='table-wrap'>
|
||||
<ReactTable
|
||||
className='-striped -highlight'
|
||||
data={data}
|
||||
columns={columns}
|
||||
defaultPageSize={10}
|
||||
/>
|
||||
</div>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<br />
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>
|
||||
}]}
|
||||
defaultPageSize={10}
|
||||
className="-striped -highlight"
|
||||
/>
|
||||
<br />
|
||||
<Tips />
|
||||
<Logo />
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Source Code
|
||||
const CodeHighlight = require('./components/codeHighlight').default
|
||||
const source = require('!raw!./CellRenderers')
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Story />
|
||||
<CodeHighlight>{() => source}</CodeHighlight>
|
||||
</div>
|
||||
)
|
||||
render(<App />, document.getElementById("root"));
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "react-table-cell-renderers",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"keywords": [
|
||||
"react",
|
||||
"react-table",
|
||||
"datagrid",
|
||||
"grid",
|
||||
"table"
|
||||
],
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"react-table": "6.5.3",
|
||||
"react-dom": "15.5.3",
|
||||
"react": "15.5.3",
|
||||
"namor": "1.0.1"
|
||||
}
|
||||
}
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
Executable
+1863
File diff suppressed because it is too large
Load Diff
Executable
+22
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "react-table-controlled-table",
|
||||
"version": "0.0.2",
|
||||
"description": null,
|
||||
"keywords": [],
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"react-table": "6.5.3",
|
||||
"react-dom": "15.5.3",
|
||||
"react": "15.5.3",
|
||||
"namor": "1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"react-scripts": "1.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
}
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
Executable
+38
@@ -0,0 +1,38 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="theme-color" content="#000000">
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is added to the
|
||||
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"start_url": "./index.html",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
import React from "react";
|
||||
import namor from "namor";
|
||||
import "./index.css";
|
||||
|
||||
const range = len => {
|
||||
const arr = [];
|
||||
for (let i = 0; i < len; i++) {
|
||||
arr.push(i);
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
const newPerson = () => {
|
||||
const statusChance = Math.random();
|
||||
return {
|
||||
firstName: namor.generate({ words: 1, numbers: 0 }),
|
||||
lastName: namor.generate({ words: 1, numbers: 0 }),
|
||||
age: Math.floor(Math.random() * 30),
|
||||
visits: Math.floor(Math.random() * 100),
|
||||
progress: Math.floor(Math.random() * 100),
|
||||
status:
|
||||
statusChance > 0.66
|
||||
? "relationship"
|
||||
: statusChance > 0.33 ? "complicated" : "single"
|
||||
};
|
||||
};
|
||||
|
||||
export function makeData(len = 5553) {
|
||||
return range(len).map(d => {
|
||||
return {
|
||||
...newPerson(),
|
||||
children: range(10).map(newPerson)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export const Logo = () =>
|
||||
<div style={{ margin: '1rem auto', display: 'flex', flexWrap: 'wrap', alignItems: 'center', justifyContent: 'center'}}>
|
||||
For more examples, visit {''}
|
||||
<br />
|
||||
<a href="https://github.com/react-tools/react-table" target="_blank">
|
||||
<img
|
||||
src="https://github.com/react-tools/media/raw/master/logo-react-table.png"
|
||||
style={{ width: `150px`, margin: ".5em auto .3em" }}
|
||||
/>
|
||||
</a>
|
||||
</div>;
|
||||
|
||||
export const Tips = () =>
|
||||
<div style={{ textAlign: "center" }}>
|
||||
<em>Tip: Hold shift when sorting to multi-sort!</em>
|
||||
</div>;
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
// In production, we register a service worker to serve assets from local cache.
|
||||
|
||||
// This lets the app load faster on subsequent visits in production, and gives
|
||||
// it offline capabilities. However, it also means that developers (and users)
|
||||
// will only see deployed updates on the "N+1" visit to a page, since previously
|
||||
// cached resources are updated in the background.
|
||||
|
||||
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
|
||||
// This link also includes instructions on opting out of this behavior.
|
||||
|
||||
export default function register() {
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
navigator.serviceWorker
|
||||
.register(swUrl)
|
||||
.then(registration => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the old content will have been purged and
|
||||
// the fresh content will have been added to the cache.
|
||||
// It's the perfect time to display a "New content is
|
||||
// available; please refresh." message in your web app.
|
||||
console.log('New content is available; please refresh.'); // eslint-disable-line no-console
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log('Content is cached for offline use.'); // eslint-disable-line no-console
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error during service worker registration:', error);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister();
|
||||
});
|
||||
}
|
||||
}
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
body {
|
||||
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
|
||||
font-weight: 300;
|
||||
font-size: 14px;
|
||||
}
|
||||
Executable
+97
@@ -0,0 +1,97 @@
|
||||
import React from "react";
|
||||
import { render } from "react-dom";
|
||||
import { makeData, Logo, Tips } from "./Utils";
|
||||
|
||||
// Import React Table
|
||||
import ReactTable from "react-table";
|
||||
import "react-table/react-table.css";
|
||||
|
||||
const data = makeData()
|
||||
|
||||
const makeDefaultState = () => ({
|
||||
sorted: [],
|
||||
page: 0,
|
||||
pageSize: 10,
|
||||
expanded: {},
|
||||
resized: [],
|
||||
filtered: []
|
||||
});
|
||||
|
||||
class App extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = makeDefaultState();
|
||||
this.resetState = this.resetState.bind(this);
|
||||
}
|
||||
resetState() {
|
||||
this.setState(makeDefaultState());
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
<button onClick={this.resetState}>Reset State</button>
|
||||
</div>
|
||||
<pre>
|
||||
<code>
|
||||
<strong>this.state ===</strong>{" "}
|
||||
{JSON.stringify(this.state, null, 2)}
|
||||
</code>
|
||||
</pre>
|
||||
<ReactTable
|
||||
data={data}
|
||||
columns={[
|
||||
{
|
||||
Header: "Name",
|
||||
columns: [
|
||||
{
|
||||
Header: "First Name",
|
||||
accessor: "firstName"
|
||||
},
|
||||
{
|
||||
Header: "Last Name",
|
||||
id: "lastName",
|
||||
accessor: d => d.lastName,
|
||||
width: 170
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
Header: "Info",
|
||||
columns: [
|
||||
{
|
||||
Header: "Age",
|
||||
accessor: "age"
|
||||
}
|
||||
]
|
||||
}
|
||||
]}
|
||||
pivotBy={["lastName"]}
|
||||
filterable
|
||||
defaultPageSize={10}
|
||||
className="-striped -highlight"
|
||||
// Controlled props
|
||||
sorted={this.state.sorted}
|
||||
page={this.state.page}
|
||||
pageSize={this.state.pageSize}
|
||||
expanded={this.state.expanded}
|
||||
resized={this.state.resized}
|
||||
filtered={this.state.filtered}
|
||||
// Callbacks
|
||||
onSortedChange={sorted => this.setState({ sorted })}
|
||||
onPageChange={page => this.setState({ page })}
|
||||
onPageSizeChange={(pageSize, page) =>
|
||||
this.setState({ page, pageSize })}
|
||||
onExpandedChange={expanded => this.setState({ expanded })}
|
||||
onResizedChange={resized => this.setState({ resized })}
|
||||
onFilteredChange={filtered => this.setState({ filtered })}
|
||||
/>
|
||||
<br />
|
||||
<Tips />
|
||||
<Logo />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
render(<App />, document.getElementById("root"));
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "react-table-controlled-table",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"keywords": [],
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"react-table": "6.5.3",
|
||||
"react-dom": "15.5.3",
|
||||
"react": "15.5.3",
|
||||
"namor": "1.0.1"
|
||||
}
|
||||
}
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
Executable
+1863
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user