diff --git a/.changeset/fix-should-auto-remove-filter.md b/.changeset/fix-should-auto-remove-filter.md new file mode 100644 index 0000000000..136bb1834b --- /dev/null +++ b/.changeset/fix-should-auto-remove-filter.md @@ -0,0 +1,5 @@ +--- +'@tanstack/table-core': patch +--- + +fix(table-core): respect custom `autoRemove` in `shouldAutoRemoveFilter` diff --git a/packages/table-core/src/features/ColumnFiltering.ts b/packages/table-core/src/features/ColumnFiltering.ts index 77b9927c04..6f93271b22 100644 --- a/packages/table-core/src/features/ColumnFiltering.ts +++ b/packages/table-core/src/features/ColumnFiltering.ts @@ -418,11 +418,9 @@ export function shouldAutoRemoveFilter( value?: any, column?: Column, ) { - return ( - (filterFn && filterFn.autoRemove - ? filterFn.autoRemove(value, column) - : false) || - typeof value === 'undefined' || - (typeof value === 'string' && !value) - ) + if (filterFn?.autoRemove) { + return filterFn.autoRemove(value, column) + } + + return typeof value === 'undefined' || (typeof value === 'string' && !value) } diff --git a/packages/table-core/tests/shouldAutoRemoveFilter.test.ts b/packages/table-core/tests/shouldAutoRemoveFilter.test.ts new file mode 100644 index 0000000000..5d6968c456 --- /dev/null +++ b/packages/table-core/tests/shouldAutoRemoveFilter.test.ts @@ -0,0 +1,73 @@ +import { describe, it, expect } from 'vitest' +import { FilterFn } from '../src' +import { shouldAutoRemoveFilter } from '../src/features/ColumnFiltering' + +const customAutoRemove: FilterFn = (row, columnId, filterValue) => { + return filterValue === row.getValue(columnId) +} +customAutoRemove.autoRemove = (val) => val === undefined + +const neverAutoRemove: FilterFn = (row, columnId, filterValue) => { + return filterValue === row.getValue(columnId) +} +neverAutoRemove.autoRemove = () => false + +const noAutoRemove: FilterFn = (row, columnId, filterValue) => { + return filterValue === row.getValue(columnId) +} + +describe('shouldAutoRemoveFilter', () => { + describe('with custom autoRemove defined', () => { + it('should use custom autoRemove result for empty string', () => { + expect(shouldAutoRemoveFilter(customAutoRemove, '')).toBe(false) + }) + + it('should use custom autoRemove result for undefined', () => { + expect(shouldAutoRemoveFilter(customAutoRemove, undefined)).toBe(true) + }) + + it('should use custom autoRemove result for null', () => { + expect(shouldAutoRemoveFilter(customAutoRemove, null)).toBe(false) + }) + + it('should use custom autoRemove result for zero', () => { + expect(shouldAutoRemoveFilter(customAutoRemove, 0)).toBe(false) + }) + + it('should use custom autoRemove result for false', () => { + expect(shouldAutoRemoveFilter(customAutoRemove, false)).toBe(false) + }) + + it('should keep undefined filter when custom autoRemove returns false for it', () => { + expect(shouldAutoRemoveFilter(neverAutoRemove, undefined)).toBe(false) + }) + }) + + describe('without autoRemove defined', () => { + it('should remove undefined filter', () => { + expect(shouldAutoRemoveFilter(noAutoRemove, undefined)).toBe(true) + }) + + it('should remove empty string filter', () => { + expect(shouldAutoRemoveFilter(noAutoRemove, '')).toBe(true) + }) + + it('should keep null filter', () => { + expect(shouldAutoRemoveFilter(noAutoRemove, null)).toBe(false) + }) + }) + + describe('without filterFn', () => { + it('should remove undefined filter', () => { + expect(shouldAutoRemoveFilter(undefined, undefined)).toBe(true) + }) + + it('should remove empty string filter', () => { + expect(shouldAutoRemoveFilter(undefined, '')).toBe(true) + }) + + it('should keep null filter', () => { + expect(shouldAutoRemoveFilter(undefined, null)).toBe(false) + }) + }) +})