Compare commits

...
Author SHA1 Message Date
tannerlinsley e5c04614c1 v7.0.0-beta.7 2019-10-03 13:40:22 -06:00
tannerlinsley 0ef0bc4126 fix(userowselect): useRowSelect fixed to take into account filters
useRowSelect now takes into account filtered data when doing selectAll toggling and
isAllRowsSelected state.
2019-10-03 13:39:35 -06:00
tannerlinsley ef67b15c07 Merge branch 'master' of https://github.com/react-tools/react-table 2019-10-03 08:39:12 -06:00
Tanner Linsley d248be8877 Fix sandbox loop protection 2019-10-03 08:38:33 -06:00
10 changed files with 71 additions and 35 deletions
View File
-4
View File
@@ -209,10 +209,6 @@ The following properties are available on the table instance returned from `useT
- **Required**
- This function is responsible for lazily preparing a row for rendering. Any row that you intend to render in your table needs to be passed to this function **before every render**.
- **Why?** Since table data could potentially be very large, it can become very expensive to compute all of the necessary state for every row to be rendered regardless if it actually is rendered or not (for example if you are paginating or virtualizing the rows, you may only have a few rows visible at any given moment). This function allows only the rows you intend to display to be computed and prepped with the correct state.
- `rowPaths: Array<string>`
- An array containing the stringified `path` of every original row in the table. eg. If a row has a path of `[0, 3, 2]`, its stringified path would be `0.3.2`.
- This array is used by many plugin hooks including `useRowSelect` to manage row selection state
- Only rows that exist on the original `data` array will have a path in this array. Rows created by `useGroupBy`'s aggregations and grouping are not included in this array, since they do not reference an original data row.
- `flatRows: Array<Row>`
- An array of all rows, including subRows which have been flattened into the order in which they were detected (depth first)
- This can be helpful in calculating total row counts that must include subRows
@@ -0,0 +1,5 @@
{
"infiniteLoopProtection": false,
"hardReloadOnChange": false,
"view": "browser"
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "react-table",
"version": "7.0.0-beta.6",
"version": "7.0.0-beta.7",
"description": "A fast, lightweight, opinionated table and datagrid built on React",
"license": "MIT",
"homepage": "https://github.com/tannerlinsley/react-table#readme",
+13 -17
View File
@@ -137,12 +137,11 @@ export const useTable = (props, ...plugins) => {
})
// Access the row model
const [rows, rowPaths, flatRows] = React.useMemo(() => {
const [rows, flatRows] = React.useMemo(() => {
if (process.env.NODE_ENV === 'development' && debug)
console.time('getAccessedRows')
let flatRows = 0
const rowPaths = []
let flatRows = []
// Access the row's data
const accessRow = (originalRow, i, depth = 0, parentPath = []) => {
@@ -154,23 +153,21 @@ export const useTable = (props, ...plugins) => {
// Make the new path for the row
const path = [...parentPath, rowID]
flatRows++
rowPaths.push(path.join('.'))
const row = {
original,
index: i,
path, // used to create a key for each row even if not nested
depth,
cells: [{}], // This is a dummy cell
}
flatRows.push(row)
// Process any subRows
let subRows = getSubRows(originalRow, i)
if (subRows) {
subRows = subRows.map((d, i) => accessRow(d, i, depth + 1, path))
}
const row = {
original,
index: i,
path, // used to create a key for each row even if not nested
subRows,
depth,
cells: [{}], // This is a dummy cell
row.subRows = subRows.map((d, i) => accessRow(d, i, depth + 1, path))
}
// Override common array functions (and the dummy cell's getCellProps function)
@@ -200,11 +197,10 @@ export const useTable = (props, ...plugins) => {
const accessedData = data.map((d, i) => accessRow(d, i))
if (process.env.NODE_ENV === 'development' && debug)
console.timeEnd('getAccessedRows')
return [accessedData, rowPaths, flatRows]
return [accessedData, flatRows]
}, [debug, data, getRowID, getSubRows, flatColumns])
instanceRef.current.rows = rows
instanceRef.current.rowPaths = rowPaths
instanceRef.current.flatRows = flatRows
// Determine column visibility
+8 -1
View File
@@ -87,7 +87,14 @@ function useMain(instance) {
}
return rows
}, [debug, paginateExpandedRows, rows, manualExpandedKey, expanded])
}, [
debug,
paginateExpandedRows,
rows,
manualExpandedKey,
expanded,
expandSubRows,
])
const expandedDepth = findExpandedDepth(expanded)
+25 -4
View File
@@ -33,6 +33,7 @@ function useMain(instance) {
const {
debug,
rows,
flatRows,
flatColumns,
filterTypes: userFilterTypes,
manualFilters,
@@ -41,6 +42,7 @@ function useMain(instance) {
} = instance
const preFilteredRows = rows
const preFilteredFlatRows = flatRows
const setFilter = (id, updater) => {
const column = flatColumns.find(d => d.id === id)
@@ -129,11 +131,16 @@ function useMain(instance) {
// cache for each row group (top-level rows, and each row's recursive subrows)
// This would make multi-filtering a lot faster though. Too far?
const filteredRows = React.useMemo(() => {
const { filteredRows, filteredFlatRows } = React.useMemo(() => {
if (manualFilters || !Object.keys(filters).length) {
return rows
return {
filteredRows: rows,
filteredFlatRows: flatRows,
}
}
const filteredFlatRows = []
if (process.env.NODE_ENV === 'development' && debug)
console.info('getFilteredRows')
@@ -179,6 +186,7 @@ function useMain(instance) {
// but that would severely hinder the API for the user, since they
// would be required to do that recursion in some scenarios
filteredRows = filteredRows.map(row => {
filteredFlatRows.push(row)
if (!row.subRows) {
return row
}
@@ -194,8 +202,19 @@ function useMain(instance) {
return filteredRows
}
return filterRows(rows)
}, [manualFilters, filters, debug, rows, flatColumns, userFilterTypes])
return {
filteredRows: filterRows(rows),
filteredFlatRows,
}
}, [
manualFilters,
filters,
debug,
rows,
flatRows,
flatColumns,
userFilterTypes,
])
React.useMemo(() => {
// Now that each filtered column has it's partially filtered rows,
@@ -216,7 +235,9 @@ function useMain(instance) {
setFilter,
setAllFilters,
preFilteredRows,
preFilteredFlatRows,
rows: filteredRows,
flatRows: filteredFlatRows,
}
}
+1
View File
@@ -105,6 +105,7 @@ function useMain(instance) {
return expandRows(page, { manualExpandedKey, expanded, expandSubRows })
}, [
debug,
expandSubRows,
expanded,
manualExpandedKey,
manualPagination,
+18 -8
View File
@@ -27,7 +27,7 @@ function useMain(instance) {
hooks,
manualRowSelectedKey = 'isSelected',
plugins,
rowPaths,
flatRows,
state: [{ selectedRows }, setState],
} = instance
@@ -38,14 +38,22 @@ function useMain(instance) {
[]
)
const isAllRowsSelected = rowPaths.length > 0 && rowPaths.length === selectedRows.length
const flatRowPaths = flatRows.map(d => d.path.join('.'))
let isAllRowsSelected = !!flatRowPaths.length && !!selectedRows.length
if (isAllRowsSelected) {
if (flatRowPaths.some(d => !selectedRows.includes(d))) {
isAllRowsSelected = false
}
}
const toggleRowSelectedAll = set => {
setState(old => {
const selectAll = typeof set !== 'undefined' ? set : !isAllRowsSelected
return {
...old,
selectedRows: selectAll ? [...rowPaths] : [],
selectedRows: selectAll ? flatRowPaths : [],
}
}, actions.toggleRowSelectedAll)
}
@@ -54,12 +62,14 @@ function useMain(instance) {
const parentPath = path.slice(0, path.length - 1)
const parentKey = parentPath.join('.')
const selected =
rowPaths.filter(
path =>
flatRowPaths.filter(rowPath => {
const path = rowPath
return (
path !== parentKey &&
path.startsWith(parentKey) &&
!selectedRows.has(path)
).length === 0
)
}).length === 0
if (selected) {
selectedRows.add(parentKey)
} else {
@@ -81,13 +91,13 @@ function useMain(instance) {
let newSelectedRows = new Set(old.selectedRows)
if (!exists && shouldExist) {
rowPaths.forEach(rowPath => {
flatRowPaths.forEach(rowPath => {
if (rowPath === key || rowPath.startsWith(childRowPrefixKey)) {
newSelectedRows.add(rowPath)
}
})
} else if (exists && !shouldExist) {
rowPaths.forEach(rowPath => {
flatRowPaths.forEach(rowPath => {
if (rowPath === key || rowPath.startsWith(childRowPrefixKey)) {
newSelectedRows.delete(rowPath)
}
View File