From 4c549da552b90a027e36521694320f70d3386baa Mon Sep 17 00:00:00 2001 From: nchaudhary1 Date: Thu, 5 Feb 2026 14:14:05 +0530 Subject: [PATCH] fix(table-core): clear stale columnFiltersMeta in getFilteredRowModel --- .../src/utils/getFilteredRowModel.ts | 1 + .../tests/getFilteredRowModel.test.ts | 69 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 packages/table-core/tests/getFilteredRowModel.test.ts diff --git a/packages/table-core/src/utils/getFilteredRowModel.ts b/packages/table-core/src/utils/getFilteredRowModel.ts index 3d09f0af2e..c30e39b895 100644 --- a/packages/table-core/src/utils/getFilteredRowModel.ts +++ b/packages/table-core/src/utils/getFilteredRowModel.ts @@ -87,6 +87,7 @@ export function getFilteredRowModel(): ( const row = rowModel.flatRows[j]! row.columnFilters = {} + row.columnFiltersMeta = {} if (resolvedColumnFilters.length) { for (let i = 0; i < resolvedColumnFilters.length; i++) { diff --git a/packages/table-core/tests/getFilteredRowModel.test.ts b/packages/table-core/tests/getFilteredRowModel.test.ts new file mode 100644 index 0000000000..5c4b7ac658 --- /dev/null +++ b/packages/table-core/tests/getFilteredRowModel.test.ts @@ -0,0 +1,69 @@ +import { describe, expect, it } from 'vitest' +import { + createColumnHelper, + createTable, + functionalUpdate, + getCoreRowModel, + getFilteredRowModel, +} from '../src' + +type TestRow = { + a: string + b: string +} + +describe('#getFilteredRowModel', () => { + it('clears columnFiltersMeta between filter runs so removed filter meta does not persist', () => { + const data: TestRow[] = [ + { a: 'x', b: 'y' }, + { a: 'x', b: 'z' }, + ] + + const columnHelper = createColumnHelper() + const columns = [ + columnHelper.accessor('a', { + id: 'a', + filterFn: (row, columnId, filterValue, addMeta) => { + addMeta?.({ from: 'a' }) + return row.getValue(columnId) === filterValue + }, + }), + columnHelper.accessor('b', { + id: 'b', + filterFn: (row, columnId, filterValue) => { + return row.getValue(columnId) === filterValue + }, + }), + ] + + let state: any = { + columnFilters: [], + globalFilter: undefined, + } + + // Create a tiny state container so `table.setColumnFilters` updates `table.options.state` + let table: ReturnType> + table = createTable({ + data, + columns, + renderFallbackValue: '', + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), + state, + onStateChange: (updater) => { + state = functionalUpdate(updater, state) + table.setOptions((prev) => ({ ...prev, state })) + }, + }) + + table.setColumnFilters([{ id: 'a', value: 'x' }]) + const first = table.getFilteredRowModel().flatRows[0]! + expect(first.columnFiltersMeta.a).toEqual({ from: 'a' }) + + // Switch to a different filter that does not write meta + table.setColumnFilters([{ id: 'b', value: 'y' }]) + const second = table.getFilteredRowModel().flatRows[0]! + expect(second.columnFiltersMeta.a).toBeUndefined() + }) +}) +