mirror of
https://github.com/gosticks/react-table.git
synced 2026-08-19 16:30:21 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b72b81cf3 |
+7
-26
@@ -1,39 +1,20 @@
|
||||
{
|
||||
"dist/index.js": {
|
||||
"bundled": 108184,
|
||||
"minified": 51333,
|
||||
"gzipped": 13486
|
||||
"bundled": 100428,
|
||||
"minified": 47447,
|
||||
"gzipped": 12338
|
||||
},
|
||||
"dist/index.es.js": {
|
||||
"bundled": 107341,
|
||||
"minified": 50583,
|
||||
"gzipped": 13333,
|
||||
"bundled": 99612,
|
||||
"minified": 46722,
|
||||
"gzipped": 12193,
|
||||
"treeshaked": {
|
||||
"rollup": {
|
||||
"code": 80,
|
||||
"import_statements": 21
|
||||
},
|
||||
"webpack": {
|
||||
"code": 8904
|
||||
}
|
||||
}
|
||||
},
|
||||
"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
|
||||
"code": 8457
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +1,3 @@
|
||||
## 7.0.0-rc.8
|
||||
|
||||
- Fix an issue where `useResizeColumns` would crash when using the resizer prop getter
|
||||
- Fix an issue where `useBlockLayout` was clobbering props sent to headers
|
||||
|
||||
## 7.0.0-rc.7
|
||||
|
||||
Removed:
|
||||
|
||||
- `applyHooks` (exported but undocumented) function has been deprecated. Please use either `reduceHooks` or `loopHooks` utilities in your custom plugins now.
|
||||
- `applyPropHooks` (exported but undocumented) function has been deprecated. Please use the `makePropGetter` utility in your custom plugins now.
|
||||
|
||||
Added:
|
||||
|
||||
- `reduceHooks` exported utility which is used to reduce a value through a collection of hooks. Each hook must return a value (mutation is discouraged)
|
||||
- `loopHooks` exported utility which is used to loop over a collection of hooks. Hooks are not allowed to return a value (mutation is encouraged)
|
||||
- `makePropGetter` exported utility which is used to create prop getters from a prop getter hook.
|
||||
- `useOptions` plugin hook, which allows a plugin to reduce/modify the initial options being passed to the table
|
||||
- `useFinalInstance` plugin hook, which allows a plugin access to the final table instance before it is returned to the user.
|
||||
|
||||
Modified:
|
||||
|
||||
- Prop-getter hook functions now support returning an array (in addition to the typical object of props). When an array is returned, each item in the array is smart-merged into a new props object (meaning it will intelligently compose and override styles and className)
|
||||
- Prop-getter function supplied to the table have 2 new overloaded options (in addition to the typical object of props):
|
||||
- `Function(props, instance, ...row/col/context) => Array<props> | props` - If a function is passed to a prop getter function, it will receive the previous props, the table instance, and potentially more context arguments. It is then be expected to return either an array of new props (to be smart-merged with styles and classes, the latest values taking priority over the previous values) or a props object (which will replace all previous props)
|
||||
- `Array<props>` - If an array is passed to a prop getter function, each prop object in the array will be smart-merged with styles and classes into the props from previous hooks (with the latest values taking priority over the previous values).
|
||||
- Extracted default hooks into separate file.
|
||||
- Converted almost all usages of `instanceRef.current` to use `useGetLatest(instanceRef.current)` to help with avoiding memory leaks and to be more terse.
|
||||
- Converted all previous prop-getter definitions to use the new `makePropGetter`
|
||||
- Reorganized plugin hooks to declare as many hooks in the main plugin function as opposed to in the `useInstance` hook.
|
||||
- Changed the `useInstanceBeforeDimensions` hook to be a `loopHooks` call instead of a reducer. An error will be thrown now if any of these hook functions returns a value (to encourage mutation of the instance)
|
||||
- Changed the `useInstance` hook to be a `loopHooks` call instead of a reducer. An error will be thrown now if any of these hook functions returns a value (to encourage mutation of the instance)
|
||||
- Change the `prepareRow` hook to be a `loopHooks` call instead of a reducer. An error will be thrown now if any of these hook functions returns a value (to encourage mutation of the row)
|
||||
|
||||
## 7.0.0-rc.6
|
||||
|
||||
- The `columnsBeforeHeaderGroups` and `columnsBeforeHeaderGroupsDeps` hooks have been renamed to `flatColumns` and `flatColumnsDeps` respectively, which better reflects what they are used for, rather than their order, which can remain implicit.
|
||||
- Added `headerGroups` and `headerGroupDeps` hooks, which, similar to `flatColumns`, allow you to decorate (and trigger) the memoized header group generation.
|
||||
- Added `columns` and `columnsDeps` hooks, which, similar to `flatColumns` and `headerGroups`, allow you to decorate (and trigger) the memoized column generation/decoration.
|
||||
- The new hook order is as follows: `columns/columnsDeps` => `flatColumns/flatColumnsDeps` => `headerGroups/headerGroupsDeps`
|
||||
- `useColumnVisibility` now uses the new `headerGroupsDeps` hook to trigger header group regeneration when visibility changes
|
||||
|
||||
## 7.0.0-rc.5
|
||||
|
||||
- Fixed an issue where the exported `useAsyncDebounce` method would crash if its promise throw an error.
|
||||
|
||||
## 7.0.0-rc.4
|
||||
|
||||
- A maintenance release, purely intended to update the @latest tag (which was overwritten by a v6 publish)
|
||||
|
||||
## 7.0.0-rc.3
|
||||
|
||||
- Fixed an issue where `column.clearSortBy` would crash
|
||||
|
||||
## 7.0.0-rc.2
|
||||
|
||||
- `reducerHandlers` has been deprecated in favor of the new `stateReducers` hook.
|
||||
|
||||
@@ -21,7 +21,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 (4kb - 11kb depending on features and tree-shaking)
|
||||
- Headless (100% customizable, Bring-your-own-UI)
|
||||
- Auto out of the box, fully controllable API
|
||||
- Sorting (Multi and Stable)
|
||||
@@ -35,6 +35,7 @@ Enjoy this library? Try them all! [React Query](https://github.com/tannerlinsley
|
||||
- Resizable
|
||||
- Server-side/controlled data/state
|
||||
- Extensible via hook-based plugin system
|
||||
- <a href="https://medium.com/@tannerlinsley/why-i-wrote-react-table-and-the-problems-it-has-solved-for-nozzle-others-445c4e93d4a8#.axza4ixba" target="\_parent">"Why I wrote React Table and the problems it has solved for Nozzle.io"</a> by Tanner Linsley
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
@@ -35,7 +35,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
|
||||
|
||||
|
||||
@@ -27,10 +27,10 @@ The following options are supported via the main options object passed to `useTa
|
||||
- Must be **memoized**
|
||||
- Allows overriding or adding additional filter types for columns to use. If a column's filter 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
|
||||
- `autoResetFilters: Boolean`
|
||||
- Defaults to `true`
|
||||
- When `true`, the `filters` state will automatically reset if any of the following conditions are met:
|
||||
- `data` is changed
|
||||
- `getResetFiltersDeps: Function(instance) => [...useEffectDependencies]`
|
||||
- Optional
|
||||
- Defaults to `false`
|
||||
- If set, the dependencies returned from this function will be used to determine when the effect to reset the `filters` state is fired.
|
||||
- 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)
|
||||
|
||||
|
||||
+25
-23
@@ -28,29 +28,6 @@ useTable({
|
||||
|
||||
> **It's important that the state override is done within a `useMemo` call to prevent the state variable from changing on every render. It's also extremely important that you always use the `state` in any dependencies to ensure that you do not block normal state updates.**
|
||||
|
||||
## How can I use the table state to fetch new data?
|
||||
|
||||
When managing your data externally or asynchronously (eg. server-side pagination/sorting/grouping/etc), you will need to fetch new data as the internal table state changes. With React Hooks, this is fantastically easier than it was before now that we have the `React.useEffect` hook. We can use this hook to "watch" the table state for specific changes and use those effects to trigger fetches for new data (or synchronize any other state you may be managing externally from your table component):
|
||||
|
||||
```js
|
||||
function Table({ data, onFetchData }) {
|
||||
const {
|
||||
state: { pageIndex, pageSize, sortBy, filters },
|
||||
} = useTable({
|
||||
data,
|
||||
})
|
||||
|
||||
// When the these table states change, fetch new data!
|
||||
React.useEffect(() => {
|
||||
onFetchData({ pageIndex, pageSize, sortBy, filters })
|
||||
}, [fetchData, pageIndex, pageSize, sortBy, filters])
|
||||
|
||||
return </>
|
||||
}
|
||||
```
|
||||
|
||||
Using this approach, you can respond and trigger any type of side-effect using the table instance!
|
||||
|
||||
## How can I debounce rapid table state changes?
|
||||
|
||||
React Table has a few built-in side-effects of it's own (most of which are meant for resetting parts of the state when `data` changes). By default, these state side-effects are on and when their conditions are met, they immediately fire off actions that will manipulate the table state. Sometimes, this may result in multiple rapid rerenders (usually just 2, or one more than normal), and could cause any side-effects you have watching the table state to also fire multiple times in-a-row. To alleviate this edge-case, React Table exports a `useAsyncDebounce` function that will allow you to debounce rapid side-effects and only use the latest one.
|
||||
@@ -81,6 +58,29 @@ function Table({ data, onFetchData }) {
|
||||
}
|
||||
```
|
||||
|
||||
## How can I use the table state to fetch new data?
|
||||
|
||||
When managing your data externally or asynchronously (eg. server-side pagination/sorting/grouping/etc), you will need to fetch new data as the internal table state changes. With React Hooks, this is fantastically easier than it was before now that we have the `React.useEffect` hook. We can use this hook to "watch" the table state for specific changes and use those effects to trigger fetches for new data (or synchronize any other state you may be managing externally from your table component):
|
||||
|
||||
```js
|
||||
function Table({ data, onFetchData }) {
|
||||
const {
|
||||
state: { pageIndex, pageSize, sortBy, filters },
|
||||
} = useTable({
|
||||
data,
|
||||
})
|
||||
|
||||
// When the these table states change, fetch new data!
|
||||
React.useEffect(() => {
|
||||
onFetchData({ pageIndex, pageSize, sortBy, filters })
|
||||
}, [fetchData, pageIndex, pageSize, sortBy, filters])
|
||||
|
||||
return </>
|
||||
}
|
||||
```
|
||||
|
||||
Using this approach, you can respond and trigger any type of side-effect using the table instance!
|
||||
|
||||
## How do I stop my table state from automatically resetting when my data changes?
|
||||
|
||||
Most plugins use state that _should_ normally reset when the data sources changes, but sometimes you need to suppress that from happening if you are filtering your data externally, or immutably editing your data while looking at it, or simply doing anything external with your data that you don't want to trigger a piece of table state to reset automatically.
|
||||
@@ -119,3 +119,5 @@ useTable({
|
||||
```
|
||||
|
||||
Now, when we update our data, the above table states will not automatically reset!
|
||||
|
||||
<!-- ## How can I hide/show columns? -->
|
||||
|
||||
@@ -92,18 +92,19 @@ function Table({ columns, data }) {
|
||||
</div>
|
||||
|
||||
<div className="rows" {...getTableBodyProps()}>
|
||||
{rows.map((row, i) => {
|
||||
prepareRow(row)
|
||||
return (
|
||||
<div {...row.getRowProps()} className="row body">
|
||||
{row.cells.map((cell, index) => (
|
||||
<div {...cell.getCellProps()} key={index} className="cell">
|
||||
{cell.render('Cell')}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
{rows.map(
|
||||
(row, i) => {
|
||||
prepareRow(row);
|
||||
return (
|
||||
<div {...row.getRowProps()} className="row body">
|
||||
{row.cells.map((cell,index) => (
|
||||
<div {...cell.getCellProps()} key={index} className="cell">
|
||||
{cell.render('Cell')}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -35,18 +35,18 @@ const Styles = styled.div`
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
${'' /* The resizer styles! */}
|
||||
|
||||
.resizer {
|
||||
display: inline-block;
|
||||
background: blue;
|
||||
width: 10px;
|
||||
width: 5px;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
transform: translateX(50%);
|
||||
z-index: 1;
|
||||
${'' /* prevents from scrolling while dragging on touch devices */}
|
||||
touch-action:none;
|
||||
|
||||
&.isResizing {
|
||||
background: red;
|
||||
|
||||
@@ -8087,10 +8087,10 @@ react-scripts@3.0.1:
|
||||
optionalDependencies:
|
||||
fsevents "2.0.6"
|
||||
|
||||
react-table@latest:
|
||||
version "7.0.0-rc.7"
|
||||
resolved "https://registry.yarnpkg.com/react-table/-/react-table-7.0.0-rc.7.tgz#1bf3e248cdef22213821c021236e895bdc3cb5d2"
|
||||
integrity sha512-24Yofwkh822NyCmnpsrChV8SNOCENQWpV4A5f/MzapTi6iwje644Q11/wbLIgJdPnUJJ0/JbhjsDjxlB6yFV7Q==
|
||||
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@^16.8.6:
|
||||
version "16.8.6"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import { useTable } from 'react-table'
|
||||
import { useTable, mergeProps } from 'react-table'
|
||||
|
||||
import makeData from './makeData'
|
||||
|
||||
@@ -68,15 +68,16 @@ function Table({
|
||||
<tr {...headerGroup.getHeaderGroupProps()}>
|
||||
{headerGroup.headers.map(column => (
|
||||
<th
|
||||
// Return an array of prop objects and react-table will merge them appropriately
|
||||
{...column.getHeaderProps([
|
||||
// Merge all of the header Props
|
||||
{...mergeProps(
|
||||
column.getHeaderProps(),
|
||||
{
|
||||
className: column.className,
|
||||
style: column.style,
|
||||
},
|
||||
getColumnProps(column),
|
||||
getHeaderProps(column),
|
||||
])}
|
||||
getHeaderProps(column)
|
||||
)}
|
||||
>
|
||||
{column.render('Header')}
|
||||
</th>
|
||||
@@ -88,20 +89,21 @@ function Table({
|
||||
{rows.map((row, i) => {
|
||||
prepareRow(row)
|
||||
return (
|
||||
// Merge user row props in
|
||||
<tr {...row.getRowProps(getRowProps(row))}>
|
||||
// Merge row props
|
||||
<tr {...mergeProps(row.getRowProps(), getRowProps(row))}>
|
||||
{row.cells.map(cell => {
|
||||
return (
|
||||
<td
|
||||
// Return an array of prop objects and react-table will merge them appropriately
|
||||
{...cell.getCellProps([
|
||||
// Merge cell props
|
||||
{...mergeProps(
|
||||
cell.getCellProps(),
|
||||
{
|
||||
className: cell.column.className,
|
||||
style: cell.column.style,
|
||||
},
|
||||
getColumnProps(cell.column),
|
||||
getCellProps(cell),
|
||||
])}
|
||||
getCellProps(cell)
|
||||
)}
|
||||
>
|
||||
{cell.render('Cell')}
|
||||
</td>
|
||||
|
||||
@@ -3652,16 +3652,16 @@ eslint-scope@^4.0.0, eslint-scope@^4.0.3:
|
||||
estraverse "^4.1.1"
|
||||
|
||||
eslint-utils@^1.3.1:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f"
|
||||
integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.0.tgz#e2c3c8dba768425f897cf0f9e51fe2e241485d4c"
|
||||
integrity sha512-7ehnzPaP5IIEh1r1tkjuIrxqhNkzUJa9z3R92tLJdZIVdWaczEhr3EbhGtsMrVxi1KeR8qA7Off6SWc5WNQqyQ==
|
||||
dependencies:
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
eslint-visitor-keys "^1.0.0"
|
||||
|
||||
eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2"
|
||||
integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==
|
||||
eslint-visitor-keys@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
|
||||
integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==
|
||||
|
||||
eslint@^5.16.0:
|
||||
version "5.16.0"
|
||||
|
||||
@@ -8218,10 +8218,10 @@ react-scripts@3.0.1:
|
||||
optionalDependencies:
|
||||
fsevents "2.0.6"
|
||||
|
||||
react-table@latest:
|
||||
version "7.0.0-rc.6"
|
||||
resolved "https://registry.yarnpkg.com/react-table/-/react-table-7.0.0-rc.6.tgz#3cb43919e31166659d6aa223bd3dfee765981f6b"
|
||||
integrity sha512-iFgxMla6JnxjZwKG3eiHHOlIIANiK/HzvRFWXT8LV78N9bEOGC5A5N44S/xQ1PaZN/1c+NDBz5fBazhx/vG7/A==
|
||||
react-table@next:
|
||||
version "7.0.0-beta.19"
|
||||
resolved "https://registry.yarnpkg.com/react-table/-/react-table-7.0.0-beta.19.tgz#8563ae56f693cbffa10060772ba1f1cd4e926bb2"
|
||||
integrity sha512-BRt7zW7PGyg67fR2CK9M2fwP6BocjQN870w3P+K+vDJMkpewGjSPDscCU5sJMBqCEjKWg85k2pVkiwQPg9ofgQ==
|
||||
|
||||
react@^16.8.6:
|
||||
version "16.12.0"
|
||||
|
||||
@@ -105,7 +105,7 @@ function Table({
|
||||
{headerGroups.map(headerGroup => (
|
||||
<tr {...headerGroup.getHeaderGroupProps()}>
|
||||
{headerGroup.headers.map(column => (
|
||||
<th {...column.getHeaderProps()}>
|
||||
<th {...column.getHeaderProps(column.getSortByToggleProps())}>
|
||||
{column.render('Header')}
|
||||
<span>
|
||||
{column.isSorted
|
||||
@@ -133,9 +133,9 @@ function Table({
|
||||
<tr>
|
||||
{loading ? (
|
||||
// Use our custom loading state to show a loading indicator
|
||||
<td colSpan="10000">Loading...</td>
|
||||
<td>Loading...</td>
|
||||
) : (
|
||||
<td colSpan="10000">
|
||||
<td>
|
||||
Showing {page.length} of ~{controlledPageCount * pageSize}{' '}
|
||||
results
|
||||
</td>
|
||||
|
||||
@@ -3652,16 +3652,16 @@ eslint-scope@^4.0.0, eslint-scope@^4.0.3:
|
||||
estraverse "^4.1.1"
|
||||
|
||||
eslint-utils@^1.3.1:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f"
|
||||
integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.0.tgz#e2c3c8dba768425f897cf0f9e51fe2e241485d4c"
|
||||
integrity sha512-7ehnzPaP5IIEh1r1tkjuIrxqhNkzUJa9z3R92tLJdZIVdWaczEhr3EbhGtsMrVxi1KeR8qA7Off6SWc5WNQqyQ==
|
||||
dependencies:
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
eslint-visitor-keys "^1.0.0"
|
||||
|
||||
eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2"
|
||||
integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==
|
||||
eslint-visitor-keys@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
|
||||
integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==
|
||||
|
||||
eslint@^5.16.0:
|
||||
version "5.16.0"
|
||||
@@ -8087,10 +8087,10 @@ react-scripts@3.0.1:
|
||||
optionalDependencies:
|
||||
fsevents "2.0.6"
|
||||
|
||||
react-table@latest:
|
||||
version "7.0.0-rc.6"
|
||||
resolved "https://registry.yarnpkg.com/react-table/-/react-table-7.0.0-rc.6.tgz#3cb43919e31166659d6aa223bd3dfee765981f6b"
|
||||
integrity sha512-iFgxMla6JnxjZwKG3eiHHOlIIANiK/HzvRFWXT8LV78N9bEOGC5A5N44S/xQ1PaZN/1c+NDBz5fBazhx/vG7/A==
|
||||
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@^16.8.6:
|
||||
version "16.8.6"
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-table",
|
||||
"version": "7.0.0-rc.8",
|
||||
"version": "7.0.0-rc.3",
|
||||
"description": "Hooks for building lightweight, fast and extendable datagrids for React",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/tannerlinsley/react-table#readme",
|
||||
|
||||
@@ -1,84 +1,4 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1576007021431,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.js",
|
||||
"size": 22643,
|
||||
"delta": -7
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1576004320856,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.js",
|
||||
"size": 22650,
|
||||
"delta": 30
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1576003432935,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.js",
|
||||
"size": 22620,
|
||||
"delta": 652
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1575985310396,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.js",
|
||||
"size": 21968,
|
||||
"delta": 323
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1575910923566,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.js",
|
||||
"size": 21645,
|
||||
"delta": 56
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1575859193604,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.js",
|
||||
"size": 21589,
|
||||
"delta": 563
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1575690248030,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.js",
|
||||
"size": 21026,
|
||||
"delta": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1575675308812,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.js",
|
||||
"size": 21025,
|
||||
"delta": -421
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1575620433902,
|
||||
"files": [
|
||||
|
||||
@@ -1,74 +1,4 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1576007027792,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.es.js",
|
||||
"size": 22461,
|
||||
"delta": -7
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1576004327554,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.es.js",
|
||||
"size": 22468,
|
||||
"delta": 30
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1576003439933,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.es.js",
|
||||
"size": 22438,
|
||||
"delta": 656
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1575985317929,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.es.js",
|
||||
"size": 21782,
|
||||
"delta": 324
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1575910931774,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.es.js",
|
||||
"size": 21458,
|
||||
"delta": 55
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1575859200604,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.es.js",
|
||||
"size": 21403,
|
||||
"delta": 561
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1575675317538,
|
||||
"files": [
|
||||
{
|
||||
"filename": "index.es.js",
|
||||
"size": 20842,
|
||||
"delta": -383
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1575620442742,
|
||||
"files": [
|
||||
|
||||
@@ -3,9 +3,9 @@ import React from 'react'
|
||||
import {
|
||||
actions,
|
||||
functionalUpdate,
|
||||
mergeProps,
|
||||
applyPropHooks,
|
||||
useGetLatest,
|
||||
useConsumeHookGetter,
|
||||
makePropGetter,
|
||||
} from '../utils'
|
||||
|
||||
actions.resetHiddenColumns = 'resetHiddenColumns'
|
||||
@@ -14,12 +14,12 @@ actions.setHiddenColumns = 'setHiddenColumns'
|
||||
actions.toggleHideAllColumns = 'toggleHideAllColumns'
|
||||
|
||||
export const useColumnVisibility = hooks => {
|
||||
hooks.getToggleHiddenProps = [defaultGetToggleHiddenProps]
|
||||
hooks.getToggleHideAllColumnsProps = [defaultGetToggleHideAllColumnsProps]
|
||||
hooks.getToggleHiddenProps = []
|
||||
hooks.getToggleHideAllColumnsProps = []
|
||||
|
||||
hooks.stateReducers.push(reducer)
|
||||
hooks.useInstanceBeforeDimensions.push(useInstanceBeforeDimensions)
|
||||
hooks.headerGroupsDeps.push((deps, instance) => [
|
||||
hooks.columnsBeforeHeaderGroupsDeps.push((deps, instance) => [
|
||||
...deps,
|
||||
instance.state.hiddenColumns,
|
||||
])
|
||||
@@ -28,36 +28,6 @@ export const useColumnVisibility = hooks => {
|
||||
|
||||
useColumnVisibility.pluginName = 'useColumnVisibility'
|
||||
|
||||
const defaultGetToggleHiddenProps = (props, instance, column) => [
|
||||
props,
|
||||
{
|
||||
onChange: e => {
|
||||
column.toggleHidden(!e.target.checked)
|
||||
},
|
||||
style: {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
checked: column.isVisible,
|
||||
title: 'Toggle Column Visible',
|
||||
},
|
||||
]
|
||||
|
||||
const defaultGetToggleHideAllColumnsProps = (props, instance) => [
|
||||
props,
|
||||
{
|
||||
onChange: e => {
|
||||
instance.toggleHideAllColumns(!e.target.checked)
|
||||
},
|
||||
style: {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
checked: !instance.allColumnsHidden && !instance.state.hiddenColumns.length,
|
||||
title: 'Toggle All Columns Hidden',
|
||||
indeterminate:
|
||||
!instance.allColumnsHidden && instance.state.hiddenColumns.length,
|
||||
},
|
||||
]
|
||||
|
||||
function reducer(state, action, previousState, instanceRef) {
|
||||
if (action.type === actions.init) {
|
||||
return {
|
||||
@@ -141,6 +111,8 @@ function useInstanceBeforeDimensions(instance) {
|
||||
headers.forEach(
|
||||
subHeader => (totalVisibleHeaderCount += handleColumn(subHeader, true))
|
||||
)
|
||||
|
||||
return instance
|
||||
}
|
||||
|
||||
function useInstance(instance) {
|
||||
@@ -155,6 +127,33 @@ function useInstance(instance) {
|
||||
|
||||
const allColumnsHidden = flatColumns.length === hiddenColumns.length
|
||||
|
||||
flatHeaders.forEach(column => {
|
||||
column.toggleHidden = value => {
|
||||
dispatch({
|
||||
type: actions.toggleHideColumn,
|
||||
columnId: column.id,
|
||||
value,
|
||||
})
|
||||
}
|
||||
|
||||
column.getToggleHiddenProps = props => {
|
||||
return mergeProps(
|
||||
{
|
||||
onChange: e => {
|
||||
column.toggleHidden(!e.target.checked)
|
||||
},
|
||||
style: {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
checked: column.isVisible,
|
||||
title: 'Toggle Column Visible',
|
||||
},
|
||||
applyPropHooks(getInstance().hooks.getToggleHiddenProps, getInstance()),
|
||||
props
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
const toggleHideColumn = React.useCallback(
|
||||
(columnId, value) =>
|
||||
dispatch({ type: actions.toggleHideColumn, columnId, value }),
|
||||
@@ -171,44 +170,32 @@ function useInstance(instance) {
|
||||
[dispatch]
|
||||
)
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getToggleHideAllColumnsPropsHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
'getToggleHideAllColumnsProps'
|
||||
)
|
||||
|
||||
const getToggleHideAllColumnsProps = makePropGetter(
|
||||
getToggleHideAllColumnsPropsHooks(),
|
||||
getInstance()
|
||||
)
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getToggleHiddenPropsHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
'getToggleHiddenProps'
|
||||
)
|
||||
|
||||
flatHeaders.forEach(column => {
|
||||
column.toggleHidden = value => {
|
||||
dispatch({
|
||||
type: actions.toggleHideColumn,
|
||||
columnId: column.id,
|
||||
value,
|
||||
})
|
||||
}
|
||||
|
||||
column.getToggleHiddenProps = makePropGetter(
|
||||
getToggleHiddenPropsHooks(),
|
||||
getInstance(),
|
||||
column
|
||||
const getToggleHideAllColumnsProps = props => {
|
||||
return mergeProps(
|
||||
{
|
||||
onChange: e => {
|
||||
toggleHideAllColumns(!e.target.checked)
|
||||
},
|
||||
style: {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
checked: !allColumnsHidden && !hiddenColumns.length,
|
||||
title: 'Toggle All Columns Hidden',
|
||||
indeterminate: !allColumnsHidden && hiddenColumns.length,
|
||||
},
|
||||
applyPropHooks(
|
||||
getInstance().hooks.getToggleHideAllColumnsProps,
|
||||
getInstance()
|
||||
),
|
||||
props
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
Object.assign(instance, {
|
||||
allColumnsHidden,
|
||||
return {
|
||||
...instance,
|
||||
toggleHideColumn,
|
||||
setHiddenColumns,
|
||||
toggleHideAllColumns,
|
||||
getToggleHideAllColumnsProps,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+185
-219
@@ -3,9 +3,9 @@ import React from 'react'
|
||||
//
|
||||
import {
|
||||
actions,
|
||||
reduceHooks,
|
||||
loopHooks,
|
||||
makePropGetter,
|
||||
applyHooks,
|
||||
applyPropHooks,
|
||||
mergeProps,
|
||||
flexRender,
|
||||
decorateColumnTree,
|
||||
makeHeaderGroups,
|
||||
@@ -14,8 +14,6 @@ import {
|
||||
useConsumeHookGetter,
|
||||
} from '../utils'
|
||||
|
||||
import makeDefaultPluginHooks from '../makeDefaultPluginHooks'
|
||||
|
||||
import { useColumnVisibility } from './useColumnVisibility'
|
||||
|
||||
let renderErr = 'Renderer Error'
|
||||
@@ -27,83 +25,60 @@ const defaultGetSubRows = (row, index) => row.subRows || []
|
||||
const defaultGetRowId = (row, index) => index
|
||||
const defaultUseControlledState = d => d
|
||||
|
||||
function applyDefaults(props) {
|
||||
const {
|
||||
export const useTable = (props, ...plugins) => {
|
||||
// Destructure props
|
||||
let {
|
||||
data,
|
||||
columns: userColumns,
|
||||
initialState = defaultInitialState,
|
||||
defaultColumn = defaultColumnInstance,
|
||||
getSubRows = defaultGetSubRows,
|
||||
getRowId = defaultGetRowId,
|
||||
stateReducer = defaultReducer,
|
||||
stateReducer: userStateReducer = defaultReducer,
|
||||
useControlledState = defaultUseControlledState,
|
||||
...rest
|
||||
} = props
|
||||
|
||||
return {
|
||||
...rest,
|
||||
initialState,
|
||||
defaultColumn,
|
||||
getSubRows,
|
||||
getRowId,
|
||||
stateReducer,
|
||||
useControlledState,
|
||||
}
|
||||
}
|
||||
|
||||
export const useTable = (props, ...plugins) => {
|
||||
// Apply default props
|
||||
props = applyDefaults(props)
|
||||
|
||||
// Add core plugins
|
||||
plugins = [useColumnVisibility, ...plugins]
|
||||
|
||||
// Create the table instance
|
||||
// The table instance
|
||||
let instanceRef = React.useRef({})
|
||||
|
||||
// Create a getter for the instance (helps avoid a lot of potential memory leaks)
|
||||
const getInstance = useGetLatest(instanceRef.current)
|
||||
|
||||
// Assign the props, plugins and hooks to the instance
|
||||
Object.assign(getInstance(), {
|
||||
Object.assign(instanceRef.current, {
|
||||
...props,
|
||||
plugins,
|
||||
hooks: makeDefaultPluginHooks(),
|
||||
data,
|
||||
hooks: {
|
||||
stateReducers: [],
|
||||
columnsBeforeHeaderGroups: [],
|
||||
columnsBeforeHeaderGroupsDeps: [],
|
||||
useInstanceBeforeDimensions: [],
|
||||
useInstance: [],
|
||||
useRows: [],
|
||||
prepareRow: [],
|
||||
getTableProps: [],
|
||||
getTableBodyProps: [],
|
||||
getRowProps: [],
|
||||
getHeaderGroupProps: [],
|
||||
getFooterGroupProps: [],
|
||||
getHeaderProps: [],
|
||||
getFooterProps: [],
|
||||
getCellProps: [],
|
||||
},
|
||||
})
|
||||
|
||||
// Allow plugins to register hooks as early as possible
|
||||
plugins.filter(Boolean).forEach(plugin => {
|
||||
plugin(getInstance().hooks)
|
||||
plugin(instanceRef.current.hooks)
|
||||
})
|
||||
|
||||
const getUseOptionsHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
'useOptions'
|
||||
)
|
||||
|
||||
// Allow useOptions hooks to modify the options coming into the table
|
||||
Object.assign(
|
||||
getInstance(),
|
||||
reduceHooks(getUseOptionsHooks(), applyDefaults(props))
|
||||
)
|
||||
|
||||
const {
|
||||
data,
|
||||
columns: userColumns,
|
||||
initialState,
|
||||
defaultColumn,
|
||||
getSubRows,
|
||||
getRowId,
|
||||
stateReducer,
|
||||
useControlledState,
|
||||
} = getInstance()
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getStateReducers = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
instanceRef.current.hooks,
|
||||
'stateReducers'
|
||||
)
|
||||
|
||||
// Setup user reducer ref
|
||||
const getStateReducer = useGetLatest(stateReducer)
|
||||
const getUserStateReducer = useGetLatest(userStateReducer)
|
||||
|
||||
// Build the reducer
|
||||
const reducer = React.useCallback(
|
||||
@@ -118,15 +93,15 @@ export const useTable = (props, ...plugins) => {
|
||||
return [
|
||||
...getStateReducers(),
|
||||
// Allow the user to add their own state reducer(s)
|
||||
...(Array.isArray(getStateReducer())
|
||||
? getStateReducer()
|
||||
: [getStateReducer()]),
|
||||
...(Array.isArray(getUserStateReducer())
|
||||
? getUserStateReducer()
|
||||
: [getUserStateReducer()]),
|
||||
].reduce(
|
||||
(s, handler) => handler(s, action, state, instanceRef) || s,
|
||||
state
|
||||
)
|
||||
},
|
||||
[getStateReducers, getStateReducer]
|
||||
[getStateReducers, getUserStateReducer]
|
||||
)
|
||||
|
||||
// Start the reducer
|
||||
@@ -137,110 +112,63 @@ export const useTable = (props, ...plugins) => {
|
||||
// Allow the user to control the final state with hooks
|
||||
const state = useControlledState(reducerState)
|
||||
|
||||
Object.assign(getInstance(), {
|
||||
state,
|
||||
dispatch,
|
||||
Object.assign(instanceRef.current, {
|
||||
state, // The state dispatcher
|
||||
dispatch, // The resolved table state
|
||||
})
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getColumnsHooks = useConsumeHookGetter(getInstance().hooks, 'columns')
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getColumnsDepsHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
'columnsDeps'
|
||||
)
|
||||
|
||||
// Decorate All the columns
|
||||
let columns = React.useMemo(
|
||||
() =>
|
||||
reduceHooks(
|
||||
getColumnsHooks(),
|
||||
decorateColumnTree(userColumns, defaultColumn),
|
||||
getInstance()
|
||||
),
|
||||
[
|
||||
defaultColumn,
|
||||
getColumnsHooks,
|
||||
getInstance,
|
||||
userColumns,
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
...getColumnsDepsHooks(getInstance()),
|
||||
]
|
||||
)
|
||||
|
||||
getInstance().columns = columns
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getFlatColumns = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
'flatColumns'
|
||||
() => decorateColumnTree(userColumns, defaultColumn),
|
||||
[defaultColumn, userColumns]
|
||||
)
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getFlatColumnsDeps = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
'flatColumnsDeps'
|
||||
const getColumnsBeforeHeaderGroups = useConsumeHookGetter(
|
||||
instanceRef.current.hooks,
|
||||
'columnsBeforeHeaderGroups'
|
||||
)
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getColumnsBeforeHeaderGroupsDeps = useConsumeHookGetter(
|
||||
instanceRef.current.hooks,
|
||||
'columnsBeforeHeaderGroupsDeps'
|
||||
)
|
||||
|
||||
// Get the flat list of all columns and allow hooks to decorate
|
||||
// those columns (and trigger this memoization via deps)
|
||||
let flatColumns = React.useMemo(
|
||||
() =>
|
||||
reduceHooks(
|
||||
getFlatColumns(),
|
||||
flattenBy(columns, 'columns'),
|
||||
getInstance()
|
||||
),
|
||||
[
|
||||
columns,
|
||||
getFlatColumns,
|
||||
getInstance,
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
getFlatColumnsDeps(getInstance()),
|
||||
]
|
||||
)
|
||||
let flatColumns = React.useMemo(() => {
|
||||
let newColumns = applyHooks(
|
||||
getColumnsBeforeHeaderGroups(),
|
||||
flattenBy(columns, 'columns'),
|
||||
instanceRef.current
|
||||
)
|
||||
|
||||
getInstance().flatColumns = flatColumns
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getHeaderGroups = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
'headerGroups'
|
||||
)
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getHeaderGroupsDeps = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
'headerGroupsDeps'
|
||||
)
|
||||
return newColumns
|
||||
}, [
|
||||
columns,
|
||||
getColumnsBeforeHeaderGroups,
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
...getColumnsBeforeHeaderGroupsDeps(),
|
||||
])
|
||||
|
||||
// Make the headerGroups
|
||||
const headerGroups = React.useMemo(
|
||||
() =>
|
||||
reduceHooks(
|
||||
getHeaderGroups(),
|
||||
makeHeaderGroups(flatColumns, defaultColumn),
|
||||
getInstance()
|
||||
),
|
||||
[
|
||||
defaultColumn,
|
||||
flatColumns,
|
||||
getHeaderGroups,
|
||||
getInstance,
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
...getHeaderGroupsDeps(getInstance()),
|
||||
]
|
||||
() => makeHeaderGroups(flatColumns, defaultColumn),
|
||||
[defaultColumn, flatColumns]
|
||||
)
|
||||
|
||||
getInstance().headerGroups = headerGroups
|
||||
|
||||
const headers = React.useMemo(
|
||||
() => (headerGroups.length ? headerGroups[0].headers : []),
|
||||
[headerGroups]
|
||||
)
|
||||
|
||||
getInstance().headers = headers
|
||||
Object.assign(instanceRef.current, {
|
||||
columns,
|
||||
flatColumns,
|
||||
headerGroups,
|
||||
headers,
|
||||
})
|
||||
|
||||
// Access the row model
|
||||
const [rows, flatRows] = React.useMemo(() => {
|
||||
@@ -300,51 +228,54 @@ export const useTable = (props, ...plugins) => {
|
||||
const accessedData = data.map((d, i) => accessRow(d, i))
|
||||
|
||||
return [accessedData, flatRows]
|
||||
}, [data, flatColumns, getRowId, getSubRows])
|
||||
}, [data, getRowId, getSubRows, flatColumns])
|
||||
|
||||
getInstance().rows = rows
|
||||
getInstance().flatRows = flatRows
|
||||
instanceRef.current.rows = rows
|
||||
instanceRef.current.flatRows = flatRows
|
||||
|
||||
// Provide a flat header list for utilities
|
||||
getInstance().flatHeaders = headerGroups.reduce(
|
||||
instanceRef.current.flatHeaders = headerGroups.reduce(
|
||||
(all, headerGroup) => [...all, ...headerGroup.headers],
|
||||
[]
|
||||
)
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getUseInstanceBeforeDimensions = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
instanceRef.current.hooks,
|
||||
'useInstanceBeforeDimensions'
|
||||
)
|
||||
|
||||
loopHooks(getUseInstanceBeforeDimensions(), getInstance())
|
||||
instanceRef.current = applyHooks(
|
||||
getUseInstanceBeforeDimensions(),
|
||||
instanceRef.current
|
||||
)
|
||||
|
||||
// Header Visibility is needed by this point
|
||||
getInstance().totalColumnsWidth = calculateHeaderWidths(headers)
|
||||
calculateDimensions(instanceRef.current)
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getUseInstance = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
instanceRef.current.hooks,
|
||||
'useInstance'
|
||||
)
|
||||
|
||||
loopHooks(getUseInstance(), getInstance())
|
||||
instanceRef.current = applyHooks(getUseInstance(), instanceRef.current)
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getHeaderPropsHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
instanceRef.current.hooks,
|
||||
'getHeaderProps'
|
||||
)
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getFooterPropsHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
instanceRef.current.hooks,
|
||||
'getFooterProps'
|
||||
)
|
||||
|
||||
// Each materialized header needs to be assigned a render function and other
|
||||
// prop getter properties here.
|
||||
getInstance().flatHeaders.forEach(column => {
|
||||
instanceRef.current.flatHeaders.forEach(column => {
|
||||
// Give columns/headers rendering power
|
||||
column.render = (type, userProps = {}) => {
|
||||
const Comp = typeof type === 'string' ? column[type] : type
|
||||
@@ -354,40 +285,48 @@ export const useTable = (props, ...plugins) => {
|
||||
}
|
||||
|
||||
return flexRender(Comp, {
|
||||
...getInstance(),
|
||||
...instanceRef.current,
|
||||
column,
|
||||
...userProps,
|
||||
})
|
||||
}
|
||||
|
||||
// Give columns/headers a default getHeaderProps
|
||||
column.getHeaderProps = makePropGetter(
|
||||
getHeaderPropsHooks(),
|
||||
getInstance(),
|
||||
column
|
||||
)
|
||||
column.getHeaderProps = props =>
|
||||
mergeProps(
|
||||
{
|
||||
key: ['header', column.id].join('_'),
|
||||
colSpan: column.totalVisibleHeaderCount,
|
||||
},
|
||||
applyPropHooks(getHeaderPropsHooks(), column, instanceRef.current),
|
||||
props
|
||||
)
|
||||
|
||||
// Give columns/headers a default getFooterProps
|
||||
column.getFooterProps = makePropGetter(
|
||||
getFooterPropsHooks(),
|
||||
getInstance(),
|
||||
column
|
||||
)
|
||||
column.getFooterProps = props =>
|
||||
mergeProps(
|
||||
{
|
||||
key: ['footer', column.id].join('_'),
|
||||
colSpan: column.totalVisibleHeaderCount,
|
||||
},
|
||||
applyPropHooks(getFooterPropsHooks(), column, instanceRef.current),
|
||||
props
|
||||
)
|
||||
})
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getHeaderGroupPropsHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
instanceRef.current.hooks,
|
||||
'getHeaderGroupProps'
|
||||
)
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getFooterGroupPropsHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
const getFooterGroupsPropsHooks = useConsumeHookGetter(
|
||||
instanceRef.current.hooks,
|
||||
'getFooterGroupProps'
|
||||
)
|
||||
|
||||
getInstance().headerGroups = getInstance().headerGroups.filter(
|
||||
instanceRef.current.headerGroups = instanceRef.current.headerGroups.filter(
|
||||
(headerGroup, i) => {
|
||||
// Filter out any headers and headerGroups that don't have visible columns
|
||||
headerGroup.headers = headerGroup.headers.filter(column => {
|
||||
@@ -406,19 +345,31 @@ export const useTable = (props, ...plugins) => {
|
||||
|
||||
// Give headerGroups getRowProps
|
||||
if (headerGroup.headers.length) {
|
||||
headerGroup.getHeaderGroupProps = makePropGetter(
|
||||
getHeaderGroupPropsHooks(),
|
||||
getInstance(),
|
||||
headerGroup,
|
||||
i
|
||||
)
|
||||
headerGroup.getHeaderGroupProps = (props = {}) =>
|
||||
mergeProps(
|
||||
{
|
||||
key: [`header${i}`].join('_'),
|
||||
},
|
||||
applyPropHooks(
|
||||
getHeaderGroupPropsHooks(),
|
||||
headerGroup,
|
||||
instanceRef.current
|
||||
),
|
||||
props
|
||||
)
|
||||
|
||||
headerGroup.getFooterGroupProps = makePropGetter(
|
||||
getFooterGroupPropsHooks(),
|
||||
getInstance(),
|
||||
headerGroup,
|
||||
i
|
||||
)
|
||||
headerGroup.getFooterGroupProps = (props = {}) =>
|
||||
mergeProps(
|
||||
{
|
||||
key: [`footer${i}`].join('_'),
|
||||
},
|
||||
applyPropHooks(
|
||||
getFooterGroupsPropsHooks(),
|
||||
headerGroup,
|
||||
instanceRef.current
|
||||
),
|
||||
props
|
||||
)
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -427,17 +378,22 @@ export const useTable = (props, ...plugins) => {
|
||||
}
|
||||
)
|
||||
|
||||
getInstance().footerGroups = [...getInstance().headerGroups].reverse()
|
||||
instanceRef.current.footerGroups = [
|
||||
...instanceRef.current.headerGroups,
|
||||
].reverse()
|
||||
|
||||
// Run the rows (this could be a dangerous hook with a ton of data)
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getUseRowsHooks = useConsumeHookGetter(getInstance().hooks, 'useRows')
|
||||
const getUseRowsHooks = useConsumeHookGetter(
|
||||
instanceRef.current.hooks,
|
||||
'useRows'
|
||||
)
|
||||
|
||||
getInstance().rows = reduceHooks(
|
||||
instanceRef.current.rows = applyHooks(
|
||||
getUseRowsHooks(),
|
||||
getInstance().rows,
|
||||
getInstance()
|
||||
instanceRef.current.rows,
|
||||
instanceRef.current
|
||||
)
|
||||
|
||||
// The prepareRow function is absolutely necessary and MUST be called on
|
||||
@@ -445,29 +401,34 @@ export const useTable = (props, ...plugins) => {
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getPrepareRowHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
instanceRef.current.hooks,
|
||||
'prepareRow'
|
||||
)
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getRowPropsHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
instanceRef.current.hooks,
|
||||
'getRowProps'
|
||||
)
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getCellPropsHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
instanceRef.current.hooks,
|
||||
'getCellProps'
|
||||
)
|
||||
|
||||
getInstance().prepareRow = React.useCallback(
|
||||
instanceRef.current.prepareRow = React.useCallback(
|
||||
row => {
|
||||
row.getRowProps = makePropGetter(getRowPropsHooks(), getInstance(), row)
|
||||
row.getRowProps = props =>
|
||||
mergeProps(
|
||||
{ key: ['row', ...row.path].join('_') },
|
||||
applyPropHooks(getRowPropsHooks(), row, instanceRef.current),
|
||||
props
|
||||
)
|
||||
|
||||
// Build the visible cells for each row
|
||||
row.cells = getInstance()
|
||||
.flatColumns.filter(d => d.isVisible)
|
||||
row.cells = instanceRef.current.flatColumns
|
||||
.filter(d => d.isVisible)
|
||||
.map(column => {
|
||||
const cell = {
|
||||
column,
|
||||
@@ -476,11 +437,16 @@ export const useTable = (props, ...plugins) => {
|
||||
}
|
||||
|
||||
// Give each cell a getCellProps base
|
||||
cell.getCellProps = makePropGetter(
|
||||
getCellPropsHooks(),
|
||||
getInstance(),
|
||||
cell
|
||||
)
|
||||
cell.getCellProps = props => {
|
||||
const columnPathStr = [...row.path, column.id].join('_')
|
||||
return mergeProps(
|
||||
{
|
||||
key: ['cell', columnPathStr].join('_'),
|
||||
},
|
||||
applyPropHooks(getCellPropsHooks(), cell, instanceRef.current),
|
||||
props
|
||||
)
|
||||
}
|
||||
|
||||
// Give each cell a renderer function (supports multiple renderers)
|
||||
cell.render = (type, userProps = {}) => {
|
||||
@@ -491,7 +457,7 @@ export const useTable = (props, ...plugins) => {
|
||||
}
|
||||
|
||||
return flexRender(Comp, {
|
||||
...getInstance(),
|
||||
...instanceRef.current,
|
||||
column,
|
||||
row,
|
||||
cell,
|
||||
@@ -503,42 +469,42 @@ export const useTable = (props, ...plugins) => {
|
||||
})
|
||||
|
||||
// need to apply any row specific hooks (useExpanded requires this)
|
||||
loopHooks(getPrepareRowHooks(), row, getInstance())
|
||||
applyHooks(getPrepareRowHooks(), row, instanceRef.current)
|
||||
},
|
||||
[getCellPropsHooks, getInstance, getPrepareRowHooks, getRowPropsHooks]
|
||||
[getCellPropsHooks, getPrepareRowHooks, getRowPropsHooks]
|
||||
)
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getTablePropsHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
instanceRef.current.hooks,
|
||||
'getTableProps'
|
||||
)
|
||||
|
||||
getInstance().getTableProps = makePropGetter(
|
||||
getTablePropsHooks(),
|
||||
getInstance()
|
||||
)
|
||||
instanceRef.current.getTableProps = userProps =>
|
||||
mergeProps(
|
||||
applyPropHooks(getTablePropsHooks(), instanceRef.current),
|
||||
userProps
|
||||
)
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getTableBodyPropsHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
instanceRef.current.hooks,
|
||||
'getTableBodyProps'
|
||||
)
|
||||
|
||||
getInstance().getTableBodyProps = makePropGetter(
|
||||
getTableBodyPropsHooks(),
|
||||
getInstance()
|
||||
)
|
||||
instanceRef.current.getTableBodyProps = userProps =>
|
||||
mergeProps(
|
||||
applyPropHooks(getTableBodyPropsHooks(), instanceRef.current),
|
||||
userProps
|
||||
)
|
||||
|
||||
// Snapshot hook and disallow more from being added
|
||||
const getUseFinalInstanceHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
'useFinalInstance'
|
||||
)
|
||||
return instanceRef.current
|
||||
}
|
||||
|
||||
loopHooks(getUseFinalInstanceHooks(), getInstance())
|
||||
function calculateDimensions(instance) {
|
||||
const { headers } = instance
|
||||
|
||||
return getInstance()
|
||||
instance.totalColumnsWidth = calculateHeaderWidths(headers)
|
||||
}
|
||||
|
||||
function calculateHeaderWidths(headers, left = 0) {
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
const defaultGetHeaderProps = (props, instance, column) => ({
|
||||
key: ['header', column.id].join('_'),
|
||||
colSpan: column.totalVisibleHeaderCount,
|
||||
...props,
|
||||
})
|
||||
|
||||
const defaultGetFooterProps = (props, instance, column) => ({
|
||||
key: ['footer', column.id].join('_'),
|
||||
colSpan: column.totalVisibleHeaderCount,
|
||||
...props,
|
||||
})
|
||||
|
||||
const defaultGetHeaderGroupProps = (props, instance, headerGroup, index) => ({
|
||||
key: ['header', index].join('_'),
|
||||
...props,
|
||||
})
|
||||
|
||||
const defaultGetFooterGroupProps = (props, instance, headerGroup, index) => ({
|
||||
key: ['footer', index].join('_'),
|
||||
...props,
|
||||
})
|
||||
|
||||
const defaultGetRowProps = (props, instance, row) => ({
|
||||
key: ['row', ...row.path].join('_'),
|
||||
...props,
|
||||
})
|
||||
|
||||
const defaultGetCellProps = (props, instance, cell) => ({
|
||||
...props,
|
||||
key: ['cell', ...cell.row.path, cell.column.id].join('_'),
|
||||
})
|
||||
|
||||
export default function makeDefaultPluginHooks() {
|
||||
return {
|
||||
useOptions: [],
|
||||
stateReducers: [],
|
||||
columns: [],
|
||||
columnsDeps: [],
|
||||
flatColumns: [],
|
||||
flatColumnsDeps: [],
|
||||
headerGroups: [],
|
||||
headerGroupsDeps: [],
|
||||
useInstanceBeforeDimensions: [],
|
||||
useInstance: [],
|
||||
useRows: [],
|
||||
prepareRow: [],
|
||||
getTableProps: [],
|
||||
getTableBodyProps: [],
|
||||
getHeaderGroupProps: [defaultGetHeaderGroupProps],
|
||||
getFooterGroupProps: [defaultGetFooterGroupProps],
|
||||
getHeaderProps: [defaultGetHeaderProps],
|
||||
getFooterProps: [defaultGetFooterProps],
|
||||
getRowProps: [defaultGetRowProps],
|
||||
getCellProps: [defaultGetCellProps],
|
||||
useFinalInstance: [],
|
||||
}
|
||||
}
|
||||
@@ -1,45 +1,57 @@
|
||||
// Calculating column/cells widths
|
||||
const cellStyles = {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
export const useAbsoluteLayout = hooks => {
|
||||
hooks.useInstance.push(useInstance)
|
||||
}
|
||||
|
||||
export const useAbsoluteLayout = hooks => {
|
||||
hooks.getTableBodyProps.push(getRowStyles)
|
||||
hooks.getRowProps.push(getRowStyles)
|
||||
hooks.getHeaderGroupProps.push(getRowStyles)
|
||||
useAbsoluteLayout.pluginName = 'useAbsoluteLayout'
|
||||
|
||||
hooks.getHeaderProps.push((props, instance, header) => [
|
||||
props,
|
||||
{
|
||||
const useInstance = instance => {
|
||||
const {
|
||||
totalColumnsWidth,
|
||||
hooks: {
|
||||
getRowProps,
|
||||
getTableBodyProps,
|
||||
getHeaderGroupProps,
|
||||
getHeaderProps,
|
||||
getCellProps,
|
||||
},
|
||||
} = instance
|
||||
|
||||
const rowStyles = {
|
||||
style: {
|
||||
position: 'relative',
|
||||
width: `${totalColumnsWidth}px`,
|
||||
},
|
||||
}
|
||||
|
||||
getTableBodyProps.push(() => rowStyles)
|
||||
getRowProps.push(() => rowStyles)
|
||||
getHeaderGroupProps.push(() => rowStyles)
|
||||
|
||||
// Calculating column/cells widths
|
||||
const cellStyles = {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
}
|
||||
|
||||
getHeaderProps.push(header => {
|
||||
return {
|
||||
style: {
|
||||
...cellStyles,
|
||||
left: `${header.totalLeft}px`,
|
||||
width: `${header.totalWidth}px`,
|
||||
},
|
||||
},
|
||||
])
|
||||
}
|
||||
})
|
||||
|
||||
hooks.getCellProps.push((props, instance, cell) => [
|
||||
props,
|
||||
{
|
||||
getCellProps.push(cell => {
|
||||
return {
|
||||
style: {
|
||||
...cellStyles,
|
||||
left: `${cell.column.totalLeft}px`,
|
||||
width: `${cell.column.totalWidth}px`,
|
||||
},
|
||||
},
|
||||
])
|
||||
}
|
||||
})
|
||||
|
||||
return instance
|
||||
}
|
||||
|
||||
useAbsoluteLayout.pluginName = 'useAbsoluteLayout'
|
||||
|
||||
const getRowStyles = (props, instance) => [
|
||||
props,
|
||||
{
|
||||
style: {
|
||||
position: 'relative',
|
||||
width: `${instance.totalColumnsWidth}px`,
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1,41 +1,47 @@
|
||||
const cellStyles = {
|
||||
display: 'inline-block',
|
||||
boxSizing: 'border-box',
|
||||
export const useBlockLayout = hooks => {
|
||||
hooks.useInstance.push(useInstance)
|
||||
}
|
||||
|
||||
const getRowStyles = (props, instance) => [
|
||||
props,
|
||||
{
|
||||
useBlockLayout.pluginName = 'useBlockLayout'
|
||||
|
||||
const useInstance = instance => {
|
||||
const {
|
||||
totalColumnsWidth,
|
||||
hooks: { getRowProps, getHeaderGroupProps, getHeaderProps, getCellProps },
|
||||
} = instance
|
||||
|
||||
const rowStyles = {
|
||||
style: {
|
||||
display: 'flex',
|
||||
width: `${instance.totalColumnsWidth}px`,
|
||||
width: `${totalColumnsWidth}px`,
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
export const useBlockLayout = hooks => {
|
||||
hooks.getRowProps.push(getRowStyles)
|
||||
hooks.getHeaderGroupProps.push(getRowStyles)
|
||||
getRowProps.push(() => rowStyles)
|
||||
getHeaderGroupProps.push(() => rowStyles)
|
||||
|
||||
hooks.getHeaderProps.push((props, instance, header) => [
|
||||
props,
|
||||
{
|
||||
const cellStyles = {
|
||||
display: 'inline-block',
|
||||
boxSizing: 'border-box',
|
||||
}
|
||||
|
||||
getHeaderProps.push(header => {
|
||||
return {
|
||||
style: {
|
||||
...cellStyles,
|
||||
width: `${header.totalWidth}px`,
|
||||
},
|
||||
},
|
||||
])
|
||||
}
|
||||
})
|
||||
|
||||
hooks.getCellProps.push((props, instance, cell) => [
|
||||
props,
|
||||
{
|
||||
getCellProps.push(cell => {
|
||||
return {
|
||||
style: {
|
||||
...cellStyles,
|
||||
width: `${cell.column.totalWidth}px`,
|
||||
},
|
||||
},
|
||||
])
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
useBlockLayout.pluginName = 'useBlockLayout'
|
||||
return instance
|
||||
}
|
||||
|
||||
@@ -8,10 +8,10 @@ actions.setColumnOrder = 'setColumnOrder'
|
||||
|
||||
export const useColumnOrder = hooks => {
|
||||
hooks.stateReducers.push(reducer)
|
||||
hooks.flatColumnsDeps.push((deps, instance) => {
|
||||
hooks.columnsBeforeHeaderGroupsDeps.push((deps, instance) => {
|
||||
return [...deps, instance.state.columnOrder]
|
||||
})
|
||||
hooks.flatColumns.push(flatColumns)
|
||||
hooks.columnsBeforeHeaderGroups.push(columnsBeforeHeaderGroups)
|
||||
hooks.useInstance.push(useInstance)
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ function reducer(state, action) {
|
||||
}
|
||||
}
|
||||
|
||||
function flatColumns(columns, instance) {
|
||||
function columnsBeforeHeaderGroups(columns, instance) {
|
||||
const {
|
||||
state: { columnOrder },
|
||||
} = instance
|
||||
@@ -74,10 +74,15 @@ function flatColumns(columns, instance) {
|
||||
function useInstance(instance) {
|
||||
const { dispatch } = instance
|
||||
|
||||
instance.setColumnOrder = React.useCallback(
|
||||
const setColumnOrder = React.useCallback(
|
||||
columnOrder => {
|
||||
return dispatch({ type: actions.setColumnOrder, columnOrder })
|
||||
},
|
||||
[dispatch]
|
||||
)
|
||||
|
||||
return {
|
||||
...instance,
|
||||
setColumnOrder,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,39 +2,26 @@ import React from 'react'
|
||||
|
||||
import {
|
||||
actions,
|
||||
makePropGetter,
|
||||
mergeProps,
|
||||
applyPropHooks,
|
||||
expandRows,
|
||||
useMountedLayoutEffect,
|
||||
useGetLatest,
|
||||
} from '../utils'
|
||||
import { useConsumeHookGetter } from '../publicUtils'
|
||||
|
||||
// Actions
|
||||
actions.toggleExpandedByPath = 'toggleExpandedByPath'
|
||||
actions.resetExpanded = 'resetExpanded'
|
||||
|
||||
export const useExpanded = hooks => {
|
||||
hooks.getExpandedToggleProps = [defaultGetExpandedToggleProps]
|
||||
hooks.getExpandedToggleProps = []
|
||||
|
||||
hooks.stateReducers.push(reducer)
|
||||
hooks.useInstance.push(useInstance)
|
||||
}
|
||||
|
||||
useExpanded.pluginName = 'useExpanded'
|
||||
|
||||
const defaultGetExpandedToggleProps = (props, instance, row) => [
|
||||
props,
|
||||
{
|
||||
onClick: e => {
|
||||
e.persist()
|
||||
row.toggleExpanded()
|
||||
},
|
||||
style: {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
title: 'Toggle Expanded',
|
||||
},
|
||||
]
|
||||
|
||||
// Reducer
|
||||
function reducer(state, action) {
|
||||
if (action.type === actions.init) {
|
||||
@@ -55,7 +42,7 @@ function reducer(state, action) {
|
||||
const { path, expanded } = action
|
||||
const key = path.join('.')
|
||||
const exists = state.expanded.includes(key)
|
||||
const shouldExist = typeof expanded !== 'undefined' ? expanded : !exists
|
||||
const shouldExist = typeof set !== 'undefined' ? expanded : !exists
|
||||
let newExpanded = new Set(state.expanded)
|
||||
|
||||
if (!exists && shouldExist) {
|
||||
@@ -100,21 +87,32 @@ function useInstance(instance) {
|
||||
}
|
||||
|
||||
// use reference to avoid memory leak in #1608
|
||||
const getInstance = useGetLatest(instance)
|
||||
|
||||
const getExpandedTogglePropsHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
'getExpandedToggleProps'
|
||||
)
|
||||
const instanceRef = React.useRef()
|
||||
instanceRef.current = instance
|
||||
|
||||
hooks.prepareRow.push(row => {
|
||||
row.toggleExpanded = set => instance.toggleExpandedByPath(row.path, set)
|
||||
|
||||
row.getExpandedToggleProps = makePropGetter(
|
||||
getExpandedTogglePropsHooks(),
|
||||
getInstance(),
|
||||
row
|
||||
)
|
||||
row.toggleExpanded = set => toggleExpandedByPath(row.path, set)
|
||||
row.getExpandedToggleProps = props => {
|
||||
return mergeProps(
|
||||
{
|
||||
onClick: e => {
|
||||
e.persist()
|
||||
row.toggleExpanded()
|
||||
},
|
||||
style: {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
title: 'Toggle Expanded',
|
||||
},
|
||||
applyPropHooks(
|
||||
instanceRef.current.hooks.getExpandedToggleProps,
|
||||
row,
|
||||
instanceRef.current
|
||||
),
|
||||
props
|
||||
)
|
||||
}
|
||||
return row
|
||||
})
|
||||
|
||||
const expandedRows = React.useMemo(() => {
|
||||
@@ -127,13 +125,12 @@ function useInstance(instance) {
|
||||
|
||||
const expandedDepth = findExpandedDepth(expanded)
|
||||
|
||||
Object.assign(instance, {
|
||||
return {
|
||||
...instance,
|
||||
toggleExpandedByPath,
|
||||
preExpandedRows: rows,
|
||||
expandedRows,
|
||||
rows: expandedRows,
|
||||
expandedDepth,
|
||||
})
|
||||
rows: expandedRows,
|
||||
}
|
||||
}
|
||||
|
||||
function findExpandedDepth(expanded) {
|
||||
|
||||
@@ -117,6 +117,9 @@ function useInstance(instance) {
|
||||
autoResetFilters = true,
|
||||
} = instance
|
||||
|
||||
const preFilteredRows = rows
|
||||
const preFilteredFlatRows = flatRows
|
||||
|
||||
const setFilter = (columnId, filterValue) => {
|
||||
dispatch({ type: actions.setFilter, columnId, filterValue })
|
||||
}
|
||||
@@ -262,16 +265,15 @@ function useInstance(instance) {
|
||||
}
|
||||
}, [dispatch, manualFilters ? null : data])
|
||||
|
||||
Object.assign(instance, {
|
||||
return {
|
||||
...instance,
|
||||
setFilter,
|
||||
setAllFilters,
|
||||
preFilteredRows: rows,
|
||||
preFilteredFlatRows: flatRows,
|
||||
filteredRows,
|
||||
filteredFlatRows,
|
||||
preFilteredRows,
|
||||
preFilteredFlatRows,
|
||||
rows: filteredRows,
|
||||
flatRows: filteredFlatRows,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function shouldAutoRemove(autoRemove, value) {
|
||||
|
||||
@@ -3,48 +3,31 @@ import React from 'react'
|
||||
import * as aggregations from '../aggregations'
|
||||
import {
|
||||
actions,
|
||||
makePropGetter,
|
||||
mergeProps,
|
||||
applyPropHooks,
|
||||
defaultGroupByFn,
|
||||
getFirstDefined,
|
||||
ensurePluginOrder,
|
||||
useMountedLayoutEffect,
|
||||
useGetLatest,
|
||||
} from '../utils'
|
||||
import { useConsumeHookGetter } from '../publicUtils'
|
||||
|
||||
// Actions
|
||||
actions.resetGroupBy = 'resetGroupBy'
|
||||
actions.toggleGroupBy = 'toggleGroupBy'
|
||||
|
||||
export const useGroupBy = hooks => {
|
||||
hooks.getGroupByToggleProps = [defaultGetGroupByToggleProps]
|
||||
hooks.stateReducers.push(reducer)
|
||||
hooks.flatColumnsDeps.push((deps, instance) => [
|
||||
hooks.columnsBeforeHeaderGroupsDeps.push((deps, instance) => [
|
||||
...deps,
|
||||
instance.state.groupBy,
|
||||
])
|
||||
hooks.flatColumns.push(flatColumns)
|
||||
hooks.columnsBeforeHeaderGroups.push(columnsBeforeHeaderGroups)
|
||||
hooks.useInstance.push(useInstance)
|
||||
}
|
||||
|
||||
useGroupBy.pluginName = 'useGroupBy'
|
||||
|
||||
const defaultGetGroupByToggleProps = (props, instance, header) => [
|
||||
props,
|
||||
{
|
||||
onClick: header.canGroupBy
|
||||
? e => {
|
||||
e.persist()
|
||||
header.toggleGroupBy()
|
||||
}
|
||||
: undefined,
|
||||
style: {
|
||||
cursor: header.canGroupBy ? 'pointer' : undefined,
|
||||
},
|
||||
title: 'Toggle GroupBy',
|
||||
},
|
||||
]
|
||||
|
||||
// Reducer
|
||||
function reducer(state, action) {
|
||||
if (action.type === actions.init) {
|
||||
@@ -81,7 +64,7 @@ function reducer(state, action) {
|
||||
}
|
||||
}
|
||||
|
||||
function flatColumns(flatColumns, { state: { groupBy } }) {
|
||||
function columnsBeforeHeaderGroups(flatColumns, { state: { groupBy } }) {
|
||||
// Sort grouped columns to the start of the column list
|
||||
// before the headers are built
|
||||
|
||||
@@ -123,8 +106,6 @@ function useInstance(instance) {
|
||||
|
||||
ensurePluginOrder(plugins, [], 'useGroupBy', ['useSortBy', 'useExpanded'])
|
||||
|
||||
const getInstance = useGetLatest(instance)
|
||||
|
||||
flatColumns.forEach(column => {
|
||||
const {
|
||||
id,
|
||||
@@ -154,17 +135,36 @@ function useInstance(instance) {
|
||||
dispatch({ type: actions.toggleGroupBy, columnId, toggle })
|
||||
}
|
||||
|
||||
const getGroupByTogglePropsHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
'getGroupByToggleProps'
|
||||
)
|
||||
hooks.getGroupByToggleProps = []
|
||||
|
||||
// use reference to avoid memory leak in #1608
|
||||
const instanceRef = React.useRef()
|
||||
instanceRef.current = instance
|
||||
|
||||
flatHeaders.forEach(header => {
|
||||
header.getGroupByToggleProps = makePropGetter(
|
||||
getGroupByTogglePropsHooks(),
|
||||
getInstance(),
|
||||
header
|
||||
)
|
||||
const { canGroupBy } = header
|
||||
header.getGroupByToggleProps = props => {
|
||||
return mergeProps(
|
||||
{
|
||||
onClick: canGroupBy
|
||||
? e => {
|
||||
e.persist()
|
||||
header.toggleGroupBy()
|
||||
}
|
||||
: undefined,
|
||||
style: {
|
||||
cursor: canGroupBy ? 'pointer' : undefined,
|
||||
},
|
||||
title: 'Toggle GroupBy',
|
||||
},
|
||||
applyPropHooks(
|
||||
instanceRef.current.hooks.getGroupByToggleProps,
|
||||
header,
|
||||
instanceRef.current
|
||||
),
|
||||
props
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
hooks.prepareRow.push(row => {
|
||||
@@ -177,6 +177,7 @@ function useInstance(instance) {
|
||||
cell.isAggregated =
|
||||
!cell.isGrouped && !cell.isRepeatedValue && row.canExpand
|
||||
})
|
||||
return row
|
||||
})
|
||||
|
||||
const [groupedRows, groupedFlatRows] = React.useMemo(() => {
|
||||
@@ -302,12 +303,11 @@ function useInstance(instance) {
|
||||
}
|
||||
}, [dispatch, manaulGroupBy ? null : data])
|
||||
|
||||
Object.assign(instance, {
|
||||
groupedRows,
|
||||
groupedFlatRows,
|
||||
return {
|
||||
...instance,
|
||||
toggleGroupBy,
|
||||
rows: groupedRows,
|
||||
flatRows: groupedFlatRows,
|
||||
preGroupedRows: rows,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +168,8 @@ function useInstance(instance) {
|
||||
[dispatch]
|
||||
)
|
||||
|
||||
Object.assign(instance, {
|
||||
return {
|
||||
...instance,
|
||||
pageOptions,
|
||||
pageCount,
|
||||
page,
|
||||
@@ -178,5 +179,7 @@ function useInstance(instance) {
|
||||
previousPage,
|
||||
nextPage,
|
||||
setPageSize,
|
||||
})
|
||||
pageIndex,
|
||||
pageSize,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@ import {
|
||||
actions,
|
||||
defaultColumn,
|
||||
getFirstDefined,
|
||||
makePropGetter,
|
||||
mergeProps,
|
||||
applyPropHooks,
|
||||
useGetLatest,
|
||||
} from '../utils'
|
||||
import { useConsumeHookGetter } from '../publicUtils'
|
||||
|
||||
// Default Column
|
||||
defaultColumn.canResize = true
|
||||
@@ -16,107 +16,10 @@ actions.columnResizing = 'columnResizing'
|
||||
actions.columnDoneResizing = 'columnDoneResizing'
|
||||
|
||||
export const useResizeColumns = hooks => {
|
||||
hooks.getResizerProps = [defaultGetResizerProps]
|
||||
hooks.stateReducers.push(reducer)
|
||||
hooks.useInstanceBeforeDimensions.push(useInstanceBeforeDimensions)
|
||||
}
|
||||
|
||||
const defaultGetResizerProps = (props, instance, header) => {
|
||||
const { dispatch } = instance
|
||||
|
||||
const onResizeStart = (e, header) => {
|
||||
let isTouchEvent = false
|
||||
if (e.type === 'touchstart') {
|
||||
// lets not respond to multiple touches (e.g. 2 or 3 fingers)
|
||||
if (e.touches && e.touches.length > 1) {
|
||||
return
|
||||
}
|
||||
isTouchEvent = true
|
||||
}
|
||||
const headersToResize = getLeafHeaders(header)
|
||||
const headerIdWidths = headersToResize.map(d => [d.id, d.totalWidth])
|
||||
|
||||
const clientX = isTouchEvent ? Math.round(e.touches[0].clientX) : e.clientX
|
||||
|
||||
const dispatchMove = clientXPos => {
|
||||
dispatch({ type: actions.columnResizing, clientX: clientXPos })
|
||||
}
|
||||
const dispatchEnd = () => dispatch({ type: actions.columnDoneResizing })
|
||||
|
||||
const handlersAndEvents = {
|
||||
mouse: {
|
||||
moveEvent: 'mousemove',
|
||||
moveHandler: e => dispatchMove(e.clientX),
|
||||
upEvent: 'mouseup',
|
||||
upHandler: e => {
|
||||
document.removeEventListener(
|
||||
'mousemove',
|
||||
handlersAndEvents.mouse.moveHandler
|
||||
)
|
||||
document.removeEventListener(
|
||||
'mouseup',
|
||||
handlersAndEvents.mouse.upHandler
|
||||
)
|
||||
dispatchEnd()
|
||||
},
|
||||
},
|
||||
touch: {
|
||||
moveEvent: 'touchmove',
|
||||
moveHandler: e => {
|
||||
if (e.cancelable) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
}
|
||||
dispatchMove(e.touches[0].clientX)
|
||||
return false
|
||||
},
|
||||
upEvent: 'touchend',
|
||||
upHandler: e => {
|
||||
document.removeEventListener(
|
||||
handlersAndEvents.touch.moveEvent,
|
||||
handlersAndEvents.touch.moveHandler
|
||||
)
|
||||
document.removeEventListener(
|
||||
handlersAndEvents.touch.upEvent,
|
||||
handlersAndEvents.touch.moveHandler
|
||||
)
|
||||
dispatchEnd()
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const events = isTouchEvent
|
||||
? handlersAndEvents.touch
|
||||
: handlersAndEvents.mouse
|
||||
document.addEventListener(events.moveEvent, events.moveHandler, {
|
||||
passive: false,
|
||||
})
|
||||
document.addEventListener(events.upEvent, events.upHandler, {
|
||||
passive: false,
|
||||
})
|
||||
|
||||
dispatch({
|
||||
type: actions.columnStartResizing,
|
||||
columnId: header.id,
|
||||
columnWidth: header.totalWidth,
|
||||
headerIdWidths,
|
||||
clientX,
|
||||
})
|
||||
}
|
||||
|
||||
return [
|
||||
props,
|
||||
{
|
||||
onMouseDown: e => e.persist() || onResizeStart(e, header),
|
||||
onTouchStart: e => e.persist() || onResizeStart(e, header),
|
||||
style: {
|
||||
cursor: 'ew-resize',
|
||||
},
|
||||
draggable: false,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
useResizeColumns.pluginName = 'useResizeColumns'
|
||||
|
||||
function reducer(state, action) {
|
||||
@@ -185,25 +88,57 @@ function reducer(state, action) {
|
||||
}
|
||||
|
||||
const useInstanceBeforeDimensions = instance => {
|
||||
instance.hooks.getResizerProps = []
|
||||
|
||||
const {
|
||||
flatHeaders,
|
||||
disableResizing,
|
||||
hooks: { getHeaderProps },
|
||||
state: { columnResizing },
|
||||
dispatch,
|
||||
} = instance
|
||||
|
||||
getHeaderProps.push({
|
||||
style: {
|
||||
position: 'relative',
|
||||
},
|
||||
getHeaderProps.push(() => {
|
||||
return {
|
||||
style: {
|
||||
position: 'relative',
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
const getInstance = useGetLatest(instance)
|
||||
const onMouseDown = (e, header) => {
|
||||
const headersToResize = getLeafHeaders(header)
|
||||
const headerIdWidths = headersToResize.map(d => [d.id, d.totalWidth])
|
||||
|
||||
const getResizerPropsHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
'getResizerProps'
|
||||
)
|
||||
const clientX = e.clientX
|
||||
|
||||
const onMouseMove = e => {
|
||||
const clientX = e.clientX
|
||||
|
||||
dispatch({ type: actions.columnResizing, clientX })
|
||||
}
|
||||
|
||||
const onMouseUp = e => {
|
||||
document.removeEventListener('mousemove', onMouseMove)
|
||||
document.removeEventListener('mouseup', onMouseUp)
|
||||
|
||||
dispatch({ type: actions.columnDoneResizing })
|
||||
}
|
||||
|
||||
document.addEventListener('mousemove', onMouseMove)
|
||||
document.addEventListener('mouseup', onMouseUp)
|
||||
|
||||
dispatch({
|
||||
type: actions.columnStartResizing,
|
||||
columnId: header.id,
|
||||
columnWidth: header.totalWidth,
|
||||
headerIdWidths,
|
||||
clientX,
|
||||
})
|
||||
}
|
||||
|
||||
// use reference to avoid memory leak in #1608
|
||||
const getInstance = useGetLatest(instance)
|
||||
|
||||
flatHeaders.forEach(header => {
|
||||
const canResize = getFirstDefined(
|
||||
@@ -217,13 +152,27 @@ const useInstanceBeforeDimensions = instance => {
|
||||
header.isResizing = columnResizing.isResizingColumn === header.id
|
||||
|
||||
if (canResize) {
|
||||
header.getResizerProps = makePropGetter(
|
||||
getResizerPropsHooks(),
|
||||
getInstance(),
|
||||
header
|
||||
)
|
||||
header.getResizerProps = userProps => {
|
||||
return mergeProps(
|
||||
{
|
||||
onMouseDown: e => e.persist() || onMouseDown(e, header),
|
||||
style: {
|
||||
cursor: 'ew-resize',
|
||||
},
|
||||
draggable: false,
|
||||
},
|
||||
applyPropHooks(
|
||||
getInstance().hooks.getResizerProps,
|
||||
header,
|
||||
getInstance()
|
||||
),
|
||||
userProps
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return instance
|
||||
}
|
||||
|
||||
function getLeafHeaders(header) {
|
||||
|
||||
@@ -2,11 +2,11 @@ import React from 'react'
|
||||
|
||||
import {
|
||||
actions,
|
||||
makePropGetter,
|
||||
mergeProps,
|
||||
applyPropHooks,
|
||||
ensurePluginOrder,
|
||||
useGetLatest,
|
||||
useMountedLayoutEffect,
|
||||
useConsumeHookGetter,
|
||||
} from '../utils'
|
||||
|
||||
const pluginName = 'useRowSelect'
|
||||
@@ -17,8 +17,9 @@ actions.toggleRowSelectedAll = 'toggleRowSelectedAll'
|
||||
actions.toggleRowSelected = 'toggleRowSelected'
|
||||
|
||||
export const useRowSelect = hooks => {
|
||||
hooks.getToggleRowSelectedProps = [defaultGetToggleRowSelectedProps]
|
||||
hooks.getToggleAllRowsSelectedProps = [defaultGetToggleAllRowsSelectedProps]
|
||||
hooks.getToggleRowSelectedProps = []
|
||||
hooks.getToggleAllRowsSelectedProps = []
|
||||
|
||||
hooks.stateReducers.push(reducer)
|
||||
hooks.useRows.push(useRows)
|
||||
hooks.useInstance.push(useInstance)
|
||||
@@ -26,45 +27,6 @@ export const useRowSelect = hooks => {
|
||||
|
||||
useRowSelect.pluginName = pluginName
|
||||
|
||||
const defaultGetToggleRowSelectedProps = (props, instance, row) => {
|
||||
const { manualRowSelectedKey = 'isSelected' } = instance
|
||||
let checked = false
|
||||
|
||||
if (row.original && row.original[manualRowSelectedKey]) {
|
||||
checked = true
|
||||
} else {
|
||||
checked = row.isSelected
|
||||
}
|
||||
|
||||
return [
|
||||
props,
|
||||
{
|
||||
onChange: e => {
|
||||
row.toggleRowSelected(e.target.checked)
|
||||
},
|
||||
style: {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
checked,
|
||||
title: 'Toggle Row Selected',
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
const defaultGetToggleAllRowsSelectedProps = (props, instance) => [
|
||||
props,
|
||||
{
|
||||
onChange: e => {
|
||||
instance.toggleRowSelectedAll(e.target.checked)
|
||||
},
|
||||
style: {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
checked: instance.isAllRowsSelected,
|
||||
title: 'Toggle All Rows Selected',
|
||||
},
|
||||
]
|
||||
|
||||
function reducer(state, action, previousState, instanceRef) {
|
||||
if (action.type === actions.init) {
|
||||
return {
|
||||
@@ -181,6 +143,7 @@ function useInstance(instance) {
|
||||
const {
|
||||
data,
|
||||
hooks,
|
||||
manualRowSelectedKey = 'isSelected',
|
||||
plugins,
|
||||
flatRows,
|
||||
autoResetSelectedRows = true,
|
||||
@@ -220,40 +183,71 @@ function useInstance(instance) {
|
||||
dispatch({ type: actions.toggleRowSelected, path, selected })
|
||||
|
||||
// use reference to avoid memory leak in #1608
|
||||
const getInstance = useGetLatest(instance)
|
||||
const instanceRef = React.useRef()
|
||||
instanceRef.current = instance
|
||||
|
||||
const getToggleAllRowsSelectedPropsHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
'getToggleAllRowsSelectedProps'
|
||||
)
|
||||
|
||||
const getToggleAllRowsSelectedProps = makePropGetter(
|
||||
getToggleAllRowsSelectedPropsHooks(),
|
||||
getInstance()
|
||||
)
|
||||
|
||||
const getToggleRowSelectedPropsHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
'getToggleRowSelectedProps'
|
||||
)
|
||||
const getToggleAllRowsSelectedProps = props => {
|
||||
return mergeProps(
|
||||
{
|
||||
onChange: e => {
|
||||
toggleRowSelectedAll(e.target.checked)
|
||||
},
|
||||
style: {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
checked: isAllRowsSelected,
|
||||
title: 'Toggle All Rows Selected',
|
||||
},
|
||||
applyPropHooks(
|
||||
instanceRef.current.hooks.getToggleAllRowsSelectedProps,
|
||||
instanceRef.current
|
||||
),
|
||||
props
|
||||
)
|
||||
}
|
||||
|
||||
hooks.prepareRow.push(row => {
|
||||
row.toggleRowSelected = set => toggleRowSelected(row.path, set)
|
||||
row.getToggleRowSelectedProps = props => {
|
||||
let checked = false
|
||||
|
||||
row.getToggleRowSelectedProps = makePropGetter(
|
||||
getToggleRowSelectedPropsHooks(),
|
||||
getInstance(),
|
||||
row
|
||||
)
|
||||
if (row.original && row.original[manualRowSelectedKey]) {
|
||||
checked = true
|
||||
} else {
|
||||
checked = row.isSelected
|
||||
}
|
||||
|
||||
return mergeProps(
|
||||
{
|
||||
onChange: e => {
|
||||
row.toggleRowSelected(e.target.checked)
|
||||
},
|
||||
style: {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
checked,
|
||||
title: 'Toggle Row Selected',
|
||||
},
|
||||
applyPropHooks(
|
||||
instanceRef.current.hooks.getToggleRowSelectedProps,
|
||||
row,
|
||||
instanceRef.current
|
||||
),
|
||||
props
|
||||
)
|
||||
}
|
||||
|
||||
return row
|
||||
})
|
||||
|
||||
Object.assign(instance, {
|
||||
return {
|
||||
...instance,
|
||||
flatRowPaths,
|
||||
toggleRowSelected,
|
||||
toggleRowSelectedAll,
|
||||
getToggleAllRowsSelectedProps,
|
||||
isAllRowsSelected,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function getRowIsSelected(row, selectedRowPaths) {
|
||||
|
||||
@@ -91,6 +91,14 @@ function useInstance(instance) {
|
||||
[setRowState]
|
||||
)
|
||||
|
||||
const getAutoResetRowState = useGetLatest(autoResetRowState)
|
||||
|
||||
useMountedLayoutEffect(() => {
|
||||
if (getAutoResetRowState()) {
|
||||
dispatch({ type: actions.resetRowState })
|
||||
}
|
||||
}, [data])
|
||||
|
||||
hooks.prepareRow.push(row => {
|
||||
const pathKey = row.path.join('.')
|
||||
|
||||
@@ -112,18 +120,13 @@ function useInstance(instance) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return row
|
||||
})
|
||||
|
||||
const getAutoResetRowState = useGetLatest(autoResetRowState)
|
||||
|
||||
useMountedLayoutEffect(() => {
|
||||
if (getAutoResetRowState()) {
|
||||
dispatch({ type: actions.resetRowState })
|
||||
}
|
||||
}, [data])
|
||||
|
||||
Object.assign(instance, {
|
||||
return {
|
||||
...instance,
|
||||
setRowState,
|
||||
setCellState,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import {
|
||||
actions,
|
||||
ensurePluginOrder,
|
||||
defaultColumn,
|
||||
makePropGetter,
|
||||
useConsumeHookGetter,
|
||||
mergeProps,
|
||||
applyPropHooks,
|
||||
getFirstDefined,
|
||||
defaultOrderByFn,
|
||||
isFunction,
|
||||
@@ -24,36 +24,12 @@ defaultColumn.sortType = 'alphanumeric'
|
||||
defaultColumn.sortDescFirst = false
|
||||
|
||||
export const useSortBy = hooks => {
|
||||
hooks.getSortByToggleProps = [defaultGetSortByToggleProps]
|
||||
hooks.stateReducers.push(reducer)
|
||||
hooks.useInstance.push(useInstance)
|
||||
}
|
||||
|
||||
useSortBy.pluginName = 'useSortBy'
|
||||
|
||||
const defaultGetSortByToggleProps = (props, instance, column) => {
|
||||
const { isMultiSortEvent = e => e.shiftKey } = instance
|
||||
|
||||
return [
|
||||
props,
|
||||
{
|
||||
onClick: column.canSort
|
||||
? e => {
|
||||
e.persist()
|
||||
column.toggleSortBy(
|
||||
undefined,
|
||||
!instance.disableMultiSort && isMultiSortEvent(e)
|
||||
)
|
||||
}
|
||||
: undefined,
|
||||
style: {
|
||||
cursor: column.canSort ? 'pointer' : undefined,
|
||||
},
|
||||
title: column.canSort ? 'Toggle SortBy' : undefined,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
// Reducer
|
||||
function reducer(state, action, previousState, instanceRef) {
|
||||
if (action.type === actions.init) {
|
||||
@@ -187,7 +163,9 @@ function useInstance(instance) {
|
||||
manualSortBy,
|
||||
defaultCanSort,
|
||||
disableSortBy,
|
||||
isMultiSortEvent = e => e.shiftKey,
|
||||
flatHeaders,
|
||||
hooks,
|
||||
state: { sortBy },
|
||||
dispatch,
|
||||
plugins,
|
||||
@@ -195,6 +173,8 @@ function useInstance(instance) {
|
||||
} = instance
|
||||
|
||||
ensurePluginOrder(plugins, ['useFilters'], 'useSortBy', [])
|
||||
// Add custom hooks
|
||||
hooks.getSortByToggleProps = []
|
||||
|
||||
// Updates sorting based on a columnId, desc flag and multi flag
|
||||
const toggleSortBy = (columnId, desc, multi) => {
|
||||
@@ -204,11 +184,6 @@ function useInstance(instance) {
|
||||
// use reference to avoid memory leak in #1608
|
||||
const getInstance = useGetLatest(instance)
|
||||
|
||||
const getSortByTogglePropsHooks = useConsumeHookGetter(
|
||||
getInstance().hooks,
|
||||
'getSortByToggleProps'
|
||||
)
|
||||
|
||||
// Add the getSortByToggleProps method to columns and headers
|
||||
flatHeaders.forEach(column => {
|
||||
const {
|
||||
@@ -237,11 +212,31 @@ function useInstance(instance) {
|
||||
}
|
||||
}
|
||||
|
||||
column.getSortByToggleProps = makePropGetter(
|
||||
getSortByTogglePropsHooks(),
|
||||
getInstance(),
|
||||
column
|
||||
)
|
||||
column.getSortByToggleProps = props => {
|
||||
return mergeProps(
|
||||
{
|
||||
onClick: canSort
|
||||
? e => {
|
||||
e.persist()
|
||||
column.toggleSortBy(
|
||||
undefined,
|
||||
!getInstance().disableMultiSort && isMultiSortEvent(e)
|
||||
)
|
||||
}
|
||||
: undefined,
|
||||
style: {
|
||||
cursor: canSort ? 'pointer' : undefined,
|
||||
},
|
||||
title: canSort ? 'Toggle SortBy' : undefined,
|
||||
},
|
||||
applyPropHooks(
|
||||
getInstance().hooks.getSortByToggleProps,
|
||||
column,
|
||||
getInstance()
|
||||
),
|
||||
props
|
||||
)
|
||||
}
|
||||
|
||||
const columnSort = sortBy.find(d => d.id === id)
|
||||
column.isSorted = !!columnSort
|
||||
@@ -334,10 +329,10 @@ function useInstance(instance) {
|
||||
}
|
||||
}, [manualSortBy ? null : data])
|
||||
|
||||
Object.assign(instance, {
|
||||
return {
|
||||
...instance,
|
||||
toggleSortBy,
|
||||
preSortedRows: rows,
|
||||
sortedRows,
|
||||
rows: sortedRows,
|
||||
})
|
||||
preSortedRows: rows,
|
||||
}
|
||||
}
|
||||
|
||||
+25
-68
@@ -36,77 +36,41 @@ export function defaultGroupByFn(rows, columnId) {
|
||||
}, {})
|
||||
}
|
||||
|
||||
function mergeProps(...propList) {
|
||||
return propList.reduce((props, next) => {
|
||||
const { style, className, ...rest } = next
|
||||
export const mergeProps = (...groups) => {
|
||||
let props = {}
|
||||
|
||||
groups.forEach(({ style = {}, className, ...rest } = {}) => {
|
||||
props = {
|
||||
...props,
|
||||
...rest,
|
||||
style: {
|
||||
...(props.style || {}),
|
||||
...(style || {}),
|
||||
...style,
|
||||
},
|
||||
className: [props.className, className].filter(Boolean).join(' '),
|
||||
}
|
||||
})
|
||||
|
||||
if (props.className === '') {
|
||||
delete props.className
|
||||
}
|
||||
|
||||
return props
|
||||
}, {})
|
||||
}
|
||||
|
||||
function handlePropGetter(prevProps, userProps, ...meta) {
|
||||
// Handle a lambda, pass it the previous props
|
||||
if (typeof userProps === 'function') {
|
||||
return handlePropGetter({}, userProps(prevProps, ...meta))
|
||||
if (props.className === '') {
|
||||
delete props.className
|
||||
}
|
||||
|
||||
// Handle an array, merge each item as separate props
|
||||
if (Array.isArray(userProps)) {
|
||||
return mergeProps(prevProps, ...userProps)
|
||||
}
|
||||
|
||||
// Handle an object by default, merge the two objects
|
||||
return mergeProps(prevProps, userProps)
|
||||
return props
|
||||
}
|
||||
|
||||
export const makePropGetter = (hooks, ...meta) => {
|
||||
return (userProps = {}) =>
|
||||
[...hooks, userProps].reduce(
|
||||
(prev, next) => handlePropGetter(prev, next, ...meta),
|
||||
{}
|
||||
)
|
||||
}
|
||||
|
||||
export const reduceHooks = (hooks, initial, ...args) =>
|
||||
export const applyHooks = (hooks, initial, ...args) =>
|
||||
hooks.reduce((prev, next) => {
|
||||
const nextValue = next(prev, ...args)
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (typeof nextValue === 'undefined') {
|
||||
console.info(next)
|
||||
throw new Error(
|
||||
'React Table: A reducer hook ☝️ just returned undefined! This is not allowed.'
|
||||
)
|
||||
}
|
||||
if (typeof nextValue === 'undefined') {
|
||||
throw new Error(
|
||||
'React Table: A hook just returned undefined! This is not allowed.'
|
||||
)
|
||||
}
|
||||
return nextValue
|
||||
}, initial)
|
||||
|
||||
export const loopHooks = (hooks, ...args) =>
|
||||
hooks.forEach(hook => {
|
||||
const nextValue = hook(...args)
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (typeof nextValue !== 'undefined') {
|
||||
console.info(hook, nextValue)
|
||||
throw new Error(
|
||||
'React Table: A loop-type hook ☝️ just returned a value! This is not allowed.'
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
export const applyPropHooks = (hooks, ...args) =>
|
||||
hooks.reduce((prev, next) => mergeProps(prev, next(...args)), {})
|
||||
|
||||
export function ensurePluginOrder(plugins, befores, pluginName, afters) {
|
||||
const pluginIndex = plugins.findIndex(
|
||||
@@ -114,13 +78,11 @@ export function ensurePluginOrder(plugins, befores, pluginName, afters) {
|
||||
)
|
||||
|
||||
if (pluginIndex === -1) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
throw new Error(`The plugin "${pluginName}" was not found in the plugin list!
|
||||
throw new Error(`The plugin ${pluginName} was not found in the plugin list!
|
||||
This usually means you need to need to name your plugin hook by setting the 'pluginName' property of the hook function, eg:
|
||||
|
||||
${pluginName}.pluginName = '${pluginName}'
|
||||
`)
|
||||
}
|
||||
}
|
||||
|
||||
befores.forEach(before => {
|
||||
@@ -128,22 +90,18 @@ This usually means you need to need to name your plugin hook by setting the 'plu
|
||||
plugin => plugin.pluginName === before
|
||||
)
|
||||
if (beforeIndex > -1 && beforeIndex > pluginIndex) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
throw new Error(
|
||||
`React Table: The ${pluginName} plugin hook must be placed after the ${before} plugin hook!`
|
||||
)
|
||||
}
|
||||
throw new Error(
|
||||
`React Table: The ${pluginName} plugin hook must be placed after the ${before} plugin hook!`
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
afters.forEach(after => {
|
||||
const afterIndex = plugins.findIndex(plugin => plugin.pluginName === after)
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (afterIndex > -1 && afterIndex < pluginIndex) {
|
||||
throw new Error(
|
||||
`React Table: The ${pluginName} plugin hook must be placed before the ${after} plugin hook!`
|
||||
)
|
||||
}
|
||||
if (afterIndex > -1 && afterIndex < pluginIndex) {
|
||||
throw new Error(
|
||||
`React Table: The ${pluginName} plugin hook must be placed before the ${after} plugin hook!`
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -175,7 +133,7 @@ export function useMountedLayoutEffect(fn, deps) {
|
||||
}, deps)
|
||||
}
|
||||
|
||||
export function useAsyncDebounce(defaultFn, defaultWait = 0) {
|
||||
export default function useAsyncDebounce(defaultFn, defaultWait = 0) {
|
||||
const debounceRef = React.useRef({})
|
||||
debounceRef.current.defaultFn = defaultFn
|
||||
debounceRef.current.defaultWait = defaultWait
|
||||
@@ -186,9 +144,8 @@ export function useAsyncDebounce(defaultFn, defaultWait = 0) {
|
||||
wait = debounceRef.current.defaultWait
|
||||
) => {
|
||||
if (!debounceRef.current.promise) {
|
||||
debounceRef.current.promise = new Promise((resolve, reject) => {
|
||||
debounceRef.current.promise = new Promise(resolve => {
|
||||
debounceRef.current.resolve = resolve
|
||||
debounceRef.current.reject = reject
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user