mirror of
https://github.com/gosticks/react-table.git
synced 2026-08-19 16:30:21 +00:00
Compare commits
164
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
428382c17c | ||
|
|
ad3ce36930 | ||
|
|
7c08467ddb | ||
|
|
34d8b77210 | ||
|
|
e949994e9b | ||
|
|
41647dfd35 | ||
|
|
e73199a04d | ||
|
|
0f695e7321 | ||
|
|
354d9bed14 | ||
|
|
d51aac11f3 | ||
|
|
d7cabd9e06 | ||
|
|
4eb430a0cb | ||
|
|
d2acfc4235 | ||
|
|
d0a9b97ed0 | ||
|
|
294193376d | ||
|
|
683bc20b8c | ||
|
|
0db7980add | ||
|
|
2c39bd89e2 | ||
|
|
61e65e84d3 | ||
|
|
e935d349e7 | ||
|
|
60d8244f58 | ||
|
|
e5c2d6ba84 | ||
|
|
689db0755f | ||
|
|
5e875aa6e2 | ||
|
|
73627b8dcb | ||
|
|
813d152b0a | ||
|
|
64b64f7a60 | ||
|
|
581c174301 | ||
|
|
2deb526378 | ||
|
|
aad37b84e5 | ||
|
|
5dfb08c615 | ||
|
|
5dd628144c | ||
|
|
0d0ce01544 | ||
|
|
afa21b0ad4 | ||
|
|
f42300d9e2 | ||
|
|
920420e330 | ||
|
|
6482869e8a | ||
|
|
42b41d1260 | ||
|
|
3aa016e056 | ||
|
|
bfcc08e7eb | ||
|
|
512f615988 | ||
|
|
63754a58dd | ||
|
|
4a483214ff | ||
|
|
b2af02407b | ||
|
|
b9f7bda223 | ||
|
|
acdb28df60 | ||
|
|
34be17b093 | ||
|
|
544c30b358 | ||
|
|
343e76ce65 | ||
|
|
23c9ad23fa | ||
|
|
9e1a3bfe99 | ||
|
|
6d4a733a88 | ||
|
|
c740a0c7af | ||
|
|
48d6fcd60d | ||
|
|
10b84faa29 | ||
|
|
292bbea1bf | ||
|
|
2a72667ec1 | ||
|
|
c92f3fb855 | ||
|
|
fe1c9b4b11 | ||
|
|
e28fa775f2 | ||
|
|
d9b2a9dc54 | ||
|
|
73ed7efbe6 | ||
|
|
7498059e98 | ||
|
|
a52a2e1265 | ||
|
|
facb216f5c | ||
|
|
b1a31b8176 | ||
|
|
5949932e77 | ||
|
|
f330b795dc | ||
|
|
07625844fd | ||
|
|
6c2df78b20 | ||
|
|
917cfcc910 | ||
|
|
b161d6d47b | ||
|
|
a3c0d22dd6 | ||
|
|
da82358d14 | ||
|
|
7eabe4b5cc | ||
|
|
083e81dc81 | ||
|
|
53f379f789 | ||
|
|
2bf99aaea0 | ||
|
|
164b3d6b7e | ||
|
|
2f14310808 | ||
|
|
32ca5a240b | ||
|
|
98b3161b2d | ||
|
|
4f8f7cd118 | ||
|
|
074211003a | ||
|
|
1eb492694a | ||
|
|
5ab8842ccf | ||
|
|
6b11d48b43 | ||
|
|
14ff3ef6c5 | ||
|
|
fce2ebe763 | ||
|
|
475c0a0637 | ||
|
|
af58d06a1e | ||
|
|
42ad10a7d8 | ||
|
|
812b416367 | ||
|
|
c984796190 | ||
|
|
05d946ecfb | ||
|
|
49bdf95205 | ||
|
|
677dcdc250 | ||
|
|
7dc9b85165 | ||
|
|
21826a93e0 | ||
|
|
e62fc0c535 | ||
|
|
b989a8fa76 | ||
|
|
b1b71103c4 | ||
|
|
8f5fc11905 | ||
|
|
29c7cb3483 | ||
|
|
dd3b50cc17 | ||
|
|
2eb5fa9c1b | ||
|
|
6db990250e | ||
|
|
5f9950339b | ||
|
|
5486293677 | ||
|
|
703f83e6f4 | ||
|
|
140ca06086 | ||
|
|
8277bfd4db | ||
|
|
7645107d3d | ||
|
|
8ea93b9fed | ||
|
|
6ebf3183a0 | ||
|
|
5778bc3dce | ||
|
|
3b4a120ff5 | ||
|
|
2a0dc6778d | ||
|
|
8e310bd0e6 | ||
|
|
c7b146cf1e | ||
|
|
68606bb77c | ||
|
|
c880da6c3d | ||
|
|
9d97ac29a6 | ||
|
|
b018ed64ed | ||
|
|
71e7c542c4 | ||
|
|
e3223ed1b9 | ||
|
|
35d36db4c9 | ||
|
|
649259ba77 | ||
|
|
017ad2884e | ||
|
|
59c4558dc8 | ||
|
|
9baf3c275b | ||
|
|
7db50b0f21 | ||
|
|
ac1eeb4756 | ||
|
|
1d8ffb18f7 | ||
|
|
ed2fe54371 | ||
|
|
4a93e0f306 | ||
|
|
66cc06365c | ||
|
|
ede79d8b38 | ||
|
|
d43e4be548 | ||
|
|
58c28b574a | ||
|
|
45e5bed468 | ||
|
|
94a9b49187 | ||
|
|
aa6d859ce9 | ||
|
|
555fc828f5 | ||
|
|
3e789ffe83 | ||
|
|
b430f8e702 | ||
|
|
cef55d58f3 | ||
|
|
d18f1ba4d8 | ||
|
|
73344a47e4 | ||
|
|
bf82d3c656 | ||
|
|
63d54b1e87 | ||
|
|
6e853a3cff | ||
|
|
30a40aa0a2 | ||
|
|
a8e1b33284 | ||
|
|
67ce7d8f0b | ||
|
|
4e08fd500e | ||
|
|
cb59098685 | ||
|
|
d7b6e69c5f | ||
|
|
b69e300b00 | ||
|
|
04e1309ed7 | ||
|
|
4ed950d990 | ||
|
|
fdc3b22e54 | ||
|
|
4e013632dd | ||
|
|
80ceeee83f |
@@ -11,7 +11,8 @@
|
||||
],
|
||||
"env": {
|
||||
"test": {
|
||||
"presets": ["@babel/preset-env", "@babel/react"]
|
||||
"presets": ["@babel/preset-env", "@babel/react"],
|
||||
"plugins": ["@babel/plugin-transform-runtime"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,18 +3,13 @@ name: Bug report
|
||||
about: Create a report to help us improve
|
||||
---
|
||||
|
||||
# Using v6?
|
||||
|
||||
v6 is now considered feature complete to its current abilities and limitations. We are not actively working to fix any issues for v6 any more. We will, however, merge any non-breaking pull requests submitted to fix anything in v6.
|
||||
|
||||
# Using v7?
|
||||
|
||||
Thanks for using the beta version of React Table v7! We're very excited about it.
|
||||
|
||||
**Describe the bug**
|
||||
**Describe the bug (required)**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
**Provide an example via Codesandbox! (required)**
|
||||
Use a new [react-table codesandbox](https://codesandbox.io/s/m5lxzzpz69) to reproduce the issue.
|
||||
|
||||
**Steps To Reproduce (required)**
|
||||
Steps to reproduce the behavior:
|
||||
|
||||
1. Go to '...'
|
||||
@@ -22,12 +17,9 @@ Steps to reproduce the behavior:
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
**Expected behavior (Recommended)**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Codesandbox!**
|
||||
Use a new [react-table codesandbox](https://codesandbox.io/s/m5lxzzpz69) to reproduce the issue.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
|
||||
---
|
||||
|
||||
# STOP
|
||||
|
||||
We do not track feature requests through Github. Please use the [Spectrum React Table Forum](https://spectrum.chat/react-table) to talk about new ideas and features.
|
||||
We do not track feature requests through Github. Please use [Github Discussions](https://github.com/tannerlinsley/react-table/discussions) to talk about new ideas and features.
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
---
|
||||
name: Questions, Support & Help
|
||||
about: Looking for help? Need a question answered?
|
||||
|
||||
---
|
||||
|
||||
# STOP
|
||||
|
||||
We do not use Github to track general support. Please use our public support forum at https://spectrum.chat/react-table.
|
||||
We do not use Github to track general support. Please use our public support forum at https://github.com/tannerlinsley/react-table/discussions.
|
||||
|
||||
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,27 +0,0 @@
|
||||
name: CI
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
jobs:
|
||||
build-and-test:
|
||||
name: '${{ matrix.platform }}: node.js ${{ matrix.node-version }}'
|
||||
strategy:
|
||||
matrix:
|
||||
platform: [ubuntu-latest, windows-latest, macos-latest]
|
||||
node-version: [10, 12]
|
||||
runs-on: ${{ matrix.platform }}
|
||||
env:
|
||||
CI: true
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@master
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@master
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Build and test
|
||||
run: |
|
||||
yarn install
|
||||
yarn test
|
||||
@@ -1,3 +0,0 @@
|
||||
size-files:
|
||||
- sizes-cjs.json
|
||||
- sizes-es.json
|
||||
@@ -0,0 +1,15 @@
|
||||
name: Compressed Size
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2-beta
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- uses: preactjs/compressed-size-action@v1
|
||||
with:
|
||||
repo-token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
@@ -0,0 +1,26 @@
|
||||
name: react-table tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: 'node ${{ matrix.node }} ${{ matrix.os }} '
|
||||
runs-on: '${{ matrix.os }}'
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
node: [12, 10]
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
- uses: actions/checkout@v2-beta
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- run: npm i -g yarn
|
||||
- run: yarn --frozen-lockfile
|
||||
- run: yarn test:ci
|
||||
@@ -10,4 +10,7 @@ react-table.css
|
||||
.idea
|
||||
.DS_Store
|
||||
.history
|
||||
.vscode
|
||||
package-lock.json
|
||||
coverage
|
||||
.docz
|
||||
@@ -1,6 +0,0 @@
|
||||
module.exports = {
|
||||
hooks: {
|
||||
'pre-commit': 'lint-staged && yarn test:ci',
|
||||
// 'commit-msg': 'commitlint -E HUSKY_GIT_PARAMS',
|
||||
},
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
{
|
||||
"dist/index.js": {
|
||||
"bundled": 107213,
|
||||
"minified": 49659,
|
||||
"gzipped": 13264
|
||||
},
|
||||
"dist/index.es.js": {
|
||||
"bundled": 106302,
|
||||
"minified": 48847,
|
||||
"gzipped": 13099,
|
||||
"treeshaked": {
|
||||
"rollup": {
|
||||
"code": 80,
|
||||
"import_statements": 21
|
||||
},
|
||||
"webpack": {
|
||||
"code": 8249
|
||||
}
|
||||
}
|
||||
},
|
||||
"dist\\index.js": {
|
||||
"bundled": 105386,
|
||||
"minified": 49565,
|
||||
"gzipped": 13008
|
||||
},
|
||||
"dist\\index.es.js": {
|
||||
"bundled": 104543,
|
||||
"minified": 48815,
|
||||
"gzipped": 12856,
|
||||
"treeshaked": {
|
||||
"rollup": {
|
||||
"code": 80,
|
||||
"import_statements": 21
|
||||
},
|
||||
"webpack": {
|
||||
"code": 8444
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
language: node_js
|
||||
|
||||
node_js:
|
||||
- 10
|
||||
- 12
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
- windows
|
||||
|
||||
env:
|
||||
global:
|
||||
- YARN_GPG=no
|
||||
|
||||
cache: yarn
|
||||
|
||||
script: yarn test
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"workbench.colorCustomizations": {
|
||||
"titleBar.inactiveBackground": "#ff4154", // change this color!
|
||||
"titleBar.activeBackground": "#ff4154", // change this color!
|
||||
"titleBar.inactiveForeground": "#ffffff", // change this color!
|
||||
"titleBar.activeForeground": "#ffffff" // change this color!
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,94 @@
|
||||
---
|
||||
name: Changelog
|
||||
route: /changelog
|
||||
---
|
||||
|
||||
# React Table Changelog
|
||||
|
||||
## 7.0.1 🎉
|
||||
|
||||
- Added the `value` property to cell renderers so that destructurin the value from the `cell` property is now not necessary. This should help with people migrating from v6 and also just to cut down on noise in cell renderers
|
||||
- Fixed an issue where rollup would not build correctly
|
||||
- Fixed an issue where a page index of `-1` would result in an error
|
||||
|
||||
## 7.0.0 🎉
|
||||
|
||||
- Fixed an issue where page options array could be empty
|
||||
- Fixed an issue where duplicate columns would be silently deduped. There is now a warning when duplicate columns are found based on their IDs
|
||||
- Moved some functions around so they will get treeshaked with their respective plugins that use them.
|
||||
- Fixed an issue where filters, sorting, or grouping changes would not reset pagination
|
||||
- Added table and column level options for disabling global filters
|
||||
- Fixed an issue where row selection was not deselecting rows
|
||||
- Fixed an issue where flex table rendering was not giving the table a minimum width with necessary
|
||||
- Fixed an issue where row selection would not work when using other row-transformative plugins like filters or grouping
|
||||
- Fixed an issue where header groups were not memoized correctly
|
||||
|
||||
## 7.0.0-rc.16
|
||||
|
||||
- Moved away from snapshot tests. No more testing implementation details.
|
||||
- Added `visibleColumns` and `visibleColumnsDeps` hooks to manipulate columns after all data is processed. Further visibility processing may result in these columns not being visible, such as `hiddenColumn` state
|
||||
- The `useRows` hook has been deprecated due to its dangerous nature 💀
|
||||
- Added the `instance.rowsById` object
|
||||
- Renamed `instance.flatColumns` to `instance.allColumns` which now accumulates ALL columns created for the table, visible or not.
|
||||
- Added the `instance.visibleColumns` object
|
||||
- Fix an issue where `useAsyncDebounce` would crash when passed arguments
|
||||
- Started development on the `usePivotColumns` plugin, which can be tested currently using the `_UNSTABLE_usePivotColumns` export.
|
||||
- Renamed `cell.isRepeatedValue` to `cell.isPlaceholder`
|
||||
- Removed `useConsumeHookGetter` as it was inefficient most of the time and noisy
|
||||
- All hooks are now "consumed" right after main plugin functions are run. This means that any attempt to add a plugin after that will result in a runtime error (for good reason, since using hook points should not be a conditional or async operation)
|
||||
- Added `instance.getHooks` for getting the list of hooks that was captured after plugins are run
|
||||
- Normalized all "toggle" actions to use an optional `value` property to set the value instead of toggle. Previously properties like `selected`, `groupBy`, etc. were used, but not any more!
|
||||
- Undocument `instance.dispatch`. Both plugins and users should be interacting with the table via methods assigned to the instance and other structures on the table. This should both reduce the surface API that React Table needs to expose and also the amount of documentation that is needed to understand how to use the API.
|
||||
- `useRowState`'s `initialRowStateAccessor` and `initialCellStateAccessor` options now have a default of `row => ({})` and `cell => ({})` respectively.
|
||||
- Removed the concept of complex aggregations (eg. `column.aggregate = ['sum', 'count']`). Instead, a better aggregation function signature is now used to allow for leaf node aggregation when needed.
|
||||
- Added the `column.aggregateValue` option which allows resolving (or pre-aggregating) a cell's value before it is grouped and aggregated across rows. This is useful for cell values that are not primitive, eg. an array of values that you may want to unique and count before summing that count across your groupings
|
||||
- The function signature for aggregation functions has changed to be `(leafValues, aggregatedValues) => aggregatedValue` where `leafValues` is a flat array containing all leaf rows currently grouped at the aggregation level and `aggregatedValues` is an array containing the aggregated values from the immediate child sub rows. Each has purpose in the types of aggregations they power where optimizations are made for either accuracy or performance.
|
||||
- Fixed an issue where `setGlobalFilter` was not a stable callback
|
||||
- Added a Bootstrap UI example
|
||||
- Added fixed with column support for useFlexLayout
|
||||
- Fixed an issue where `manualGlobalFilter` was not resetting pagination properly
|
||||
- Fixed an issue where `useGlobalFilter` could be placed after `usePagination`
|
||||
- Added the sort order direction as a parameter to the sortMethod function
|
||||
- Fixed an issue where user filter types were not being referenced correctly
|
||||
- Renamed the `row.getExpandedToggleProps` to `row.getToggleRowExpandedProps`
|
||||
- Renamed the `row.toggleExpanded` method to `row.toggleRowExpanded`
|
||||
- Added the `instance.toggleRowExpanded` and `instance.toggleAllRowsExpanded` methods
|
||||
- Added the `instance.getToggleAllRowsExpandedProps` prop getter
|
||||
- Added the `instance.filteredRowsById` property
|
||||
- Added the `instance.preFilteredRowsById` property
|
||||
- useFilters now properly updates the `instance.rowsById` property
|
||||
- Added the `instance.globalFilteredRowsById` property
|
||||
- Added the `instance.preGlobalFilteredRowsById` property
|
||||
- useGlobalFilter now properly updates the `instance.rowsById` property
|
||||
- Added the `instance.nonGroupedFlatRows` property
|
||||
- Added the `instance.nonGroupedRowsById` property
|
||||
- Added the `instance.onlyGroupedFlatRows` property
|
||||
- Added the `instance.onlyGroupedRowsById` property
|
||||
- Improved the api around ensuring plugin ordering
|
||||
- Added more plugin order rules to avoid strange plugin integration results
|
||||
|
||||
## 7.0.0-rc.15
|
||||
|
||||
- Added `useGlobalFilter` hook for performing table-wide filtering
|
||||
- Filter function signature has changed to supply an array of column IDs (to support both the tranditional single column style and the new multi-column search style introduced with `useGlobalFilter`).
|
||||
- Removed the `column` parameter from the filter function signature as it was unused and no longer made sense with the array of IDs change above.
|
||||
- Updated the `filtering` example to use a global filter in addition to the column filters
|
||||
|
||||
## 7.0.0-rc.14
|
||||
|
||||
- Changed the function signature for all propGetter hooks to accept a single object of named meta properties instead of a variable length of meta arguments. The user props object has also been added as a property to all prop getters. For example, `hooks.getRowProps.push((props, instance, row) => [...])` is now written `hooks.getRowProps.push((props, { instance, row, userProps }) => [...])`
|
||||
- Changed the function signature for all reduceHooks accept a single object of named meta properties instead of a variable length of meta arguments. For example, `hooks.flatColumns.push((flatColumns, instance) => flatColumns)` is now written `hooks.flatColumns.push((flatColumns, { instance }) => flatColumns)`
|
||||
- Changed the function signature for all loopHooks accept a single object of named meta properties instead of a variable length of meta arguments. For example, `hooks.prepareRow.push((row, instance) => void)` is now written `hooks.prepareRow.push((row, { instance }) => void)`
|
||||
|
||||
## 7.0.0-rc.13
|
||||
|
||||
- Added the `useControlledState` hook for plugins to manipulate the final state of the table similar to how users can
|
||||
- Fixed an issue where column hiding wasn't working properly.
|
||||
|
||||
## 7.0.0-rc.12
|
||||
|
||||
- Fixed an issue where removing a grouped column would result in a crash
|
||||
|
||||
## 7.0.0-rc.11
|
||||
|
||||
- Fixed an issue where plugins using the `columns` hook were not getting decorated properly
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
---
|
||||
name: Code of Conduct
|
||||
route: /code-of-conduct
|
||||
---
|
||||
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
+8
-3
@@ -1,12 +1,17 @@
|
||||
---
|
||||
name: Contributing
|
||||
route: /contributing
|
||||
---
|
||||
|
||||
# Contributing
|
||||
|
||||
## Questions
|
||||
|
||||
If you have questions about implementation details, help or support, then please use our dedicated community forum at [Spectrum.chat/react-table](https://spectrum.chat/react-table) **PLEASE NOTE:** If you choose to instead open an issue for your question, your issue will be immediately closed and redirected to the forum.
|
||||
If you have questions about implementation details, help or support, then please use our dedicated community forum at [Github Discussions](https://github.com/tannerlinsley/react-table/discussions) **PLEASE NOTE:** If you choose to instead open an issue for your question, your issue will be immediately closed and redirected to the forum.
|
||||
|
||||
## Reporting Issues
|
||||
|
||||
If you have found what you think is a bug, please [file an issue](https://github.com/tannerlinsley/react-table/issues/new). **PLEASE NOTE:** Issues that are identified as implementation questions or non-issues will be immediately closed and redirected to [Spectrum.chat/react-table](https://spectrum.chat/react-table)
|
||||
If you have found what you think is a bug, please [file an issue](https://github.com/tannerlinsley/react-table/issues/new). **PLEASE NOTE:** Issues that are identified as implementation questions or non-issues will be immediately closed and redirected to [Github Discussions](https://github.com/tannerlinsley/react-table/discussions)
|
||||
|
||||
## Suggesting new features
|
||||
|
||||
@@ -23,6 +28,6 @@ If you have been assigned to fix an issue or develop a new feature, please follo
|
||||
- Implement your changes and tests to files in the `src/` directory and corresponding test files
|
||||
- To run examples, follow their individual directions. Usually this is just `$ yarn && yarn start`.
|
||||
- To run examples using your local build, link to the local `react-table` by running `$ yarn link react-table` from the example's directory
|
||||
- Document your changes in the root `README.md`
|
||||
- Document your changes in the appropriate doc page
|
||||
- To stage a commit, run `yarn commit`
|
||||
- Submit PR for review
|
||||
|
||||
@@ -1,19 +1,29 @@
|
||||
---
|
||||
name: Getting Started
|
||||
route: /
|
||||
---
|
||||
|
||||

|
||||
|
||||
<img src='https://github.com/tannerlinsley/react-table/raw/master/media/logo.png' width='300'/>
|
||||
|
||||
Hooks for building **lightweight, fast and extendable datagrids** for React
|
||||
|
||||
[](https://twitter.com/intent/tweet?button_hashtag=TanStack)
|
||||
|
||||
<!-- [](https://github.com/tannerlinsley/react-table/actions) -->
|
||||
|
||||
[](https://travis-ci.org/tannerlinsley/react-table)
|
||||
[](https://bundlephobia.com/result?p=react-table@next)
|
||||
[](https://npmjs.com/package/react-table)
|
||||
[](https://spectrum.chat/react-table)
|
||||
[](https://github.com/tannerlinsley/react-table)
|
||||
[](https://twitter.com/tannerlinsley)
|
||||
<a href="https://twitter.com/intent/tweet?button_hashtag=TanStack" target="\_parent">
|
||||
<img alt="#TanStack" src="https://img.shields.io/twitter/url?color=%2308a0e9&label=%23TanStack&style=social&url=https%3A%2F%2Ftwitter.com%2Fintent%2Ftweet%3Fbutton_hashtag%3DTanStack" />
|
||||
</a><a href="https://github.com/tannerlinsley/react-table/actions?table=workflow%3A%22react-table+tests%22">
|
||||
<img src="https://github.com/tannerlinsley/react-table/workflows/react-table%20tests/badge.svg" />
|
||||
</a><a href="https://npmjs.com/package/react-table" target="\_parent">
|
||||
<img alt="" src="https://img.shields.io/npm/dm/react-table.svg" />
|
||||
</a><a href="https://bundlephobia.com/result?p=react-table@latest" target="\_parent">
|
||||
<img alt="" src="https://badgen.net/bundlephobia/minzip/react-table@latest" />
|
||||
</a><a href="https://github.com/tannerlinsley/react-table/discussions">
|
||||
<img alt="Join the discussion on Github" src="https://img.shields.io/badge/Github%20Discussions%20%26%20Support-Chat%20now!-blue" />
|
||||
</a><a href="https://github.com/tannerlinsley/react-table" target="\_parent">
|
||||
<img alt="" src="https://img.shields.io/github/stars/tannerlinsley/react-table.svg?style=social&label=Star" />
|
||||
</a><a href="https://twitter.com/tannerlinsley" target="\_parent">
|
||||
<img alt="" src="https://img.shields.io/twitter/follow/tannerlinsley.svg?style=social&label=Follow" />
|
||||
</a>
|
||||
|
||||
Enjoy this library? Try them all! [React Query](https://github.com/tannerlinsley/react-query), [React Form](https://github.com/tannerlinsley/react-form), [React Charts](https://github.com/tannerlinsley/react-charts)
|
||||
|
||||
@@ -21,7 +31,7 @@ Enjoy this library? Try them all! [React Query](https://github.com/tannerlinsley
|
||||
|
||||
## Features
|
||||
|
||||
- Lightweight (5kb - 12kb+ depending on features used and tree-shaking)
|
||||
- Lightweight (5kb - 14kb+ depending on features used and tree-shaking)
|
||||
- Headless (100% customizable, Bring-your-own-UI)
|
||||
- Auto out of the box, fully controllable API
|
||||
- Sorting (Multi and Stable)
|
||||
@@ -38,14 +48,7 @@ Enjoy this library? Try them all! [React Query](https://github.com/tannerlinsley
|
||||
|
||||
## Documentation
|
||||
|
||||
- [Installation](./docs/installation.md) - Walk through how to install React Table
|
||||
- [Concepts](./docs/concepts.md) - Read how React Table works and how you can use it better
|
||||
- [Examples](./docs/examples.md) - Experience and learn from some examples and guides of how to use React Table and implement common patterns
|
||||
- [API](./docs/api/README.md) - Get to know React Table's API
|
||||
- [FAQ](./docs/faq.md) - Learn how to use React Table for specific challenges and tasks
|
||||
- [Previous Versions](#previous-versions)
|
||||
- [Contributing](./CONTRIBUTING.md) - Become familiar with how to contribute back to React Table
|
||||
- [Code of Conduct](./CODE_OF_CONDUCT.md) - Be a good React Table citizen by following these repository rules
|
||||
Visit our new documentation site at https://react-table.js.org
|
||||
|
||||
## Sponsors
|
||||
|
||||
@@ -56,7 +59,7 @@ This library is being built and maintained by me, @tannerlinsley and I am always
|
||||
<tr>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://github.com/sponsors/tannerlinsley" target="_blank">
|
||||
<img width='150' src="https://raw.githubusercontent.com/tannerlinsley/files/master/images/patreon/diamond.png">
|
||||
<img width='150' src="https://raw.githubusercontent.com/tannerlinsley/files/master/images/patreon/diamond.png" />
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
@@ -73,17 +76,12 @@ This library is being built and maintained by me, @tannerlinsley and I am always
|
||||
<tr>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://github.com/sponsors/tannerlinsley/" target="_blank">
|
||||
<img width='150' src="https://raw.githubusercontent.com/tannerlinsley/files/master/images/patreon/platinum.png">
|
||||
<img width='150' src="https://raw.githubusercontent.com/tannerlinsley/files/master/images/patreon/platinum.png" />
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://tryretool.com/?utm_source=sponsor&utm_campaign=react_table" target="_blank">
|
||||
<img width='225' src="https://raw.githubusercontent.com/tannerlinsley/files/master/images/patreon/sponsor-retool.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="http://bjntech.com/index.html?utm_campaign=react_table" target="_blank">
|
||||
<img width='225' src="https://raw.githubusercontent.com/tannerlinsley/files/master/images/patreon/sponsor-bjn.png">
|
||||
<img width='300' src="https://raw.githubusercontent.com/tannerlinsley/files/master/images/patreon/sponsor-retool.png" />
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
@@ -100,17 +98,12 @@ This library is being built and maintained by me, @tannerlinsley and I am always
|
||||
<tr>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://github.com/sponsors/tannerlinsley/" target="_blank">
|
||||
<img width='150' src="https://raw.githubusercontent.com/tannerlinsley/files/master/images/patreon/gold.png">
|
||||
<img width='150' src="https://raw.githubusercontent.com/tannerlinsley/files/master/images/patreon/gold.png" />
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://nozzle.io" target="_blank">
|
||||
<img width='225' src="https://nozzle.io/img/logo-blue.png">
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://zappi.io/web/" target="_blank">
|
||||
<img width='225' src="https://raw.githubusercontent.com/tannerlinsley/files/master/images/patreon/sponsor-zappi.png">
|
||||
<img width='225' src="https://nozzle.io/img/logo-blue.png" />
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
@@ -127,7 +120,17 @@ This library is being built and maintained by me, @tannerlinsley and I am always
|
||||
<tr>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://github.com/sponsors/tannerlinsley/" target="_blank">
|
||||
<img width='150' src="https://raw.githubusercontent.com/tannerlinsley/files/master/images/patreon/silver.png">
|
||||
<img width='150' src="https://raw.githubusercontent.com/tannerlinsley/files/master/images/patreon/silver.png" />
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://tripwire.com" target="_blank">
|
||||
<img width='170' src="https://www.tripwire.com/-/media/tripwiredotcom/icons/tripwire-logo-footer.svg" />
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
<a href="https://www.fream.pl/" target="_blank">
|
||||
<img width='170' src="https://www.fream.pl/wp-content/uploads/2017/08/logo.png" />
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" valign="middle">
|
||||
@@ -150,7 +153,8 @@ This library is being built and maintained by me, @tannerlinsley and I am always
|
||||
<td>
|
||||
<ul>
|
||||
<li>Jon Eickmeier</li>
|
||||
<li><a href="https://github.com/Shah-Sahab">Syed Hussain<a></li>
|
||||
<li><a href="https://github.com/rhefner">Richard Hefner (@rhefner)</a></li>
|
||||
<li><a href="https://gitHub.com/snorkypie"> Steeve Lennmark (@snorkypie)</a></li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
@@ -172,18 +176,19 @@ This library is being built and maintained by me, @tannerlinsley and I am always
|
||||
</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li>Sortmy.games</li>
|
||||
<li>Hugo Meissner</li>
|
||||
<li>Benoit Leger-Derville</li>
|
||||
<li>Thomas Funk</li>
|
||||
<li>Dan Houle</li>
|
||||
<li>David Pickut</li>
|
||||
<li>Jordan Soltman</li>
|
||||
<li>Robert Tajnšek</li>
|
||||
<li>Pekka Tapani</li>
|
||||
<li>Eric Lanehart (@pushred)</li>
|
||||
<li>Anish P Patel (@anishpatelyaadada)</li>
|
||||
<li>Alin Porumb (@alinporumb)</li>
|
||||
<li>Hugo Meissner</li>
|
||||
<li>Benoit Leger-Derville</li>
|
||||
<li>Thomas Funk</li>
|
||||
<li>David Pickut</li>
|
||||
<li>Jordan Soltman</li>
|
||||
<li>Robert Tajnšek</li>
|
||||
<li>Eric Lanehart (@pushred)</li>
|
||||
<li>Anish P Patel (@anishpatelyaadada)</li>
|
||||
<li>Alin Porumb (@alinporumb)</li>
|
||||
<li>Janus Reith (@janus-reith)</li>
|
||||
<li>Timo Mämecke (@timomeh)</li>
|
||||
<li>Tyler Reiff (@reiff12)</li>
|
||||
<li>Matt Stvartak (@mattstvartak)</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
module.exports = { extends: ['@commitlint/config-conventional'] }
|
||||
@@ -13,5 +13,5 @@ module.exports = {
|
||||
rootDir: path.resolve(__dirname, '../../'),
|
||||
roots: ['<rootDir>/src', __dirname],
|
||||
transformIgnorePatterns: ['node_modules'],
|
||||
snapshotSerializers: [require.resolve('snapshot-diff/serializer.js')],
|
||||
collectCoverageFrom: ['src/**/*.js', '!**/*.test.js'],
|
||||
}
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
import '@testing-library/jest-dom/extend-expect'
|
||||
import 'snapshot-diff/extend-expect'
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
To get started with React Table, [click here](../README.md), or select a specific document from this directory.
|
||||
+23
-16
@@ -1,3 +1,9 @@
|
||||
---
|
||||
name: Overview
|
||||
route: /api
|
||||
menu: API
|
||||
---
|
||||
|
||||
# API
|
||||
|
||||
React Table uses React Hooks both internally and externally for almost all of its configuration and lifecycle management. Naturally, this is what allows React Table to be headless and lightweight while still having a concise and simple API.
|
||||
@@ -5,23 +11,24 @@ React Table uses React Hooks both internally and externally for almost all of it
|
||||
React Table is essentially a compatible collection of **custom React hooks**:
|
||||
|
||||
- The primary React Table hook
|
||||
- [`useTable`](./useTable.md)
|
||||
- [`useTable`](./api/useTable)
|
||||
- Plugin Hooks
|
||||
- Core Plugin Hooks
|
||||
- [`useGroupBy`](./useGroupBy.md)
|
||||
- [`useFilters`](./useFilters.md)
|
||||
- [`useSortBy`](./useSortBy.md)
|
||||
- [`useExpanded`](./useExpanded.md)
|
||||
- [`usePagination`](./usePagination.md)
|
||||
- [`useTokenPagination` (Coming Soon)](./useTokenPagination.md)
|
||||
- [`useRowSelect`](./useRowSelect.md)
|
||||
- [`useRowState`](./useRowState.md)
|
||||
- [`useColumnOrder`](./useColumnOrder.md)
|
||||
- [`useGroupBy`](./api/useGroupBy)
|
||||
- [`useFilters`](./api/useFilters)
|
||||
- [`useGlobalFilter`](./api/useGlobalFilter)
|
||||
- [`useSortBy`](./api/useSortBy)
|
||||
- [`useExpanded`](./api/useExpanded)
|
||||
- [`usePagination`](./api/usePagination)
|
||||
- [`useTokenPagination` (Coming Soon)](./api/useTokenPagination)
|
||||
- [`useRowSelect`](./api/useRowSelect)
|
||||
- [`useRowState`](./api/useRowState)
|
||||
- [`useColumnOrder`](./api/useColumnOrder)
|
||||
- Layout Hooks
|
||||
- [`useBlockLayout`](./useBlockLayout.md)
|
||||
- [`useAbsoluteLayout`](./useAbsoluteLayout.md)
|
||||
- [`useFlexLayout`](./useFlexLayout.md)
|
||||
- [`useResizeColumns`](./useResizeColumns.md)
|
||||
- [`useBlockLayout`](./api/useBlockLayout)
|
||||
- [`useAbsoluteLayout`](./api/useAbsoluteLayout)
|
||||
- [`useFlexLayout`](./api/useFlexLayout)
|
||||
- [`useResizeColumns`](./api/useResizeColumns)
|
||||
- 3rd Party Plugin Hooks
|
||||
- Want your custom plugin hook listed here? [Submit a PR!](https://github.com/tannerlinsley/react-table/compare)
|
||||
|
||||
@@ -54,7 +61,7 @@ const instance = useTable(
|
||||
|
||||
This multi-stage process is the secret sauce that allows React Table plugin hooks to work together and compose nicely, while not stepping on each others toes.
|
||||
|
||||
To dive deeper into plugins, see Plugins](TODO) and the [Plugin Guide
|
||||
To dive deeper into plugins, see Plugins and the Plugin Guide
|
||||
|
||||
### Plugin Hook Order & Consistency
|
||||
|
||||
@@ -64,4 +71,4 @@ The order and usage of plugin hooks must follow The Laws of Hooks, just like any
|
||||
|
||||
### Option Memoization
|
||||
|
||||
React Table relies on memoization to determine when state and side effects should update or be calculated. This means that every option you pass to `useTable` should be memoized either via `React.useMemo` (for objects) or `React.useCallback` (for functions).
|
||||
React Table relies on memoization to determine when state and side effects should update or be calculated. This means that every option you pass to `useTable` should be memoized either via [`React.useMemo`](https://reactjs.org/docs/hooks-reference.html#usememo) (for objects) or [`React.useCallback`](https://reactjs.org/docs/hooks-reference.html#usecallback) (for functions).
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
name: useAbsoluteLayout
|
||||
route: /api/useAbsoluteLayout
|
||||
menu: API
|
||||
---
|
||||
|
||||
# `useAbsoluteLayout`
|
||||
|
||||
- Plugin Hook
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
name: useBlocklayout
|
||||
route: /api/useBlocklayout
|
||||
menu: API
|
||||
---
|
||||
|
||||
# `useBlocklayout`
|
||||
|
||||
- Plugin Hook
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
name: useColumnOrder
|
||||
route: /api/useColumnOrder
|
||||
menu: API
|
||||
---
|
||||
|
||||
# `useColumnOrder`
|
||||
|
||||
- Plugin Hook
|
||||
|
||||
+15
-2
@@ -1,3 +1,9 @@
|
||||
---
|
||||
name: useExpanded
|
||||
route: /api/useExpanded
|
||||
menu: API
|
||||
---
|
||||
|
||||
# `useExpanded`
|
||||
|
||||
- Plugin Hook
|
||||
@@ -33,7 +39,7 @@ The following options are supported via the main options object passed to `useTa
|
||||
- When `true`, the `expanded` state will automatically reset if any of the following conditions are met:
|
||||
- `data` is changed
|
||||
- To disable, set to `false`
|
||||
- For more information see the FAQ ["How do I stop my table state from automatically resetting when my data changes?"](../faq.md#how-do-i-stop-my-table-state-from-automatically-resetting-when-my-data-changes)
|
||||
- For more information see the FAQ ["How do I stop my table state from automatically resetting when my data changes?"](/faq#how-do-i-stop-my-table-state-from-automatically-resetting-when-my-data-changes)
|
||||
|
||||
### Instance Properties
|
||||
|
||||
@@ -41,6 +47,13 @@ The following properties are available on the table instance returned from `useT
|
||||
|
||||
- `rows: Array<Row>`
|
||||
- An array of **expanded** rows.
|
||||
- `toggleRowExpanded: Function(rowId, isExpanded?)`
|
||||
- A function to toggle whether a row is expanded or not. The `isExpanded` boolean is optional, otherwise it will be a true toggle action
|
||||
- `toggleAllRowsExpanded: Function(isExpanded?)`
|
||||
- A function to toggle whether all of the rows in the table are expanded or not. The `isExpanded` boolean is optional, otherwise it will be a true toggle action
|
||||
- `isAllRowsExpanded`
|
||||
- `getToggleAllRowsExpandedProps: Function(userProps) => props`
|
||||
- A prop getter function that returns all necessary props for an element to be clicked and toggle all of the rows expanded or not.
|
||||
|
||||
### Row Properties
|
||||
|
||||
@@ -48,7 +61,7 @@ The following additional properties are available on every `row` object returned
|
||||
|
||||
- `isExpanded: Bool`
|
||||
- If `true`, this row is in an expanded state.
|
||||
- `toggleExpanded: Function(?isExpanded: Bool) => void`
|
||||
- `toggleRowExpanded: Function(?isExpanded: Bool) => void`
|
||||
- This function will toggle the expanded state of a row between `true` and `false` or, if an `isExpanded` boolean is passed to the function, it will be set as the new `isExpanded` value.
|
||||
- Rows with a hard-coded `manualExpandedKey` (defaults to `expanded`) set to `true` are not affected by this function or the internal expanded state.
|
||||
|
||||
|
||||
+11
-3
@@ -1,9 +1,15 @@
|
||||
---
|
||||
name: useFilters
|
||||
route: /api/useFilters
|
||||
menu: API
|
||||
---
|
||||
|
||||
# `useFilters`
|
||||
|
||||
- Plugin Hook
|
||||
- Optional
|
||||
|
||||
`useFilters` is the hook that implements **row filtering**.
|
||||
`useFilters` is the hook that implements **row filtering** and can even be used in conjunction with `useGlobalFilter`. It's also important to note that this hook can be used either **before or after** `useGlobalFilter`, depending on the performance characteristics you want to code for.
|
||||
|
||||
### Table Options
|
||||
|
||||
@@ -30,7 +36,7 @@ The following options are supported via the main options object passed to `useTa
|
||||
- When `true`, the `filters` state will automatically reset if any of the following conditions are met:
|
||||
- `data` is changed
|
||||
- To disable, set to `false`
|
||||
- For more information see the FAQ ["How do I stop my table state from automatically resetting when my data changes?"](./faq#how-do-i-stop-my-table-state-from-automatically-resetting-when-my-data-changes)
|
||||
- For more information see the FAQ ["How do I stop my table state from automatically resetting when my data changes?"](../faq#how-do-i-stop-my-table-state-from-automatically-resetting-when-my-data-changes)
|
||||
|
||||
### Column Options
|
||||
|
||||
@@ -68,8 +74,10 @@ The following values are provided to the table `instance`:
|
||||
- Among many other use-cases, these rows are directly useful for building option lists in filters, since the resulting filtered `rows` do not contain every possible option.
|
||||
- `setFilter: Function(columnId, filterValue) => void`
|
||||
- An instance-level function used to update the filter value for a specific column.
|
||||
- `setAllFilters: Function(filtersObject) => void`
|
||||
- `setAllFilters: Function(filtersObjectArray) => void`
|
||||
- An instance-level function used to update the values for **all** filters on the table, all at once.
|
||||
- filtersObjectArray is an array of objects with id and value keys. Example: `[{ id: 'columnAccessor', value: 'valueToFilter' }]`
|
||||
- Note: You must call setAllFilters with an array, even if that array is empty. eg: `setAllFilters([])`.
|
||||
|
||||
### Column Properties
|
||||
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
name: useFlexLayout
|
||||
route: /api/useFlexLayout
|
||||
menu: API
|
||||
---
|
||||
|
||||
# `useFlexLayout`
|
||||
|
||||
- Plugin Hook
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
---
|
||||
name: useGlobalFilter
|
||||
route: /api/useGlobalFilter
|
||||
menu: API
|
||||
---
|
||||
|
||||
# `useGlobalFilter`
|
||||
|
||||
- Plugin Hook
|
||||
- Optional
|
||||
|
||||
`useGlobalFilter` is the hook that implements **global row filtering** and can even be used in conjunction with `useFilters`. It's also important to note that this hook can be used either **before or after** `useFilters`, depending on the performance characteristics you want to code for.
|
||||
|
||||
### Table Options
|
||||
|
||||
The following options are supported via the main options object passed to `useTable(options)`
|
||||
|
||||
- `initialState.globalFilter: any`
|
||||
- Must be **memoized**
|
||||
- An array of objects containing columnId's and their corresponding filter values. This information is stored in state since the table is allowed to manipulate the filter through user interaction.
|
||||
- `globalFilter: String | Function`
|
||||
- Optional
|
||||
- Defaults to `text`
|
||||
- The resolved function from the this string/function will be used to filter the table's data.
|
||||
- If a `string` is passed, the function with that name located on either the custom `filterTypes` option or the built-in filtering types object will be used. If
|
||||
- If a `function` is passed, it will be used directly.
|
||||
- For more information on filter types, see Filtering
|
||||
- If a **function** is passed, it must be **memoized**
|
||||
- `manualGlobalFilter: Bool`
|
||||
- Enables filter detection functionality, but does not automatically perform row filtering.
|
||||
- Turn this on if you wish to implement your own row filter outside of the table (eg. server-side or manual row grouping/nesting)
|
||||
- `disableGlobalFilter: Bool`
|
||||
- Disables global filtering for every column in the entire table.
|
||||
- `filterTypes: Object<filterKey: filterType>`
|
||||
- Must be **memoized**
|
||||
- Allows overriding or adding additional filter types for the table to use. If the globalFilter type isn't found on this object, it will default to using the built-in filter types.
|
||||
- For more information on filter types, see Filtering
|
||||
- `autoResetGlobalFilter: Boolean`
|
||||
- Defaults to `true`
|
||||
- When `true`, the `globalFilter` state will automatically reset if any of the following conditions are met:
|
||||
- `data` is changed
|
||||
- To disable, set to `false`
|
||||
- For more information see the FAQ ["How do I stop my table state from automatically resetting when my data changes?"](./faq#how-do-i-stop-my-table-state-from-automatically-resetting-when-my-data-changes)
|
||||
|
||||
### Column Options
|
||||
|
||||
The following options are supported on any `Column` object passed to the `columns` option in `useTable()`
|
||||
|
||||
- `disableGlobalFilter: Bool`
|
||||
- Optional
|
||||
- If set to `true`, will disable global filtering for this column
|
||||
|
||||
### Instance Properties
|
||||
|
||||
The following values are provided to the table `instance`:
|
||||
|
||||
- `rows: Array<Row>`
|
||||
- An array of **filtered** rows.
|
||||
- `preGlobalFilteredRows: Array<Row>`
|
||||
- The array of rows **used right before filtering**.
|
||||
- Among many other use-cases, these rows are directly useful for building option lists in filters, since the resulting filtered `rows` do not contain every possible option.
|
||||
- `setGlobalFilter: Function(filterValue) => void`
|
||||
- An instance-level function used to update the global filter value.
|
||||
|
||||
### Example
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/filtering)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/filtering)
|
||||
+20
-6
@@ -1,3 +1,9 @@
|
||||
---
|
||||
name: useGroupBy
|
||||
route: /api/useGroupBy
|
||||
menu: API
|
||||
---
|
||||
|
||||
# `useGroupBy`
|
||||
|
||||
- Plugin Hook
|
||||
@@ -38,12 +44,18 @@ The following options are supported on any `Column` object passed to the `column
|
||||
- Receives the table instance and cell model as props
|
||||
- Must return valid JSX
|
||||
- This function (or component) formats this column's value when it is being grouped and aggregated, eg. If this column was showing the number of visits for a user to a website and it was currently being grouped to show an **average** of the values, the `Aggregated` function for this column could format that value to `1,000 Avg. Visits`
|
||||
- `aggregate: String | [String, String] | Function(values, rows, isAggregated: Bool) => any`
|
||||
- `aggregate: String | Function(leafValues, aggregatedValues) => any`
|
||||
- Optional
|
||||
- Used to aggregate values across rows, eg. `average`-ing the ages of many cells in a table"
|
||||
- If a single `String` is passed, it must be the key of either a user defined or predefined `aggregations` function.
|
||||
- If a tuple array of `[String, String]` is passed, both must be a key of either a user defined or predefined `aggregations` function.
|
||||
- The first is used to aggregate raw values, eg. `sum`-ing raw values together
|
||||
- The second is used to aggregate values that have already been aggregated, eg. `average`-ing the sums produced by the raw aggregation level
|
||||
- If a `Function` is passed, this function will receive the `values`, original `rows` of those values, and an `isAggregated` `Bool` of whether or not the values and rows have already been aggregated.
|
||||
- If a `Function` is passed, this function will receive both the leaf-row values and (if the rows have already been aggregated, the previously aggregated values) to be aggregated into a single value.
|
||||
- The function signature for all aggregation functions is `(leafValues, aggregatedValues) => aggregatedValue` where `leafValues` is a flat array containing all leaf rows currently grouped at the aggregation level and `aggregatedValues` is an array containing the aggregated values from the immediate child sub rows. Each has purpose in the types of aggregations they power where optimizations are made for either accuracy or performance.
|
||||
- For examples on how an aggregation functions work, see the source code for the built in aggregations in the [src/aggregations.js](../../src/aggregations.js) file.
|
||||
- `aggregateValue: String | Function(values, row, column) => any`
|
||||
- Optional
|
||||
- When attempting to group/aggregate non primitive cell values (eg. arrays of items) you will likely need to resolve a stable primitive value like a number or string to use in normal row aggregations. This property can be used to aggregate or simply access the value to be used in aggregations eg. `count`-ing the unique number of items in a cell's array value before `sum`-ing that count across the table.
|
||||
- If a single `String` is passed, it must be the key of either a user defined or predefined `aggregations` function.
|
||||
- If a `Function` is passed, this function will receive the cell's accessed value, the original `row` object and the `column` associated with the cell
|
||||
- `disableGroupBy: Boolean`
|
||||
- Defaults to `false`
|
||||
- If `true`, will disable grouping for this column.
|
||||
@@ -92,6 +104,8 @@ The following properties are available on every `Row` object returned by the tab
|
||||
- This object contains the **aggregated** values for this row's sub rows
|
||||
- `subRows: Array<Row>`
|
||||
- If the row is a materialized group row, this property is the array of materialized subRows that were grouped inside of this row.
|
||||
- `leafRows: Array<Row>`
|
||||
- If the row is a materialized group row, this property is an array containing all leaf node rows aggregated into this row.
|
||||
- `depth: Int`
|
||||
- If the row is a materialized group row, this is the grouping depth at which this row was created.
|
||||
- `id: String`
|
||||
@@ -108,7 +122,7 @@ The following additional properties are available on every `Cell` object returne
|
||||
|
||||
- `isGrouped: Bool`
|
||||
- If `true`, this cell is a grouped cell, meaning it contains a grouping value and should usually display and expander.
|
||||
- `isRepeatedValue: Bool`
|
||||
- `isPlaceholder: Bool`
|
||||
- If `true`, this cell is a repeated value cell, meaning it contains a value that is already being displayed elsewhere (usually by a parent row's cell).
|
||||
- Most of the time, this cell is not required to be displayed and can safely be hidden during rendering
|
||||
- `isAggregated: Bool`
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
---
|
||||
name: usePagination
|
||||
route: /api/usePagination
|
||||
menu: API
|
||||
---
|
||||
# `usePagination`
|
||||
|
||||
- Plugin Hook
|
||||
@@ -30,10 +35,11 @@ The following options are supported via the main options object passed to `useTa
|
||||
- When `true`, the `pageIndex` state will automatically reset if `manualPagination` is `false` and any of the following conditions are met:
|
||||
- `data` is changed
|
||||
- `manualSortBy` is `false` and `state.sortBy` is changed
|
||||
- `manualGlobalFilter` is `false` and `state.globalFilter` is changed
|
||||
- `manualFilters` is `false` and `state.filters` is changed
|
||||
- `manualGroupBy` is `false` and `state.groupBy` is changed
|
||||
- To disable, set to `false`
|
||||
- For more information see the FAQ ["How do I stop my table state from automatically resetting when my data changes?"](./faq#how-do-i-stop-my-table-state-from-automatically-resetting-when-my-data-changes)
|
||||
- For more information see the FAQ ["How do I stop my table state from automatically resetting when my data changes?"](/faq#how-do-i-stop-my-table-state-from-automatically-resetting-when-my-data-changes)
|
||||
- `paginateExpandedRows: Bool`
|
||||
- Optional
|
||||
- Only applies when using the `useExpanded` plugin hook simultaneously
|
||||
@@ -80,5 +86,5 @@ The following values are provided to the table `instance`:
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/pagination)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/pagination)
|
||||
- Controlled Pagination
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/pagination)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/pagination)
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/pagination-controlled)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/pagination-controlled)
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
name: useResizeColumns
|
||||
route: /api/useResizeColumns
|
||||
menu: API
|
||||
---
|
||||
|
||||
# `useResizeColumns`
|
||||
|
||||
- Plugin Hook
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
name: useRowSelect
|
||||
route: /api/useRowSelect
|
||||
menu: API
|
||||
---
|
||||
|
||||
# `useRowSelect`
|
||||
|
||||
- Plugin Hook
|
||||
@@ -58,6 +64,13 @@ The following additional properties are available on every **prepared** `row` ob
|
||||
- `toggleRowSelected: Function(?set)`
|
||||
- Use this function to toggle this row's selected state.
|
||||
- Optionally pass `true` or `false` to set it to that state
|
||||
- `getToggleRowSelectedProps: Function(props) => props`
|
||||
- Use this function to get the props needed for a **select row checkbox**.
|
||||
- Props:
|
||||
- `onChange: Function()`
|
||||
- `style.cursor: 'pointer'`
|
||||
- `checked: Bool`
|
||||
- `title: 'Toggle Row Selected'`
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
+14
-2
@@ -1,3 +1,9 @@
|
||||
---
|
||||
name: useRowState
|
||||
route: /api/useRowState
|
||||
menu: API
|
||||
---
|
||||
|
||||
# `useRowState`
|
||||
|
||||
- Plugin Hook
|
||||
@@ -15,10 +21,16 @@ The following options are supported via the main options object passed to `useTa
|
||||
- If a row's ID is found in this array, it will have the state of the value corresponding to that key.
|
||||
- Individual row states can contain anything, but they also contain a `cellState` key, which provides cell-level state based on column ID's to every
|
||||
**prepared** cell in the table.
|
||||
- `initialRowStateAccessor: Function`
|
||||
- `initialRowStateAccessor: Function(originalRow) => Object<any>`
|
||||
- Optional
|
||||
- This function may optionally return the initial state for a row.
|
||||
- Defaults to: `row => ({})`
|
||||
- This function should return the initial state for a row.
|
||||
- If this function is defined, it will be passed a `Row` object, from which you can return a value to use as the initial state, eg. `row => row.original.initialState`
|
||||
- `initialCellStateAccessor: Function(originalRow) => Object<any>`
|
||||
- **Optional**
|
||||
- Defaults to: `cell => ({})`
|
||||
- This function should return the initial state for a cell.
|
||||
- If this function is defined, it will be passed a `Cell` object, from which you can return a value to use as the initial state, eg. `cell => cell.row.original.initialCellState[cell.column.id]`
|
||||
- `autoResetRowState: Boolean`
|
||||
- Defaults to `true`
|
||||
- When `true`, the `rowState` state will automatically reset if any of the following conditions are met:
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
name: useSortBy
|
||||
route: /api/useSortBy
|
||||
menu: API
|
||||
---
|
||||
|
||||
# `useSortBy`
|
||||
|
||||
- Plugin Hook
|
||||
@@ -49,7 +55,7 @@ The following options are supported via the main options object passed to `useTa
|
||||
- When `true`, the `sortBy` state will automatically reset if any of the following conditions are met:
|
||||
- `data` is changed
|
||||
- To disable, set to `false`
|
||||
- For more information see the FAQ ["How do I stop my table state from automatically resetting when my data changes?"](./faq#how-do-i-stop-my-table-state-from-automatically-resetting-when-my-data-changes)
|
||||
- For more information see the FAQ ["How do I stop my table state from automatically resetting when my data changes?"](/faq#how-do-i-stop-my-table-state-from-automatically-resetting-when-my-data-changes)
|
||||
|
||||
### Column Options
|
||||
|
||||
@@ -72,7 +78,7 @@ The following options are supported on any `Column` object passed to the `column
|
||||
- Defaults to `false`
|
||||
- If set to `true`, the underlying sorting direction will be inverted, but the UI will not.
|
||||
- This may be useful in situations where positive and negative connotation is inverted, eg. a Golfing score where a lower score is considered more positive than a higher one.
|
||||
- `sortType: String | Function`
|
||||
- `sortType: String | Function(rowA: <Row>, rowB: <Row>, columnId: String, desc: Bool)`
|
||||
- Used to compare 2 rows of data and order them correctly.
|
||||
- If a **function** is passed, it must be **memoized**
|
||||
- String options: `basic`, `datetime`, `alphanumeric`. Defaults to `alphanumeric`.
|
||||
@@ -106,7 +112,7 @@ The following properties are available on every `Column` object returned by the
|
||||
- This function is used to resolve any props needed for this column's UI that is responsible for toggling the sort direction when the user clicks it.
|
||||
- You can use the `getSortByToggleProps` hook to extend its functionality.
|
||||
- Custom props may be passed. **NOTE: Custom props may override built-in sortBy props, so be careful!**
|
||||
- `clearSorting: Function() => void`
|
||||
- `clearSortBy: Function() => void`
|
||||
- This function can be used to programmatically clear the sorting for this column.
|
||||
- `isSorted: Boolean`
|
||||
- Denotes whether this column is currently being sorted
|
||||
|
||||
+20
-16
@@ -1,3 +1,9 @@
|
||||
---
|
||||
name: useTable
|
||||
route: /api/useTable
|
||||
menu: API
|
||||
---
|
||||
|
||||
# `useTable`
|
||||
|
||||
- Required
|
||||
@@ -25,7 +31,12 @@ The following options are supported via the main options object passed to `useTa
|
||||
- Optional
|
||||
- The initial state object for hidden columns
|
||||
- If a column's ID is contained in this array, it will be hidden
|
||||
- `reducer: Function(newState, action, prevState) => newState`
|
||||
- `autoResetHiddenColumns: Boolean`
|
||||
- Defaults to `true`
|
||||
- When `true`, the `hiddenColumns` state will automatically reset if any of the following conditions are met:
|
||||
- `columns` is changed
|
||||
- To disable, set to `false`
|
||||
- `stateReducer: Function(newState, action, prevState) => newState`
|
||||
- Optional
|
||||
- With every action that is dispatched to the table's internal `React.useReducer` instance, this reducer is called and is allowed to modify the final state object for updating.
|
||||
- It is passed the `newState`, `action`, and `prevState` and is expected to either return the `newState` or a modified version of the `newState`
|
||||
@@ -35,7 +46,7 @@ The following options are supported via the main options object passed to `useTa
|
||||
- If you need to control part of the table state, this is the place to do it.
|
||||
- This function is run on every single render, just like a hook and allows you to alter the final state of the table if necessary.
|
||||
- You can use hooks inside of this function, but most of the time, we just suggest using `React.useMemo` to memoize your state overrides.
|
||||
- See the FAQ ["How can I manually control the table state?"](./faq.md#how-can-i-manually-control-the-table-state) for a an example.
|
||||
- See the FAQ ["How can I manually control the table state?"](/faq#how-can-i-manually-control-the-table-state) for a an example.
|
||||
- `defaultColumn: Object`
|
||||
- Optional
|
||||
- Defaults to `{}`
|
||||
@@ -67,12 +78,13 @@ The following options are supported via the main options object passed to `useTa
|
||||
|
||||
The following options are supported on any column object you can pass to `columns`.
|
||||
|
||||
- `accessor: String | Function`
|
||||
- `accessor: String | Function(originalRow, rowIndex) => any`
|
||||
- **Required**
|
||||
- This string/function is used to build the data model for your column.
|
||||
- The data returned by an accessor should be **primitive** and sortable.
|
||||
- If a string is passed, the column's value will be looked up on the original row via that key, eg. If your column's accessor is `firstName` then its value would be read from `row['firstName']`. You can also specify deeply nested values with accessors like `info.hobbies` or even `address[0].street`
|
||||
- If a function is passed, the column's value will be looked up on the original row using this accessor function, eg. If your column's accessor is `row => row.firstName`, then its value would be determined by passing the row to this function and using the resulting value.
|
||||
- Technically speaking, this field isn't required if you have a unique `id` for a column. This is used for things like expander or row selection columns. **Warning**: Only omit `accessor` if you really know what you're doing.
|
||||
- `id: String`
|
||||
- **Required if `accessor` is a function**
|
||||
- This is the unique ID for the column. It is used by reference in things like sorting, grouping, filtering etc.
|
||||
@@ -89,15 +101,10 @@ The following options are supported on any column object you can pass to `column
|
||||
- If a function/component is passed, it will be used for formatting the header value, eg. You can use a `Header` function to dynamically format the header using any table or column state.
|
||||
- `Cell: Function | React.Component => JSX`
|
||||
- Optional
|
||||
- Defaults to `({ cell: { value } }) => String(value)`
|
||||
- Defaults to `({ value }) => String(value)`
|
||||
- Receives the table instance and cell model as props
|
||||
- Must return valid JSX
|
||||
- This function (or component) is primarily used for formatting the column value, eg. If your column accessor returns a date object, you can use a `Cell` function to format that date to a readable format.
|
||||
- `show: Bool`
|
||||
- Optional
|
||||
- Defaults to `undefined`
|
||||
- If set to `true`, will take priority over any state in `hiddenColumns` and force this column to be visible at all times.
|
||||
- If set to `false` will take priority over any state in `hiddenColumns` and force this column to be hidden at all times.
|
||||
- `width: Int`
|
||||
- Optional
|
||||
- Defaults to `150`
|
||||
@@ -120,18 +127,15 @@ The following properties are available on the table instance returned from `useT
|
||||
- `state: Object`
|
||||
- **Memoized** - This object reference will not change unless the internal table state is modified.
|
||||
- This is the final state object of the table, which is the product of the `initialState`, internal table reducer and (optionally) a custom `reducer` supplied by the user.
|
||||
- `dispatch: Function({ type: Actions[type], ...payload }) => void`
|
||||
- This function is used both internally by React Table, and optionally by you (the developer) to update the table state programmatically.
|
||||
- `type: Actions[type] | String`
|
||||
- The action type corresponding to what action being taken against the state.
|
||||
- `...payload`
|
||||
- Any other action data that is associated with the action
|
||||
- `columns: Array<Column>`
|
||||
- A **nested** array of final column objects, **similar in structure to the original columns configuration option**.
|
||||
- See [Column Properties](#column-properties) for more information
|
||||
- `flatColumns: Array<Column>`
|
||||
- `allColumns: Array<Column>`
|
||||
- A **flat** array of all final column objects.
|
||||
- See [Column Properties](#column-properties) for more information
|
||||
- `visibleColumns: Array<Column>`
|
||||
- A **flat** array of all visible column objects derived from `allColumns`.
|
||||
- See [Column Properties](#column-properties) for more information
|
||||
- `headerGroups: Array<HeaderGroup>`
|
||||
- An array of normalized header groups, each containing a flattened array of final column objects for that row.
|
||||
- **Some of these headers may be materialized as placeholders**
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
name: useTokenPagination
|
||||
route: /api/useTokenPagination
|
||||
menu: API
|
||||
---
|
||||
|
||||
# `useTokenPagination (Coming Soon)`
|
||||
|
||||
- Plugin Hook
|
||||
|
||||
+10
-5
@@ -1,8 +1,13 @@
|
||||
---
|
||||
name: Concepts
|
||||
route: /concepts
|
||||
---
|
||||
|
||||
# Concepts
|
||||
|
||||
## React Table is a "headless" UI library
|
||||
|
||||
React Table is a headless utility, which means out of the box, it doesn't render or supply any actual UI elements. You are in charge of utilizing the state and callbacks of the hooks provided by this library to render your own table markup. [Read this article to understand why React Table is built this way](https://medium.com/merrickchristensen/headless-user-interface-components-565b0c0f2e18). If you don't want to, then here's a quick rundown anyway:
|
||||
React Table is a headless utility, which means out of the box, it doesn't render or supply any actual UI elements. You are in charge of utilizing the state and callbacks of the hooks provided by this library to render your own table markup. [Read this article to understand why React Table is built this way](https://www.merrickchristensen.com/articles/headless-user-interface-components/). If you don't want to, then here's a quick rundown anyway:
|
||||
|
||||
- Separation of Concerns - Not that superficial kind you read about all the time. The real kind. React Table as a library honestly has no business being in charge of your UI. The look, feel, and overall experience of your table is what makes your app or product great. The less React Table gets in the way of that, the better!
|
||||
- Maintenance - By removing the massive (and seemingly endless) API surface area required to support every UI use-case, React Table can remain small, easy-to-use and simple to update/maintain.
|
||||
@@ -23,11 +28,11 @@ At the heart of every React Table is the `useTable` hook and the table `instance
|
||||
|
||||
## Rendering your own UI
|
||||
|
||||
As of React Table v7, **you the developer** are responsible for rendering your own UI, but don't let that intimidate you! Table UIs are fun and React Table makes it so easy to wire up your own table UI. The easiest way to learn how to build your own table UI is to [see some existing React Table examples](./examples.md)!
|
||||
As of React Table v7, **you the developer** are responsible for rendering your own UI, but don't let that intimidate you! Table UIs are fun and React Table makes it so easy to wire up your own table UI. The easiest way to learn how to build your own table UI is to [see some existing React Table examples](./examples)!
|
||||
|
||||
---
|
||||
|
||||
After reading about React Table's concepts, you should:
|
||||
|
||||
- [Check Out Some Examples](./examples.md)
|
||||
- [Study the API](./api/README.md)
|
||||
- [Follow the Quick Start](./quickstart)
|
||||
- [Check Out Some Examples](./examples)
|
||||
- [Study the API](./api)
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
# Examples
|
||||
|
||||
- **Simple** - All of these examples use automatic state management, meaning, they don't hoist any state out of the table or manually control anything. Start here for understanding the basics about how to build your table UI.
|
||||
- Basic
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/basic)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/basic)
|
||||
- Footers
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/footers)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/footers)
|
||||
- Sorting
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/sorting)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/sorting)
|
||||
- Filtering
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/filtering)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/filtering)
|
||||
- Grouping
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/grouping)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/grouping)
|
||||
- Grouping (Single Column)
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/grouping-column)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/grouping-column)
|
||||
- Pagination
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/pagination)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/pagination)
|
||||
- Row Selection
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/row-selection)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/row-selection)
|
||||
- Expanding
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/expanding)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/expanding)
|
||||
- Sub Components
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/sub-components)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/sub-components)
|
||||
- Editable Data
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/editable-data)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/editable-data)
|
||||
- Column Ordering
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/column-ordering)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/column-ordering)
|
||||
- Column Hiding
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/column-hiding)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/column-hiding)
|
||||
- Column Resizing
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/column-resizing)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/column-resizing)
|
||||
- Data-Driven Classes and Styles
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/data-driven-classes-and-styles)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/data-driven-classes-and-styles)
|
||||
- Row DnD
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/row-dnd)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/row-dnd)
|
||||
- Full Width Table (Table Elements with collapsible content)
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/full-width-table)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/full-width-table)
|
||||
- Full Width Resizable Table (via `useFlexLayout`)
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/full-width-resizable-table)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/full-width-resizable-table)
|
||||
- **Complex**
|
||||
- The "Kitchen Sink"
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/kitchen-sink)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/kitchen-sink)
|
||||
- **Controlled** - These examples are more advanced because they demonstrate how to manually control and respond to the state of the table.
|
||||
- Pagination (Controlled)
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/pagination-controlled)
|
||||
- [Open in CodeSandobx](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/pagination-controlled)
|
||||
- **UI & Rendering** - These examples demonstrate how to use React Table with your favorite UI libraries or tools!
|
||||
- Virtualized Rows (React-Window)
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/virtualized-rows)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/virtualized-rows)
|
||||
- Animated (Framer-Motion)
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/animated-framer-motion)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/animated-framer-motion)
|
||||
- Material-UI
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/material-UI-components)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/material-UI-components)
|
||||
- [ ] Styled-Components
|
||||
- [ ] CSS
|
||||
- [ ] Bootstrap
|
||||
- Want to write one of these examples or add another? [Submit a PR!](https://github.com/tannerlinsley/react-table/compare)
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
name: Examples
|
||||
route: /examples
|
||||
---
|
||||
|
||||
# Examples
|
||||
|
||||
- [**Simple**](./examples/simple) - All of these examples use automatic state management, meaning, they don't hoist any state out of the table or manually control anything. Start here for understanding the basics about how to build your table UI.
|
||||
|
||||
- [**Complex**](./examples/complex) - These examples are more advanced because they demonstrate how to manually control and respond to the state of the table.
|
||||
|
||||
- [**Controlled**](./examples/controlled) - These examples are more advanced because they demonstrate how to manually control and respond to the state of the table.
|
||||
|
||||
- [**UI & Rendering**](./examples/ui) - These examples demonstrate how to use React Table with your favorite UI libraries or tools!
|
||||
|
||||
* Want to add another example? [Submit a PR!](https://github.com/tannerlinsley/react-table/compare)
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: Complex
|
||||
route: /examples/complex
|
||||
menu: Examples
|
||||
---
|
||||
|
||||
# Complex
|
||||
|
||||
These examples are more advanced because they demonstrate how to manually control and respond to the state of the table.
|
||||
|
||||
## The "Kitchen Sink"
|
||||
|
||||
This example includes Pagination, Sorting, Filtering, Grouping, Expandable Rows and Row Selection so it's called the _Kitchen Sink_.
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/kitchen-sink)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/kitchen-sink)
|
||||
<iframe
|
||||
src="https://codesandbox.io/embed/github/tannerlinsley/react-table/tree/master/examples/kitchen-sink?autoresize=1&fontsize=14&module=%2Fsrc%2FApp.js&theme=dark"
|
||||
style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"
|
||||
title="tannerlinsley/react-table: kitchen-sink"
|
||||
allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb"
|
||||
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
|
||||
></iframe>
|
||||
|
||||
* Want to add another example? [Submit a PR!](https://github.com/tannerlinsley/react-table/compare)
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
name: Controlled
|
||||
route: /examples/controlled
|
||||
menu: Examples
|
||||
---
|
||||
|
||||
# Controlled
|
||||
|
||||
These examples are more advanced because they demonstrate how to manually control and respond to the state of the table.
|
||||
|
||||
## Pagination (Controlled)
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/pagination-controlled)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/pagination-controlled)
|
||||
<iframe
|
||||
src="https://codesandbox.io/embed/github/tannerlinsley/react-table/tree/master/examples/pagination-controlled?autoresize=1&fontsize=14&module=%2Fsrc%2FApp.js&theme=dark"
|
||||
style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"
|
||||
title="tannerlinsley/react-table: pagination-controlled"
|
||||
allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb"
|
||||
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
|
||||
></iframe>
|
||||
|
||||
* Want to add another example? [Submit a PR!](https://github.com/tannerlinsley/react-table/compare)
|
||||
@@ -0,0 +1,108 @@
|
||||
---
|
||||
name: Simple
|
||||
route: /examples/simple
|
||||
menu: Examples
|
||||
---
|
||||
|
||||
# Simple
|
||||
|
||||
All of these examples use automatic state management, meaning, they don't hoist any state out of the table or manually control anything. Start here for understanding the basics about how to build your table UI.
|
||||
|
||||
## Basic
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/basic)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/embed/github/tannerlinsley/react-table/tree/master/examples/basic)
|
||||
<iframe
|
||||
src="https://codesandbox.io/embed/github/tannerlinsley/react-table/tree/master/examples/basic?autoresize=1&fontsize=14&module=%2Fsrc%2FApp.js&theme=dark"
|
||||
style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"
|
||||
title="tannerlinsley/react-table: basic"
|
||||
allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb"
|
||||
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
|
||||
></iframe>
|
||||
|
||||
## Footers
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/footers)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/embed/github/tannerlinsley/react-table/tree/master/examples/footers)
|
||||
|
||||
## Sorting
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/sorting)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/embed/github/tannerlinsley/react-table/tree/master/examples/sorting)
|
||||
|
||||
## Filtering
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/filtering)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/embed/github/tannerlinsley/react-table/tree/master/examples/filtering)
|
||||
|
||||
## Grouping
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/grouping)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/embed/github/tannerlinsley/react-table/tree/master/examples/grouping)
|
||||
|
||||
## Grouping (Single Column)
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/grouping-column)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/embed/github/tannerlinsley/react-table/tree/master/examples/grouping-column)
|
||||
|
||||
## Pagination
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/pagination)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/embed/github/tannerlinsley/react-table/tree/master/examples/pagination)
|
||||
|
||||
## Row Selection
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/row-selection)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/embed/github/tannerlinsley/react-table/tree/master/examples/row-selection)
|
||||
|
||||
## Expanding
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/expanding)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/embed/github/tannerlinsley/react-table/tree/master/examples/sub-components)
|
||||
|
||||
## Sub Components
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/sub-components)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/embed/github/tannerlinsley/react-table/tree/master/examples/sub-components)
|
||||
|
||||
## Editable Data
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/editable-data)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/embed/github/tannerlinsley/react-table/tree/master/examples/editable-data)
|
||||
|
||||
## Column Ordering
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/column-ordering)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/column-ordering)
|
||||
|
||||
## Column Hiding
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/column-hiding)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/column-hiding)
|
||||
|
||||
## Column Resizing
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/column-resizing)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/column-resizing)
|
||||
|
||||
## Data-Driven Classes and Styles
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/data-driven-classes-and-styles)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/data-driven-classes-and-styles)
|
||||
|
||||
## Row DnD
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/row-dnd)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/row-dnd)
|
||||
|
||||
## Full Width Table (Table Elements with collapsible content)
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/full-width-table)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/full-width-table)
|
||||
|
||||
## Full Width Resizable Table (via `useFlexLayout`)
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/full-width-resizable-table)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/full-width-resizable-table)
|
||||
|
||||
* Want to add another example? [Submit a PR!](https://github.com/tannerlinsley/react-table/compare)
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
name: UI/Rendering
|
||||
route: /examples/ui
|
||||
menu: Examples
|
||||
---
|
||||
|
||||
# UI and Rendering
|
||||
|
||||
These examples demonstrate how to use React Table with your favorite UI libraries or tools!
|
||||
|
||||
## Virtualized Rows (React-Window)
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/virtualized-rows)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/virtualized-rows)
|
||||
<iframe
|
||||
src="https://codesandbox.io/embed/github/tannerlinsley/react-table/tree/master/examples/virtualized-rows?autoresize=1&fontsize=14&module=%2Fsrc%2FApp.js&theme=dark"
|
||||
style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"
|
||||
title="tannerlinsley/react-table: virtualized-rows"
|
||||
allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb"
|
||||
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
|
||||
></iframe>
|
||||
|
||||
## Animated (Framer-Motion)
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/animated-framer-motion)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/animated-framer-motion)
|
||||
<iframe
|
||||
src="https://codesandbox.io/embed/github/tannerlinsley/react-table/tree/master/examples/animated-framer-motion?autoresize=1&fontsize=14&module=%2Fsrc%2FApp.js&theme=dark"
|
||||
style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"
|
||||
title="tannerlinsley/react-table: animated-framer-motion"
|
||||
allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb"
|
||||
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
|
||||
></iframe>
|
||||
|
||||
## Material-UI
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/material-UI-components)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/material-UI-components)
|
||||
<iframe
|
||||
src="https://codesandbox.io/embed/github/tannerlinsley/react-table/tree/master/examples/material-UI-components?autoresize=1&fontsize=14&module=%2Fsrc%2FApp.js&theme=dark"
|
||||
style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"
|
||||
title="tannerlinsley/react-table: material-UI-components"
|
||||
allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb"
|
||||
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
|
||||
></iframe>
|
||||
|
||||
## Material-UI Enhanced Table
|
||||
|
||||
- [Source](https://github.com/tannerlinsley/react-table/tree/master/examples/material-UI-enhanced-table)
|
||||
- [Open in CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/material-UI-enhanced-table)
|
||||
<iframe
|
||||
src="https://codesandbox.io/embed/github/tannerlinsley/react-table/tree/master/examples/material-UI-enhanced-table?autoresize=1&fontsize=14&module=%2Fsrc%2FApp.js&theme=dark"
|
||||
style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"
|
||||
title="tannerlinsley/react-table: material-UI-enhanced-table"
|
||||
allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb"
|
||||
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
|
||||
></iframe>
|
||||
|
||||
## Todo
|
||||
|
||||
- [ ] Styled-Components
|
||||
- [ ] CSS
|
||||
- [ ] Bootstrap
|
||||
|
||||
* Want to write one of these examples or add another? [Submit a PR!](https://github.com/tannerlinsley/react-table/compare)
|
||||
+14
-9
@@ -1,3 +1,8 @@
|
||||
---
|
||||
name: FAQ
|
||||
route: /faq
|
||||
---
|
||||
|
||||
# FAQ
|
||||
|
||||
Below are some of the most frequently asked questions on how to use the React Table API to solve various table challenges you may encounter
|
||||
@@ -40,10 +45,10 @@ function Table({ data, onFetchData }) {
|
||||
data,
|
||||
})
|
||||
|
||||
// When the these table states change, fetch new data!
|
||||
// When these table states change, fetch new data!
|
||||
React.useEffect(() => {
|
||||
onFetchData({ pageIndex, pageSize, sortBy, filters })
|
||||
}, [fetchData, pageIndex, pageSize, sortBy, filters])
|
||||
}, [onFetchData, pageIndex, pageSize, sortBy, filters])
|
||||
|
||||
return </>
|
||||
}
|
||||
@@ -108,13 +113,13 @@ React.useEffect(() => {
|
||||
|
||||
useTable({
|
||||
...
|
||||
autoResetPage: !skipPageReset,
|
||||
autoResetExpanded: !skipPageReset,
|
||||
autoResetGroupBy: !skipPageReset,
|
||||
autoResetSelectedRows: !skipPageReset,
|
||||
autoResetSortBy: !skipPageReset,
|
||||
autoResetFilters: !skipPageReset,
|
||||
autoResetRowState: !skipPageReset,
|
||||
autoResetPage: !skipPageResetRef.current,
|
||||
autoResetExpanded: !skipPageResetRef.current,
|
||||
autoResetGroupBy: !skipPageResetRef.current,
|
||||
autoResetSelectedRows: !skipPageResetRef.current,
|
||||
autoResetSortBy: !skipPageResetRef.current,
|
||||
autoResetFilters: !skipPageResetRef.current,
|
||||
autoResetRowState: !skipPageResetRef.current,
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
+12
-1
@@ -1,3 +1,8 @@
|
||||
---
|
||||
name: Installation
|
||||
route: /installation
|
||||
---
|
||||
|
||||
# Installation
|
||||
|
||||
Install React Table as a dependency using `npm` or `yarn`
|
||||
@@ -10,6 +15,12 @@ $ npm install react-table
|
||||
$ yarn add react-table
|
||||
```
|
||||
|
||||
React Table uses [Scarf](https://www.npmjs.com/package/@scarf/scarf) to collect
|
||||
anonymized installation analytics. These anlytics help support the maintainers
|
||||
of this library. However, if you'd like to opt out, you can do so by setting the
|
||||
environment variable `SCARF_ANALYTICS=false` before you install, or by setting
|
||||
`scarfSettings.enabled = false` in your project's `package.json`
|
||||
|
||||
To import React Table:
|
||||
|
||||
```js
|
||||
@@ -24,4 +35,4 @@ import {
|
||||
} from 'react-table'
|
||||
```
|
||||
|
||||
Once you've installed React Table, continue to [Concepts](./concepts.md) to read more about how to utilize its API
|
||||
Once you've installed React Table, continue to [Concepts](./concepts) to read more about how to utilize its API
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
---
|
||||
name: Quick Start
|
||||
route: /quickstart
|
||||
---
|
||||
|
||||
# Quick Start
|
||||
|
||||
As explained in the [Concepts](./concepts) document, react-table is a headless tool, meaning you'll have to build your own UI. We recognize this can be potentially daunting, so here's a very basic table to start with.
|
||||
|
||||
## Define Row Shape
|
||||
|
||||
When thinking about a table, you typically have a number of rows split into a number of columns. While table configurations can get far more complex with nested columns, subrows, etc. for this basic quick start, we need to define some data. Note that this data must be defined using [`React.useMemo`](https://reactjs.org/docs/hooks-reference.html#usememo) in order to take advantage of the power of memoization.
|
||||
|
||||
```javascript
|
||||
const data = React.useMemo(
|
||||
() => [
|
||||
{
|
||||
col1: 'Hello',
|
||||
col2: 'World',
|
||||
},
|
||||
{
|
||||
col1: 'react-table',
|
||||
col2: 'rocks',
|
||||
},
|
||||
{
|
||||
col1: 'whatever',
|
||||
col2: 'you want',
|
||||
},
|
||||
],
|
||||
[]
|
||||
)
|
||||
```
|
||||
|
||||
## Define Columns
|
||||
|
||||
The first step to using react-table is to create a set of column definitions to pass into the `useTable` hook. These columns must be defined using `React.useMemo` in order to take advantage of the power of memoization.
|
||||
|
||||
```javascript
|
||||
const columns = React.useMemo(
|
||||
() => [
|
||||
{
|
||||
Header: 'Column 1',
|
||||
accessor: 'col1', // accessor is the "key" in the data
|
||||
},
|
||||
{
|
||||
Header: 'Column 2',
|
||||
accessor: 'col2',
|
||||
},
|
||||
],
|
||||
[]
|
||||
)
|
||||
```
|
||||
|
||||
## Implement `useTable` hook
|
||||
|
||||
Now that you have the basic `columns` and `data` defined, you can pass those into `useTable` and retrieve the properties you need.
|
||||
|
||||
```javascript
|
||||
const {
|
||||
getTableProps,
|
||||
getTableBodyProps,
|
||||
headerGroups,
|
||||
rows,
|
||||
prepareRow,
|
||||
} = useTable({ columns, data })
|
||||
```
|
||||
|
||||
If you're new to JavaScript (especially ES2015+), this syntax may look a little strange. The lefthand side of the assigment is using [object destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) to extract the properties we need that are returned from the `useTable` hook (or function). On the right hand side, at a minimum, `useTable` needs to be provided with an object containing the memoized columns and data that we created above.
|
||||
|
||||
## Build a basic UI structure
|
||||
|
||||
OK, so that's great, we've implemented the hook, but we still don't have a table to show, right? Let's use the properties returned from `useTable` to build a basic table structure.
|
||||
|
||||
```javascript
|
||||
return (
|
||||
<table {...getTableProps()}>
|
||||
<thead>
|
||||
{headerGroups.map(headerGroup => (
|
||||
<tr {...headerGroup.getHeaderGroupProps()}>
|
||||
{headerGroup.headers.map(column => (
|
||||
<th {...column.getHeaderProps()}>{column.render('Header')}</th>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</thead>
|
||||
<tbody {...getTableBodyProps()}>
|
||||
{rows.map(row => {
|
||||
prepareRow(row)
|
||||
return (
|
||||
<tr {...row.getRowProps()}>
|
||||
{row.cells.map(cell => {
|
||||
return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
|
||||
})}
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
)
|
||||
```
|
||||
|
||||
Again, if you're relatively new to JavaScript (or ES2015+ syntax), you may wonder, "What is with all the ...s?". This is the [spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) that _spreads_ all properties of an object (or array) without having to manually extract them all. So, with the first row, `<table {...getRowProps()}>` will return a `table` element with all of the properties returned by `getTableProps()`.
|
||||
|
||||
## Final Result
|
||||
|
||||
If we put all of this together, we should get a very basic (boring) table. (_Styles added just to make it a little more attractive..._)
|
||||
|
||||
_The following example is a live component, so as you make changes in the code, it should update the table at the top._
|
||||
|
||||
import { Playground } from 'docz'
|
||||
import { useTable } from '../src/hooks/useTable'
|
||||
|
||||
<Playground>
|
||||
{() => {
|
||||
const data = React.useMemo(
|
||||
() => [
|
||||
{
|
||||
col1: 'Hello',
|
||||
col2: 'World',
|
||||
},
|
||||
{
|
||||
col1: 'react-table',
|
||||
col2: 'rocks',
|
||||
},
|
||||
{
|
||||
col1: 'whatever',
|
||||
col2: 'you want',
|
||||
},
|
||||
],
|
||||
[]
|
||||
)
|
||||
const columns = React.useMemo(
|
||||
() => [
|
||||
{
|
||||
Header: 'Column 1',
|
||||
accessor: 'col1', // accessor is the "key" in the data
|
||||
},
|
||||
{
|
||||
Header: 'Column 2',
|
||||
accessor: 'col2',
|
||||
},
|
||||
],
|
||||
[]
|
||||
)
|
||||
const {
|
||||
getTableProps,
|
||||
getTableBodyProps,
|
||||
headerGroups,
|
||||
rows,
|
||||
prepareRow,
|
||||
} = useTable({ columns, data })
|
||||
return (
|
||||
<table {...getTableProps()} style={{ border: 'solid 1px blue'}}>
|
||||
<thead>
|
||||
{headerGroups.map(headerGroup => (
|
||||
<tr {...headerGroup.getHeaderGroupProps()}>
|
||||
{headerGroup.headers.map(column => (
|
||||
<th {...column.getHeaderProps()} style={{ borderBottom: 'solid 3px red', background: 'aliceblue', color: 'black', fontWeight: 'bold'}}>{column.render('Header')}</th>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</thead>
|
||||
<tbody {...getTableBodyProps()}>
|
||||
{rows.map(row => {
|
||||
prepareRow(row)
|
||||
return (
|
||||
<tr {...row.getRowProps()}>
|
||||
{row.cells.map(cell => {
|
||||
return <td {...cell.getCellProps()} style={{ padding: '10px', border: 'solid 1px gray', background: 'papayawhip'}}>{cell.render('Cell')}</td>
|
||||
})}
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
)
|
||||
}}
|
||||
</Playground>
|
||||
@@ -0,0 +1,23 @@
|
||||
export default {
|
||||
title: 'React Table Documentation',
|
||||
description: 'Documentation for the react-table library built in Docz',
|
||||
ignore: ['docs/README.md', 'examples/**/*.md'],
|
||||
propsParser: false,
|
||||
port: 3002,
|
||||
menu: [
|
||||
'Getting Started',
|
||||
'Installation',
|
||||
'Concepts',
|
||||
'Quick Start',
|
||||
{
|
||||
name: 'Examples',
|
||||
menu: ['Simple', 'Complex', 'Controlled', 'UI/Rendering'],
|
||||
},
|
||||
{ name: 'API', menu: ['Overview', 'useTable'] },
|
||||
'FAQ',
|
||||
'Contributing',
|
||||
'Code of Conduct',
|
||||
'Typescript',
|
||||
'Changelog',
|
||||
],
|
||||
}
|
||||
@@ -205,7 +205,7 @@ function Table({ columns, data }) {
|
||||
getTableBodyProps,
|
||||
headerGroups,
|
||||
rows,
|
||||
flatColumns,
|
||||
visibleColumns,
|
||||
prepareRow,
|
||||
setColumnOrder,
|
||||
state,
|
||||
@@ -230,7 +230,7 @@ function Table({ columns, data }) {
|
||||
)
|
||||
|
||||
const randomizeColumns = () => {
|
||||
setColumnOrder(shuffle(flatColumns.map(d => d.id)))
|
||||
setColumnOrder(shuffle(visibleColumns.map(d => d.id)))
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -267,30 +267,29 @@ function Table({ columns, data }) {
|
||||
</thead>
|
||||
<tbody {...getTableBodyProps()}>
|
||||
<AnimatePresence>
|
||||
{rows.slice(0, 10).map(
|
||||
(row, i) => {
|
||||
prepareRow(row);
|
||||
return (
|
||||
<motion.tr
|
||||
{...row.getRowProps({
|
||||
layoutTransition: spring,
|
||||
exit: { opacity: 0, maxHeight: 0 },
|
||||
})}
|
||||
>
|
||||
{row.cells.map((cell, i) => {
|
||||
return (
|
||||
<motion.td
|
||||
{...cell.getCellProps({
|
||||
layoutTransition: spring,
|
||||
})}
|
||||
>
|
||||
{cell.render('Cell')}
|
||||
</motion.td>
|
||||
)
|
||||
})}
|
||||
</motion.tr>
|
||||
)}
|
||||
)}
|
||||
{rows.slice(0, 10).map((row, i) => {
|
||||
prepareRow(row)
|
||||
return (
|
||||
<motion.tr
|
||||
{...row.getRowProps({
|
||||
layoutTransition: spring,
|
||||
exit: { opacity: 0, maxHeight: 0 },
|
||||
})}
|
||||
>
|
||||
{row.cells.map((cell, i) => {
|
||||
return (
|
||||
<motion.td
|
||||
{...cell.getCellProps({
|
||||
layoutTransition: spring,
|
||||
})}
|
||||
>
|
||||
{cell.render('Cell')}
|
||||
</motion.td>
|
||||
)
|
||||
})}
|
||||
</motion.tr>
|
||||
)
|
||||
})}
|
||||
</AnimatePresence>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
+10
-11
@@ -59,17 +59,16 @@ function Table({ columns, data }) {
|
||||
))}
|
||||
</thead>
|
||||
<tbody {...getTableBodyProps()}>
|
||||
{rows.map(
|
||||
(row, i) => {
|
||||
prepareRow(row);
|
||||
return (
|
||||
<tr {...row.getRowProps()}>
|
||||
{row.cells.map(cell => {
|
||||
return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
|
||||
})}
|
||||
</tr>
|
||||
)}
|
||||
)}
|
||||
{rows.map((row, i) => {
|
||||
prepareRow(row)
|
||||
return (
|
||||
<tr {...row.getRowProps()}>
|
||||
{row.cells.map(cell => {
|
||||
return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
|
||||
})}
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
)
|
||||
|
||||
+16
-11
@@ -1578,9 +1578,9 @@ acorn-walk@^6.0.1:
|
||||
integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==
|
||||
|
||||
acorn@^5.5.3:
|
||||
version "5.7.3"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
|
||||
integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==
|
||||
version "5.7.4"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e"
|
||||
integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==
|
||||
|
||||
acorn@^6.0.1, acorn@^6.0.4, acorn@^6.0.5, acorn@^6.0.7:
|
||||
version "6.2.0"
|
||||
@@ -2632,7 +2632,7 @@ commander@2.17.x:
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
|
||||
integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==
|
||||
|
||||
commander@^2.11.0, commander@^2.19.0, commander@^2.20.0, commander@~2.20.0:
|
||||
commander@^2.11.0, commander@^2.19.0, commander@^2.20.0:
|
||||
version "2.20.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
|
||||
integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
|
||||
@@ -2642,6 +2642,11 @@ commander@~2.19.0:
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
|
||||
integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
|
||||
|
||||
commander@~2.20.3:
|
||||
version "2.20.3"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
||||
|
||||
common-tags@^1.8.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937"
|
||||
@@ -4369,9 +4374,9 @@ handle-thing@^2.0.0:
|
||||
integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==
|
||||
|
||||
handlebars@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67"
|
||||
integrity sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==
|
||||
version "4.5.3"
|
||||
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.3.tgz#5cf75bd8714f7605713511a56be7c349becb0482"
|
||||
integrity sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==
|
||||
dependencies:
|
||||
neo-async "^2.6.0"
|
||||
optimist "^0.6.1"
|
||||
@@ -9435,11 +9440,11 @@ uglify-js@3.4.x:
|
||||
source-map "~0.6.1"
|
||||
|
||||
uglify-js@^3.1.4:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.0.tgz#704681345c53a8b2079fb6cec294b05ead242ff5"
|
||||
integrity sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==
|
||||
version "3.7.3"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.3.tgz#f918fce9182f466d5140f24bb0ff35c2d32dcc6a"
|
||||
integrity sha512-7tINm46/3puUA4hCkKYo4Xdts+JDaVC9ZPRcG8Xw9R4nhO/gZgUM3TENq8IF4Vatk8qCig4MzP/c8G4u2BkVQg==
|
||||
dependencies:
|
||||
commander "~2.20.0"
|
||||
commander "~2.20.3"
|
||||
source-map "~0.6.1"
|
||||
|
||||
unicode-canonical-property-names-ecmascript@^1.0.4:
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"presets": ["react-app"]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
SKIP_PREFLIGHT_CHECK=true
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": ["react-app", "prettier"],
|
||||
"rules": {
|
||||
// "eqeqeq": 0,
|
||||
// "jsx-a11y/anchor-is-valid": 0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# 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*
|
||||
@@ -0,0 +1,29 @@
|
||||
const path = require('path')
|
||||
const resolveFrom = require('resolve-from')
|
||||
|
||||
const fixLinkedDependencies = config => {
|
||||
config.resolve = {
|
||||
...config.resolve,
|
||||
alias: {
|
||||
...config.resolve.alias,
|
||||
react$: resolveFrom(path.resolve('node_modules'), 'react'),
|
||||
'react-dom$': resolveFrom(path.resolve('node_modules'), 'react-dom'),
|
||||
},
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
const includeSrcDirectory = config => {
|
||||
config.resolve = {
|
||||
...config.resolve,
|
||||
modules: [path.resolve('src'), ...config.resolve.modules],
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
module.exports = [
|
||||
['use-babel-config', '.babelrc'],
|
||||
['use-eslint-config', '.eslintrc'],
|
||||
fixLinkedDependencies,
|
||||
// includeSrcDirectory,
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app) and Rescripts.
|
||||
|
||||
You can:
|
||||
|
||||
- [Open this example in a new CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/material-UI-components)
|
||||
- `yarn` and `yarn start` to run and edit the example
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "rescripts start",
|
||||
"build": "rescripts build",
|
||||
"test": "rescripts test",
|
||||
"eject": "rescripts eject"
|
||||
},
|
||||
"dependencies": {
|
||||
"namor": "^1.1.2",
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-scripts": "3.0.1",
|
||||
"react-table": "latest",
|
||||
"bootstrap": "^4.4.1",
|
||||
"react-bootstrap": "^1.0.0-beta.16"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rescripts/cli": "^0.0.11",
|
||||
"@rescripts/rescript-use-babel-config": "^0.0.8",
|
||||
"@rescripts/rescript-use-eslint-config": "^0.0.9",
|
||||
"babel-eslint": "10.0.1",
|
||||
"eslint-config-prettier": "^6.3.0"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!--
|
||||
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>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<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>
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
import React from 'react'
|
||||
|
||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
|
||||
import BTable from 'react-bootstrap/Table';
|
||||
|
||||
import { useTable } from 'react-table'
|
||||
|
||||
import makeData from './makeData'
|
||||
|
||||
function Table({ columns, data }) {
|
||||
// Use the state and functions returned from useTable to build your UI
|
||||
const { getTableProps, headerGroups, rows, prepareRow } = useTable({
|
||||
columns,
|
||||
data,
|
||||
})
|
||||
|
||||
// Render the UI for your table
|
||||
return (
|
||||
<BTable striped bordered hover size="sm" {...getTableProps()}>
|
||||
<thead>
|
||||
{headerGroups.map(headerGroup => (
|
||||
<tr {...headerGroup.getHeaderGroupProps()}>
|
||||
{headerGroup.headers.map(column => (
|
||||
<th {...column.getHeaderProps()}>
|
||||
{column.render('Header')}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows.map((row, i) => {
|
||||
prepareRow(row)
|
||||
return (
|
||||
<tr {...row.getRowProps()}>
|
||||
{row.cells.map(cell => {
|
||||
return (
|
||||
<th {...cell.getCellProps()}>
|
||||
{cell.render('Cell')}
|
||||
</th>
|
||||
)
|
||||
})}
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</BTable>
|
||||
)
|
||||
}
|
||||
|
||||
function App() {
|
||||
const columns = React.useMemo(
|
||||
() => [
|
||||
{
|
||||
Header: 'Name',
|
||||
columns: [
|
||||
{
|
||||
Header: 'First Name',
|
||||
accessor: 'firstName',
|
||||
},
|
||||
{
|
||||
Header: 'Last Name',
|
||||
accessor: 'lastName',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
Header: 'Info',
|
||||
columns: [
|
||||
{
|
||||
Header: 'Age',
|
||||
accessor: 'age',
|
||||
},
|
||||
{
|
||||
Header: 'Visits',
|
||||
accessor: 'visits',
|
||||
},
|
||||
{
|
||||
Header: 'Status',
|
||||
accessor: 'status',
|
||||
},
|
||||
{
|
||||
Header: 'Profile Progress',
|
||||
accessor: 'progress',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
[]
|
||||
)
|
||||
|
||||
const data = React.useMemo(() => makeData(20), [])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Table columns={columns} data={data} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
||||
@@ -0,0 +1,9 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import App from './App';
|
||||
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
ReactDOM.render(<App />, div);
|
||||
ReactDOM.unmountComponentAtNode(div);
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import './index.css'
|
||||
import App from './App'
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById('root'))
|
||||
@@ -0,0 +1,40 @@
|
||||
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 default function makeData(...lens) {
|
||||
const makeDataLevel = (depth = 0) => {
|
||||
const len = lens[depth]
|
||||
return range(len).map(d => {
|
||||
return {
|
||||
...newPerson(),
|
||||
subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return makeDataLevel()
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"presets": ["react-app"]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
SKIP_PREFLIGHT_CHECK=true
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": ["react-app", "prettier"],
|
||||
"rules": {
|
||||
// "eqeqeq": 0,
|
||||
// "jsx-a11y/anchor-is-valid": 0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# 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*
|
||||
@@ -0,0 +1,29 @@
|
||||
const path = require('path')
|
||||
const resolveFrom = require('resolve-from')
|
||||
|
||||
const fixLinkedDependencies = config => {
|
||||
config.resolve = {
|
||||
...config.resolve,
|
||||
alias: {
|
||||
...config.resolve.alias,
|
||||
react$: resolveFrom(path.resolve('node_modules'), 'react'),
|
||||
'react-dom$': resolveFrom(path.resolve('node_modules'), 'react-dom'),
|
||||
},
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
const includeSrcDirectory = config => {
|
||||
config.resolve = {
|
||||
...config.resolve,
|
||||
modules: [path.resolve('src'), ...config.resolve.modules],
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
module.exports = [
|
||||
['use-babel-config', '.babelrc'],
|
||||
['use-eslint-config', '.eslintrc'],
|
||||
fixLinkedDependencies,
|
||||
// includeSrcDirectory,
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app) and Rescripts.
|
||||
|
||||
You can:
|
||||
|
||||
- [Open this example in a new CodeSandbox](https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/material-UI-components)
|
||||
- `yarn` and `yarn start` to run and edit the example
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "rescripts start",
|
||||
"build": "rescripts build",
|
||||
"test": "rescripts test",
|
||||
"eject": "rescripts eject"
|
||||
},
|
||||
"dependencies": {
|
||||
"namor": "^1.1.2",
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-scripts": "3.0.1",
|
||||
"react-table": "latest",
|
||||
"bootstrap": "^4.4.1",
|
||||
"react-bootstrap": "^1.0.0-beta.16"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rescripts/cli": "^0.0.11",
|
||||
"@rescripts/rescript-use-babel-config": "^0.0.8",
|
||||
"@rescripts/rescript-use-eslint-config": "^0.0.9",
|
||||
"babel-eslint": "10.0.1",
|
||||
"eslint-config-prettier": "^6.3.0"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!--
|
||||
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>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<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>
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
import React from 'react'
|
||||
|
||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
|
||||
import BTable from 'react-bootstrap/Table';
|
||||
|
||||
import { useTable } from 'react-table'
|
||||
|
||||
import makeData from './makeData'
|
||||
|
||||
function Table({ columns, data }) {
|
||||
// Use the state and functions returned from useTable to build your UI
|
||||
const { getTableProps, headerGroups, rows, prepareRow } = useTable({
|
||||
columns,
|
||||
data,
|
||||
})
|
||||
|
||||
// Render the UI for your table
|
||||
return (
|
||||
<BTable striped bordered hover size="sm" {...getTableProps()}>
|
||||
<thead>
|
||||
{headerGroups.map(headerGroup => (
|
||||
<tr {...headerGroup.getHeaderGroupProps()}>
|
||||
{headerGroup.headers.map(column => (
|
||||
<th {...column.getHeaderProps()}>
|
||||
{column.render('Header')}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows.map((row, i) => {
|
||||
prepareRow(row)
|
||||
return (
|
||||
<tr {...row.getRowProps()}>
|
||||
{row.cells.map(cell => {
|
||||
return (
|
||||
<th {...cell.getCellProps()}>
|
||||
{cell.render('Cell')}
|
||||
</th>
|
||||
)
|
||||
})}
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</BTable>
|
||||
)
|
||||
}
|
||||
|
||||
function App() {
|
||||
const columns = React.useMemo(
|
||||
() => [
|
||||
{
|
||||
Header: 'Name',
|
||||
columns: [
|
||||
{
|
||||
Header: 'First Name',
|
||||
accessor: 'firstName',
|
||||
},
|
||||
{
|
||||
Header: 'Last Name',
|
||||
accessor: 'lastName',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
Header: 'Info',
|
||||
columns: [
|
||||
{
|
||||
Header: 'Age',
|
||||
accessor: 'age',
|
||||
},
|
||||
{
|
||||
Header: 'Visits',
|
||||
accessor: 'visits',
|
||||
},
|
||||
{
|
||||
Header: 'Status',
|
||||
accessor: 'status',
|
||||
},
|
||||
{
|
||||
Header: 'Profile Progress',
|
||||
accessor: 'progress',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
[]
|
||||
)
|
||||
|
||||
const data = React.useMemo(() => makeData(20), [])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Table columns={columns} data={data} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
||||
@@ -0,0 +1,9 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import App from './App';
|
||||
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
ReactDOM.render(<App />, div);
|
||||
ReactDOM.unmountComponentAtNode(div);
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import './index.css'
|
||||
import App from './App'
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById('root'))
|
||||
@@ -0,0 +1,40 @@
|
||||
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 default function makeData(...lens) {
|
||||
const makeDataLevel = (depth = 0) => {
|
||||
const len = lens[depth]
|
||||
return range(len).map(d => {
|
||||
return {
|
||||
...newPerson(),
|
||||
subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return makeDataLevel()
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -53,7 +53,7 @@ function Table({ columns, data }) {
|
||||
headerGroups,
|
||||
rows,
|
||||
prepareRow,
|
||||
flatColumns,
|
||||
allColumns,
|
||||
getToggleHideAllColumnsProps,
|
||||
state,
|
||||
} = useTable({
|
||||
@@ -69,10 +69,12 @@ function Table({ columns, data }) {
|
||||
<IndeterminateCheckbox {...getToggleHideAllColumnsProps()} /> Toggle
|
||||
All
|
||||
</div>
|
||||
{flatColumns.map(column => (
|
||||
{allColumns.map(column => (
|
||||
<div key={column.id}>
|
||||
<input type="checkbox" {...column.getToggleHiddenProps()} />{' '}
|
||||
{column.id}
|
||||
<label>
|
||||
<input type="checkbox" {...column.getToggleHiddenProps()} />{' '}
|
||||
{column.id}
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
<br />
|
||||
|
||||
@@ -1578,9 +1578,9 @@ acorn-walk@^6.0.1:
|
||||
integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==
|
||||
|
||||
acorn@^5.5.3:
|
||||
version "5.7.3"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
|
||||
integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==
|
||||
version "5.7.4"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e"
|
||||
integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==
|
||||
|
||||
acorn@^6.0.1, acorn@^6.0.4, acorn@^6.0.5, acorn@^6.0.7:
|
||||
version "6.2.0"
|
||||
@@ -2632,7 +2632,7 @@ commander@2.17.x:
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
|
||||
integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==
|
||||
|
||||
commander@^2.11.0, commander@^2.19.0, commander@^2.20.0, commander@~2.20.0:
|
||||
commander@^2.11.0, commander@^2.19.0, commander@^2.20.0:
|
||||
version "2.20.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
|
||||
integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
|
||||
@@ -2642,6 +2642,11 @@ commander@~2.19.0:
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
|
||||
integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
|
||||
|
||||
commander@~2.20.3:
|
||||
version "2.20.3"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
||||
|
||||
common-tags@^1.8.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937"
|
||||
@@ -4369,9 +4374,9 @@ handle-thing@^2.0.0:
|
||||
integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==
|
||||
|
||||
handlebars@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67"
|
||||
integrity sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.6.0.tgz#33af6c3eda930d7a924f5d8f1c6d8edc3180512e"
|
||||
integrity sha512-i1ZUP7Qp2JdkMaFon2a+b0m5geE8Z4ZTLaGkgrObkEd+OkUKyRbRWw4KxuFCoHfdETSY1yf9/574eVoNSiK7pw==
|
||||
dependencies:
|
||||
neo-async "^2.6.0"
|
||||
optimist "^0.6.1"
|
||||
@@ -9435,11 +9440,11 @@ uglify-js@3.4.x:
|
||||
source-map "~0.6.1"
|
||||
|
||||
uglify-js@^3.1.4:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.0.tgz#704681345c53a8b2079fb6cec294b05ead242ff5"
|
||||
integrity sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==
|
||||
version "3.7.4"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.4.tgz#e6d83a1aa32ff448bd1679359ab13d8db0fe0743"
|
||||
integrity sha512-tinYWE8X1QfCHxS1lBS8yiDekyhSXOO6R66yNOCdUJeojxxw+PX2BHAz/BWyW7PQ7pkiWVxJfIEbiDxyLWvUGg==
|
||||
dependencies:
|
||||
commander "~2.20.0"
|
||||
commander "~2.20.3"
|
||||
source-map "~0.6.1"
|
||||
|
||||
unicode-canonical-property-names-ecmascript@^1.0.4:
|
||||
|
||||
@@ -50,7 +50,7 @@ function Table({ columns, data }) {
|
||||
getTableBodyProps,
|
||||
headerGroups,
|
||||
rows,
|
||||
flatColumns,
|
||||
visibleColumns,
|
||||
prepareRow,
|
||||
setColumnOrder,
|
||||
state,
|
||||
@@ -63,7 +63,7 @@ function Table({ columns, data }) {
|
||||
)
|
||||
|
||||
const randomizeColumns = () => {
|
||||
setColumnOrder(shuffle(flatColumns.map(d => d.id)))
|
||||
setColumnOrder(shuffle(visibleColumns.map(d => d.id)))
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -80,19 +80,16 @@ function Table({ columns, data }) {
|
||||
))}
|
||||
</thead>
|
||||
<tbody {...getTableBodyProps()}>
|
||||
{rows.slice(0, 10).map(
|
||||
(row, i) => {
|
||||
prepareRow(row);
|
||||
return (
|
||||
<tr {...row.getRowProps()}>
|
||||
{row.cells.map((cell, i) => {
|
||||
return (
|
||||
<td {...cell.getCellProps()}>{cell.render('Cell')}</td>
|
||||
)
|
||||
})}
|
||||
</tr>
|
||||
)}
|
||||
)}
|
||||
{rows.slice(0, 10).map((row, i) => {
|
||||
prepareRow(row)
|
||||
return (
|
||||
<tr {...row.getRowProps()}>
|
||||
{row.cells.map((cell, i) => {
|
||||
return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
|
||||
})}
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
<pre>
|
||||
|
||||
@@ -46,7 +46,7 @@ const Styles = styled.div`
|
||||
|
||||
// Create an editable cell renderer
|
||||
const EditableCell = ({
|
||||
cell: { value: initialValue },
|
||||
value: initialValue,
|
||||
row: { index },
|
||||
column: { id },
|
||||
updateMyData, // This is a custom function that we supplied to our table instance
|
||||
@@ -63,7 +63,7 @@ const EditableCell = ({
|
||||
updateMyData(index, id, value)
|
||||
}
|
||||
|
||||
// If the initialValue is changed externall, sync it up with our state
|
||||
// If the initialValue is changed external, sync it up with our state
|
||||
React.useEffect(() => {
|
||||
setValue(initialValue)
|
||||
}, [initialValue])
|
||||
|
||||
@@ -88,14 +88,18 @@ function App() {
|
||||
() => [
|
||||
{
|
||||
// Build our expander column
|
||||
Header: () => null, // No header, please
|
||||
id: 'expander', // Make sure it has an ID
|
||||
Header: ({ getToggleAllRowsExpandedProps, isAllRowsExpanded }) => (
|
||||
<span {...getToggleAllRowsExpandedProps()}>
|
||||
{isAllRowsExpanded ? '👇' : '👉'}
|
||||
</span>
|
||||
),
|
||||
Cell: ({ row }) =>
|
||||
// Use the row.canExpand and row.getExpandedToggleProps prop getter
|
||||
// Use the row.canExpand and row.getToggleRowExpandedProps prop getter
|
||||
// to build the toggle for expanding a row
|
||||
row.canExpand ? (
|
||||
<span
|
||||
{...row.getExpandedToggleProps({
|
||||
{...row.getToggleRowExpandedProps({
|
||||
style: {
|
||||
// We can even use the row.depth property
|
||||
// and paddingLeft to indicate the depth
|
||||
|
||||
@@ -8087,10 +8087,10 @@ react-scripts@3.0.1:
|
||||
optionalDependencies:
|
||||
fsevents "2.0.6"
|
||||
|
||||
react-table@next:
|
||||
version "7.0.0-alpha.7"
|
||||
resolved "https://registry.yarnpkg.com/react-table/-/react-table-7.0.0-alpha.7.tgz#0cb6da6f32adb397e68505b7cdd4880d15d73017"
|
||||
integrity sha512-oXE9RRkE2CFk1OloNCSTPQ9qxOdujgkCoW5b/srbJsBog/ySkWuozBTQkxH1wGNmnSxGyTrTxJqXdXPQam7VAw==
|
||||
react-table@latest:
|
||||
version "7.0.0-rc.15"
|
||||
resolved "https://registry.yarnpkg.com/react-table/-/react-table-7.0.0-rc.15.tgz#bb855e4e2abbb4aaf0ed2334404a41f3ada8e13a"
|
||||
integrity sha512-ofMOlgrioHhhvHjvjsQkxvfQzU98cqwy6BjPGNwhLN1vhgXeWi0mUGreaCPvRenEbTiXsQbMl4k3Xmx3Mut8Rw==
|
||||
|
||||
react@^16.8.6:
|
||||
version "16.8.6"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import { useTable, useFilters } from 'react-table'
|
||||
import { useTable, useFilters, useGlobalFilter } from 'react-table'
|
||||
// A great library for fuzzy filtering/sorting items
|
||||
import matchSorter from 'match-sorter'
|
||||
|
||||
@@ -35,6 +35,32 @@ const Styles = styled.div`
|
||||
}
|
||||
`
|
||||
|
||||
// Define a default UI for filtering
|
||||
function GlobalFilter({
|
||||
preGlobalFilteredRows,
|
||||
globalFilter,
|
||||
setGlobalFilter,
|
||||
}) {
|
||||
const count = preGlobalFilteredRows.length
|
||||
|
||||
return (
|
||||
<span>
|
||||
Search:{' '}
|
||||
<input
|
||||
value={globalFilter || ''}
|
||||
onChange={e => {
|
||||
setGlobalFilter(e.target.value || undefined) // Set undefined to remove the filter entirely
|
||||
}}
|
||||
placeholder={`${count} records...`}
|
||||
style={{
|
||||
fontSize: '1.1rem',
|
||||
border: '0',
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
// Define a default UI for filtering
|
||||
function DefaultColumnFilter({
|
||||
column: { filterValue, preFilteredRows, setFilter },
|
||||
@@ -217,6 +243,9 @@ function Table({ columns, data }) {
|
||||
rows,
|
||||
prepareRow,
|
||||
state,
|
||||
visibleColumns,
|
||||
preGlobalFilteredRows,
|
||||
setGlobalFilter,
|
||||
} = useTable(
|
||||
{
|
||||
columns,
|
||||
@@ -224,7 +253,8 @@ function Table({ columns, data }) {
|
||||
defaultColumn, // Be sure to pass the defaultColumn option
|
||||
filterTypes,
|
||||
},
|
||||
useFilters // useFilters!
|
||||
useFilters, // useFilters!
|
||||
useGlobalFilter // useGlobalFilter!
|
||||
)
|
||||
|
||||
// We don't want to render all of the rows for this example, so cap
|
||||
@@ -233,11 +263,6 @@ function Table({ columns, data }) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<pre>
|
||||
<code>{JSON.stringify(state.filters, null, 2)}</code>
|
||||
</pre>
|
||||
</div>
|
||||
<table {...getTableProps()}>
|
||||
<thead>
|
||||
{headerGroups.map(headerGroup => (
|
||||
@@ -251,25 +276,41 @@ function Table({ columns, data }) {
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
<tr>
|
||||
<th
|
||||
colSpan={visibleColumns.length}
|
||||
style={{
|
||||
textAlign: 'left',
|
||||
}}
|
||||
>
|
||||
<GlobalFilter
|
||||
preGlobalFilteredRows={preGlobalFilteredRows}
|
||||
globalFilter={state.globalFilter}
|
||||
setGlobalFilter={setGlobalFilter}
|
||||
/>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody {...getTableBodyProps()}>
|
||||
{firstPageRows.map(
|
||||
(row, i) => {
|
||||
prepareRow(row);
|
||||
return (
|
||||
<tr {...row.getRowProps()}>
|
||||
{row.cells.map(cell => {
|
||||
return (
|
||||
<td {...cell.getCellProps()}>{cell.render('Cell')}</td>
|
||||
)
|
||||
})}
|
||||
</tr>
|
||||
)}
|
||||
)}
|
||||
{firstPageRows.map((row, i) => {
|
||||
prepareRow(row)
|
||||
return (
|
||||
<tr {...row.getRowProps()}>
|
||||
{row.cells.map(cell => {
|
||||
return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
|
||||
})}
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
<br />
|
||||
<div>Showing the first 20 results of {rows.length} rows</div>
|
||||
<div>
|
||||
<pre>
|
||||
<code>{JSON.stringify(state.filters, null, 2)}</code>
|
||||
</pre>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8094,10 +8094,10 @@ react-scripts@3.0.1:
|
||||
optionalDependencies:
|
||||
fsevents "2.0.6"
|
||||
|
||||
react-table@next:
|
||||
version "7.0.0-alpha.7"
|
||||
resolved "https://registry.yarnpkg.com/react-table/-/react-table-7.0.0-alpha.7.tgz#0cb6da6f32adb397e68505b7cdd4880d15d73017"
|
||||
integrity sha512-oXE9RRkE2CFk1OloNCSTPQ9qxOdujgkCoW5b/srbJsBog/ySkWuozBTQkxH1wGNmnSxGyTrTxJqXdXPQam7VAw==
|
||||
react-table@latest:
|
||||
version "7.0.0-rc.14"
|
||||
resolved "https://registry.yarnpkg.com/react-table/-/react-table-7.0.0-rc.14.tgz#bb4171fbdd56d78dd5f6b9e18694a36c00bd6261"
|
||||
integrity sha512-9NyzAE0kLH8HA+DK86ynxVDxniO5ZdggAqI7nDKauWXQGVYNFId8+JJSescJ2vwP9nR2JKyCEDG9c+CjIaLNkA==
|
||||
|
||||
react@^16.8.6:
|
||||
version "16.8.6"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"namor": "^1.1.2",
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-scripts": "3.0.1",
|
||||
"react-scripts": "3.3.0",
|
||||
"react-table": "latest",
|
||||
"styled-components": "^4.3.2"
|
||||
},
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import { useTable, useResizeColumns, useFlexLayout } from 'react-table'
|
||||
import {
|
||||
useTable,
|
||||
useResizeColumns,
|
||||
useFlexLayout,
|
||||
useRowSelect,
|
||||
} from 'react-table'
|
||||
|
||||
import makeData from './makeData'
|
||||
|
||||
const Styles = styled.div`
|
||||
padding: 1rem;
|
||||
${'' /* These styles are suggested for the table fill all available space in its containing element */}
|
||||
display: block;
|
||||
${'' /* These styles are required for a horizontaly scrollable table overflow */}
|
||||
overflow: auto;
|
||||
|
||||
.table {
|
||||
${'' /* These styles are suggested for the table fill all available space in its containing element */}
|
||||
display: block;
|
||||
${'' /* These styles are required for a horizontaly scrollable table overflow */}
|
||||
overflow: auto;
|
||||
|
||||
border-spacing: 0;
|
||||
border: 1px solid black;
|
||||
|
||||
@@ -35,13 +39,13 @@ const Styles = styled.div`
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
border-bottom: 1px solid black;
|
||||
}
|
||||
|
||||
.th,
|
||||
.td {
|
||||
margin: 0;
|
||||
padding: 0.5rem;
|
||||
border-bottom: 1px solid black;
|
||||
border-right: 1px solid black;
|
||||
|
||||
${'' /* In this example we use an absolutely position resizer,
|
||||
@@ -53,16 +57,15 @@ const Styles = styled.div`
|
||||
}
|
||||
|
||||
.resizer {
|
||||
display: inline-block;
|
||||
right: 0;
|
||||
background: blue;
|
||||
width: 10px;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
${'' /* prevents from scrolling while dragging on touch devices */}
|
||||
touch-action:none;
|
||||
touch-action :none;
|
||||
|
||||
&.isResizing {
|
||||
background: red;
|
||||
@@ -72,6 +75,38 @@ const Styles = styled.div`
|
||||
}
|
||||
`
|
||||
|
||||
const headerProps = (props, { column }) => getStyles(props, column.align)
|
||||
|
||||
const cellProps = (props, { cell }) => getStyles(props, cell.column.align)
|
||||
|
||||
const getStyles = (props, align = 'left') => [
|
||||
props,
|
||||
{
|
||||
style: {
|
||||
justifyContent: align === 'right' ? 'flex-end' : 'flex-start',
|
||||
alignItems: 'flex-start',
|
||||
display: 'flex',
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
const IndeterminateCheckbox = React.forwardRef(
|
||||
({ indeterminate, ...rest }, ref) => {
|
||||
const defaultRef = React.useRef()
|
||||
const resolvedRef = ref || defaultRef
|
||||
|
||||
React.useEffect(() => {
|
||||
resolvedRef.current.indeterminate = indeterminate
|
||||
}, [resolvedRef, indeterminate])
|
||||
|
||||
return (
|
||||
<>
|
||||
<input type="checkbox" ref={resolvedRef} {...rest} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
function Table({ columns, data }) {
|
||||
const defaultColumn = React.useMemo(
|
||||
() => ({
|
||||
@@ -83,49 +118,84 @@ function Table({ columns, data }) {
|
||||
[]
|
||||
)
|
||||
|
||||
const {
|
||||
getTableProps,
|
||||
getTableBodyProps,
|
||||
headerGroups,
|
||||
rows,
|
||||
prepareRow,
|
||||
} = useTable(
|
||||
const { getTableProps, headerGroups, rows, prepareRow } = useTable(
|
||||
{
|
||||
columns,
|
||||
data,
|
||||
defaultColumn,
|
||||
},
|
||||
useResizeColumns,
|
||||
useFlexLayout
|
||||
useFlexLayout,
|
||||
useRowSelect,
|
||||
hooks => {
|
||||
hooks.allColumns.push(columns => [
|
||||
// Let's make a column for selection
|
||||
{
|
||||
id: 'selection',
|
||||
disableResizing: true,
|
||||
minWidth: 35,
|
||||
width: 35,
|
||||
maxWidth: 35,
|
||||
// The header can use the table's getToggleAllRowsSelectedProps method
|
||||
// to render a checkbox
|
||||
Header: ({ getToggleAllRowsSelectedProps }) => (
|
||||
<div>
|
||||
<IndeterminateCheckbox {...getToggleAllRowsSelectedProps()} />
|
||||
</div>
|
||||
),
|
||||
// The cell can use the individual row's getToggleRowSelectedProps method
|
||||
// to the render a checkbox
|
||||
Cell: ({ row }) => (
|
||||
<div>
|
||||
<IndeterminateCheckbox {...row.getToggleRowSelectedProps()} />
|
||||
</div>
|
||||
),
|
||||
},
|
||||
...columns,
|
||||
])
|
||||
hooks.useInstanceBeforeDimensions.push(({ headerGroups }) => {
|
||||
// fix the parent group of the selection button to not be resizable
|
||||
const selectionGroupHeader = headerGroups[0].headers[0]
|
||||
selectionGroupHeader.canResize = false
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
return (
|
||||
<div {...getTableProps()} className="table">
|
||||
<div>
|
||||
{headerGroups.map(headerGroup => (
|
||||
<div {...headerGroup.getHeaderGroupProps()} className="tr">
|
||||
<div
|
||||
{...headerGroup.getHeaderGroupProps({
|
||||
// style: { paddingRight: '15px' },
|
||||
})}
|
||||
className="tr"
|
||||
>
|
||||
{headerGroup.headers.map(column => (
|
||||
<div {...column.getHeaderProps()} className="th">
|
||||
<div {...column.getHeaderProps(headerProps)} className="th">
|
||||
{column.render('Header')}
|
||||
{/* Use column.getResizerProps to hook up the events correctly */}
|
||||
<div
|
||||
{...column.getResizerProps()}
|
||||
className={`resizer ${column.isResizing ? 'isResizing' : ''}`}
|
||||
/>
|
||||
{column.canResize && (
|
||||
<div
|
||||
{...column.getResizerProps()}
|
||||
className={`resizer ${
|
||||
column.isResizing ? 'isResizing' : ''
|
||||
}`}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div {...getTableBodyProps()} className="tbody">
|
||||
{rows.map((row, i) => {
|
||||
<div className="tbody">
|
||||
{rows.map(row => {
|
||||
prepareRow(row)
|
||||
return (
|
||||
<div {...row.getRowProps()} className="tr">
|
||||
{row.cells.map(cell => {
|
||||
return (
|
||||
<div {...cell.getCellProps()} className="td">
|
||||
<div {...cell.getCellProps(cellProps)} className="td">
|
||||
{cell.render('Cell')}
|
||||
</div>
|
||||
)
|
||||
@@ -161,11 +231,13 @@ function App() {
|
||||
Header: 'Age',
|
||||
accessor: 'age',
|
||||
width: 50,
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
Header: 'Visits',
|
||||
accessor: 'visits',
|
||||
width: 50,
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
Header: 'Status',
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -33,6 +33,20 @@ const Styles = styled.div`
|
||||
}
|
||||
`
|
||||
|
||||
function useControlledState(state, { instance }) {
|
||||
return React.useMemo(() => {
|
||||
if (state.groupBy.length) {
|
||||
return {
|
||||
...state,
|
||||
hiddenColumns: [...state.hiddenColumns, ...state.groupBy].filter(
|
||||
(d, i, all) => all.indexOf(d) === i
|
||||
),
|
||||
}
|
||||
}
|
||||
return state
|
||||
}, [state])
|
||||
}
|
||||
|
||||
function Table({ columns, data }) {
|
||||
const {
|
||||
getTableProps,
|
||||
@@ -40,7 +54,7 @@ function Table({ columns, data }) {
|
||||
headerGroups,
|
||||
rows,
|
||||
prepareRow,
|
||||
state: { groupBy, expanded },
|
||||
state,
|
||||
} = useTable(
|
||||
{
|
||||
columns,
|
||||
@@ -50,7 +64,8 @@ function Table({ columns, data }) {
|
||||
useExpanded,
|
||||
// Our custom plugin to add the expander column
|
||||
hooks => {
|
||||
hooks.flatColumns.push((columns, instance) => {
|
||||
hooks.useControlledState.push(useControlledState)
|
||||
hooks.visibleColumns.push((columns, { instance }) => {
|
||||
if (!instance.state.groupBy.length) {
|
||||
return columns
|
||||
}
|
||||
@@ -59,9 +74,9 @@ function Table({ columns, data }) {
|
||||
{
|
||||
id: 'expander', // Make sure it has an ID
|
||||
// Build our expander column
|
||||
Header: ({ flatColumns, state: { groupBy } }) => {
|
||||
Header: ({ allColumns, state: { groupBy } }) => {
|
||||
return groupBy.map(columnId => {
|
||||
const column = flatColumns.find(d => d.id === columnId)
|
||||
const column = allColumns.find(d => d.id === columnId)
|
||||
|
||||
return (
|
||||
<span {...column.getHeaderProps()}>
|
||||
@@ -82,7 +97,7 @@ function Table({ columns, data }) {
|
||||
|
||||
return (
|
||||
<span
|
||||
{...row.getExpandedToggleProps({
|
||||
{...row.getToggleRowExpandedProps({
|
||||
style: {
|
||||
// We can even use the row.depth property
|
||||
// and paddingLeft to indicate the depth
|
||||
@@ -100,20 +115,20 @@ function Table({ columns, data }) {
|
||||
return null
|
||||
},
|
||||
},
|
||||
...columns.map(d => ({ ...d, isVisible: !d.isGrouped })),
|
||||
...columns,
|
||||
]
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
// We don't want to render all of the rows for this example, so cap
|
||||
// it at 20 for this use case
|
||||
// it at 100 for this use case
|
||||
const firstPageRows = rows.slice(0, 100)
|
||||
|
||||
return (
|
||||
<>
|
||||
<pre>
|
||||
<code>{JSON.stringify({ groupBy, expanded: expanded }, null, 2)}</code>
|
||||
<code>{JSON.stringify({ state }, null, 2)}</code>
|
||||
</pre>
|
||||
<Legend />
|
||||
<table {...getTableProps()}>
|
||||
@@ -151,7 +166,7 @@ function Table({ columns, data }) {
|
||||
? '#0aff0082'
|
||||
: cell.isAggregated
|
||||
? '#ffa50078'
|
||||
: cell.isRepeatedValue
|
||||
: cell.isPlaceholder
|
||||
? '#ff000042'
|
||||
: 'white',
|
||||
}}
|
||||
@@ -160,7 +175,7 @@ function Table({ columns, data }) {
|
||||
? // If the cell is aggregated, use the Aggregated
|
||||
// renderer for cell
|
||||
cell.render('Aggregated')
|
||||
: cell.isRepeatedValue
|
||||
: cell.isPlaceholder
|
||||
? null // For cells with repeated values, render null
|
||||
: // Otherwise, just render the regular cell
|
||||
cell.render('Cell')}
|
||||
@@ -210,20 +225,20 @@ function Legend() {
|
||||
padding: '0.5rem',
|
||||
}}
|
||||
>
|
||||
Repeated Value
|
||||
Placeholder
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// This is a custom aggregator that
|
||||
// takes in an array of values and
|
||||
// takes in an array of leaf values and
|
||||
// returns the rounded median
|
||||
function roundedMedian(values) {
|
||||
let min = values[0] || ''
|
||||
let max = values[0] || ''
|
||||
function roundedMedian(leafValues) {
|
||||
let min = leafValues[0] || 0
|
||||
let max = leafValues[0] || 0
|
||||
|
||||
values.forEach(value => {
|
||||
leafValues.forEach(value => {
|
||||
min = Math.min(min, value)
|
||||
max = Math.max(max, value)
|
||||
})
|
||||
@@ -244,8 +259,8 @@ function App() {
|
||||
// count the total rows being aggregated,
|
||||
// then sum any of those counts if they are
|
||||
// aggregated further
|
||||
aggregate: ['sum', 'count'],
|
||||
Aggregated: ({ cell: { value } }) => `${value} Names`,
|
||||
aggregate: 'count',
|
||||
Aggregated: ({ value }) => `${value} Names`,
|
||||
},
|
||||
{
|
||||
Header: 'Last Name',
|
||||
@@ -254,8 +269,8 @@ function App() {
|
||||
// first count the UNIQUE values from the rows
|
||||
// being aggregated, then sum those counts if
|
||||
// they are aggregated further
|
||||
aggregate: ['sum', 'uniqueCount'],
|
||||
Aggregated: ({ cell: { value } }) => `${value} Unique Names`,
|
||||
aggregate: 'uniqueCount',
|
||||
Aggregated: ({ value }) => `${value} Unique Names`,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -267,14 +282,14 @@ function App() {
|
||||
accessor: 'age',
|
||||
// Aggregate the average age of visitors
|
||||
aggregate: 'average',
|
||||
Aggregated: ({ cell: { value } }) => `${value} (avg)`,
|
||||
Aggregated: ({ value }) => `${value} (avg)`,
|
||||
},
|
||||
{
|
||||
Header: 'Visits',
|
||||
accessor: 'visits',
|
||||
// Aggregate the sum of all visits
|
||||
aggregate: 'sum',
|
||||
Aggregated: ({ cell: { value } }) => `${value} (total)`,
|
||||
Aggregated: ({ value }) => `${value} (total)`,
|
||||
},
|
||||
{
|
||||
Header: 'Status',
|
||||
@@ -285,7 +300,7 @@ function App() {
|
||||
accessor: 'progress',
|
||||
// Use our custom roundedMedian aggregator
|
||||
aggregate: roundedMedian,
|
||||
Aggregated: ({ cell: { value } }) => `${value} (med)`,
|
||||
Aggregated: ({ value }) => `${value} (med)`,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -51,7 +51,7 @@ function Table({ columns, data }) {
|
||||
)
|
||||
|
||||
// We don't want to render all of the rows for this example, so cap
|
||||
// it at 20 for this use case
|
||||
// it at 100 for this use case
|
||||
const firstPageRows = rows.slice(0, 100)
|
||||
|
||||
return (
|
||||
@@ -79,50 +79,49 @@ function Table({ columns, data }) {
|
||||
))}
|
||||
</thead>
|
||||
<tbody {...getTableBodyProps()}>
|
||||
{firstPageRows.map(
|
||||
(row, i) => {
|
||||
prepareRow(row);
|
||||
return (
|
||||
<tr {...row.getRowProps()}>
|
||||
{row.cells.map(cell => {
|
||||
return (
|
||||
<td
|
||||
// For educational purposes, let's color the
|
||||
// cell depending on what type it is given
|
||||
// from the useGroupBy hook
|
||||
{...cell.getCellProps()}
|
||||
style={{
|
||||
background: cell.isGrouped
|
||||
? '#0aff0082'
|
||||
: cell.isAggregated
|
||||
? '#ffa50078'
|
||||
: cell.isRepeatedValue
|
||||
? '#ff000042'
|
||||
: 'white',
|
||||
}}
|
||||
>
|
||||
{cell.isGrouped ? (
|
||||
// If it's a grouped cell, add an expander and row count
|
||||
<>
|
||||
<span {...row.getExpandedToggleProps()}>
|
||||
{row.isExpanded ? '👇' : '👉'}
|
||||
</span>{' '}
|
||||
{cell.render('Cell')} ({row.subRows.length})
|
||||
</>
|
||||
) : cell.isAggregated ? (
|
||||
// If the cell is aggregated, use the Aggregated
|
||||
// renderer for cell
|
||||
cell.render('Aggregated')
|
||||
) : cell.isRepeatedValue ? null : ( // For cells with repeated values, render null
|
||||
// Otherwise, just render the regular cell
|
||||
cell.render('Cell')
|
||||
)}
|
||||
</td>
|
||||
)
|
||||
})}
|
||||
</tr>
|
||||
)}
|
||||
)}
|
||||
{firstPageRows.map((row, i) => {
|
||||
prepareRow(row)
|
||||
return (
|
||||
<tr {...row.getRowProps()}>
|
||||
{row.cells.map(cell => {
|
||||
return (
|
||||
<td
|
||||
// For educational purposes, let's color the
|
||||
// cell depending on what type it is given
|
||||
// from the useGroupBy hook
|
||||
{...cell.getCellProps()}
|
||||
style={{
|
||||
background: cell.isGrouped
|
||||
? '#0aff0082'
|
||||
: cell.isAggregated
|
||||
? '#ffa50078'
|
||||
: cell.isPlaceholder
|
||||
? '#ff000042'
|
||||
: 'white',
|
||||
}}
|
||||
>
|
||||
{cell.isGrouped ? (
|
||||
// If it's a grouped cell, add an expander and row count
|
||||
<>
|
||||
<span {...row.getToggleRowExpandedProps()}>
|
||||
{row.isExpanded ? '👇' : '👉'}
|
||||
</span>{' '}
|
||||
{cell.render('Cell')} ({row.subRows.length})
|
||||
</>
|
||||
) : cell.isAggregated ? (
|
||||
// If the cell is aggregated, use the Aggregated
|
||||
// renderer for cell
|
||||
cell.render('Aggregated')
|
||||
) : cell.isPlaceholder ? null : ( // For cells with repeated values, render null
|
||||
// Otherwise, just render the regular cell
|
||||
cell.render('Cell')
|
||||
)}
|
||||
</td>
|
||||
)
|
||||
})}
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
<br />
|
||||
@@ -170,13 +169,13 @@ function Legend() {
|
||||
}
|
||||
|
||||
// This is a custom aggregator that
|
||||
// takes in an array of values and
|
||||
// takes in an array of leaf values and
|
||||
// returns the rounded median
|
||||
function roundedMedian(values) {
|
||||
let min = values[0] || ''
|
||||
let max = values[0] || ''
|
||||
function roundedMedian(leafValues) {
|
||||
let min = leafValues[0] || 0
|
||||
let max = leafValues[0] || 0
|
||||
|
||||
values.forEach(value => {
|
||||
leafValues.forEach(value => {
|
||||
min = Math.min(min, value)
|
||||
max = Math.max(max, value)
|
||||
})
|
||||
@@ -197,8 +196,8 @@ function App() {
|
||||
// count the total rows being aggregated,
|
||||
// then sum any of those counts if they are
|
||||
// aggregated further
|
||||
aggregate: ['sum', 'count'],
|
||||
Aggregated: ({ cell: { value } }) => `${value} Names`,
|
||||
aggregate: 'count',
|
||||
Aggregated: ({ value }) => `${value} Names`,
|
||||
},
|
||||
{
|
||||
Header: 'Last Name',
|
||||
@@ -207,8 +206,8 @@ function App() {
|
||||
// first count the UNIQUE values from the rows
|
||||
// being aggregated, then sum those counts if
|
||||
// they are aggregated further
|
||||
aggregate: ['sum', 'uniqueCount'],
|
||||
Aggregated: ({ cell: { value } }) => `${value} Unique Names`,
|
||||
aggregate: 'uniqueCount',
|
||||
Aggregated: ({ value }) => `${value} Unique Names`,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -220,14 +219,14 @@ function App() {
|
||||
accessor: 'age',
|
||||
// Aggregate the average age of visitors
|
||||
aggregate: 'average',
|
||||
Aggregated: ({ cell: { value } }) => `${value} (avg)`,
|
||||
Aggregated: ({ value }) => `${Math.round(value * 100) / 100} (avg)`,
|
||||
},
|
||||
{
|
||||
Header: 'Visits',
|
||||
accessor: 'visits',
|
||||
// Aggregate the sum of all visits
|
||||
aggregate: 'sum',
|
||||
Aggregated: ({ cell: { value } }) => `${value} (total)`,
|
||||
Aggregated: ({ value }) => `${value} (total)`,
|
||||
},
|
||||
{
|
||||
Header: 'Status',
|
||||
@@ -238,7 +237,7 @@ function App() {
|
||||
accessor: 'progress',
|
||||
// Use our custom roundedMedian aggregator
|
||||
aggregate: roundedMedian,
|
||||
Aggregated: ({ cell: { value } }) => `${value} (med)`,
|
||||
Aggregated: ({ value }) => `${value} (med)`,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
+16
-11
@@ -1578,9 +1578,9 @@ acorn-walk@^6.0.1:
|
||||
integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==
|
||||
|
||||
acorn@^5.5.3:
|
||||
version "5.7.3"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
|
||||
integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==
|
||||
version "5.7.4"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e"
|
||||
integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==
|
||||
|
||||
acorn@^6.0.1, acorn@^6.0.4, acorn@^6.0.5, acorn@^6.0.7:
|
||||
version "6.2.0"
|
||||
@@ -2632,7 +2632,7 @@ commander@2.17.x:
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
|
||||
integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==
|
||||
|
||||
commander@^2.11.0, commander@^2.19.0, commander@^2.20.0, commander@~2.20.0:
|
||||
commander@^2.11.0, commander@^2.19.0, commander@^2.20.0:
|
||||
version "2.20.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
|
||||
integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
|
||||
@@ -2642,6 +2642,11 @@ commander@~2.19.0:
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
|
||||
integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
|
||||
|
||||
commander@~2.20.3:
|
||||
version "2.20.3"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
||||
|
||||
common-tags@^1.8.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937"
|
||||
@@ -4369,9 +4374,9 @@ handle-thing@^2.0.0:
|
||||
integrity sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==
|
||||
|
||||
handlebars@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67"
|
||||
integrity sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==
|
||||
version "4.5.3"
|
||||
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.3.tgz#5cf75bd8714f7605713511a56be7c349becb0482"
|
||||
integrity sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==
|
||||
dependencies:
|
||||
neo-async "^2.6.0"
|
||||
optimist "^0.6.1"
|
||||
@@ -9435,11 +9440,11 @@ uglify-js@3.4.x:
|
||||
source-map "~0.6.1"
|
||||
|
||||
uglify-js@^3.1.4:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.0.tgz#704681345c53a8b2079fb6cec294b05ead242ff5"
|
||||
integrity sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==
|
||||
version "3.7.3"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.3.tgz#f918fce9182f466d5140f24bb0ff35c2d32dcc6a"
|
||||
integrity sha512-7tINm46/3puUA4hCkKYo4Xdts+JDaVC9ZPRcG8Xw9R4nhO/gZgUM3TENq8IF4Vatk8qCig4MzP/c8G4u2BkVQg==
|
||||
dependencies:
|
||||
commander "~2.20.0"
|
||||
commander "~2.20.3"
|
||||
source-map "~0.6.1"
|
||||
|
||||
unicode-canonical-property-names-ecmascript@^1.0.4:
|
||||
|
||||
@@ -57,7 +57,7 @@ const Styles = styled.div`
|
||||
|
||||
// Create an editable cell renderer
|
||||
const EditableCell = ({
|
||||
cell: { value: initialValue },
|
||||
value: initialValue,
|
||||
row: { index },
|
||||
column: { id },
|
||||
updateMyData, // This is a custom function that we supplied to our table instance
|
||||
@@ -301,14 +301,14 @@ function Table({ columns, data, updateMyData, skipPageReset }) {
|
||||
// when we edit the data, undefined means using the default
|
||||
autoResetPage: !skipPageReset,
|
||||
},
|
||||
useGroupBy,
|
||||
useFilters,
|
||||
useGroupBy,
|
||||
useSortBy,
|
||||
useExpanded,
|
||||
usePagination,
|
||||
useRowSelect,
|
||||
hooks => {
|
||||
hooks.flatColumns.push(columns => [
|
||||
hooks.visibleColumns.push(columns => [
|
||||
{
|
||||
id: 'selection',
|
||||
// Make this column a groupByBoundary. This ensures that groupBy columns
|
||||
@@ -378,7 +378,7 @@ function Table({ columns, data, updateMyData, skipPageReset }) {
|
||||
{cell.isGrouped ? (
|
||||
// If it's a grouped cell, add an expander and row count
|
||||
<>
|
||||
<span {...row.getExpandedToggleProps()}>
|
||||
<span {...row.getToggleRowExpandedProps()}>
|
||||
{row.isExpanded ? '👇' : '👉'}
|
||||
</span>{' '}
|
||||
{cell.render('Cell', { editable: false })} (
|
||||
@@ -388,7 +388,7 @@ function Table({ columns, data, updateMyData, skipPageReset }) {
|
||||
// If the cell is aggregated, use the Aggregated
|
||||
// renderer for cell
|
||||
cell.render('Aggregated')
|
||||
) : cell.isRepeatedValue ? null : ( // For cells with repeated values, render null
|
||||
) : cell.isPlaceholder ? null : ( // For cells with repeated values, render null
|
||||
// Otherwise, just render the regular cell
|
||||
cell.render('Cell', { editable: true })
|
||||
)}
|
||||
@@ -400,8 +400,8 @@ function Table({ columns, data, updateMyData, skipPageReset }) {
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
{/*
|
||||
Pagination can be built however you'd like.
|
||||
{/*
|
||||
Pagination can be built however you'd like.
|
||||
This is just a very basic UI implementation:
|
||||
*/}
|
||||
<div className="pagination">
|
||||
@@ -486,13 +486,13 @@ function filterGreaterThan(rows, id, filterValue) {
|
||||
filterGreaterThan.autoRemove = val => typeof val !== 'number'
|
||||
|
||||
// This is a custom aggregator that
|
||||
// takes in an array of values and
|
||||
// takes in an array of leaf values and
|
||||
// returns the rounded median
|
||||
function roundedMedian(values) {
|
||||
let min = values[0] || ''
|
||||
let max = values[0] || ''
|
||||
function roundedMedian(leafValues) {
|
||||
let min = leafValues[0] || 0
|
||||
let max = leafValues[0] || 0
|
||||
|
||||
values.forEach(value => {
|
||||
leafValues.forEach(value => {
|
||||
min = Math.min(min, value)
|
||||
max = Math.max(max, value)
|
||||
})
|
||||
@@ -513,8 +513,8 @@ function App() {
|
||||
// count the total rows being aggregated,
|
||||
// then sum any of those counts if they are
|
||||
// aggregated further
|
||||
aggregate: ['sum', 'count'],
|
||||
Aggregated: ({ cell: { value } }) => `${value} Names`,
|
||||
aggregate: 'count',
|
||||
Aggregated: ({ value }) => `${value} Names`,
|
||||
},
|
||||
{
|
||||
Header: 'Last Name',
|
||||
@@ -525,8 +525,8 @@ function App() {
|
||||
// first count the UNIQUE values from the rows
|
||||
// being aggregated, then sum those counts if
|
||||
// they are aggregated further
|
||||
aggregate: ['sum', 'uniqueCount'],
|
||||
Aggregated: ({ cell: { value } }) => `${value} Unique Names`,
|
||||
aggregate: 'uniqueCount',
|
||||
Aggregated: ({ value }) => `${value} Unique Names`,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -540,7 +540,7 @@ function App() {
|
||||
filter: 'equals',
|
||||
// Aggregate the average age of visitors
|
||||
aggregate: 'average',
|
||||
Aggregated: ({ cell: { value } }) => `${value} (avg)`,
|
||||
Aggregated: ({ value }) => `${value} (avg)`,
|
||||
},
|
||||
{
|
||||
Header: 'Visits',
|
||||
@@ -549,7 +549,7 @@ function App() {
|
||||
filter: 'between',
|
||||
// Aggregate the sum of all visits
|
||||
aggregate: 'sum',
|
||||
Aggregated: ({ cell: { value } }) => `${value} (total)`,
|
||||
Aggregated: ({ value }) => `${value} (total)`,
|
||||
},
|
||||
{
|
||||
Header: 'Status',
|
||||
@@ -564,7 +564,7 @@ function App() {
|
||||
filter: filterGreaterThan,
|
||||
// Use our custom roundedMedian aggregator
|
||||
aggregate: roundedMedian,
|
||||
Aggregated: ({ cell: { value } }) => `${value} (med)`,
|
||||
Aggregated: ({ value }) => `${value} (med)`,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -8095,10 +8095,10 @@ react-scripts@3.0.1:
|
||||
optionalDependencies:
|
||||
fsevents "2.0.6"
|
||||
|
||||
react-table@next:
|
||||
version "7.0.0-alpha.7"
|
||||
resolved "https://registry.yarnpkg.com/react-table/-/react-table-7.0.0-alpha.7.tgz#0cb6da6f32adb397e68505b7cdd4880d15d73017"
|
||||
integrity sha512-oXE9RRkE2CFk1OloNCSTPQ9qxOdujgkCoW5b/srbJsBog/ySkWuozBTQkxH1wGNmnSxGyTrTxJqXdXPQam7VAw==
|
||||
react-table@latest:
|
||||
version "7.0.0-rc.15"
|
||||
resolved "https://registry.yarnpkg.com/react-table/-/react-table-7.0.0-rc.15.tgz#bb855e4e2abbb4aaf0ed2334404a41f3ada8e13a"
|
||||
integrity sha512-ofMOlgrioHhhvHjvjsQkxvfQzU98cqwy6BjPGNwhLN1vhgXeWi0mUGreaCPvRenEbTiXsQbMl4k3Xmx3Mut8Rw==
|
||||
|
||||
react@^16.8.6:
|
||||
version "16.8.6"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user