Compare commits

..
Author SHA1 Message Date
Tanner Linsley 792c3ec392 v7.0.0-beta.19 2019-12-01 00:12:33 -07:00
63 changed files with 1585 additions and 1239 deletions
-3
View File
@@ -1,3 +0,0 @@
size-files:
- sizes-cjs.json
- sizes-es.json
+8 -8
View File
@@ -1,20 +1,20 @@
{
"dist/index.js": {
"bundled": 96781,
"minified": 46762,
"gzipped": 12304
"bundled": 90278,
"minified": 43057,
"gzipped": 11502
},
"dist/index.es.js": {
"bundled": 96216,
"minified": 46270,
"gzipped": 12188,
"bundled": 89695,
"minified": 42549,
"gzipped": 11382,
"treeshaked": {
"rollup": {
"code": 78,
"code": 450,
"import_statements": 21
},
"webpack": {
"code": 11143
"code": 3712
}
}
}
-44
View File
@@ -1,47 +1,3 @@
## 7.0.0-beta.25
- Fixed an issue where `useRowState` would crash due to invalid initial state of previous cell state on `columnId` lookup
## 7.0.0-beta.24
- Changed `selectedRowPaths` to use a `Set()` instead of an array for performance.
- Removed types and related files from the repo. The community will now maintain types externally on Definitely Typed
## 7.0.0-beta.23
- The internal `useMain` hook has been renamed to `useInstance`
- The internal `useBeforeDimensions` hook has been renamed to `useInstanceBeforeDimensions`
- Fixed an issue where `useResizeColumns` wasn't working properly
## 7.0.0-beta.22
- Fixed an issue where `useRowState` would crash due to invalid initial state attempting to spread into the new state
## 7.0.0-beta.21
- Removed deprecated `defaultState` export
## 7.0.0-beta.20
- Internals have been reworked to use `useReducer` instead of `useState` for stability and architecture
- The `state` option has been removed in favor of using a custom reducer
- The `reducer` option has been changed to a new function signature: `function (newState, action, oldState) => newState`
- The `setState` table instance method is no longer supported
- The `dispatch` table instanced method was added
- The `ReactTable.actions` export is now a plain object of action types mapped to identically named action strings
- The `ReactTable.reducerHandlers` export was added, which is a plain object of plugin hook names mapped to their respective reducer functions
## 7.0.0-beta.19
- Added an `isAggregated` boolean parameter to the `aggregate` function signature
## 7.0.0-beta.16
- Removed service workers from examples
- Fixed a memory leak when `instance` was referenced in function closures
- Fixed an issue where the table would infinitely rerender due to incorrect effect dependencies
- Fixed an issue where row grouping and row selection would not work properly together.
## 7.0.0-beta.15
- Fixed an issue where `defaultGetResetPageDeps` was using `data` instead of `rows`
+25 -18
View File
@@ -21,7 +21,7 @@ Enjoy this library? Try them all! [React Query](https://github.com/tannerlinsley
## Features
- Lightweight (4kb - 11kb depending on features and tree-shaking)
- Lightweight (4kb - 10kb 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)
@@ -37,13 +37,36 @@ Enjoy this library? Try them all! [React Query](https://github.com/tannerlinsley
- 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
## News / Q&A
#### What is the current state of React Table?
React Table v7 is still under active development, and its API is still changing, albeit only slightly. For this reason, it is currently in an **beta** release state. It's estimated that it will be fully released as a stable version sometime during October 2019.
#### Should I use v7@beta in production?
You can use it in production as long as you lock in the beta version in your package.json and also accept that there may be unlikely, but possible bug fixes and/or API changes before it's official release.
#### I'm still using v6, what should I do?
v6 is a great library and is still the default install for `react-table`, however, I do not intend on offering any long-term support for it. If you intend to keep using v6, I recommend maintaining your own fork of the library and keeping it up to date for your version of React.
#### Where are the docs for the older v6 version?
Please [visit the v6 branch](https://github.com/tannerlinsley/react-table/tree/v6)
#### I want to migrate from v6 to v7. How do I do that?
The differences between the 2 versions are incredibly massive. Unfortunately, I cannot write a one-to-one upgrade guide for any of v6's API, simply because much of it is irrelevant with v7's headless approach. The best approach for migrating to v7 is to learn its API by reading the documentation and then following some of the examples to begin building your own table component.
In case you would need to have both v6 and v7 in one app during the migration process (large codebase, complex use cases), you can install an official [`react-table-6` package](https://www.npmjs.com/package/react-table-6) alongside the `react-table`.
## 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.md) - Get to know React Table's API, how to use it and how to extend its functionality
- [Using V6 Still?](#v6-info)
- [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
@@ -193,19 +216,3 @@ This library is being built and maintained by me, @tannerlinsley and I am always
</table>
### [Become a Sponsor](https://github.com/sponsors/tannerlinsley/)
## v6 Info
#### I'm still using v6, what should I do?
v6 is a great library and while it is still available for use, I do not intend on offering any long-term support for it. If you intend to keep using v6, I recommend maintaining your own fork of the library and keeping it up to date for your version of React.
#### Where are the docs for the older v6 version?
Please [visit the v6 branch](https://github.com/tannerlinsley/react-table/tree/v6)
#### I want to migrate from v6 to v7. How do I do that?
The differences between the 2 versions are incredibly massive. Unfortunately, I cannot write a one-to-one upgrade guide for any of v6's API, simply because much of it is irrelevant with v7's headless approach. The best approach for migrating to v7 is to learn its API by reading the documentation and then following some of the examples to begin building your own table component.
In case you would need to have both v6 and v7 in one app during the migration process (large codebase, complex use cases), you can install an official [`react-table-6` package](https://www.npmjs.com/package/react-table-6) alongside the `react-table`.
+36 -2
View File
@@ -1,5 +1,39 @@
# Using TypeScript with React-Table
Types for React Table are maintained externally by the Typescript community and are located at https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react-table.
React-table is a very flexible library, because of this, the shape of data at almost every contact point is defined by the specific set of plugins that you choose to pass to `useTable`.
Because React Table is not written in Typescript and the types are not maintained by the core team, there are no guarantees around the types always being up to date or working perfectly. If this is an issue for you, please contribute to the community types and discuss solutions there.
To get started, copy the file `react-table-config.d.ts` into your source tree (e.g. into a types folder). This expands the default types with all of the plugin extensions currently in the type definitions.
You can stop here if you like, but while this is simple, it's a bit misleading. Out of the box, these types will suggest that you have access to values that come from plugins that you aren't using, i.e. the error checking is weakened.
To bring the resulting types into better alignment with your plugins, you should edit your local copy of `react-table-config.d.ts` and comment out all of the interfaces that don't apply to your chosen set of plugins.
e.g.
if you are only using `useSortBy` and `usePagination` then you would take this:
```tsx
extends UseExpandedOptions<D>,
UseFiltersOptions<D>,
UseGroupByOptions<D>,
UsePaginationOptions<D>,
UseRowSelectOptions<D>,
UseSortByOptions<D>,
UseFiltersOptions<D>,
UseResizeColumnsOptions<D>,
Record<string, any> {}
```
and convert it to this:
```tsx
export interface TableOptions<D extends object>
extends UsePaginationOptions<D>,
UseSortByOptions<D> {}
```
Then follow the same pattern for all of the other interfaces in the file. You'll notice that many plugins don't extend all of the top-level interfaces.
## Caveat
The interfaces are all global. If you have several different configurations for the table, you should create interfaces using the union of all of the plugins that you are using.
+42 -47
View File
@@ -25,7 +25,7 @@ React Table is essentially a compatible collection of **custom React hooks**:
### Hook Usage
`useTable` is the **primary** hook used to build a React Table. It serves as the starting point for **every option and every plugin hook** that React Table supports. The options passed into `useTable` are supplied to every plugin hook after it in the order they are supplied, eventually resulting in a final `instance` object that you can use to build your table UI and interact with the table's state.
`useTable` is the **primary** hook used to build a React Table. It serves as the starting point for **every option and every plugin hook** that React Table supports. The options passed into `useTable` are supplied to every plugin hook after it in the order they are supplied, eventually resulting a final `instance` object that you can use to build your table UI and interact with the table's state.
```js
const instance = useTable(
@@ -87,11 +87,16 @@ The following options are supported via the main options object passed to `useTa
- Optional
- The initial state object for the table.
- Upon table initialization, this object is **merged over the table's `defaultState` object** (eg. `{...defaultState, ...initialState}`) that React Table and its hooks use to register default state to produce the final initial state object passed to the `React.useState` hook internally.
- `reducer: Function(newState, action, prevState) => newState`
- `state: Object`
- 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`
- May also be used to "control" the state of the table, by overriding certain pieces of state regardless of the action.
- Must be **memoized**
- When either the internal `state` or this `state` object change, this object is **always merged over the internal table state** (eg. `{...state, ...overrides}`) to produce the final state object that is then passed to the `useTable` options.
- `reducer: Function(oldState, newState) => finalState`
- Optional
- Must be **memoized**
- Inspired by Kent C. Dodd's [State Reducer Pattern](https://kentcdodds.com/blog/the-state-reducer-pattern-with-react-hooks)
- With every `setState` call to the table's internal `React.useState` instance, this reducer is called and is allowed to modify the final state object for updating.
- It is passed the `oldState`, the `newState`, and when provided, an optional action `type`.
- `defaultColumn: Object`
- Optional
- Defaults to `{}`
@@ -109,7 +114,7 @@ The following options are supported via the main options object passed to `useTa
- Defaults to `(row) => row.subRows || []`
- Use this function to change how React Table detects subrows. You could even use this function to generate sub rows if you want.
- By default, it will attempt to return the `subRows` property on the row, or an empty array if that is not found.
- `getRowId: Function(row, relativeIndex) => string`
- `getRowID: Function(row, relativeIndex) => string`
- Use this function to change how React Table detects unique rows and also how it constructs each row's underlying `path` property.
- Optional
- Must be **memoized**
@@ -177,14 +182,18 @@ The following options are supported on any column object you can pass to `column
The following properties are available on the table instance returned from `useTable`
- `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`
- **Memoized** - This object reference will not change unless either the internal state or the `state` overrides option provided change.
- This is the final state object of the table, which is the product of the `initialState`, internal state, optional `state` overrides option and the `reducer` option (if applicable).
- `setState: Function(updater, type) => void`
- **Memoized** - This function reference will not change unless the internal state `reducer` is changed
- 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`
- `updater: Function`
- This parameter is identical to the `setState` API exposed by `React.useState`.
- If a function is passed, that function will be called with the previous state and is expected to return a new version of the state.
- If a value is passed, it will replace the state entirely.
- `type: String`
- Optional
- 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
@@ -196,7 +205,7 @@ The following properties are available on the table instance returned from `useT
- **Some of these headers may be materialized as placeholders**
- See [Header Group Properties](#headergroup-properties) for more information
- `headers: Array<Column>`
- A **nested** array of final header objects, **similar in structure to the original columns configuration option, but rebuilt for ordering**
- An **nested** array of final header objects, **similar in structure to the original columns configuration option, but rebuilt for ordering**
- Each contains the headers that are displayed underneath it.
- **Some of these headers may be materialized as placeholders**
- See [Column Properties](#column-properties) for more information
@@ -228,9 +237,9 @@ The following properties are available on the table instance returned from `useT
- This function can be used to update the internal state for any row.
- Pass it a valid `rowPath` array and `updater`. The `updater` may be a value or function, similar to `React.useState`'s usage.
- If `updater` is a function, it will be passed the previous value
- `setCellState: Function(rowPath, columnId, updater: Function | any) => void`
- `setCellState: Function(rowPath, columnID, updater: Function | any) => void`
- This function can be used to update the internal state for any cell.
- Pass it a valid `rowPath` array, `columnId` and `updater`. The `updater` may be a value or function, similar to `React.useState`'s usage.
- Pass it a valid `rowPath` array, `columnID` and `updater`. The `updater` may be a value or function, similar to `React.useState`'s usage.
- If `updater` is a function, it will be passed the previous value
### HeaderGroup Properties
@@ -278,8 +287,8 @@ The following additional properties are available on every `row` object returned
- `cells: Array<Cell>`
- An array of `Cell` objects containing properties and functions specific to the row and column it belongs to.
- See [Cell Properties](#cell-properties) for more information
- `values: Object<columnId: any>`
- A map of this row's **resolved** values by columnId, eg. `{ firstName: 'Tanner', lastName: 'Linsley' }`
- `values: Object<columnID: any>`
- A map of this row's **resolved** values by columnID, eg. `{ firstName: 'Tanner', lastName: 'Linsley' }`
- `getRowProps: Function(?props)`
- **Required**
- This function is used to resolve any props needed for this row.
@@ -343,7 +352,7 @@ The following additional properties are available on every `Cell` object returne
The following options are supported via the main options object passed to `useTable(options)`
- `state.sortBy: Array<Object<id: columnId, desc: Bool>>`
- `state.sortBy: Array<Object<id: columnID, desc: Bool>>`
- Must be **memoized**
- An array of sorting objects. If there is more than one object in the array, multi-sorting will be enabled. Each sorting object should contain an `id` key with the corresponding column ID to sort by. An optional `desc` key may be set to true or false to indicated ascending or descending sorting for that column. This information is stored in state since the table is allowed to manipulate the filter through user interaction.
- `initialState.sortBy`
@@ -419,7 +428,7 @@ The following values are provided to the table `instance`:
- An array of **sorted** rows.
- `preSortedRows: Array<Row>`
- The array of rows that were originally sorted.
- `toggleSortBy: Function(ColumnId: String, descending: Bool, isMulti: Bool) => void`
- `toggleSortBy: Function(ColumnID: String, descending: Bool, isMulti: Bool) => void`
- This function can be used to programmatically toggle the sorting for any specific column
### Column Properties
@@ -430,7 +439,7 @@ The following properties are available on every `Column` object returned by the
- Denotes whether a column is sortable or not depending on if it has a valid accessor/data model or is manually disabled via an option.
- `toggleSortBy: Function(descending, multi) => void`
- This function can be used to programmatically toggle the sorting for this column.
- This function is similar to the `instance`-level `toggleSortBy`, however, passing a columnId is not required since it is located on a `Column` object already.
- This function is similar to the `instance`-level `toggleSortBy`, however, passing a columnID is not required since it is located on a `Column` object already.
- `getSortByToggleProps: Function(props) => props`
- **Required**
- 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.
@@ -465,9 +474,9 @@ The following properties are available on every `Column` object returned by the
The following options are supported via the main options object passed to `useTable(options)`
- `state.filters: Object<columnId: filterValue>`
- `state.filters: Object<columnID: filterValue>`
- Must be **memoized**
- An object of 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.
- An object of 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.
- `initialState.filters`
- Identical to the `state.filters` option above
- `manualFilters: Bool`
@@ -523,7 +532,7 @@ The following values are provided to the table `instance`:
- `preFilteredRows: 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.
- `setFilter: Function(columnId, filterValue) => void`
- `setFilter: Function(columnID, filterValue) => void`
- An instance-level function used to update the filter value for a specific column.
- `setAllFilters: Function(filtersObject) => void`
- An instance-level function used to update the values for **all** filters on the table, all at once.
@@ -535,7 +544,7 @@ The following properties are available on every `Column` object returned by the
- `canFilter: Bool`
- Denotes whether a column is filterable or not depending on if it has a valid accessor/data model or is manually disabled via an option.
- `setFilter: Function(filterValue) => void`
- A column-level function used to update the filter value for this column
- An column-level function used to update the filter value for this column
- `filterValue: any`
- The current filter value for this column, resolved from the table state's `filters` object
- `preFilteredRows: Array<row>`
@@ -592,12 +601,6 @@ 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`
- 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.
- `disableGroupBy: Boolean`
- Defaults to `false`
- If `true`, will disable grouping for this column.
@@ -610,7 +613,7 @@ The following values are provided to the table `instance`:
- An array of **grouped and aggregated** rows.
- `preGroupedRows: Array<Row>`
- The array of rows originally used to create the grouped rows.
- `toggleGroupBy: Function(columnId: String, ?set: Bool) => void`
- `toggleGroupBy: Function(columnID: String, ?set: Bool) => void`
- This function can be used to programmatically set or toggle the groupBy state for a specific column.
### Column Properties
@@ -636,7 +639,7 @@ The following properties are available on every `Column` object returned by the
The following properties are available on every `Row` object returned by the table instance.
- `groupById: String`
- `groupByID: String`
- The column ID for which this row is being grouped.
- Will be `undefined` if the row is an original row from `data` and not a materialized one from the grouping.
- `groupByVal: any`
@@ -847,9 +850,9 @@ The following values are provided to the table `instance`:
The following options are supported via the main options object passed to `useTable(options)`
- `state.selectedRowPaths: Set<RowPathKey>`
- `state.selectedRowPaths: Array<RowPathKey>`
- Optional
- Defaults to `new Set()`
- Defaults to `[]`
- If a row's path key (eg. a row path of `[1, 3, 2]` would have a path key of `1.3.2`) is found in this array, it will have a selected state.
- `initialState.selectedRowPaths`
- Identical to the `state.selectedRowPaths` option above
@@ -915,7 +918,7 @@ The following additional properties are available on every **prepared** `row` ob
The following options are supported via the main options object passed to `useTable(options)`
- `state.rowState: Object<RowPathKey:Object<any, cellState: {columnId: Object}>>`
- `state.rowState: Object<RowPathKey:Object<any, cellState: {columnID: Object}>>`
- Optional
- Defaults to `{}`
- If a row's path key (eg. a row path of `[1, 3, 2]` would have a path key of `1.3.2`) is found in this array, it will have the state of the value corresponding to that key.
@@ -927,14 +930,6 @@ The following options are supported via the main options object passed to `useTa
- Optional
- This function may optionally 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`
- `getResetRowStateDeps: Function(instance) => [...useEffectDependencies]`
- Optional
- Defaults to resetting the `rowState` state to `{}` when the dependencies below change
- ```js
const getResetRowStateDeps = ({ data }) => [data]
```
- If set, the dependencies returned from this function will be used to determine when the effect to reset the `rowState` state is fired.
- To disable, set to `false`
### Instance Properties
@@ -943,7 +938,7 @@ The following values are provided to the table `instance`:
- `setRowState: Function(rowPath: Array<string>, updater: Function | Any) => void`
- Use this function to programmatically update the state of a row.
- `updater` can be a function or value. If a `function` is passed, it will receive the current value and expect a new one to be returned.
- `setCellState: Function(rowPath: Array<string>, columnId: String, updater: Function | Any) => void`
- `setCellState: Function(rowPath: Array<string>, columnID: String, updater: Function | Any) => void`
- Use this function to programmatically update the cell of a row.
- `updater` can be a function or value. If a `function` is passed, it will receive the current value and expect a new one to be returned.
@@ -963,7 +958,7 @@ The following additional properties are available on every **prepared** `row` ob
The following additional properties are available on every `Cell` object returned in an array of `cells` on every row object.
- `state: Object`
- This is the state object for each cell, pre-mapped to the cell from the table state's `rowState` object via `rowState[row.path.join('.')].cellState[columnId]`
- This is the state object for each cell, pre-mapped to the cell from the table state's `rowState` object via `rowState[row.path.join('.')].cellState[columnID]`
- `setState: Function(updater: Function | any)`
- Use this function to programmatically update the state of a cell.
- `updater` can be a function or value. If a `function` is passed, it will receive the current value and expect a new one to be returned.
@@ -1085,7 +1080,7 @@ The core column options `width`, `minWidth` and `maxWidth` are used to calculate
The following options are supported via the main options object passed to `useTable(options)`
- `state.columnOrder: Array<ColumnId>`
- `state.columnOrder: Array<ColumnID>`
- Optional
- Defaults to `[]`
- Any column ID's not represented in this array will be naturally ordered based on their position in the original table's `column` structure
@@ -1096,7 +1091,7 @@ The following options are supported via the main options object passed to `useTa
The following values are provided to the table `instance`:
- `setColumnOrder: Function(updater: Function | Array<ColumnId>) => void`
- `setColumnOrder: Function(updater: Function | Array<ColumnID>) => void`
- Use this function to programmatically update the columnOrder.
- `updater` can be a function or value. If a `function` is passed, it will receive the current value and expect a new one to be returned.
+1 -1
View File
@@ -11,7 +11,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2"
},
"devDependencies": {
+1 -1
View File
@@ -13,7 +13,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2"
},
"devDependencies": {
+1 -1
View File
@@ -11,7 +11,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2"
},
"devDependencies": {
+1 -1
View File
@@ -11,7 +11,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2"
},
"devDependencies": {
+1 -1
View File
@@ -11,7 +11,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2"
},
"devDependencies": {
+1 -1
View File
@@ -11,7 +11,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2"
},
"devDependencies": {
+17 -16
View File
@@ -59,9 +59,9 @@ const Styles = styled.div`
function Table({ columns, data }) {
const defaultColumn = React.useMemo(
() => ({
minWidth: 30,
minWidth: 20,
width: 150,
maxWidth: 400,
maxWidth: 500,
}),
[]
)
@@ -102,20 +102,21 @@ function Table({ columns, data }) {
</div>
<div {...getTableBodyProps()}>
{rows.map((row, i) => {
prepareRow(row)
return (
<div {...row.getRowProps()} className="tr">
{row.cells.map(cell => {
return (
<div {...cell.getCellProps()} className="td">
{cell.render('Cell')}
</div>
)
})}
</div>
)
})}
{rows.map(
(row, i) => {
prepareRow(row);
return (
<div {...row.getRowProps()} className="tr">
{row.cells.map(cell => {
return (
<div {...cell.getCellProps()} className="td">
{cell.render('Cell')}
</div>
)
})}
</div>
)}
)}
</div>
</div>
)
@@ -11,7 +11,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2"
},
"devDependencies": {
+1 -1
View File
@@ -11,7 +11,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2"
},
"devDependencies": {
+3 -3
View File
@@ -236,9 +236,9 @@ function App() {
// Update data. So we can keep track of that flag with a ref.
// When our cell renderer calls updateMyData, we'll use
// the rowIndex, columnId and new value to update the
// the rowIndex, columnID and new value to update the
// original data
const updateMyData = (rowIndex, columnId, value) => {
const updateMyData = (rowIndex, columnID, value) => {
// We also turn on the flag to not reset the page
setSkipPageReset(true)
setData(old =>
@@ -246,7 +246,7 @@ function App() {
if (index === rowIndex) {
return {
...old[rowIndex],
[columnId]: value,
[columnID]: value,
}
}
return row
+1 -1
View File
@@ -11,7 +11,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2"
},
"devDependencies": {
+1 -1
View File
@@ -12,7 +12,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2"
},
"devDependencies": {
+1 -1
View File
@@ -11,7 +11,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2"
},
"devDependencies": {
+1 -1
View File
@@ -11,7 +11,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2"
},
"devDependencies": {
@@ -12,7 +12,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2"
},
"devDependencies": {
+3 -3
View File
@@ -582,9 +582,9 @@ function App() {
const skipPageResetRef = React.useRef(false)
// When our cell renderer calls updateMyData, we'll use
// the rowIndex, columnId and new value to update the
// the rowIndex, columnID and new value to update the
// original data
const updateMyData = (rowIndex, columnId, value) => {
const updateMyData = (rowIndex, columnID, value) => {
// We also turn on the flag to not reset the page
skipPageResetRef.current = true
setData(old =>
@@ -592,7 +592,7 @@ function App() {
if (index === rowIndex) {
return {
...row,
[columnId]: value,
[columnID]: value,
}
}
return row
+1 -1
View File
@@ -12,7 +12,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2"
},
"devDependencies": {
+3 -3
View File
@@ -581,9 +581,9 @@ function App() {
const skipResetRef = React.useRef(false)
// When our cell renderer calls updateMyData, we'll use
// the rowIndex, columnId and new value to update the
// the rowIndex, columnID and new value to update the
// original data
const updateMyData = (rowIndex, columnId, value) => {
const updateMyData = (rowIndex, columnID, value) => {
// We also turn on the flag to not reset the page
skipResetRef.current = true
setData(old =>
@@ -591,7 +591,7 @@ function App() {
if (index === rowIndex) {
return {
...row,
[columnId]: value,
[columnID]: value,
}
}
return row
+12 -5
View File
@@ -918,7 +918,7 @@
dependencies:
regenerator-runtime "^0.13.2"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.2", "@babel/runtime@^7.5.5":
"@babel/runtime@^7.0.0", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5":
version "7.7.4"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.4.tgz#b23a856751e4bf099262f867767889c0e3fe175b"
integrity sha512-r24eVUUr0QqNZa+qrImUk8fn5SPhHq+IfYvIoIMg0do3GdK9sMdiLKP3GYVVaxpPKORgm8KRKaNTEhAjgIpLMw==
@@ -8218,10 +8218,10 @@ react-scripts@3.0.1:
optionalDependencies:
fsevents "2.0.6"
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-table@^7.0.0-beta.15:
version "7.0.0-beta.15"
resolved "https://registry.yarnpkg.com/react-table/-/react-table-7.0.0-beta.15.tgz#66dc4c71f9e77f5c92ac65a307341d6d3e045d33"
integrity sha512-Qr0HjVkYIPLi7BJiHm6ZfRIH00Ziu/bdonwouwKY10hsaqQi9AyH9kF4cXJChBQuspfjsnqnP9kQAjsEIoAeUQ==
react@^16.8.6:
version "16.12.0"
@@ -9093,6 +9093,13 @@ stealthy-require@^1.1.1:
resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b"
integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=
stop-runaway-react-effects@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/stop-runaway-react-effects/-/stop-runaway-react-effects-1.2.1.tgz#ffc9df565021c69cd2c04171e7f0e4a6c7eb2b21"
integrity sha512-56AK/rkH+/Y1ZUF+QYsl/7Z/caSnF46RmkbF6AemYWue2tZpAlOOj+VdcLdhFGo5Vg7ajDP2Lqq+3UhbdWQRmQ==
dependencies:
"@babel/runtime" "^7.4.4"
stream-browserify@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b"
+1 -1
View File
@@ -12,7 +12,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest"
"react-table": "next"
},
"devDependencies": {
"@rescripts/cli": "^0.0.11",
+1 -1
View File
@@ -11,7 +11,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2"
},
"devDependencies": {
+3 -2
View File
@@ -61,6 +61,7 @@ function Table({
nextPage,
previousPage,
setPageSize,
rows,
// Get the state from the instance
state: { pageIndex, pageSize },
} = useTable(
@@ -244,7 +245,7 @@ function App() {
// even a server. But for this example, we'll just fake it.
// Give this fetch an ID
const fetchId = ++fetchIdRef.current
const fetchID = ++fetchIdRef.current
// Set the loading state
setLoading(true)
@@ -252,7 +253,7 @@ function App() {
// We'll even set a delay to simulate a server here
setTimeout(() => {
// Only update the data if this is the latest fetch
if (fetchId === fetchIdRef.current) {
if (fetchID === fetchIdRef.current) {
const startRow = pageSize * pageIndex
const endRow = startRow + pageSize
setData(serverData.slice(startRow, endRow))
+1 -1
View File
@@ -11,7 +11,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2"
},
"devDependencies": {
+13 -11
View File
@@ -62,7 +62,6 @@ function Table({ columns, data }) {
columns,
data,
initialState: { pageIndex: 2 },
debug: true,
},
usePagination
)
@@ -96,16 +95,19 @@ function Table({ columns, data }) {
))}
</thead>
<tbody {...getTableBodyProps()}>
{page.map((row, i) => {
prepareRow(row)
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
})}
</tr>
)
})}
{page.map(
(row, i) => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return (
<td {...cell.getCellProps()}>{cell.render('Cell')}</td>
)
})}
</tr>
)}
)}
</tbody>
</table>
{/*
+2 -2
View File
@@ -11,7 +11,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2",
"react-dnd": "^9.4.0",
"react-dnd-html5-backend": "^9.4.0",
@@ -35,4 +35,4 @@
"last 1 safari version"
]
}
}
}
+2 -2
View File
@@ -39,7 +39,7 @@ const Styles = styled.div`
const Table = ({ columns, data }) => {
const [records, setRecords] = React.useState(data)
const getRowId = React.useCallback(row => {
const getRowID = React.useCallback(row => {
return row.id
}, [])
@@ -52,7 +52,7 @@ const Table = ({ columns, data }) => {
} = useTable({
data: records,
columns,
getRowId,
getRowID,
})
const moveRow = (dragIndex, hoverIndex) => {
+1 -1
View File
@@ -11,7 +11,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2"
},
"devDependencies": {
+16 -14
View File
@@ -47,7 +47,6 @@ function Table({ columns, data }) {
{
columns,
data,
debug: true,
},
useRowSelect
)
@@ -66,24 +65,27 @@ function Table({ columns, data }) {
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.slice(0, 10).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>
<p>Selected Rows: {selectedRowPaths.length}</p>
{/* <pre>
<pre>
<code>
{JSON.stringify(
{
selectedRowPaths: [...selectedRowPaths.values()],
selectedRowPaths,
'selectedFlatRows[].original': selectedFlatRows.map(
d => d.original
),
@@ -92,7 +94,7 @@ function Table({ columns, data }) {
2
)}
</code>
</pre> */}
</pre>
</>
)
}
+1 -1
View File
@@ -11,7 +11,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2"
},
"devDependencies": {
+1 -1
View File
@@ -11,7 +11,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"styled-components": "^4.3.2"
},
"devDependencies": {
+1 -1
View File
@@ -11,7 +11,7 @@
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1",
"react-table": "latest",
"react-table": "next",
"react-window": "^1.8.5",
"styled-components": "^4.3.2"
},
Vendored
+638
View File
@@ -0,0 +1,638 @@
// TypeScript Version: 3.5
import { ReactNode, ComponentType, MouseEvent } from 'react'
/**
* The empty definitions of below provides a base definition for the parts used by useTable, that can then be extended in the users code.
*
* @example
* export interface TableOptions<D extends object = {}}>
* extends
* UseExpandedOptions<D>,
* UseFiltersOptions<D> {}
*/
export interface TableOptions<D extends object> extends UseTableOptions<D> {}
export interface TableInstance<D extends object = {}>
extends Omit<TableOptions<D>, 'columns' | 'state'>,
UseTableInstanceProps<D> {}
export interface TableState<
D extends object = {}
> {} /* tslint:disable-line no-empty-interface */ // eslint-disable-line @typescript-eslint/no-empty-interface
export interface Hooks<D extends object = {}> extends UseTableHooks<D> {}
export interface Cell<D extends object = {}> extends UseTableCellProps<D> {}
export interface Column<D extends object = {}>
extends UseTableColumnOptions<D> {}
export interface ColumnInstance<D extends object = {}>
extends Omit<Column<D>, 'id'>,
UseTableColumnProps<D> {}
export interface HeaderGroup<D extends object = {}>
extends ColumnInstance<D>,
UseTableHeaderGroupProps<D> {}
export interface Row<D extends object = {}> extends UseTableRowProps<D> {}
/* #region useTable */
export function useTable<D extends object = {}>(
options: TableOptions<D>,
...plugins: Array<PluginHook<D>>
): TableInstance<D>
/**
* NOTE: To use custom options, use "Interface Merging" to add the custom options
*/
export type UseTableOptions<D extends object> = {
columns: Array<Column<D>>
data: D[]
} & Partial<{
initialState: Partial<TableState<D>>
state: Partial<TableState<D>>
reducer: (
oldState: TableState<D>,
newState: TableState<D>,
type: string
) => TableState<D>
defaultColumn: Partial<Column<D>>
initialRowStateKey: IdType<D>
getSubRows: (originalRow: D, relativeIndex: number) => Array<D>
getRowID: (originalRow: D, relativeIndex: number) => IdType<D>
debug: boolean
}>
export interface UseTableHooks<D extends object> {
columnsBeforeHeaderGroups: Array<
(
flatColumns: Array<Column<D>>,
instance: TableInstance<D>
) => Array<Column<D>>
>
columnsBeforeHeaderGroupsDeps: Array<
(deps: any[], instance: TableInstance<D>) => any[]
>
useMain: Array<(instance: TableInstance<D>) => TableInstance<D>>
useRows: Array<
(rows: Array<Row<D>>, instance: TableInstance<D>) => Array<Row<D>>
>
prepareRow: Array<(row: Row<D>, instance: TableInstance<D>) => Row<D>>
// Prop Hooks
getTableProps: Array<(instance: TableInstance<D>) => object>
getTableBodyProps: Array<(instance: TableInstance<D>) => object>
getRowProps: Array<(row: Row<D>, instance: TableInstance<D>) => object>
getHeaderGroupProps: Array<
(headerGroup: HeaderGroup<D>, instance: TableInstance<D>) => object
>
getHeaderProps: Array<
(column: Column<D>, instance: TableInstance<D>) => object
>
getCellProps: Array<(cell: Cell<D>, instance: TableInstance<D>) => object>
}
export interface UseTableColumnOptions<D extends object>
extends Accessor<D>,
Partial<{
columns: Array<Column<D>>
show: boolean | ((instance: TableInstance<D>) => boolean)
Header: Renderer<HeaderProps<D>>
Cell: Renderer<CellProps<D>>
width?: number
minWidth?: number
maxWidth?: number
}> {}
export interface UseTableInstanceProps<D extends object> {
columns: Array<ColumnInstance<D>>
flatColumns: Array<ColumnInstance<D>>
headerGroups: Array<HeaderGroup<D>>
headers: Array<ColumnInstance<D>>
flatHeaders: Array<ColumnInstance<D>>
rows: Array<Row<D>>
getTableProps: (props?: object) => object
getTableBodyProps: (props?: object) => object
prepareRow: (row: Row<D>) => void
rowPaths: string[]
flatRows: Array<Row<D>>
state: TableState<D>
setState: SetState<D>
totalColumnsWidth: number
}
export interface UseTableHeaderGroupProps<D extends object> {
headers: Array<ColumnInstance<D>>
getHeaderGroupProps: (props?: object) => object
totalHeaderCount: number
}
export interface UseTableColumnProps<D extends object> {
id: IdType<D>
isVisible: boolean
render: (type: 'Header' | string, props?: object) => ReactNode
getHeaderProps: (props?: object) => object
parent: ColumnInstance<D>
depth: number
index: number
}
export interface UseTableRowProps<D extends object> {
cells: Array<Cell<D>>
values: Record<IdType<D>, CellValue>
getRowProps: (props?: object) => object
index: number
original: D
path: Array<IdType<D>>
subRows: Array<Row<D>>
}
export interface UseTableCellProps<D extends object> {
column: ColumnInstance<D>
row: Row<D>
value: CellValue
getCellProps: (props?: object) => object
render: (type: 'Cell' | string, userProps?: object) => ReactNode
}
export type HeaderProps<D extends object> = TableInstance<D> & {
column: ColumnInstance<D>
}
export type CellProps<D extends object> = TableInstance<D> & {
column: ColumnInstance<D>
row: Row<D>
cell: Cell<D>
}
// NOTE: At least one of (id | accessor | Header as string) required
export interface Accessor<D extends object> {
accessor?:
| IdType<D>
| ((
originalRow: D,
index: number,
sub: {
subRows: D[]
depth: number
data: D[]
}
) => CellValue)
id?: IdType<D>
}
/* #endregion */
// Plugins
/* #region useColumnOrder */
export function useColumnOrder<D extends object = {}>(hooks: Hooks<D>): void
export namespace useColumnOrder {
const pluginName = 'useColumnOrder'
}
export interface UseColumnOrderState<D extends object> {
columnOrder: Array<IdType<D>>
}
export interface UseColumnOrderInstanceProps<D extends object> {
setColumnOrder: (
updater: (columnOrder: Array<IdType<D>>) => Array<IdType<D>>
) => void
}
/* #endregion */
/* #region useExpanded */
export function useExpanded<D extends object = {}>(hooks: Hooks<D>): void
export namespace useExpanded {
const pluginName = 'useExpanded'
}
export type UseExpandedOptions<D extends object> = Partial<{
manualExpandedKey: IdType<D>
paginateExpandedRows: boolean
getResetExpandedDeps: (i: TableInstance) => Array<any>
}>
export interface UseExpandedHooks<D extends object> {
getExpandedToggleProps: Array<
(row: Row<D>, instance: TableInstance<D>) => object
>
}
export interface UseExpandedState<D extends object> {
expanded: Array<IdType<D>>
}
export interface UseExpandedInstanceProps<D extends object> {
rows: Array<Row<D>>
toggleExpandedByPath: (path: Array<IdType<D>>, isExpanded: boolean) => void
expandedDepth: number
}
export interface UseExpandedRowProps<D extends object> {
isExpanded: boolean
canExpand: boolean
subRows: Array<Row<D>>
toggleExpanded: (isExpanded?: boolean) => void
getExpandedToggleProps: (props?: object) => object
}
/* #endregion */
/* #region useFilters */
export function useFilters<D extends object = {}>(hooks: Hooks<D>): void
export namespace useFilters {
const pluginName = 'useFilters'
}
export type UseFiltersOptions<D extends object> = Partial<{
manualFilters: boolean
disableFilters: boolean
filterTypes: Filters<D>
getResetFiltersDeps: (i: TableInstance) => Array<any>
}>
export interface UseFiltersState<D extends object> {
filters: Filters<D>
}
export type UseFiltersColumnOptions<D extends object> = Partial<{
disableFilters: boolean
Filter: Renderer<FilterProps<D>>
filter: FilterType<D> | DefaultFilterTypes | keyof Filters<D>
}>
export interface UseFiltersInstanceProps<D extends object> {
rows: Array<Row<D>>
preFilteredRows: Array<Row<D>>
setFilter: (
columnId: IdType<D>,
updater: ((filterValue: FilterValue) => FilterValue) | FilterValue
) => void
setAllFilters: (
updater: Filters<D> | ((filters: Filters<D>) => Filters<D>)
) => void
}
export interface UseFiltersColumnProps<D extends object> {
canFilter: boolean
setFilter: (
updater: ((filterValue: FilterValue) => FilterValue) | FilterValue
) => void
filterValue: FilterValue
preFilteredRows: Array<Row<D>>
filteredRows: Array<Row<D>>
}
export type FilterProps<D extends object> = HeaderProps<D>
export type FilterValue = any
export type Filters<D extends object> = Record<IdType<D>, FilterValue>
export type DefaultFilterTypes =
| 'text'
| 'exactText'
| 'exactTextCase'
| 'includes'
| 'includesAll'
| 'exact'
| 'equals'
| 'between'
export interface FilterType<D extends object> {
(
rows: Array<Row<D>>,
columnId: IdType<D>,
filterValue: FilterValue,
column: ColumnInstance<D>
): Array<Row<D>>
autoRemove?: (filterValue: FilterValue) => boolean
}
/* #endregion */
/* #region useGroupBy */
export function useGroupBy<D extends object = {}>(hooks: Hooks<D>): void
export namespace useGroupBy {
const pluginName = 'useGroupBy'
}
export type UseGroupByOptions<D extends object> = Partial<{
manualGroupBy: boolean
disableGroupBy: boolean
aggregations: Record<string, AggregatorFn<D>>
groupByFn: (
rows: Array<Row<D>>,
columnId: IdType<D>
) => Record<string, Row<D>>
getResetGroupByDeps: (i: TableInstance) => Array<any>
}>
export interface UseGroupByHooks<D extends object> {
getGroupByToggleProps: Array<
(header: HeaderGroup<D>, instance: TableInstance<D>) => object
>
}
export interface UseGroupByState<D extends object> {
groupBy: Array<IdType<D>>
}
export type UseGroupByColumnOptions<D extends object> = Partial<{
aggregate: Aggregator<D> | Array<Aggregator<D>>
Aggregated: Renderer<CellProps<D>>
disableGroupBy: boolean
groupByBoundary: boolean
}>
export interface UseGroupByInstanceProps<D extends object> {
rows: Array<Row<D>>
preGroupedRows: Array<Row<D>>
toggleGroupBy: (columnId: IdType<D>, toggle: boolean) => void
}
export interface UseGroupByColumnProps<D extends object> {
canGroupBy: boolean
isGrouped: boolean
groupedIndex: number
toggleGroupBy: () => void
getGroupByToggleProps: (props?: object) => object
}
export interface UseGroupByRowProps<D extends object> {
isAggregated: boolean
groupByID: IdType<D>
groupByVal: string
values: Record<IdType<D>, AggregatedValue>
subRows: Array<Row<D>>
depth: number
path: Array<IdType<D>>
index: number
}
export interface UseGroupByCellProps<D extends object> {
isGrouped: boolean
isRepeatedValue: boolean
isAggregated: boolean
}
export type DefaultAggregators =
| 'sum'
| 'average'
| 'median'
| 'uniqueCount'
| 'count'
export type AggregatorFn<D extends object> = (
columnValues: CellValue[],
rows: Array<Row<D>>
) => AggregatedValue
export type Aggregator<D extends object> =
| AggregatorFn<D>
| DefaultAggregators
| string
export type AggregatedValue = any
/* #endregion */
/* #region usePagination */
export function usePagination<D extends object = {}>(hooks: Hooks<D>): void
export namespace usePagination {
const pluginName = 'usePagination'
}
export type UsePaginationOptions<D extends object> = Partial<{
pageCount: number
manualPagination: boolean
getResetPageDeps: (i: TableInstance) => Array<any>
paginateExpandedRows: boolean
}>
export interface UsePaginationState<D extends object> {
pageSize: number
pageIndex: number
}
export interface UsePaginationInstanceProps<D extends object> {
page: Array<Row<D>>
pageCount: number
pageOptions: number[]
canPreviousPage: boolean
canNextPage: boolean
gotoPage: (updater: ((pageIndex: number) => number) | number) => void
previousPage: () => void
nextPage: () => void
setPageSize: (pageSize: number) => void
pageIndex: number
pageSize: number
}
/* #endregion */
/* #region useRowSelect */
export function useRowSelect<D extends object = {}>(hooks: Hooks<D>): void
export namespace useRowSelect {
const pluginName = 'useRowSelect'
}
export type UseRowSelectOptions<D extends object> = Partial<{
manualRowSelectedKey: IdType<D>
getResetSelectedRowPathsDeps: (i: TableInstance) => Array<any>
}>
export interface UseRowSelectHooks<D extends object> {
getToggleRowSelectedProps: Array<
(row: Row<D>, instance: TableInstance<D>) => object
>
getToggleAllRowsSelectedProps: Array<(instance: TableInstance<D>) => object>
}
export interface UseRowSelectState<D extends object> {
selectedRowPaths: Array<IdType<D>>
}
export interface UseRowSelectInstanceProps<D extends object> {
toggleRowSelected: (rowPath: IdType<D>, set?: boolean) => void
toggleRowSelectedAll: (set?: boolean) => void
getToggleAllRowsSelectedProps: (props?: object) => object
isAllRowsSelected: boolean
selectedFlatRows: Array<Row<D>>
}
export interface UseRowSelectRowProps<D extends object> {
isSelected: boolean
toggleRowSelected: (set?: boolean) => void
getToggleRowSelectedProps: (props?: object) => object
}
/* #endregion */
/* #region useRowState */
export function useRowState<D extends object = {}>(hooks: Hooks<D>): void
export namespace useRowState {
const pluginName = 'useRowState'
}
export type UseRowStateOptions<D extends object> = Partial<{
initialRowStateAccessor: (row: Row<D>) => UseRowStateLocalState<D>
}>
export interface UseRowStateState<D extends object> {
rowState: Partial<{
cellState: UseRowStateLocalState<D>
rowState: UseRowStateLocalState<D>
}>
}
export interface UseRowStateInstanceProps<D extends object> {
setRowState: (rowPath: string[], updater: UseRowUpdater) => void // Purposely not exposing action
setCellState: (
rowPath: string[],
columnID: IdType<D>,
updater: UseRowUpdater
) => void
}
export interface UseRowStateRowProps<D extends object> {
state: UseRowStateLocalState<D>
setState: (updater: UseRowUpdater) => void
}
export interface UseRowStateCellProps<D extends object> {
state: UseRowStateLocalState<D>
setState: (updater: UseRowUpdater) => void
}
export type UseRowUpdater<T = unknown> = T | ((prev: T) => T)
export type UseRowStateLocalState<D extends object, T = unknown> = Record<
IdType<D>,
T
>
/* #endregion */
/* #region useSortBy */
export function useSortBy<D extends object = {}>(hooks: Hooks<D>): void
export namespace useSortBy {
const pluginName = 'useSortBy'
}
export type UseSortByOptions<D extends object> = Partial<{
manualSorting: boolean
disableSortBy: boolean
disableMultiSort: boolean
isMultiSortEvent: (e: MouseEvent) => boolean
maxMultiSortColCount: number
disableSortRemove: boolean
disabledMultiRemove: boolean
orderByFn: (
rows: Array<Row<D>>,
sortFns: Array<SortByFn<D>>,
directions: boolean[]
) => Array<Row<D>>
sortTypes: Record<string, SortByFn<D>>
getResetSortByDeps: (i: TableInstance) => Array<any>
}>
export interface UseSortByHooks<D extends object> {
getSortByToggleProps: Array<
(column: Column<D>, instance: TableInstance<D>) => object
>
}
export interface UseSortByState<D extends object> {
sortBy: Array<SortingRule<D>>
}
export type UseSortByColumnOptions<D extends object> = Partial<{
disableSortBy: boolean
sortDescFirst: boolean
sortInverted: boolean
sortType: SortByFn<D> | DefaultSortTypes | string
}>
export interface UseSortByInstanceProps<D extends object> {
rows: Array<Row<D>>
preSortedRows: Array<Row<D>>
toggleSortBy: (
columnId: IdType<D>,
descending: boolean,
isMulti: boolean
) => void
}
export interface UseSortByColumnProps<D extends object> {
canSort: boolean
toggleSortBy: (descending: boolean, multi: boolean) => void
getSortByToggleProps: (props?: object) => object
clearSorting: () => void
isSorted: boolean
sortedIndex: number
isSortedDesc: boolean | undefined
}
export type SortByFn<D extends object> = (
rowA: Row<D>,
rowB: Row<D>,
columnId: IdType<D>
) => 0 | 1 | -1
export type DefaultSortTypes = 'alphanumeric' | 'datetime' | 'basic'
export interface SortingRule<D> {
id: IdType<D>
desc?: boolean
}
/* #endregion */
/* #region useAbsoluteLayout */
export function useAbsoluteLayout<D extends object = {}>(hooks: Hooks<D>): void
export namespace useAbsoluteLayout {
const pluginName = 'useAbsoluteLayout'
}
/* #endregion */
/* #region useBlockLayout */
export function useBlockLayout<D extends object = {}>(hooks: Hooks<D>): void
export namespace useBlockLayout {
const pluginName = 'useBlockLayout'
}
/* #endregion */
/* #region useResizeColumns */
export function useResizeColumns<D extends object = {}>(hooks: Hooks<D>): void
export namespace useResizeColumns {
const pluginName = 'useResizeColumns'
}
export interface UseResizeColumnsOptions<D extends object> {
disableResizing?: boolean
}
export interface UseResizeColumnsColumnOptions<D extends object> {
disableResizing?: boolean
}
export interface UseResizeColumnsHeaderProps<D extends object> {
getResizerProps: (props?: object) => object
canResize: boolean
isResizing: boolean
}
/* #endregion */
// Additional API
export const actions: Record<string, string>
export function addActions(...actions: string[]): void
export const defaultState: Record<string, any>
// Helpers
export type StringKey<D> = Extract<keyof D, string>
export type IdType<D> = StringKey<D> | string
export type CellValue = any
export type Renderer<Props> = ComponentType<Props> | ReactNode
export interface PluginHook<D extends object> {
(hooks: Hooks<D>): void
pluginName: string
}
export type SetState<D extends object> = (
updater: (old: TableState<D>) => TableState<D>,
type: keyof typeof actions
) => void
+5 -4
View File
@@ -1,6 +1,6 @@
{
"name": "react-table",
"version": "7.0.0-beta.26",
"version": "7.0.0-beta.19",
"description": "A fast, lightweight, opinionated table and datagrid built on React",
"license": "MIT",
"homepage": "https://github.com/tannerlinsley/react-table#readme",
@@ -20,9 +20,10 @@
"commit": "git add . && git-cz",
"test": "is-ci \"test:ci\" \"test:dev\"",
"test:dev": "jest --watch",
"test:ci": "yarn test:jest",
"test:ci": "yarn test:jest && yarn test:types",
"test:jest": "jest",
"build": "cross-env NODE_ENV=production rollup -c",
"test:types": "echo '\n****\nTODO: Re-enable dtslint\n****\n'",
"build": "rollup -c",
"start": "rollup -c -w",
"prepare": "yarn build",
"release": "yarn publish",
@@ -39,6 +40,7 @@
"README.md"
],
"peerDependencies": {
"prop-types": "^15.5.0",
"react": "^16.8.3",
"react-dom": "^16.8.3"
},
@@ -90,7 +92,6 @@
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-peer-deps-external": "^2.2.0",
"rollup-plugin-size": "^0.2.1",
"rollup-plugin-size-snapshot": "^0.10.0",
"rollup-plugin-terser": "^5.1.2",
"snapshot-diff": "^0.6.1"
+99
View File
@@ -0,0 +1,99 @@
import {
UseColumnOrderInstanceProps,
UseColumnOrderState,
UseExpandedInstanceProps,
UseExpandedOptions,
UseExpandedRowProps,
UseExpandedState,
UseFiltersColumnOptions,
UseFiltersColumnProps,
UseFiltersInstanceProps,
UseFiltersOptions,
UseFiltersState,
UseGroupByCellProps,
UseGroupByColumnOptions,
UseGroupByColumnProps,
UseGroupByInstanceProps,
UseGroupByOptions,
UseGroupByRowProps,
UseGroupByState,
UsePaginationInstanceProps,
UsePaginationOptions,
UsePaginationState,
UseResizeColumnsColumnOptions,
UseResizeColumnsHeaderProps,
UseResizeColumnsOptions,
UseRowSelectInstanceProps,
UseRowSelectOptions,
UseRowSelectRowProps,
UseRowSelectState,
UseRowStateCellProps,
UseRowStateInstanceProps,
UseRowStateRowProps,
UseSortByColumnOptions,
UseSortByColumnProps,
UseSortByInstanceProps,
UseSortByOptions,
UseSortByState,
UseTableCellProps,
} from 'react-table'
declare module 'react-table' {
// take this file as-is, or comment out the sections that don't apply to your plugin configuration
export interface TableOptions<D extends object>
extends UseExpandedOptions<D>,
UseFiltersOptions<D>,
UseGroupByOptions<D>,
UsePaginationOptions<D>,
UseRowSelectOptions<D>,
UseSortByOptions<D>,
UseFiltersOptions<D>,
UseResizeColumnsOptions<D>,
// note that having Record here allows you to add anything to the options, this matches the spirit of the
// underlying js library, but might be cleaner if it's replaced by a more specific type that matches your
// feature set, this is a safe default.
Record<string, any> {}
export interface TableInstance<D extends object = {}>
extends UseColumnOrderInstanceProps<D>,
UseExpandedInstanceProps<D>,
UseFiltersInstanceProps<D>,
UseGroupByInstanceProps<D>,
UsePaginationInstanceProps<D>,
UseRowSelectInstanceProps<D>,
UseRowStateInstanceProps<D>,
UseSortByInstanceProps<D> {}
export interface TableState<D extends object = {}>
extends UseColumnOrderState<D>,
UseExpandedState<D>,
UseFiltersState<D>,
UseGroupByState<D>,
UsePaginationState<D>,
UseRowSelectState<D>,
UseSortByState<D> {}
export interface Column<D extends object = {}>
extends UseFiltersColumnOptions<D>,
UseGroupByColumnOptions<D>,
UseSortByColumnOptions<D>,
UseResizeColumnsColumnOptions<D> {}
export interface ColumnInstance<D extends object = {}>
extends UseFiltersColumnProps<D>,
UseGroupByColumnProps<D>,
UseSortByColumnProps<D>,
UseResizeColumnsHeaderProps<D> {}
export interface Cell<D extends object = {}>
extends UseTableCellProps<D>,
UseGroupByCellProps<D>,
UseRowStateCellProps<D> {}
export interface Row<D extends object = {}>
extends UseExpandedRowProps<D>,
UseGroupByRowProps<D>,
UseRowSelectRowProps<D>,
UseRowStateRowProps<D> {}
}
+3 -25
View File
@@ -3,7 +3,7 @@ import commonjs from 'rollup-plugin-commonjs'
import external from 'rollup-plugin-peer-deps-external'
import resolve from 'rollup-plugin-node-resolve'
import { sizeSnapshot } from 'rollup-plugin-size-snapshot'
import size from 'rollup-plugin-size'
import pkg from './package.json'
export default [
@@ -14,19 +14,7 @@ export default [
format: 'cjs',
sourcemap: true,
},
plugins: [
external(),
babel(),
resolve(),
commonjs(),
size({
publish: true,
exclude: pkg.module,
filename: 'sizes-cjs.json',
writeFile: process.env.CI ? true : false,
}),
sizeSnapshot(),
],
plugins: [external(), babel(), resolve(), commonjs(), sizeSnapshot()],
},
{
input: 'src/index.js',
@@ -35,16 +23,6 @@ export default [
format: 'es',
sourcemap: true,
},
plugins: [
external(),
babel(),
size({
publish: true,
exclude: pkg.main,
filename: 'sizes-es.json',
writeFile: process.env.CI ? true : false,
}),
sizeSnapshot(),
],
plugins: [external(), babel(), sizeSnapshot()],
},
]
-32
View File
@@ -1,32 +0,0 @@
[
{
"timestamp": 1575391465436,
"files": [
{
"filename": "index.js",
"size": 20511,
"delta": 1
}
]
},
{
"timestamp": 1575345020328,
"files": [
{
"filename": "index.js",
"size": 20510,
"delta": 5
}
]
},
{
"timestamp": 1575331661254,
"files": [
{
"filename": "index.js",
"size": 20505,
"delta": 20505
}
]
}
]
-32
View File
@@ -1,32 +0,0 @@
[
{
"timestamp": 1575391457318,
"files": [
{
"filename": "index.es.js",
"size": 20368,
"delta": -1
}
]
},
{
"timestamp": 1575345027852,
"files": [
{
"filename": "index.es.js",
"size": 20369,
"delta": 4
}
]
},
{
"timestamp": 1575331668355,
"files": [
{
"filename": "index.es.js",
"size": 20365,
"delta": 20365
}
]
}
]
Executable
+15
View File
@@ -0,0 +1,15 @@
const actions = {}
const types = {}
export { actions, types }
export const addActions = (...acts) => {
acts.forEach(action => {
// Action values are formatted this way to discourage
// you (the dev) from interacting with them in any way
// other than importing `{ actions } from 'react-table'`
// and referencing an action via `actions[actionName]`
actions[action] = `React Table Action: ${action}`
types[actions[action]] = true
})
}
+58 -61
View File
@@ -15,16 +15,13 @@ import {
const renderErr =
'You must specify a valid render component. This could be "column.Cell", "column.Header", "column.Filter", "column.Aggregated" or any other custom renderer component.'
export const actions = {
init: 'init',
}
export const reducerHandlers = {}
export const defaultState = {}
const defaultInitialState = {}
const defaultColumnInstance = {}
const defaultReducer = (state, action, prevState) => state
const defaultReducer = (old, newState) => newState
const defaultGetSubRows = (row, index) => row.subRows || []
const defaultGetRowId = (row, index) => index
const defaultGetRowID = (row, index) => index
export const useTable = (props, ...plugins) => {
// Destructure props
@@ -32,60 +29,59 @@ export const useTable = (props, ...plugins) => {
data,
columns: userColumns,
initialState = defaultInitialState,
state: userState,
defaultColumn = defaultColumnInstance,
getSubRows = defaultGetSubRows,
getRowId = defaultGetRowId,
reducer: userReducer = defaultReducer,
getRowID = defaultGetRowID,
reducer = defaultReducer,
debug,
} = props
debug = process.env.NODE_ENV === 'production' ? false : debug
const reducer = (state, action) => {
let nextState = Object.keys(reducerHandlers)
.map(key => reducerHandlers[key])
.reduce((state, handler) => handler(state, action) || state, state)
nextState = userReducer(nextState, action, state)
if (process.env.NODE_ENV !== 'production' && debug) {
console.log('')
console.log('React Table Action: ', action)
console.log('New State: ', nextState)
}
return nextState
}
// But use the users table state if provided
const [state, originalDispatch] = React.useReducer(reducer, undefined, () =>
reducer(initialState, { type: actions.init })
let [originalState, originalSetState] = React.useState({
...defaultState,
...initialState,
})
const state = React.useMemo(() => {
if (userState) {
const newState = {
...originalState,
}
Object.keys(userState).forEach(key => {
newState[key] = userState[key]
})
return newState
}
return originalState
}, [originalState, userState])
const setState = React.useCallback(
(updater, type) => {
return originalSetState(old => {
const newState = typeof updater === 'function' ? updater(old) : updater
return reducer(old, newState, type)
})
},
[reducer]
)
// The table instance ref
let instanceRef = React.useRef({})
const dispatch = React.useCallback(action => {
if (!action.type) {
if (process.env.NODE_ENV !== 'production') {
console.info({ action })
throw new Error('Unknown Action Type! 👆')
}
throw new Error()
}
originalDispatch({ ...action, instanceRef })
}, [])
Object.assign(instanceRef.current, {
...props,
data, // The raw data
state, // The state dispatcher
dispatch, // The resolved table state
state,
setState, // The resolved table state
plugins, // All resolved plugins
hooks: {
columnsBeforeHeaderGroups: [],
columnsBeforeHeaderGroupsDeps: [],
useInstanceBeforeDimensions: [],
useInstance: [],
useBeforeDimensions: [],
useMain: [],
useRows: [],
prepareRow: [],
getTableProps: [],
@@ -98,13 +94,14 @@ export const useTable = (props, ...plugins) => {
})
// Allow plugins to register hooks
if (process.env.NODE_ENV !== 'production' && debug) console.time('plugins')
if (process.env.NODE_ENV === 'development' && debug) console.time('plugins')
plugins.filter(Boolean).forEach(plugin => {
plugin(instanceRef.current.hooks)
})
if (process.env.NODE_ENV !== 'production' && debug) console.timeEnd('plugins')
if (process.env.NODE_ENV === 'development' && debug)
console.timeEnd('plugins')
// Decorate All the columns
let columns = React.useMemo(
@@ -115,7 +112,7 @@ export const useTable = (props, ...plugins) => {
// Get the flat list of all columns and allow hooks to decorate
// those columns (and trigger this memoization via deps)
let flatColumns = React.useMemo(() => {
if (process.env.NODE_ENV !== 'production' && debug)
if (process.env.NODE_ENV === 'development' && debug)
console.time('hooks.columnsBeforeHeaderGroups')
let newColumns = applyHooks(
@@ -124,7 +121,7 @@ export const useTable = (props, ...plugins) => {
instanceRef.current
)
if (process.env.NODE_ENV !== 'production' && debug)
if (process.env.NODE_ENV === 'development' && debug)
console.timeEnd('hooks.columnsBeforeHeaderGroups')
return newColumns
}, [
@@ -155,7 +152,7 @@ export const useTable = (props, ...plugins) => {
// Access the row model
const [rows, flatRows] = React.useMemo(() => {
if (process.env.NODE_ENV !== 'production' && debug)
if (process.env.NODE_ENV === 'development' && debug)
console.time('getAccessedRows')
let flatRows = []
@@ -165,10 +162,10 @@ export const useTable = (props, ...plugins) => {
// Keep the original reference around
const original = originalRow
const rowId = getRowId(originalRow, i)
const rowID = getRowID(originalRow, i)
// Make the new path for the row
const path = [...parentPath, rowId]
const path = [...parentPath, rowID]
const row = {
original,
@@ -212,10 +209,10 @@ export const useTable = (props, ...plugins) => {
// Use the resolved data
const accessedData = data.map((d, i) => accessRow(d, i))
if (process.env.NODE_ENV !== 'production' && debug)
if (process.env.NODE_ENV === 'development' && debug)
console.timeEnd('getAccessedRows')
return [accessedData, flatRows]
}, [debug, data, getRowId, getSubRows, flatColumns])
}, [debug, data, getRowID, getSubRows, flatColumns])
instanceRef.current.rows = rows
instanceRef.current.flatRows = flatRows
@@ -229,25 +226,25 @@ export const useTable = (props, ...plugins) => {
[]
)
if (process.env.NODE_ENV !== 'production' && debug)
console.time('hooks.useInstanceBeforeDimensions')
if (process.env.NODE_ENV === 'development' && debug)
console.time('hooks.useBeforeDimensions')
instanceRef.current = applyHooks(
instanceRef.current.hooks.useInstanceBeforeDimensions,
instanceRef.current.hooks.useBeforeDimensions,
instanceRef.current
)
if (process.env.NODE_ENV !== 'production' && debug)
console.timeEnd('hooks.useInstanceBeforeDimensions')
if (process.env.NODE_ENV === 'development' && debug)
console.timeEnd('hooks.useBeforeDimensions')
calculateDimensions(instanceRef.current)
if (process.env.NODE_ENV !== 'production' && debug)
console.time('hooks.useInstance')
if (process.env.NODE_ENV === 'development' && debug)
console.time('hooks.useMain')
instanceRef.current = applyHooks(
instanceRef.current.hooks.useInstance,
instanceRef.current.hooks.useMain,
instanceRef.current
)
if (process.env.NODE_ENV !== 'production' && debug)
console.timeEnd('hooks.useInstance')
if (process.env.NODE_ENV === 'development' && debug)
console.timeEnd('hooks.useMain')
// Each materialized header needs to be assigned a render function and other
// prop getter properties here.
@@ -319,14 +316,14 @@ export const useTable = (props, ...plugins) => {
})
// Run the rows (this could be a dangerous hook with a ton of data)
if (process.env.NODE_ENV !== 'production' && debug)
if (process.env.NODE_ENV === 'development' && debug)
console.time('hooks.useRows')
instanceRef.current.rows = applyHooks(
instanceRef.current.hooks.useRows,
instanceRef.current.rows,
instanceRef.current
)
if (process.env.NODE_ENV !== 'production' && debug)
if (process.env.NODE_ENV === 'development' && debug)
console.timeEnd('hooks.useRows')
// The prepareRow function is absolutely necessary and MUST be called on
+2 -1
View File
@@ -1,7 +1,7 @@
import * as utils from './utils'
export { utils }
export { defaultColumn } from './utils'
export { useTable, actions, reducerHandlers } from './hooks/useTable'
export { useTable, defaultState } from './hooks/useTable'
export { useExpanded } from './plugin-hooks/useExpanded'
export { useFilters } from './plugin-hooks/useFilters'
export { useGroupBy } from './plugin-hooks/useGroupBy'
@@ -13,3 +13,4 @@ export { useColumnOrder } from './plugin-hooks/useColumnOrder'
export { useResizeColumns } from './plugin-hooks/useResizeColumns'
export { useAbsoluteLayout } from './plugin-hooks/useAbsoluteLayout'
export { useBlockLayout } from './plugin-hooks/useBlockLayout'
export { actions, addActions } from './actions'
+2 -8
View File
@@ -113,15 +113,9 @@ function Table({ columns, data }) {
)}
</tbody>
</table>
<p>Selected Rows: {selectedRowPaths.size}</p>
<p>Selected Rows: {selectedRowPaths.length}</p>
<pre>
<code>
{JSON.stringify(
{ selectedRowPaths: [...selectedRowPaths.values()] },
null,
2
)}
</code>
<code>{JSON.stringify({ selectedRowPaths }, null, 2)}</code>
</pre>
</>
)
+2 -2
View File
@@ -1,10 +1,10 @@
export const useAbsoluteLayout = hooks => {
hooks.useInstance.push(useInstance)
hooks.useMain.push(useMain)
}
useAbsoluteLayout.pluginName = 'useAbsoluteLayout'
const useInstance = instance => {
const useMain = instance => {
const {
totalColumnsWidth,
hooks: {
+2 -2
View File
@@ -1,10 +1,10 @@
export const useBlockLayout = hooks => {
hooks.useInstance.push(useInstance)
hooks.useMain.push(useMain)
}
useBlockLayout.pluginName = 'useBlockLayout'
const useInstance = instance => {
const useMain = instance => {
const {
totalColumnsWidth,
hooks: { getRowProps, getHeaderGroupProps, getHeaderProps, getCellProps },
+19 -39
View File
@@ -1,47 +1,21 @@
import React from 'react'
import { actions, reducerHandlers } from '../hooks/useTable'
import { functionalUpdate } from '../utils'
import { addActions, actions } from '../actions'
import { defaultState } from '../hooks/useTable'
const pluginName = 'useColumnOrder'
defaultState.columnOrder = []
// Actions
actions.resetColumnOrder = 'resetColumnOrder'
actions.setColumnOrder = 'setColumnOrder'
// Reducer
reducerHandlers[pluginName] = (state, action) => {
if (action.type === actions.init) {
return {
columnOrder: [],
...state,
}
}
if (action.type === actions.resetColumnOrder) {
return {
...state,
columnOrder: [],
}
}
if (action.type === actions.setColumnOrder) {
return {
...state,
columnOrder: functionalUpdate(action.columnOrder, state.columnOrder),
}
}
}
addActions('setColumnOrder')
export const useColumnOrder = hooks => {
hooks.columnsBeforeHeaderGroupsDeps.push((deps, instance) => {
return [...deps, instance.state.columnOrder]
})
hooks.columnsBeforeHeaderGroups.push(columnsBeforeHeaderGroups)
hooks.useInstance.push(useInstance)
hooks.useMain.push(useMain)
}
useColumnOrder.pluginName = pluginName
useColumnOrder.pluginName = 'useColumnOrder'
function columnsBeforeHeaderGroups(columns, instance) {
const {
@@ -63,8 +37,8 @@ function columnsBeforeHeaderGroups(columns, instance) {
// Loop over the columns and place them in order into the new array
while (columnsCopy.length && columnOrderCopy.length) {
const targetColumnId = columnOrderCopy.shift()
const foundIndex = columnsCopy.findIndex(d => d.id === targetColumnId)
const targetColumnID = columnOrderCopy.shift()
const foundIndex = columnsCopy.findIndex(d => d.id === targetColumnID)
if (foundIndex > -1) {
columnsInOrder.push(columnsCopy.splice(foundIndex, 1)[0])
}
@@ -74,14 +48,20 @@ function columnsBeforeHeaderGroups(columns, instance) {
return [...columnsInOrder, ...columnsCopy]
}
function useInstance(instance) {
const { dispatch } = instance
function useMain(instance) {
const { setState } = instance
const setColumnOrder = React.useCallback(
columnOrder => {
return dispatch({ type: actions.setColumnOrder, columnOrder })
updater => {
return setState(old => {
return {
...old,
columnOrder:
typeof updater === 'function' ? updater(old.columnOrder) : updater,
}
}, actions.setColumnOrder)
},
[dispatch]
[setState]
)
return {
+38 -52
View File
@@ -6,62 +6,23 @@ import {
expandRows,
safeUseLayoutEffect,
} from '../utils'
import { actions, reducerHandlers } from '../hooks/useTable'
import { addActions, actions } from '../actions'
import { defaultState } from '../hooks/useTable'
const pluginName = 'useExpanded'
defaultState.expanded = []
// Actions
actions.toggleExpandedByPath = 'toggleExpandedByPath'
actions.resetExpanded = 'resetExpanded'
// Reducer
reducerHandlers[pluginName] = (state, action) => {
if (action.type === actions.init) {
return {
expanded: [],
...state,
}
}
if (action.type === actions.resetExpanded) {
return {
...state,
expanded: [],
}
}
if (action.type === actions.toggleExpandedByPath) {
const { path, expanded } = action
const key = path.join('.')
const exists = state.expanded.includes(key)
const shouldExist = typeof set !== 'undefined' ? expanded : !exists
let newExpanded = new Set(state.expanded)
if (!exists && shouldExist) {
newExpanded.add(key)
} else if (exists && !shouldExist) {
newExpanded.delete(key)
} else {
return state
}
return {
...state,
expanded: [...newExpanded.values()],
}
}
}
addActions('toggleExpanded', 'setExpanded')
export const useExpanded = hooks => {
hooks.getExpandedToggleProps = []
hooks.useInstance.push(useInstance)
hooks.useMain.push(useMain)
}
useExpanded.pluginName = pluginName
useExpanded.pluginName = 'useExpanded'
const defaultGetResetExpandedDeps = ({ data }) => [data]
function useInstance(instance) {
function useMain(instance) {
const {
debug,
rows,
@@ -70,7 +31,7 @@ function useInstance(instance) {
expandSubRows = true,
hooks,
state: { expanded },
dispatch,
setState,
getResetExpandedDeps = defaultGetResetExpandedDeps,
} = instance
@@ -78,16 +39,41 @@ function useInstance(instance) {
const isMountedRef = React.useRef()
safeUseLayoutEffect(() => {
if (isMountedRef.current) {
dispatch({ type: actions.resetExpanded })
setState(
old => ({
...old,
expanded: [],
}),
actions.setExpanded
)
}
isMountedRef.current = true
}, [
dispatch,
setState,
...(getResetExpandedDeps ? getResetExpandedDeps(instance) : []),
])
const toggleExpandedByPath = (path, expanded) => {
dispatch({ type: actions.toggleExpandedByPath, path, expanded })
const toggleExpandedByPath = (path, set) => {
const key = path.join('.')
return setState(old => {
const exists = old.expanded.includes(key)
const shouldExist = typeof set !== 'undefined' ? set : !exists
let newExpanded = new Set(old.expanded)
if (!exists && shouldExist) {
newExpanded.add(key)
} else if (exists && !shouldExist) {
newExpanded.delete(key)
} else {
return old
}
return {
...old,
expanded: [...newExpanded.values()],
}
}, actions.toggleExpanded)
}
// use reference to avoid memory leak in #1608
@@ -120,7 +106,7 @@ function useInstance(instance) {
})
const expandedRows = React.useMemo(() => {
if (process.env.NODE_ENV !== 'production' && debug)
if (process.env.NODE_ENV === 'development' && debug)
console.info('getExpandedRows')
if (paginateExpandedRows) {
+79 -121
View File
@@ -1,120 +1,21 @@
import React from 'react'
import {
getFirstDefined,
isFunction,
safeUseLayoutEffect,
functionalUpdate,
} from '../utils'
import { getFirstDefined, isFunction, safeUseLayoutEffect } from '../utils'
import * as filterTypes from '../filterTypes'
import { actions, reducerHandlers } from '../hooks/useTable'
import { addActions, actions } from '../actions'
import { defaultState } from '../hooks/useTable'
const pluginName = 'useFilters'
defaultState.filters = {}
// Actions
actions.resetFilters = 'resetFilters'
actions.setFilter = 'setFilter'
actions.setAllFilters = 'setAllFilters'
// Reducer
reducerHandlers[pluginName] = (state, action) => {
if (action.type === actions.init) {
return {
filters: {},
...state,
}
}
if (action.type === actions.resetFilters) {
return {
...state,
filters: {},
}
}
if (action.type === actions.setFilter) {
const {
columnId,
filterValue,
instanceRef: {
current: { flatColumns, userFilterTypes },
},
} = action
const column = flatColumns.find(d => d.id === columnId)
if (!column) {
throw new Error(
`React-Table: Could not find a column with id: ${columnId}`
)
}
const filterMethod = getFilterMethod(
column.filter,
userFilterTypes || {},
filterTypes
)
const newFilter = functionalUpdate(filterValue, state.filters[columnId])
//
if (shouldAutoRemove(filterMethod.autoRemove, newFilter)) {
const { [columnId]: remove, ...newFilters } = state.filters
return {
...state,
filters: newFilters,
}
}
return {
...state,
filters: {
...state.filters,
[columnId]: newFilter,
},
}
}
if (action.type === actions.setAllFilters) {
const {
filters,
instanceRef: {
current: { flatColumns, filterTypes: userFilterTypes },
},
} = action
const newFilters = functionalUpdate(filters, state.filters)
// Filter out undefined values
Object.keys(newFilters).forEach(id => {
const newFilter = newFilters[id]
const column = flatColumns.find(d => d.id === id)
const filterMethod = getFilterMethod(
column.filter,
userFilterTypes || {},
filterTypes
)
if (shouldAutoRemove(filterMethod.autoRemove, newFilter)) {
delete newFilters[id]
}
})
return {
...state,
filters: newFilters,
}
}
}
addActions('setFilter', 'setAllFilters')
export const useFilters = hooks => {
hooks.useInstance.push(useInstance)
hooks.useMain.push(useMain)
}
useFilters.pluginName = pluginName
useFilters.pluginName = 'useFilters'
function useInstance(instance) {
function useMain(instance) {
const {
debug,
rows,
@@ -125,7 +26,7 @@ function useInstance(instance) {
defaultCanFilter = false,
disableFilters,
state: { filters },
dispatch,
setState,
getResetFiltersDeps = false,
} = instance
@@ -136,20 +37,77 @@ function useInstance(instance) {
const isMountedRef = React.useRef()
safeUseLayoutEffect(() => {
if (isMountedRef.current) {
dispatch({ type: actions.resetFilters })
setState(
old => ({
...old,
filters: {},
}),
actions.setAllFilters
)
}
isMountedRef.current = true
}, [dispatch, ...(getResetFiltersDeps ? getResetFiltersDeps(instance) : [])])
}, [setState, ...(getResetFiltersDeps ? getResetFiltersDeps(instance) : [])])
const setFilter = (columnId, filterValue) => {
dispatch({ type: actions.setFilter, columnId, filterValue })
const setFilter = (id, updater) => {
const column = flatColumns.find(d => d.id === id)
if (!column) {
throw new Error(`React-Table: Could not find a column with id: ${id}`)
}
const filterMethod = getFilterMethod(
column.filter,
userFilterTypes || {},
filterTypes
)
return setState(old => {
const newFilter =
typeof updater === 'function' ? updater(old.filters[id]) : updater
//
if (shouldAutoRemove(filterMethod.autoRemove, newFilter)) {
const { [id]: remove, ...newFilters } = old.filters
return {
...old,
filters: newFilters,
}
}
return {
...old,
filters: {
...old.filters,
[id]: newFilter,
},
}
}, actions.setFilter)
}
const setAllFilters = filters => {
dispatch({
type: actions.setAllFilters,
filters,
})
const setAllFilters = updater => {
return setState(old => {
const newFilters = typeof updater === 'function' ? updater(old) : updater
// Filter out undefined values
Object.keys(newFilters).forEach(id => {
const newFilter = newFilters[id]
const column = flatColumns.find(d => d.id === id)
const filterMethod = getFilterMethod(
column.filter,
userFilterTypes || {},
filterTypes
)
if (shouldAutoRemove(filterMethod.autoRemove, newFilter)) {
delete newFilters[id]
}
})
return {
...old,
filters: newFilters,
}
}, actions.setAllFilters)
}
flatColumns.forEach(column => {
@@ -192,7 +150,7 @@ function useInstance(instance) {
const filteredFlatRows = []
if (process.env.NODE_ENV !== 'production' && debug)
if (process.env.NODE_ENV === 'development' && debug)
console.info('getFilteredRows')
// Filters top level and nested rows
@@ -200,9 +158,9 @@ function useInstance(instance) {
let filteredRows = rows
filteredRows = Object.entries(filters).reduce(
(filteredSoFar, [columnId, filterValue]) => {
(filteredSoFar, [columnID, filterValue]) => {
// Find the filters column
const column = flatColumns.find(d => d.id === columnId)
const column = flatColumns.find(d => d.id === columnID)
if (!column) {
return filteredSoFar
@@ -229,7 +187,7 @@ function useInstance(instance) {
// to get the filtered rows back
column.filteredRows = filterMethod(
filteredSoFar,
columnId,
columnID,
filterValue,
column
)
+35 -56
View File
@@ -1,7 +1,8 @@
import React from 'react'
import * as aggregations from '../aggregations'
import { actions, reducerHandlers } from '../hooks/useTable'
import { addActions, actions } from '../actions'
import { defaultState } from '../hooks/useTable'
import {
mergeProps,
applyPropHooks,
@@ -10,47 +11,9 @@ import {
ensurePluginOrder,
} from '../utils'
const pluginName = 'useGroupBy'
defaultState.groupBy = []
// Actions
actions.resetGroupBy = 'resetGroupBy'
actions.toggleGroupBy = 'toggleGroupBy'
// Reducer
reducerHandlers[pluginName] = (state, action) => {
if (action.type === actions.init) {
return {
groupBy: [],
...state,
}
}
if (action.type === actions.resetGroupBy) {
return {
...state,
groupBy: [],
}
}
if (action.type === actions.toggleGroupBy) {
const { columnId, toggle } = action
const resolvedToggle =
typeof toggle !== 'undefined' ? toggle : !state.groupBy.includes(columnId)
if (resolvedToggle) {
return {
...state,
groupBy: [...state.groupBy, columnId],
}
}
return {
...state,
groupBy: state.groupBy.filter(d => d !== columnId),
}
}
}
addActions('toggleGroupBy')
export const useGroupBy = hooks => {
hooks.columnsBeforeHeaderGroups.push(columnsBeforeHeaderGroups)
@@ -58,10 +21,10 @@ export const useGroupBy = hooks => {
deps.push(instance.state.groupBy)
return deps
})
hooks.useInstance.push(useInstance)
hooks.useMain.push(useMain)
}
useGroupBy.pluginName = pluginName
useGroupBy.pluginName = 'useGroupBy'
function columnsBeforeHeaderGroups(flatColumns, { state: { groupBy } }) {
// Sort grouped columns to the start of the column list
@@ -83,7 +46,7 @@ function columnsBeforeHeaderGroups(flatColumns, { state: { groupBy } }) {
const defaultUserAggregations = {}
function useInstance(instance) {
function useMain(instance) {
const {
debug,
rows,
@@ -98,7 +61,7 @@ function useInstance(instance) {
hooks,
plugins,
state: { groupBy },
dispatch,
setState,
} = instance
ensurePluginOrder(plugins, [], 'useGroupBy', ['useSortBy', 'useExpanded'])
@@ -128,8 +91,21 @@ function useInstance(instance) {
column.Aggregated = column.Aggregated || column.Cell
})
const toggleGroupBy = (columnId, toggle) => {
dispatch({ type: actions.toggleGroupBy, columnId, toggle })
const toggleGroupBy = (id, toggle) => {
return setState(old => {
const resolvedToggle =
typeof toggle !== 'undefined' ? toggle : !groupBy.includes(id)
if (resolvedToggle) {
return {
...old,
groupBy: [...groupBy, id],
}
}
return {
...old,
groupBy: groupBy.filter(d => d !== id),
}
}, actions.toggleGroupBy)
}
hooks.getGroupByToggleProps = []
@@ -182,12 +158,12 @@ function useInstance(instance) {
return [rows, flatRows]
}
if (process.env.NODE_ENV !== 'production' && debug)
if (process.env.NODE_ENV === 'development' && debug)
console.info('getGroupedRows')
// Find the columns that can or are aggregating
// Uses each column to aggregate rows into a single value
const aggregateRowsToValues = (rows, isAggregated) => {
const aggregateRowsToValues = (rows, isSourceRows) => {
const values = {}
flatColumns.forEach(column => {
@@ -208,7 +184,7 @@ function useInstance(instance) {
`React Table: Complex aggregators must have 2 values, eg. aggregate: ['sum', 'count']. More info above...`
)
}
if (isAggregated) {
if (isSourceRows) {
aggregator = aggregator[1]
} else {
aggregator = aggregator[0]
@@ -221,7 +197,7 @@ function useInstance(instance) {
: userAggregations[aggregator] || aggregations[aggregator]
if (aggregateFn) {
values[column.id] = aggregateFn(columnValues, rows, isAggregated)
values[column.id] = aggregateFn(columnValues, rows)
} else if (aggregator) {
console.info({ column })
throw new Error(
@@ -247,23 +223,26 @@ function useInstance(instance) {
return rows
}
const columnId = groupBy[depth]
const columnID = groupBy[depth]
// Group the rows together for this level
let groupedRows = groupByFn(rows, columnId)
let groupedRows = groupByFn(rows, columnID)
// Recurse to sub rows before aggregation
groupedRows = Object.entries(groupedRows).map(
([groupByVal, subRows], index) => {
const path = [...parentPath, `${columnId}:${groupByVal}`]
const path = [...parentPath, `${columnID}:${groupByVal}`]
subRows = groupRecursively(subRows, depth + 1, path)
const values = aggregateRowsToValues(subRows, depth < groupBy.length)
const values = aggregateRowsToValues(
subRows,
depth + 1 >= groupBy.length
)
const row = {
isAggregated: true,
groupByID: columnId,
groupByID: columnID,
groupByVal,
values,
subRows,
+45 -68
View File
@@ -1,70 +1,20 @@
import React from 'react'
//
import { addActions, actions } from '../actions'
import { defaultState } from '../hooks/useTable'
import { ensurePluginOrder, safeUseLayoutEffect, expandRows } from '../utils'
import { actions, reducerHandlers } from '../hooks/useTable'
import {
ensurePluginOrder,
safeUseLayoutEffect,
expandRows,
functionalUpdate,
} from '../utils'
defaultState.pageSize = 10
defaultState.pageIndex = 0
const pluginName = 'usePagination'
// Actions
actions.resetPage = 'resetPage'
actions.gotoPage = 'gotoPage'
actions.setPageSize = 'setPageSize'
// Reducer
reducerHandlers[pluginName] = (state, action) => {
if (action.type === actions.init) {
return {
pageSize: 10,
pageIndex: 0,
...state,
}
}
if (action.type === actions.resetPage) {
return {
...state,
pageIndex: 0,
}
}
if (action.type === actions.gotoPage) {
const { pageCount } = action.instanceRef.current
const newPageIndex = functionalUpdate(action.pageIndex, state.pageIndex)
if (newPageIndex < 0 || newPageIndex > pageCount - 1) {
return state
}
return {
...state,
pageIndex: newPageIndex,
}
}
if (action.type === actions.setPageSize) {
const { pageSize } = action
const topRowIndex = state.pageSize * state.pageIndex
const pageIndex = Math.floor(topRowIndex / pageSize)
return {
...state,
pageIndex,
pageSize,
}
}
}
addActions('pageChange', 'pageSizeChange')
export const usePagination = hooks => {
hooks.useInstance.push(useInstance)
hooks.useMain.push(useMain)
}
usePagination.pluginName = pluginName
usePagination.pluginName = 'usePagination'
const defaultGetResetPageDeps = ({
data,
@@ -72,7 +22,7 @@ const defaultGetResetPageDeps = ({
state: { filters, groupBy, sortBy },
}) => [manualPagination ? null : data, filters, groupBy, sortBy]
function useInstance(instance) {
function useMain(instance) {
const {
rows,
manualPagination,
@@ -84,7 +34,7 @@ function useInstance(instance) {
paginateExpandedRows = true,
expandSubRows = true,
state: { pageSize, pageIndex, expanded },
dispatch,
setState,
} = instance
ensurePluginOrder(
@@ -98,10 +48,16 @@ function useInstance(instance) {
const isMountedRef = React.useRef()
safeUseLayoutEffect(() => {
if (isMountedRef.current) {
dispatch({ type: actions.resetPage })
setState(
old => ({
...old,
pageIndex: 0,
}),
actions.pageChange
)
}
isMountedRef.current = true
}, [dispatch, ...(getResetPageDeps ? getResetPageDeps(instance) : [])])
}, [setState, ...(getResetPageDeps ? getResetPageDeps(instance) : [])])
const pageCount = manualPagination
? userPageCount
@@ -118,7 +74,7 @@ function useInstance(instance) {
if (manualPagination) {
page = rows
} else {
if (process.env.NODE_ENV !== 'production' && debug)
if (process.env.NODE_ENV === 'development' && debug)
console.info('getPage')
const pageStart = pageSize * pageIndex
@@ -148,10 +104,23 @@ function useInstance(instance) {
const canNextPage = pageCount === -1 || pageIndex < pageCount - 1
const gotoPage = React.useCallback(
pageIndex => {
dispatch({ type: actions.gotoPage, pageIndex })
updater => {
if (process.env.NODE_ENV === 'development' && debug)
console.info('gotoPage')
return setState(old => {
const newPageIndex =
typeof updater === 'function' ? updater(old.pageIndex) : updater
if (newPageIndex < 0 || newPageIndex > pageCount - 1) {
return old
}
return {
...old,
pageIndex: newPageIndex,
}
}, actions.pageChange)
},
[dispatch]
[debug, pageCount, setState]
)
const previousPage = React.useCallback(() => {
@@ -164,9 +133,17 @@ function useInstance(instance) {
const setPageSize = React.useCallback(
pageSize => {
dispatch({ type: actions.setPageSize, pageSize })
setState(old => {
const topRowIndex = old.pageSize * old.pageIndex
const pageIndex = Math.floor(topRowIndex / pageSize)
return {
...old,
pageIndex,
pageSize,
}
}, actions.pageSizeChange)
},
[dispatch]
[setState]
)
return {
+50 -97
View File
@@ -1,96 +1,22 @@
import React from 'react'
import { actions, reducerHandlers } from '../hooks/useTable'
import {
defaultColumn,
getFirstDefined,
mergeProps,
applyPropHooks,
} from '../utils'
import { defaultState } from '../hooks/useTable'
import { defaultColumn, getFirstDefined } from '../utils'
import { mergeProps, applyPropHooks } from '../utils'
const pluginName = 'useResizeColumns'
defaultState.columnResizing = {
columnWidths: {},
}
// Default Column
defaultColumn.canResize = true
// Actions
actions.columnStartResizing = 'columnStartResizing'
actions.columnResizing = 'columnResizing'
actions.columnDoneResizing = 'columnDoneResizing'
// Reducer
reducerHandlers[pluginName] = (state, action) => {
if (action.type === actions.init) {
return {
columnResizing: {
columnWidths: {},
},
...state,
}
}
if (action.type === actions.columnStartResizing) {
const { clientX, columnId, columnWidth, headerIdWidths } = action
return {
...state,
columnResizing: {
...state.columnResizing,
startX: clientX,
headerIdWidths,
columnWidth,
isResizingColumn: columnId,
},
}
}
if (action.type === actions.columnResizing) {
const { clientX } = action
const { startX, columnWidth, headerIdWidths } = state.columnResizing
const deltaX = clientX - startX
const percentageDeltaX = deltaX / columnWidth
const newColumnWidths = {}
headerIdWidths.forEach(([headerId, headerWidth]) => {
newColumnWidths[headerId] = Math.max(
headerWidth + headerWidth * percentageDeltaX,
0
)
})
return {
...state,
columnResizing: {
...state.columnResizing,
columnWidths: {
...state.columnResizing.columnWidths,
...newColumnWidths,
},
},
}
}
if (action.type === actions.columnDoneResizing) {
return {
...state,
columnResizing: {
...state.columnResizing,
startX: null,
isResizingColumn: null,
},
}
}
}
export const useResizeColumns = hooks => {
hooks.useInstanceBeforeDimensions.push(useInstanceBeforeDimensions)
hooks.useBeforeDimensions.push(useBeforeDimensions)
}
useResizeColumns.pluginName = pluginName
useResizeColumns.pluginName = 'useResizeColumns'
const useInstanceBeforeDimensions = instance => {
const useBeforeDimensions = instance => {
instance.hooks.getResizerProps = []
const {
@@ -98,7 +24,7 @@ const useInstanceBeforeDimensions = instance => {
disableResizing,
hooks: { getHeaderProps },
state: { columnResizing },
dispatch,
setState,
} = instance
getHeaderProps.push(() => {
@@ -111,33 +37,60 @@ const useInstanceBeforeDimensions = instance => {
const onMouseDown = (e, header) => {
const headersToResize = getLeafHeaders(header)
const headerIdWidths = headersToResize.map(d => [d.id, d.totalWidth])
const clientX = e.clientX
const startWidths = headersToResize.map(header => header.totalWidth)
const startX = e.clientX
const onMouseMove = e => {
const clientX = e.clientX
const currentX = e.clientX
const deltaX = currentX - startX
dispatch({ type: actions.columnResizing, clientX })
const percentageDeltaX = deltaX / headersToResize.length
const newColumnWidths = {}
headersToResize.forEach((header, index) => {
newColumnWidths[header.id] = Math.max(
startWidths[index] + percentageDeltaX,
0
)
})
setState(old => ({
...old,
columnResizing: {
...old.columnResizing,
columnWidths: {
...old.columnResizing.columnWidths,
...newColumnWidths,
},
},
}))
}
const onMouseUp = e => {
document.removeEventListener('mousemove', onMouseMove)
document.removeEventListener('mouseup', onMouseUp)
dispatch({ type: actions.columnDoneResizing })
setState(old => ({
...old,
columnResizing: {
...old.columnResizing,
startX: null,
isResizingColumn: null,
},
}))
}
document.addEventListener('mousemove', onMouseMove)
document.addEventListener('mouseup', onMouseUp)
dispatch({
type: actions.columnStartResizing,
columnId: header.id,
columnWidth: header.totalWidth,
headerIdWidths,
clientX,
})
setState(old => ({
...old,
columnResizing: {
...old.columnResizing,
startX,
isResizingColumn: header.id,
},
}))
}
// use reference to avoid memory leak in #1608
+87 -120
View File
@@ -6,123 +6,21 @@ import {
ensurePluginOrder,
safeUseLayoutEffect,
} from '../utils'
import { actions, reducerHandlers } from '../hooks/useTable'
import { addActions, actions } from '../actions'
import { defaultState } from '../hooks/useTable'
const pluginName = 'useRowSelect'
defaultState.selectedRowPaths = []
// Actions
actions.resetSelectedRows = 'resetSelectedRows'
actions.toggleRowSelectedAll = 'toggleRowSelectedAll'
actions.toggleRowSelected = 'toggleRowSelected'
// Reducer
reducerHandlers[pluginName] = (state, action) => {
if (action.type === actions.init) {
return {
selectedRowPaths: new Set(),
...state,
}
}
if (action.type === actions.resetSelectedRows) {
return {
...state,
selectedRowPaths: new Set(),
}
}
if (action.type === actions.toggleRowSelectedAll) {
const {
selected,
instanceRef: {
current: { isAllRowsSelected, flatRowPaths },
},
} = action
const selectAll =
typeof selected !== 'undefined' ? selected : !isAllRowsSelected
return {
...state,
selectedRowPaths: selectAll ? new Set(flatRowPaths) : new Set(),
}
}
if (action.type === actions.toggleRowSelected) {
const {
path,
selected,
instanceRef: {
current: { flatRowPaths },
},
} = action
const key = path.join('.')
const childRowPrefixKey = [key, '.'].join('')
// Join the paths of deep rows
// to make a key, then manage all of the keys
// in a flat object
const exists = state.selectedRowPaths.has(key)
const shouldExist = typeof set !== 'undefined' ? selected : !exists
let newSelectedRowPaths = new Set(state.selectedRowPaths)
if (!exists && shouldExist) {
flatRowPaths.forEach(rowPath => {
if (rowPath === key || rowPath.startsWith(childRowPrefixKey)) {
newSelectedRowPaths.add(rowPath)
}
})
} else if (exists && !shouldExist) {
flatRowPaths.forEach(rowPath => {
if (rowPath === key || rowPath.startsWith(childRowPrefixKey)) {
newSelectedRowPaths.delete(rowPath)
}
})
} else {
return state
}
const updateParentRow = (selectedRowPaths, path) => {
const parentPath = path.slice(0, path.length - 1)
const parentKey = parentPath.join('.')
const selected =
flatRowPaths.filter(rowPath => {
const path = rowPath
return (
path !== parentKey &&
path.startsWith(parentKey) &&
!selectedRowPaths.has(path)
)
}).length === 0
if (selected) {
selectedRowPaths.add(parentKey)
} else {
selectedRowPaths.delete(parentKey)
}
if (parentPath.length > 1) updateParentRow(selectedRowPaths, parentPath)
}
// If the row is a subRow update
// its parent row to reflect changes
if (path.length > 1) updateParentRow(newSelectedRowPaths, path)
return {
...state,
selectedRowPaths: newSelectedRowPaths,
}
}
}
addActions('toggleRowSelected', 'toggleRowSelectedAll', 'setSelectedRowPaths')
export const useRowSelect = hooks => {
hooks.getToggleRowSelectedProps = []
hooks.getToggleAllRowsSelectedProps = []
hooks.useRows.push(useRows)
hooks.useInstance.push(useInstance)
hooks.useMain.push(useMain)
}
useRowSelect.pluginName = pluginName
useRowSelect.pluginName = 'useRowSelect'
function useRows(rows, instance) {
const {
@@ -148,7 +46,7 @@ function useRows(rows, instance) {
const defaultGetResetSelectedRowPathsDeps = ({ data }) => [data]
function useInstance(instance) {
function useMain(instance) {
const {
hooks,
manualRowSelectedKey = 'isSelected',
@@ -156,7 +54,7 @@ function useInstance(instance) {
flatRows,
getResetSelectedRowPathsDeps = defaultGetResetSelectedRowPathsDeps,
state: { selectedRowPaths },
dispatch,
setState,
} = instance
ensurePluginOrder(
@@ -168,10 +66,10 @@ function useInstance(instance) {
const flatRowPaths = flatRows.map(d => d.path.join('.'))
let isAllRowsSelected = !!flatRowPaths.length && !!selectedRowPaths.size
let isAllRowsSelected = !!flatRowPaths.length && !!selectedRowPaths.length
if (isAllRowsSelected) {
if (flatRowPaths.some(d => !selectedRowPaths.has(d))) {
if (flatRowPaths.some(d => !selectedRowPaths.includes(d))) {
isAllRowsSelected = false
}
}
@@ -180,21 +78,90 @@ function useInstance(instance) {
const isMountedRef = React.useRef()
safeUseLayoutEffect(() => {
if (isMountedRef.current) {
dispatch({ type: actions.resetSelectedRows })
setState(
old => ({
...old,
selectedRowPaths: [],
}),
actions.setSelectedRowPaths
)
}
isMountedRef.current = true
}, [
dispatch,
setState,
...(getResetSelectedRowPathsDeps
? getResetSelectedRowPathsDeps(instance)
: []),
])
const toggleRowSelectedAll = selected =>
dispatch({ type: actions.toggleRowSelectedAll, selected })
const toggleRowSelectedAll = set => {
setState(old => {
const selectAll = typeof set !== 'undefined' ? set : !isAllRowsSelected
return {
...old,
selectedRowPaths: selectAll ? flatRowPaths : [],
}
}, actions.toggleRowSelectedAll)
}
const toggleRowSelected = (path, selected) =>
dispatch({ type: actions.toggleRowSelected, path, selected })
const updateParentRow = (selectedRowPaths, path) => {
const parentPath = path.slice(0, path.length - 1)
const parentKey = parentPath.join('.')
const selected =
flatRowPaths.filter(rowPath => {
const path = rowPath
return (
path !== parentKey &&
path.startsWith(parentKey) &&
!selectedRowPaths.has(path)
)
}).length === 0
if (selected) {
selectedRowPaths.add(parentKey)
} else {
selectedRowPaths.delete(parentKey)
}
if (parentPath.length > 1) updateParentRow(selectedRowPaths, parentPath)
}
const toggleRowSelected = (path, set) => {
const key = path.join('.')
const childRowPrefixKey = [key, '.'].join('')
return setState(old => {
// Join the paths of deep rows
// to make a key, then manage all of the keys
// in a flat object
const exists = old.selectedRowPaths.includes(key)
const shouldExist = typeof set !== 'undefined' ? set : !exists
let newSelectedRows = new Set(old.selectedRowPaths)
if (!exists && shouldExist) {
flatRowPaths.forEach(rowPath => {
if (rowPath === key || rowPath.startsWith(childRowPrefixKey)) {
newSelectedRows.add(rowPath)
}
})
} else if (exists && !shouldExist) {
flatRowPaths.forEach(rowPath => {
if (rowPath === key || rowPath.startsWith(childRowPrefixKey)) {
newSelectedRows.delete(rowPath)
}
})
} else {
return old
}
// If the row is a subRow update
// its parent row to reflect changes
if (path.length > 1) updateParentRow(newSelectedRows, path)
return {
...old,
selectedRowPaths: [...newSelectedRows.values()],
}
}, actions.toggleRowSelected)
}
// use reference to avoid memory leak in #1608
const instanceRef = React.useRef()
@@ -250,13 +217,13 @@ function useInstance(instance) {
props
)
}
// }
return row
})
return {
...instance,
flatRowPaths,
toggleRowSelected,
toggleRowSelectedAll,
getToggleAllRowsSelectedProps,
@@ -271,5 +238,5 @@ function getRowIsSelected(row, selectedRowPaths) {
)
}
return selectedRowPaths.has(row.path.join('.'))
return selectedRowPaths.includes(row.path.join('.'))
}
+39 -66
View File
@@ -1,77 +1,48 @@
import React from 'react'
//
import { addActions, actions } from '../actions'
import { defaultState } from '../hooks/useTable'
import { actions, reducerHandlers } from '../hooks/useTable'
import { functionalUpdate, safeUseLayoutEffect } from '../utils'
defaultState.rowState = {}
const pluginName = 'useRowState'
// Actions
actions.setRowState = 'setRowState'
actions.resetRowState = 'resetRowState'
// Reducer
reducerHandlers[pluginName] = (state, action) => {
if (action.type === actions.init) {
return {
rowState: {},
...state,
}
}
if (action.type === actions.resetRowState) {
return {
...state,
rowState: {},
}
}
if (action.type === actions.setRowState) {
const { path, value } = action
const pathKey = path.join('.')
return {
...state,
rowState: {
...state.rowState,
[pathKey]: functionalUpdate(value, state.rowState[pathKey] || {}),
},
}
}
}
addActions('setRowState', 'setCellState')
export const useRowState = hooks => {
hooks.useInstance.push(useInstance)
hooks.useMain.push(useMain)
}
useRowState.pluginName = pluginName
useRowState.pluginName = 'useRowState'
const defaultGetResetRowStateDeps = ({ data }) => [data]
function useInstance(instance) {
function useMain(instance) {
const {
hooks,
rows,
initialRowStateAccessor,
getResetRowStateDeps = defaultGetResetRowStateDeps,
state: { rowState },
dispatch,
setState,
} = instance
const setRowState = React.useCallback(
(path, value, columnId) =>
dispatch({
type: actions.setRowState,
path,
value,
columnId,
}),
[dispatch]
(path, updater, action = actions.setRowState) => {
const pathKey = path.join('.')
return setState(old => {
return {
...old,
rowState: {
...old.rowState,
[pathKey]:
typeof updater === 'function'
? updater(old.rowState[pathKey])
: updater,
},
}
}, action)
},
[setState]
)
const setCellState = React.useCallback(
(rowPath, columnId, value) => {
(rowPath, columnID, updater) => {
return setRowState(
rowPath,
old => {
@@ -79,14 +50,14 @@ function useInstance(instance) {
...old,
cellState: {
...old.cellState,
[columnId]: functionalUpdate(
value,
(old.cellState || {})[columnId] || {}
),
[columnID]:
typeof updater === 'function'
? updater(old.cellState[columnID])
: updater,
},
}
},
columnId
actions.setCellState
)
},
[setRowState]
@@ -95,16 +66,18 @@ function useInstance(instance) {
const rowsMountedRef = React.useRef()
// When data changes, reset row and cell state
safeUseLayoutEffect(() => {
React.useEffect(() => {
if (rowsMountedRef.current) {
dispatch({ type: actions.resetRowState })
setState(old => {
return {
...old,
rowState: {},
}
}, actions.setRowState)
}
rowsMountedRef.current = true
}, [
dispatch,
...(getResetRowStateDeps ? getResetRowStateDeps(instance) : []),
])
}, [rows, setState])
hooks.prepareRow.push(row => {
const pathKey = row.path.join('.')
+119 -148
View File
@@ -1,7 +1,8 @@
import React from 'react'
import { ensurePluginOrder, defaultColumn, safeUseLayoutEffect } from '../utils'
import { actions, reducerHandlers } from '../hooks/useTable'
import { addActions, actions } from '../actions'
import { defaultState } from '../hooks/useTable'
import * as sortTypes from '../sortTypes'
import {
mergeProps,
@@ -11,150 +12,19 @@ import {
isFunction,
} from '../utils'
const pluginName = 'useSortBy'
// Actions
actions.resetSortBy = 'resetSortBy'
actions.toggleSortBy = 'toggleSortBy'
actions.clearSortBy = 'clearSortBy'
// Reducer
reducerHandlers[pluginName] = (state, action) => {
if (action.type === actions.init) {
return {
sortBy: [],
...state,
}
}
if (action.type === actions.resetSortBy) {
return {
...state,
sortBy: [],
}
}
if (action.type === actions.clearSortBy) {
const { sortBy } = state
const newSortBy = sortBy.filter(d => d.id !== action.columnID)
return {
...state,
sortBy: newSortBy,
}
}
if (action.type === actions.toggleSortBy) {
const {
columnId,
desc,
multi,
instanceRef: {
current: {
flatColumns,
disableMultiSort,
disableSortRemove,
disableMultiRemove,
maxMultiSortColCount = Number.MAX_SAFE_INTEGER,
},
},
} = action
const { sortBy } = state
// Find the column for this columnId
const column = flatColumns.find(d => d.id === columnId)
const { sortDescFirst } = column
// Find any existing sortBy for this column
const existingSortBy = sortBy.find(d => d.id === columnId)
const existingIndex = sortBy.findIndex(d => d.id === columnId)
const hasDescDefined = typeof desc !== 'undefined' && desc !== null
let newSortBy = []
// What should we do with this sort action?
let sortAction
if (!disableMultiSort && multi) {
if (existingSortBy) {
sortAction = 'toggle'
} else {
sortAction = 'add'
}
} else {
// Normal mode
if (existingIndex !== sortBy.length - 1) {
sortAction = 'replace'
} else if (existingSortBy) {
sortAction = 'toggle'
} else {
sortAction = 'replace'
}
}
// Handle toggle states that will remove the sortBy
if (
sortAction === 'toggle' && // Must be toggling
!disableSortRemove && // If disableSortRemove, disable in general
!hasDescDefined && // Must not be setting desc
(multi ? !disableMultiRemove : true) && // If multi, don't allow if disableMultiRemove
((existingSortBy && // Finally, detect if it should indeed be removed
existingSortBy.desc &&
!sortDescFirst) ||
(!existingSortBy.desc && sortDescFirst))
) {
sortAction = 'remove'
}
if (sortAction === 'replace') {
newSortBy = [
{
id: columnId,
desc: hasDescDefined ? desc : sortDescFirst,
},
]
} else if (sortAction === 'add') {
newSortBy = [
...sortBy,
{
id: columnId,
desc: hasDescDefined ? desc : sortDescFirst,
},
]
// Take latest n columns
newSortBy.splice(0, newSortBy.length - maxMultiSortColCount)
} else if (sortAction === 'toggle') {
// This flips (or sets) the
newSortBy = sortBy.map(d => {
if (d.id === columnId) {
return {
...d,
desc: hasDescDefined ? desc : !existingSortBy.desc,
}
}
return d
})
} else if (sortAction === 'remove') {
newSortBy = sortBy.filter(d => d.id !== columnId)
}
return {
...state,
sortBy: newSortBy,
}
}
}
defaultState.sortBy = []
defaultColumn.sortType = 'alphanumeric'
defaultColumn.sortDescFirst = false
addActions('sortByChange')
export const useSortBy = hooks => {
hooks.useInstance.push(useInstance)
hooks.useMain.push(useMain)
}
useSortBy.pluginName = pluginName
useSortBy.pluginName = 'useSortBy'
function useInstance(instance) {
function useMain(instance) {
const {
debug,
rows,
@@ -164,11 +34,15 @@ function useInstance(instance) {
manualSorting,
defaultCanSort,
disableSortBy,
disableSortRemove,
disableMultiRemove,
disableMultiSort,
isMultiSortEvent = e => e.shiftKey,
maxMultiSortColCount = Number.MAX_SAFE_INTEGER,
flatHeaders,
hooks,
state: { sortBy },
dispatch,
setState,
plugins,
getResetSortByDeps = false,
} = instance
@@ -181,14 +55,104 @@ function useInstance(instance) {
const isMountedRef = React.useRef()
safeUseLayoutEffect(() => {
if (isMountedRef.current) {
dispatch({ type: actions.resetSortBy })
setState(
old => ({
...old,
sortBy: [],
}),
actions.sortByChange
)
}
isMountedRef.current = true
}, [dispatch, ...(getResetSortByDeps ? getResetSortByDeps(instance) : [])])
}, [setState, ...(getResetSortByDeps ? getResetSortByDeps(instance) : [])])
// Updates sorting based on a columnId, desc flag and multi flag
const toggleSortBy = (columnId, desc, multi) => {
dispatch({ type: actions.toggleSortBy, columnId, desc, multi })
// Updates sorting based on a columnID, desc flag and multi flag
const toggleSortBy = (columnID, desc, multi) => {
return setState(old => {
const { sortBy } = old
// Find the column for this columnID
const column = flatColumns.find(d => d.id === columnID)
const { sortDescFirst } = column
// Find any existing sortBy for this column
const existingSortBy = sortBy.find(d => d.id === columnID)
const existingIndex = sortBy.findIndex(d => d.id === columnID)
const hasDescDefined = typeof desc !== 'undefined' && desc !== null
let newSortBy = []
// What should we do with this sort action?
let action
if (!disableMultiSort && multi) {
if (existingSortBy) {
action = 'toggle'
} else {
action = 'add'
}
} else {
// Normal mode
if (existingIndex !== sortBy.length - 1) {
action = 'replace'
} else if (existingSortBy) {
action = 'toggle'
} else {
action = 'replace'
}
}
// Handle toggle states that will remove the sortBy
if (
action === 'toggle' && // Must be toggling
!disableSortRemove && // If disableSortRemove, disable in general
!hasDescDefined && // Must not be setting desc
(multi ? !disableMultiRemove : true) && // If multi, don't allow if disableMultiRemove
((existingSortBy && // Finally, detect if it should indeed be removed
existingSortBy.desc &&
!sortDescFirst) ||
(!existingSortBy.desc && sortDescFirst))
) {
action = 'remove'
}
if (action === 'replace') {
newSortBy = [
{
id: columnID,
desc: hasDescDefined ? desc : sortDescFirst,
},
]
} else if (action === 'add') {
newSortBy = [
...sortBy,
{
id: columnID,
desc: hasDescDefined ? desc : sortDescFirst,
},
]
// Take latest n columns
newSortBy.splice(0, newSortBy.length - maxMultiSortColCount)
} else if (action === 'toggle') {
// This flips (or sets) the
newSortBy = sortBy.map(d => {
if (d.id === columnID) {
return {
...d,
desc: hasDescDefined ? desc : !existingSortBy.desc,
}
}
return d
})
} else if (action === 'remove') {
newSortBy = sortBy.filter(d => d.id !== columnID)
}
return {
...old,
sortBy: newSortBy,
}
}, actions.sortByChange)
}
// use reference to avoid memory leak in #1608
@@ -218,8 +182,15 @@ function useInstance(instance) {
column.toggleSortBy = (desc, multi) =>
toggleSortBy(column.id, desc, multi)
column.clearSortBy = () => {
dispatch({ type: actions.clearSortBy, columnId: column.id })
column.clearSorting = () => {
return setState(old => {
const { sortBy } = old
const newSortBy = sortBy.filter(d => d.id !== column.id)
return {
...old,
sortBy: newSortBy,
}
}, actions.sortByChange)
}
}
@@ -259,7 +230,7 @@ function useInstance(instance) {
if (manualSorting || !sortBy.length) {
return rows
}
if (process.env.NODE_ENV !== 'production' && debug)
if (process.env.NODE_ENV === 'development' && debug)
console.time('getSortedRows')
// Filter out sortBys that correspond to non existing columns
@@ -331,7 +302,7 @@ function useInstance(instance) {
return sortedData
}
if (process.env.NODE_ENV !== 'production' && debug)
if (process.env.NODE_ENV === 'development' && debug)
console.timeEnd('getSortedRows')
return sortData(rows)
+11 -11
View File
@@ -3,9 +3,9 @@ const reSplitAlphaNumeric = /([0-9]+)/gm
// Mixed sorting is slow, but very inclusive of many edge cases.
// It handles numbers, mixed alphanumeric combinations, and even
// null, undefined, and Infinity
export const alphanumeric = (rowA, rowB, columnId) => {
let a = getRowValueByColumnID(rowA, columnId)
let b = getRowValueByColumnID(rowB, columnId)
export const alphanumeric = (rowA, rowB, columnID) => {
let a = getRowValueByColumnID(rowA, columnID)
let b = getRowValueByColumnID(rowB, columnID)
// Force to strings (or "" for unsupported types)
a = toString(a)
b = toString(b)
@@ -53,9 +53,9 @@ export const alphanumeric = (rowA, rowB, columnId) => {
return a.length - b.length
}
export function datetime(rowA, rowB, columnId) {
let a = getRowValueByColumnID(rowA, columnId)
let b = getRowValueByColumnID(rowB, columnId)
export function datetime(rowA, rowB, columnID) {
let a = getRowValueByColumnID(rowA, columnID)
let b = getRowValueByColumnID(rowB, columnID)
a = a.getTime()
b = b.getTime()
@@ -63,9 +63,9 @@ export function datetime(rowA, rowB, columnId) {
return compareBasic(a, b)
}
export function basic(rowA, rowB, columnId) {
let a = getRowValueByColumnID(rowA, columnId)
let b = getRowValueByColumnID(rowB, columnId)
export function basic(rowA, rowB, columnID) {
let a = getRowValueByColumnID(rowA, columnID)
let b = getRowValueByColumnID(rowB, columnID)
return compareBasic(a, b)
}
@@ -76,8 +76,8 @@ function compareBasic(a, b) {
return a === b ? 0 : a > b ? 1 : -1
}
function getRowValueByColumnID(row, columnId) {
return row.values[columnId]
function getRowValueByColumnID(row, columnID) {
return row.values[columnID]
}
function toString(a) {
+9 -13
View File
@@ -113,24 +113,24 @@ export function makeHeaderGroups(flatColumns, defaultColumn) {
// If the column has a parent, add it if necessary
if (column.parent) {
const similarParentColumns = parentColumns.filter(
d => d.originalId === column.parent.id
d => d.originalID === column.parent.id
)
if (isFirst || latestParentColumn.originalId !== column.parent.id) {
if (isFirst || latestParentColumn.originalID !== column.parent.id) {
parentColumns.push({
...column.parent,
originalId: column.parent.id,
originalID: column.parent.id,
id: [column.parent.id, similarParentColumns.length].join('_'),
})
}
} else if (hasParents) {
// If other columns have parents, we'll need to add a place holder if necessary
const originalId = [column.id, 'placeholder'].join('_')
const originalID = [column.id, 'placeholder'].join('_')
const similarParentColumns = parentColumns.filter(
d => d.originalId === originalId
d => d.originalID === originalID
)
const placeholderColumn = decorateColumn(
{
originalId,
originalID,
id: [column.id, 'placeholder', similarParentColumns.length].join(
'_'
),
@@ -140,7 +140,7 @@ export function makeHeaderGroups(flatColumns, defaultColumn) {
)
if (
isFirst ||
latestParentColumn.originalId !== placeholderColumn.originalId
latestParentColumn.originalID !== placeholderColumn.originalID
) {
parentColumns.push(placeholderColumn)
}
@@ -245,11 +245,11 @@ export function getFirstDefined(...args) {
}
}
export function defaultGroupByFn(rows, columnId) {
export function defaultGroupByFn(rows, columnID) {
return rows.reduce((prev, row, i) => {
// TODO: Might want to implement a key serializer here so
// irregular column values can still be grouped if needed?
const resKey = `${row.values[columnId]}`
const resKey = `${row.values[columnID]}`
prev[resKey] = Array.isArray(prev[resKey]) ? prev[resKey] : []
prev[resKey].push(row)
return prev
@@ -438,10 +438,6 @@ export function expandRows(
return expandedRows
}
export function functionalUpdate(updater, old) {
return typeof updater === 'function' ? updater(old) : updater
}
//
function makePathArray(obj) {
+10
View File
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": ["es6"],
"strict": true,
"noEmit": true,
"forceConsistentCasingInFileNames": true
},
"files": ["index.d.ts"]
}
+9
View File
@@ -0,0 +1,9 @@
{
"extends": "dtslint/dtslint.json",
"rules": {
"no-empty-interface": false,
"no-unnecessary-generics": false,
"semicolon": false,
"whitespace": false
}
}
+3 -77
View File
@@ -2307,14 +2307,6 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
axios@^0.19.0:
version "0.19.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8"
integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==
dependencies:
follow-redirects "1.5.10"
is-buffer "^2.0.2"
axobject-query@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.0.2.tgz#ea187abe5b9002b377f925d8bf7d1c561adf38f9"
@@ -2496,13 +2488,6 @@ brorand@^1.0.1:
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
brotli-size@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/brotli-size/-/brotli-size-4.0.0.tgz#a05ee3faad3c0e700a2f2da826ba6b4d76e69e5e"
integrity sha512-uA9fOtlTRC0iqKfzff1W34DXUA3GyVqbUaeo3Rw3d4gd1eavKVCETXrn3NzO74W+UVkG3UHu8WxUi+XvKI/huA==
dependencies:
duplexer "0.1.1"
browser-process-hrtime@^0.1.2:
version "0.1.3"
resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4"
@@ -2786,11 +2771,6 @@ chrome-trace-event@^1.0.2:
dependencies:
tslib "^1.9.0"
ci-env@^1.11.0:
version "1.12.0"
resolved "https://registry.yarnpkg.com/ci-env/-/ci-env-1.12.0.tgz#8b430c4c8fcfe730cb8ac330836bffaa6e5f2ab8"
integrity sha512-4dS9YjX4kpaFmkJWZPuDPK3WlPKdMjx/3JH39vyHj+G4/ED2DCgHQLbh9tKBQjwAwR/sGHOqIVMTlMUZcfJPWw==
ci-info@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
@@ -3324,13 +3304,6 @@ date-fns@^1.27.2:
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c"
integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==
debug@=3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
dependencies:
ms "2.0.0"
debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@@ -3601,7 +3574,7 @@ dtslint@^0.9.8:
tslint "5.14.0"
typescript next
duplexer@0.1.1, duplexer@^0.1.1:
duplexer@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=
@@ -4333,13 +4306,6 @@ flush-write-stream@^1.0.0:
inherits "^2.0.3"
readable-stream "^2.3.6"
follow-redirects@1.5.10:
version "1.5.10"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
dependencies:
debug "=3.1.0"
for-in@^0.1.3:
version "0.1.8"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1"
@@ -4386,7 +4352,7 @@ from2@^2.1.0:
inherits "^2.0.1"
readable-stream "^2.0.0"
fs-extra@8.1.0, fs-extra@^8.1.0:
fs-extra@8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
@@ -4615,7 +4581,7 @@ growly@^1.3.0:
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=
gzip-size@^5.0.0, gzip-size@^5.1.1:
gzip-size@^5.0.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274"
integrity sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==
@@ -4974,11 +4940,6 @@ is-buffer@^1.0.2, is-buffer@^1.1.5:
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
is-buffer@^2.0.2:
version "2.0.4"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623"
integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==
is-callable@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
@@ -7285,11 +7246,6 @@ prettier@^1.19.1:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
pretty-bytes@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.3.0.tgz#f2849e27db79fb4d6cfe24764fc4134f165989f2"
integrity sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg==
pretty-format@^23.6.0:
version "23.6.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.6.0.tgz#5eaac8eeb6b33b987b7fe6097ea6a8a146ab5760"
@@ -7938,13 +7894,6 @@ rollup-plugin-size-snapshot@^0.10.0:
terser "^4.1.2"
webpack "^4.28.4"
rollup-plugin-size@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/rollup-plugin-size/-/rollup-plugin-size-0.2.1.tgz#aec287896740e73550629c43cd6d402f71cc51de"
integrity sha512-ZwOXarF21okk8u7gZKTH9JyULNFmaUyosOMifxa0vvdjJGaJs3NDhnTgFaJW8PsFMxOVgwxqJrLqqTmFfvH4EA==
dependencies:
size-plugin-core "^0.0.7"
rollup-plugin-terser@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-5.1.2.tgz#3e41256205cb75f196fc70d4634227d1002c255c"
@@ -8183,29 +8132,6 @@ sisteransi@^1.0.3:
resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.4.tgz#386713f1ef688c7c0304dc4c0632898941cad2e3"
integrity sha512-/ekMoM4NJ59ivGSfKapeG+FWtrmWvA1p6FBZwXrqojw90vJu8lBmrTxCMuBCydKtkaUe2zt4PlxeTKpjwMbyig==
size-plugin-core@^0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/size-plugin-core/-/size-plugin-core-0.0.7.tgz#f63875902d6ae694d3989b7385286934a78020cd"
integrity sha512-vMX3AhK3hh5vxfOL5VgEIxUkcm0MFfiPsZ9LqZsZRH7iQ+erU669zYsx+WCF4EQ+nn11GYXL91U/sEvS1FnPug==
dependencies:
brotli-size "^4.0.0"
chalk "^2.4.2"
fs-extra "^8.1.0"
glob "^7.1.4"
gzip-size "^5.1.1"
minimatch "^3.0.4"
pretty-bytes "^5.3.0"
size-plugin-store "^0.0.5"
util.promisify "^1.0.0"
size-plugin-store@^0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/size-plugin-store/-/size-plugin-store-0.0.5.tgz#5b36e6f0f12e2f25f7bf1cab029a52e000348f98"
integrity sha512-SIFBv0wMMMfdqg1Po8vem90OaXe2Cftfo0AiXYU9m9JxDhOd726K+0BfNcYyOmDyrH2uUM7zMlnU2OhbbsDv5Q==
dependencies:
axios "^0.19.0"
ci-env "^1.11.0"
slash@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44"