Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/leaf-up-truncated-sub-rows.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/table-core': patch
---

Fix `filterFromLeafRows` discarding the sub-rows of rows kept past `maxLeafRowFilterDepth`. The leaf-up filter path rebuilt those rows without their unfiltered subtree, so the truncated descendants vanished from `subRows`, `flatRows` and `rowsById` alike. They are now carried over and flattened, the way the root-down path already keeps them.
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,20 @@ function filterRowModelFromLeafs<
continue
}
} else {
// Past maxLeafRowFilterDepth the subtree is never filtered, so it stays
// visible through row.subRows and its rows must enter flatRows and
// rowsById as well, like the root-down path already does
newRow.subRows = row.subRows
row = newRow
if (filterRow(row)) {
filteredRows.push(row)
newFilteredRowsById[row.id] = row
newFilteredFlatRows.push(row)
addSubRowsToFlatArrays(
row.subRows,
newFilteredFlatRows,
newFilteredRowsById,
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,55 @@ describe('createFilteredRowModel', () => {
expect(model.rowsById[keepA1.id]).toBe(keepA1)
})

it('should include unfiltered descendants of kept rows in flatRows and rowsById (from leaf, depth 0)', () => {
const table = makeNestedTable({
filterFromLeafRows: true,
maxLeafRowFilterDepth: 0,
})
const model = table.getFilteredRowModel()

// The subtrees of the kept rows are never filtered at depth 0, so they
// stay visible through subRows and belong in the flat arrays too, the
// same way the root-down path keeps them
const keepA = model.rows[0]!
expect(rowNames(keepA.subRows)).toEqual(['keep-a1', 'drop-a2'])
expect(rowNames(model.flatRows)).toEqual([
'keep-a',
'keep-a1',
'drop-a1a',
'drop-a2',
'keep-c',
'keep-d',
'drop-d1',
])

const keepA1 = keepA.subRows[0]!
expect(model.rowsById[keepA1.id]).toBe(keepA1)
})

it('should include kept-as-is grandchildren in flatRows when maxLeafRowFilterDepth is 1 (from leaf)', () => {
const table = makeNestedTable({
filterFromLeafRows: true,
maxLeafRowFilterDepth: 1,
})
const model = table.getFilteredRowModel()

// Depth-1 children are still filtered (drop-a2 removed), while the
// depth-2 subtree of keep-a1 is kept as-is and joins flatRows
const keepA = model.rows[0]!
expect(rowNames(keepA.subRows)).toEqual(['keep-a1'])
expect(rowNames(keepA.subRows[0]!.subRows)).toEqual(['drop-a1a'])
expect(rowNames(model.flatRows)).toEqual([
'keep-a1',
'drop-a1a',
'keep-a',
'keep-b1',
'drop-b',
'keep-c',
'keep-d',
])
})

it('should include kept-as-is grandchildren in flatRows when maxLeafRowFilterDepth is 1 (from root)', () => {
const table = makeNestedTable({ maxLeafRowFilterDepth: 1 })
const model = table.getFilteredRowModel()
Expand Down