@tanstack/table-core 9.0.0-alpha.47 → 9.0.0-alpha.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/core/cells/coreCellsFeature.utils.cjs +11 -8
- package/dist/core/cells/coreCellsFeature.utils.cjs.map +1 -1
- package/dist/core/cells/coreCellsFeature.utils.d.cts +11 -8
- package/dist/core/cells/coreCellsFeature.utils.d.ts +11 -8
- package/dist/core/cells/coreCellsFeature.utils.js +11 -8
- package/dist/core/cells/coreCellsFeature.utils.js.map +1 -1
- package/dist/core/columns/coreColumnsFeature.types.d.cts +7 -6
- package/dist/core/columns/coreColumnsFeature.types.d.ts +7 -6
- package/dist/core/columns/coreColumnsFeature.utils.cjs +37 -27
- package/dist/core/columns/coreColumnsFeature.utils.cjs.map +1 -1
- package/dist/core/columns/coreColumnsFeature.utils.d.cts +37 -27
- package/dist/core/columns/coreColumnsFeature.utils.d.ts +37 -27
- package/dist/core/columns/coreColumnsFeature.utils.js +37 -27
- package/dist/core/columns/coreColumnsFeature.utils.js.map +1 -1
- package/dist/core/headers/coreHeadersFeature.types.d.cts +6 -4
- package/dist/core/headers/coreHeadersFeature.types.d.ts +6 -4
- package/dist/core/headers/coreHeadersFeature.utils.cjs +23 -18
- package/dist/core/headers/coreHeadersFeature.utils.cjs.map +1 -1
- package/dist/core/headers/coreHeadersFeature.utils.d.cts +23 -18
- package/dist/core/headers/coreHeadersFeature.utils.d.ts +23 -18
- package/dist/core/headers/coreHeadersFeature.utils.js +23 -18
- package/dist/core/headers/coreHeadersFeature.utils.js.map +1 -1
- package/dist/core/row-models/coreRowModelsFeature.utils.cjs +48 -36
- package/dist/core/row-models/coreRowModelsFeature.utils.cjs.map +1 -1
- package/dist/core/row-models/coreRowModelsFeature.utils.d.cts +48 -36
- package/dist/core/row-models/coreRowModelsFeature.utils.d.ts +48 -36
- package/dist/core/row-models/coreRowModelsFeature.utils.js +48 -36
- package/dist/core/row-models/coreRowModelsFeature.utils.js.map +1 -1
- package/dist/core/rows/coreRowsFeature.types.d.cts +4 -4
- package/dist/core/rows/coreRowsFeature.types.d.ts +4 -4
- package/dist/core/rows/coreRowsFeature.utils.cjs +34 -28
- package/dist/core/rows/coreRowsFeature.utils.cjs.map +1 -1
- package/dist/core/rows/coreRowsFeature.utils.d.cts +34 -28
- package/dist/core/rows/coreRowsFeature.utils.d.ts +34 -28
- package/dist/core/rows/coreRowsFeature.utils.js +34 -28
- package/dist/core/rows/coreRowsFeature.utils.js.map +1 -1
- package/dist/core/table/coreTablesFeature.types.d.cts +6 -2
- package/dist/core/table/coreTablesFeature.types.d.ts +6 -2
- package/dist/core/table/coreTablesFeature.utils.cjs +2 -2
- package/dist/core/table/coreTablesFeature.utils.cjs.map +1 -1
- package/dist/core/table/coreTablesFeature.utils.d.cts +2 -2
- package/dist/core/table/coreTablesFeature.utils.d.ts +2 -2
- package/dist/core/table/coreTablesFeature.utils.js +2 -2
- package/dist/core/table/coreTablesFeature.utils.js.map +1 -1
- package/dist/features/column-faceting/columnFacetingFeature.types.d.cts +16 -10
- package/dist/features/column-faceting/columnFacetingFeature.types.d.ts +16 -10
- package/dist/features/column-faceting/columnFacetingFeature.utils.cjs +26 -18
- package/dist/features/column-faceting/columnFacetingFeature.utils.cjs.map +1 -1
- package/dist/features/column-faceting/columnFacetingFeature.utils.d.cts +26 -18
- package/dist/features/column-faceting/columnFacetingFeature.utils.d.ts +26 -18
- package/dist/features/column-faceting/columnFacetingFeature.utils.js +26 -18
- package/dist/features/column-faceting/columnFacetingFeature.utils.js.map +1 -1
- package/dist/features/column-filtering/columnFilteringFeature.types.d.cts +21 -11
- package/dist/features/column-filtering/columnFilteringFeature.types.d.ts +21 -11
- package/dist/features/column-filtering/columnFilteringFeature.utils.cjs +39 -28
- package/dist/features/column-filtering/columnFilteringFeature.utils.cjs.map +1 -1
- package/dist/features/column-filtering/columnFilteringFeature.utils.d.cts +39 -28
- package/dist/features/column-filtering/columnFilteringFeature.utils.d.ts +39 -28
- package/dist/features/column-filtering/columnFilteringFeature.utils.js +39 -28
- package/dist/features/column-filtering/columnFilteringFeature.utils.js.map +1 -1
- package/dist/features/column-grouping/columnGroupingFeature.types.d.cts +18 -14
- package/dist/features/column-grouping/columnGroupingFeature.types.d.ts +18 -14
- package/dist/features/column-grouping/columnGroupingFeature.utils.cjs +55 -43
- package/dist/features/column-grouping/columnGroupingFeature.utils.cjs.map +1 -1
- package/dist/features/column-grouping/columnGroupingFeature.utils.d.cts +55 -43
- package/dist/features/column-grouping/columnGroupingFeature.utils.d.ts +55 -43
- package/dist/features/column-grouping/columnGroupingFeature.utils.js +55 -43
- package/dist/features/column-grouping/columnGroupingFeature.utils.js.map +1 -1
- package/dist/features/column-ordering/columnOrderingFeature.types.d.cts +14 -5
- package/dist/features/column-ordering/columnOrderingFeature.types.d.ts +14 -5
- package/dist/features/column-ordering/columnOrderingFeature.utils.cjs +30 -23
- package/dist/features/column-ordering/columnOrderingFeature.utils.cjs.map +1 -1
- package/dist/features/column-ordering/columnOrderingFeature.utils.d.cts +30 -23
- package/dist/features/column-ordering/columnOrderingFeature.utils.d.ts +30 -23
- package/dist/features/column-ordering/columnOrderingFeature.utils.js +30 -23
- package/dist/features/column-ordering/columnOrderingFeature.utils.js.map +1 -1
- package/dist/features/column-pinning/columnPinningFeature.types.d.cts +43 -31
- package/dist/features/column-pinning/columnPinningFeature.types.d.ts +43 -31
- package/dist/features/column-pinning/columnPinningFeature.utils.cjs +111 -91
- package/dist/features/column-pinning/columnPinningFeature.utils.cjs.map +1 -1
- package/dist/features/column-pinning/columnPinningFeature.utils.d.cts +111 -91
- package/dist/features/column-pinning/columnPinningFeature.utils.d.ts +111 -91
- package/dist/features/column-pinning/columnPinningFeature.utils.js +111 -91
- package/dist/features/column-pinning/columnPinningFeature.utils.js.map +1 -1
- package/dist/features/column-resizing/columnResizingFeature.types.d.cts +9 -9
- package/dist/features/column-resizing/columnResizingFeature.types.d.ts +9 -9
- package/dist/features/column-resizing/columnResizingFeature.utils.cjs +29 -20
- package/dist/features/column-resizing/columnResizingFeature.utils.cjs.map +1 -1
- package/dist/features/column-resizing/columnResizingFeature.utils.d.cts +28 -19
- package/dist/features/column-resizing/columnResizingFeature.utils.d.ts +28 -19
- package/dist/features/column-resizing/columnResizingFeature.utils.js +29 -20
- package/dist/features/column-resizing/columnResizingFeature.utils.js.map +1 -1
- package/dist/features/column-sizing/columnSizingFeature.types.d.cts +19 -12
- package/dist/features/column-sizing/columnSizingFeature.types.d.ts +19 -12
- package/dist/features/column-sizing/columnSizingFeature.utils.cjs +52 -41
- package/dist/features/column-sizing/columnSizingFeature.utils.cjs.map +1 -1
- package/dist/features/column-sizing/columnSizingFeature.utils.d.cts +52 -41
- package/dist/features/column-sizing/columnSizingFeature.utils.d.ts +52 -41
- package/dist/features/column-sizing/columnSizingFeature.utils.js +52 -41
- package/dist/features/column-sizing/columnSizingFeature.utils.js.map +1 -1
- package/dist/features/column-visibility/columnVisibilityFeature.types.d.cts +16 -13
- package/dist/features/column-visibility/columnVisibilityFeature.types.d.ts +16 -13
- package/dist/features/column-visibility/columnVisibilityFeature.utils.cjs +54 -42
- package/dist/features/column-visibility/columnVisibilityFeature.utils.cjs.map +1 -1
- package/dist/features/column-visibility/columnVisibilityFeature.utils.d.cts +54 -42
- package/dist/features/column-visibility/columnVisibilityFeature.utils.d.ts +54 -42
- package/dist/features/column-visibility/columnVisibilityFeature.utils.js +54 -42
- package/dist/features/column-visibility/columnVisibilityFeature.utils.js.map +1 -1
- package/dist/features/global-filtering/globalFilteringFeature.types.d.cts +10 -5
- package/dist/features/global-filtering/globalFilteringFeature.types.d.ts +10 -5
- package/dist/features/global-filtering/globalFilteringFeature.utils.cjs +20 -14
- package/dist/features/global-filtering/globalFilteringFeature.utils.cjs.map +1 -1
- package/dist/features/global-filtering/globalFilteringFeature.utils.d.cts +20 -14
- package/dist/features/global-filtering/globalFilteringFeature.utils.d.ts +20 -14
- package/dist/features/global-filtering/globalFilteringFeature.utils.js +20 -14
- package/dist/features/global-filtering/globalFilteringFeature.utils.js.map +1 -1
- package/dist/features/row-expanding/rowExpandingFeature.types.d.cts +16 -15
- package/dist/features/row-expanding/rowExpandingFeature.types.d.ts +16 -15
- package/dist/features/row-expanding/rowExpandingFeature.utils.cjs +56 -41
- package/dist/features/row-expanding/rowExpandingFeature.utils.cjs.map +1 -1
- package/dist/features/row-expanding/rowExpandingFeature.utils.d.cts +56 -41
- package/dist/features/row-expanding/rowExpandingFeature.utils.d.ts +56 -41
- package/dist/features/row-expanding/rowExpandingFeature.utils.js +56 -41
- package/dist/features/row-expanding/rowExpandingFeature.utils.js.map +1 -1
- package/dist/features/row-pagination/rowPaginationFeature.types.d.cts +19 -12
- package/dist/features/row-pagination/rowPaginationFeature.types.d.ts +19 -12
- package/dist/features/row-pagination/rowPaginationFeature.utils.cjs +49 -32
- package/dist/features/row-pagination/rowPaginationFeature.utils.cjs.map +1 -1
- package/dist/features/row-pagination/rowPaginationFeature.utils.d.cts +49 -32
- package/dist/features/row-pagination/rowPaginationFeature.utils.d.ts +49 -32
- package/dist/features/row-pagination/rowPaginationFeature.utils.js +49 -32
- package/dist/features/row-pagination/rowPaginationFeature.utils.js.map +1 -1
- package/dist/features/row-pinning/rowPinningFeature.types.d.cts +12 -8
- package/dist/features/row-pinning/rowPinningFeature.types.d.ts +12 -8
- package/dist/features/row-pinning/rowPinningFeature.utils.cjs +39 -29
- package/dist/features/row-pinning/rowPinningFeature.utils.cjs.map +1 -1
- package/dist/features/row-pinning/rowPinningFeature.utils.d.cts +39 -29
- package/dist/features/row-pinning/rowPinningFeature.utils.d.ts +39 -29
- package/dist/features/row-pinning/rowPinningFeature.utils.js +39 -29
- package/dist/features/row-pinning/rowPinningFeature.utils.js.map +1 -1
- package/dist/features/row-selection/rowSelectionFeature.types.d.cts +30 -24
- package/dist/features/row-selection/rowSelectionFeature.types.d.ts +30 -24
- package/dist/features/row-selection/rowSelectionFeature.utils.cjs +89 -69
- package/dist/features/row-selection/rowSelectionFeature.utils.cjs.map +1 -1
- package/dist/features/row-selection/rowSelectionFeature.utils.d.cts +89 -69
- package/dist/features/row-selection/rowSelectionFeature.utils.d.ts +89 -69
- package/dist/features/row-selection/rowSelectionFeature.utils.js +89 -69
- package/dist/features/row-selection/rowSelectionFeature.utils.js.map +1 -1
- package/dist/features/row-sorting/rowSortingFeature.types.d.cts +10 -8
- package/dist/features/row-sorting/rowSortingFeature.types.d.ts +10 -8
- package/dist/features/row-sorting/rowSortingFeature.utils.cjs +62 -45
- package/dist/features/row-sorting/rowSortingFeature.utils.cjs.map +1 -1
- package/dist/features/row-sorting/rowSortingFeature.utils.d.cts +61 -44
- package/dist/features/row-sorting/rowSortingFeature.utils.d.ts +61 -44
- package/dist/features/row-sorting/rowSortingFeature.utils.js +62 -45
- package/dist/features/row-sorting/rowSortingFeature.utils.js.map +1 -1
- package/dist/fns/aggregationFns.cjs +33 -9
- package/dist/fns/aggregationFns.cjs.map +1 -1
- package/dist/fns/aggregationFns.d.cts +33 -9
- package/dist/fns/aggregationFns.d.ts +33 -9
- package/dist/fns/aggregationFns.js +33 -9
- package/dist/fns/aggregationFns.js.map +1 -1
- package/dist/fns/filterFns.cjs +48 -17
- package/dist/fns/filterFns.cjs.map +1 -1
- package/dist/fns/filterFns.d.cts +42 -15
- package/dist/fns/filterFns.d.ts +42 -15
- package/dist/fns/filterFns.js +48 -17
- package/dist/fns/filterFns.js.map +1 -1
- package/dist/helpers/columnHelper.cjs +9 -4
- package/dist/helpers/columnHelper.cjs.map +1 -1
- package/dist/helpers/columnHelper.d.cts +9 -4
- package/dist/helpers/columnHelper.d.ts +9 -4
- package/dist/helpers/columnHelper.js +9 -4
- package/dist/helpers/columnHelper.js.map +1 -1
- package/dist/helpers/tableOptions.cjs.map +1 -1
- package/dist/helpers/tableOptions.d.cts +12 -9
- package/dist/helpers/tableOptions.d.ts +12 -9
- package/dist/helpers/tableOptions.js.map +1 -1
- package/dist/types/ColumnDef.d.cts +38 -0
- package/dist/types/ColumnDef.d.ts +38 -0
- package/dist/types/TableOptions.d.cts +15 -0
- package/dist/types/TableOptions.d.ts +15 -0
- package/dist/types/TableState.d.cts +12 -0
- package/dist/types/TableState.d.ts +12 -0
- package/package.json +5 -3
- package/skills/column-definitions/SKILL.md +333 -0
- package/skills/column-layout/SKILL.md +328 -0
- package/skills/column-layout/references/subsystems.md +220 -0
- package/skills/customizing-feature-behavior/SKILL.md +416 -0
- package/skills/filtering/SKILL.md +357 -0
- package/skills/filtering/references/faceting-and-fuzzy.md +191 -0
- package/skills/grouping/SKILL.md +448 -0
- package/skills/migrate-v8-to-v9/SKILL.md +495 -0
- package/skills/pagination/SKILL.md +385 -0
- package/skills/row-expanding/SKILL.md +348 -0
- package/skills/row-pinning/SKILL.md +269 -0
- package/skills/row-selection/SKILL.md +391 -0
- package/skills/setup/SKILL.md +400 -0
- package/skills/sorting/SKILL.md +344 -0
- package/skills/state-management/SKILL.md +388 -0
- package/src/core/cells/coreCellsFeature.utils.ts +11 -8
- package/src/core/columns/coreColumnsFeature.types.ts +7 -6
- package/src/core/columns/coreColumnsFeature.utils.ts +37 -27
- package/src/core/headers/coreHeadersFeature.types.ts +6 -4
- package/src/core/headers/coreHeadersFeature.utils.ts +23 -18
- package/src/core/row-models/coreRowModelsFeature.utils.ts +48 -36
- package/src/core/rows/coreRowsFeature.types.ts +4 -4
- package/src/core/rows/coreRowsFeature.utils.ts +34 -28
- package/src/core/table/coreTablesFeature.types.ts +6 -2
- package/src/core/table/coreTablesFeature.utils.ts +2 -2
- package/src/features/column-faceting/columnFacetingFeature.types.ts +16 -10
- package/src/features/column-faceting/columnFacetingFeature.utils.ts +26 -18
- package/src/features/column-filtering/columnFilteringFeature.types.ts +21 -11
- package/src/features/column-filtering/columnFilteringFeature.utils.ts +39 -28
- package/src/features/column-grouping/columnGroupingFeature.types.ts +18 -14
- package/src/features/column-grouping/columnGroupingFeature.utils.ts +55 -43
- package/src/features/column-ordering/columnOrderingFeature.types.ts +14 -5
- package/src/features/column-ordering/columnOrderingFeature.utils.ts +30 -23
- package/src/features/column-pinning/columnPinningFeature.types.ts +43 -31
- package/src/features/column-pinning/columnPinningFeature.utils.ts +111 -91
- package/src/features/column-resizing/columnResizingFeature.types.ts +9 -9
- package/src/features/column-resizing/columnResizingFeature.utils.ts +29 -21
- package/src/features/column-sizing/columnSizingFeature.types.ts +19 -12
- package/src/features/column-sizing/columnSizingFeature.utils.ts +52 -41
- package/src/features/column-visibility/columnVisibilityFeature.types.ts +16 -13
- package/src/features/column-visibility/columnVisibilityFeature.utils.ts +54 -42
- package/src/features/global-filtering/globalFilteringFeature.types.ts +10 -5
- package/src/features/global-filtering/globalFilteringFeature.utils.ts +20 -14
- package/src/features/row-expanding/rowExpandingFeature.types.ts +16 -15
- package/src/features/row-expanding/rowExpandingFeature.utils.ts +56 -41
- package/src/features/row-pagination/rowPaginationFeature.types.ts +19 -12
- package/src/features/row-pagination/rowPaginationFeature.utils.ts +49 -32
- package/src/features/row-pinning/rowPinningFeature.types.ts +12 -8
- package/src/features/row-pinning/rowPinningFeature.utils.ts +39 -29
- package/src/features/row-selection/rowSelectionFeature.types.ts +30 -24
- package/src/features/row-selection/rowSelectionFeature.utils.ts +89 -69
- package/src/features/row-sorting/rowSortingFeature.types.ts +10 -8
- package/src/features/row-sorting/rowSortingFeature.utils.ts +62 -45
- package/src/fns/aggregationFns.ts +33 -9
- package/src/fns/filterFns.ts +48 -17
- package/src/helpers/columnHelper.ts +9 -4
- package/src/helpers/tableOptions.ts +12 -9
- package/src/types/ColumnDef.ts +38 -0
- package/src/types/TableOptions.ts +15 -0
- package/src/types/TableState.ts +12 -0
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: filtering
|
|
3
|
+
description: >
|
|
4
|
+
Filter rows in TanStack Table v9 with the `filteredRowModel` pipeline stage.
|
|
5
|
+
Covers `columnFilteringFeature` + `globalFilteringFeature` + `columnFacetingFeature`,
|
|
6
|
+
`createFilteredRowModel(filterFns)`, `createFacetedRowModel()` /
|
|
7
|
+
`createFacetedUniqueValues()` / `createFacetedMinMaxValues()`, fuzzy filtering
|
|
8
|
+
with `@tanstack/match-sorter-utils`, the built-in `filterFns` registry, custom
|
|
9
|
+
`filterFn` + module augmentation, `state.columnFilters` (Array<{ id, value }>),
|
|
10
|
+
`state.globalFilter`, `column.setFilterValue` / `setColumnFilters` /
|
|
11
|
+
`setGlobalFilter`, `column.getFacetedUniqueValues` /
|
|
12
|
+
`column.getFacetedMinMaxValues`, `manualFiltering`, `filterFromLeafRows`,
|
|
13
|
+
`maxLeafRowFilterDepth`, `getColumnCanGlobalFilter`. Five subsystems:
|
|
14
|
+
column-filtering, global-filtering, column-faceting, global-faceting,
|
|
15
|
+
fuzzy-filtering.
|
|
16
|
+
type: core
|
|
17
|
+
library: tanstack-table
|
|
18
|
+
library_version: '9.0.0-alpha.48'
|
|
19
|
+
requires:
|
|
20
|
+
- state-management
|
|
21
|
+
- customizing-feature-behavior
|
|
22
|
+
sources:
|
|
23
|
+
- TanStack/table:docs/guide/column-filtering.md
|
|
24
|
+
- TanStack/table:docs/guide/global-filtering.md
|
|
25
|
+
- TanStack/table:docs/guide/column-faceting.md
|
|
26
|
+
- TanStack/table:docs/guide/global-faceting.md
|
|
27
|
+
- TanStack/table:docs/guide/fuzzy-filtering.md
|
|
28
|
+
- TanStack/table:examples/react/filters/src/main.tsx
|
|
29
|
+
- TanStack/table:examples/react/filters-faceted/src/main.tsx
|
|
30
|
+
- TanStack/table:examples/react/filters-fuzzy/src/main.tsx
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
This skill builds on `tanstack-table/state-management` and `tanstack-table/customizing-feature-behavior`. Read those first for the atom model and `filterFn`/`globalFilterFn` overrides.
|
|
34
|
+
|
|
35
|
+
## Setup
|
|
36
|
+
|
|
37
|
+
Filtering has five subsystems in v9 — register only the features you need:
|
|
38
|
+
|
|
39
|
+
| Subsystem | Feature | Row-model |
|
|
40
|
+
| ---------------- | ------------------------ | ----------------------------------- |
|
|
41
|
+
| column-filtering | `columnFilteringFeature` | `createFilteredRowModel(filterFns)` |
|
|
42
|
+
| global-filtering | `globalFilteringFeature` | (same `filteredRowModel`) |
|
|
43
|
+
| column-faceting | `columnFacetingFeature` | `createFacetedRowModel()` + helpers |
|
|
44
|
+
| global-faceting | `globalFacetingFeature` | global versions of the helpers |
|
|
45
|
+
| fuzzy-filtering | (custom filterFn) | `@tanstack/match-sorter-utils` |
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import {
|
|
49
|
+
tableFeatures,
|
|
50
|
+
columnFilteringFeature,
|
|
51
|
+
globalFilteringFeature,
|
|
52
|
+
rowPaginationFeature,
|
|
53
|
+
createFilteredRowModel,
|
|
54
|
+
createPaginatedRowModel,
|
|
55
|
+
filterFns,
|
|
56
|
+
} from '@tanstack/table-core'
|
|
57
|
+
import type { ColumnFiltersState } from '@tanstack/table-core'
|
|
58
|
+
|
|
59
|
+
const _features = tableFeatures({
|
|
60
|
+
columnFilteringFeature,
|
|
61
|
+
globalFilteringFeature,
|
|
62
|
+
rowPaginationFeature,
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
const table = constructTable({
|
|
66
|
+
_features,
|
|
67
|
+
_rowModels: {
|
|
68
|
+
filteredRowModel: createFilteredRowModel(filterFns),
|
|
69
|
+
paginatedRowModel: createPaginatedRowModel(),
|
|
70
|
+
},
|
|
71
|
+
columns,
|
|
72
|
+
data,
|
|
73
|
+
initialState: {
|
|
74
|
+
columnFilters: [] satisfies ColumnFiltersState,
|
|
75
|
+
globalFilter: '',
|
|
76
|
+
},
|
|
77
|
+
globalFilterFn: 'includesString',
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
table.setColumnFilters([{ id: 'firstName', value: 'Ada' }])
|
|
81
|
+
table.setGlobalFilter('Lovelace')
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Core Patterns
|
|
85
|
+
|
|
86
|
+
### Text / range / select column filters
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
// From examples/react/filters/src/main.tsx
|
|
90
|
+
function Filter({ column }) {
|
|
91
|
+
const firstValue = column
|
|
92
|
+
.getFacetedRowModel()
|
|
93
|
+
.flatRows[0]?.getValue(column.id)
|
|
94
|
+
const columnFilterValue = column.getFilterValue()
|
|
95
|
+
|
|
96
|
+
return typeof firstValue === 'number' ? (
|
|
97
|
+
<div>
|
|
98
|
+
<input
|
|
99
|
+
type="number"
|
|
100
|
+
value={(columnFilterValue as [number, number])?.[0] ?? ''}
|
|
101
|
+
onChange={(e) =>
|
|
102
|
+
column.setFilterValue((old: [number, number]) => [
|
|
103
|
+
e.target.value,
|
|
104
|
+
old?.[1],
|
|
105
|
+
])
|
|
106
|
+
}
|
|
107
|
+
placeholder="Min"
|
|
108
|
+
/>
|
|
109
|
+
<input
|
|
110
|
+
type="number"
|
|
111
|
+
value={(columnFilterValue as [number, number])?.[1] ?? ''}
|
|
112
|
+
onChange={(e) =>
|
|
113
|
+
column.setFilterValue((old: [number, number]) => [
|
|
114
|
+
old?.[0],
|
|
115
|
+
e.target.value,
|
|
116
|
+
])
|
|
117
|
+
}
|
|
118
|
+
placeholder="Max"
|
|
119
|
+
/>
|
|
120
|
+
</div>
|
|
121
|
+
) : (
|
|
122
|
+
<input
|
|
123
|
+
value={(columnFilterValue ?? '') as string}
|
|
124
|
+
onChange={(e) => column.setFilterValue(e.target.value)}
|
|
125
|
+
placeholder="Search…"
|
|
126
|
+
/>
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Faceted filter UIs and fuzzy global search
|
|
132
|
+
|
|
133
|
+
Faceting requires `createFacetedRowModel()` as the base plus `createFacetedUniqueValues()` / `createFacetedMinMaxValues()`; fuzzy filtering wires a custom `FilterFn` backed by `@tanstack/match-sorter-utils` (`rankItem` / `compareItems`) with module augmentation for `FilterFns` + `FilterMeta`. Full examples in [faceting-and-fuzzy.md](references/faceting-and-fuzzy.md).
|
|
134
|
+
|
|
135
|
+
### Server-side filtering
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
|
|
139
|
+
const { data } = useQuery({
|
|
140
|
+
queryKey: ['rows', columnFilters],
|
|
141
|
+
queryFn: () =>
|
|
142
|
+
fetch('/api/rows?' + serialize(columnFilters)).then((r) => r.json()),
|
|
143
|
+
})
|
|
144
|
+
const table = useTable({
|
|
145
|
+
_features: tableFeatures({ columnFilteringFeature }),
|
|
146
|
+
_rowModels: {}, // no filteredRowModel needed for manual filtering
|
|
147
|
+
data,
|
|
148
|
+
columns,
|
|
149
|
+
manualFiltering: true,
|
|
150
|
+
state: { columnFilters },
|
|
151
|
+
onColumnFiltersChange: setColumnFilters,
|
|
152
|
+
})
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Filter tree data and keep matching descendants visible
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
const table = constructTable({
|
|
159
|
+
_features: tableFeatures({ columnFilteringFeature, rowExpandingFeature }),
|
|
160
|
+
_rowModels: {
|
|
161
|
+
filteredRowModel: createFilteredRowModel(filterFns),
|
|
162
|
+
expandedRowModel: createExpandedRowModel(),
|
|
163
|
+
},
|
|
164
|
+
columns,
|
|
165
|
+
data,
|
|
166
|
+
getSubRows: (r) => r.subRows,
|
|
167
|
+
filterFromLeafRows: true, // bottom-up: keep parent if any descendant matches
|
|
168
|
+
})
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Common Mistakes
|
|
172
|
+
|
|
173
|
+
### [HIGH] Forgetting `createFacetedRowModel()` while registering `createFacetedUniqueValues()` / `createFacetedMinMaxValues()`
|
|
174
|
+
|
|
175
|
+
Wrong:
|
|
176
|
+
|
|
177
|
+
```tsx
|
|
178
|
+
const table = useTable({
|
|
179
|
+
_features: tableFeatures({ columnFacetingFeature, columnFilteringFeature }),
|
|
180
|
+
_rowModels: {
|
|
181
|
+
filteredRowModel: createFilteredRowModel(filterFns),
|
|
182
|
+
// BUG: missing facetedRowModel
|
|
183
|
+
facetedUniqueValues: createFacetedUniqueValues(),
|
|
184
|
+
facetedMinMaxValues: createFacetedMinMaxValues(),
|
|
185
|
+
},
|
|
186
|
+
columns,
|
|
187
|
+
data,
|
|
188
|
+
})
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Correct:
|
|
192
|
+
|
|
193
|
+
```tsx
|
|
194
|
+
const table = useTable({
|
|
195
|
+
_features: tableFeatures({
|
|
196
|
+
columnFacetingFeature,
|
|
197
|
+
columnFilteringFeature,
|
|
198
|
+
rowPaginationFeature,
|
|
199
|
+
}),
|
|
200
|
+
_rowModels: {
|
|
201
|
+
filteredRowModel: createFilteredRowModel(filterFns),
|
|
202
|
+
paginatedRowModel: createPaginatedRowModel(),
|
|
203
|
+
facetedRowModel: createFacetedRowModel(), // REQUIRED base
|
|
204
|
+
facetedMinMaxValues: createFacetedMinMaxValues(),
|
|
205
|
+
facetedUniqueValues: createFacetedUniqueValues(),
|
|
206
|
+
},
|
|
207
|
+
columns,
|
|
208
|
+
data,
|
|
209
|
+
})
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Without the base `facetedRowModel`, the unique/minMax helpers fall back to `getPreFilteredRowModel()` — facet values stop excluding the column's own active filter, and a select dropdown collapses to only the currently selected value once the user picks one.
|
|
213
|
+
|
|
214
|
+
Source: packages/table-core/src/features/column-faceting/columnFacetingFeature.utils.ts; examples/react/filters-faceted/src/main.tsx
|
|
215
|
+
|
|
216
|
+
### [HIGH] Setting `manualFiltering: true` without refetching data
|
|
217
|
+
|
|
218
|
+
Wrong:
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
// manualFiltering bypasses the filteredRowModel — filter UI changes do nothing
|
|
222
|
+
const table = useTable({
|
|
223
|
+
_features: tableFeatures({ columnFilteringFeature }),
|
|
224
|
+
_rowModels: { filteredRowModel: createFilteredRowModel(filterFns) },
|
|
225
|
+
data,
|
|
226
|
+
columns,
|
|
227
|
+
manualFiltering: true,
|
|
228
|
+
// ...but no useEffect / useQuery key tracking columnFilters
|
|
229
|
+
})
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Correct:
|
|
233
|
+
|
|
234
|
+
```tsx
|
|
235
|
+
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
|
|
236
|
+
const { data } = useQuery({
|
|
237
|
+
queryKey: ['rows', columnFilters],
|
|
238
|
+
queryFn: () =>
|
|
239
|
+
fetch('/api/rows?' + serialize(columnFilters)).then((r) => r.json()),
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
const table = useTable({
|
|
243
|
+
_features: tableFeatures({ columnFilteringFeature }),
|
|
244
|
+
_rowModels: {}, // no filteredRowModel needed
|
|
245
|
+
data,
|
|
246
|
+
columns,
|
|
247
|
+
manualFiltering: true,
|
|
248
|
+
state: { columnFilters },
|
|
249
|
+
onColumnFiltersChange: setColumnFilters,
|
|
250
|
+
})
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
With `manualFiltering: true`, `table_getFilteredRowModel` short-circuits and returns the core rows. Rows are NOT filtered client-side — you must refetch.
|
|
254
|
+
|
|
255
|
+
Source: docs/guide/column-filtering.md; packages/table-core/src/core/row-models/coreRowModelsFeature.utils.ts
|
|
256
|
+
|
|
257
|
+
### [HIGH] Custom fuzzy filter without merging into `filterFns`
|
|
258
|
+
|
|
259
|
+
Wrong:
|
|
260
|
+
|
|
261
|
+
```tsx
|
|
262
|
+
// drops the built-in registry
|
|
263
|
+
filteredRowModel: createFilteredRowModel({
|
|
264
|
+
fuzzy: fuzzyFilter,
|
|
265
|
+
}),
|
|
266
|
+
// Column with filterFn: 'includesString' now warns and never filters
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Correct:
|
|
270
|
+
|
|
271
|
+
```tsx
|
|
272
|
+
import { filterFns } from '@tanstack/react-table'
|
|
273
|
+
|
|
274
|
+
filteredRowModel: createFilteredRowModel({
|
|
275
|
+
...filterFns, // KEEP built-ins
|
|
276
|
+
fuzzy: fuzzyFilter, // ADD custom
|
|
277
|
+
}),
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
`createFilteredRowModel` replaces the registry with whatever you pass. Any column using a built-in name like `'includesString'` becomes a no-op.
|
|
281
|
+
|
|
282
|
+
Source: examples/react/filters-fuzzy/src/main.tsx
|
|
283
|
+
|
|
284
|
+
### [MEDIUM] Global filter silently skips columns with non-string/non-number values
|
|
285
|
+
|
|
286
|
+
Wrong:
|
|
287
|
+
|
|
288
|
+
```tsx
|
|
289
|
+
// createdAt is a Date object — global filter silently skips it
|
|
290
|
+
const columns = [
|
|
291
|
+
columnHelper.accessor('createdAt', { header: 'Created' }),
|
|
292
|
+
columnHelper.accessor('name', { header: 'Name' }),
|
|
293
|
+
]
|
|
294
|
+
// table.setGlobalFilter('2024') will never find Date rows
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Correct:
|
|
298
|
+
|
|
299
|
+
```tsx
|
|
300
|
+
const table = useTable({
|
|
301
|
+
_features: tableFeatures({ globalFilteringFeature }),
|
|
302
|
+
_rowModels: { filteredRowModel: createFilteredRowModel(filterFns) },
|
|
303
|
+
columns,
|
|
304
|
+
data,
|
|
305
|
+
globalFilterFn: 'includesString',
|
|
306
|
+
getColumnCanGlobalFilter: (column) => true, // include every column
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
// Or per-column:
|
|
310
|
+
columnHelper.accessor('createdAt', {
|
|
311
|
+
header: 'Created',
|
|
312
|
+
enableGlobalFilter: true,
|
|
313
|
+
})
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
`globalFilteringFeature` defaults `getColumnCanGlobalFilter` to a function that returns `typeof value === 'string' || typeof value === 'number'` sampled from the first row. Objects, dates, booleans, undefined all silently fail.
|
|
317
|
+
|
|
318
|
+
Source: packages/table-core/src/features/global-filtering/globalFilteringFeature.ts
|
|
319
|
+
|
|
320
|
+
### [CRITICAL] Reimplementing what built-in APIs provide
|
|
321
|
+
|
|
322
|
+
Wrong:
|
|
323
|
+
|
|
324
|
+
```ts
|
|
325
|
+
// Hand-rolled filter loop, bypassing the table
|
|
326
|
+
const filteredData = useMemo(
|
|
327
|
+
() => data.filter(/* …custom matching… */),
|
|
328
|
+
[data, query],
|
|
329
|
+
)
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Correct:
|
|
333
|
+
|
|
334
|
+
```ts
|
|
335
|
+
const table = useTable({
|
|
336
|
+
_features: tableFeatures({ columnFilteringFeature }),
|
|
337
|
+
_rowModels: { filteredRowModel: createFilteredRowModel(filterFns) },
|
|
338
|
+
columns,
|
|
339
|
+
data,
|
|
340
|
+
})
|
|
341
|
+
table.setColumnFilters([{ id: 'name', value: 'Ada' }])
|
|
342
|
+
// or: column.setFilterValue('Ada')
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
`table.setColumnFilters`, `column.setFilterValue`, `table.setGlobalFilter` honor reset behavior and internal invariants.
|
|
346
|
+
|
|
347
|
+
Source: maintainer interview (Phase 4, 2026-05-17)
|
|
348
|
+
|
|
349
|
+
## See also
|
|
350
|
+
|
|
351
|
+
- `tanstack-table/customizing-feature-behavior` — `filterFn` / `globalFilterFn` authoring, `addMeta` chain
|
|
352
|
+
- `tanstack-table/sorting` — fuzzy sort pairing for `match-sorter-utils`
|
|
353
|
+
- `tanstack-table/row-expanding` — `filterFromLeafRows` interaction with tree data
|
|
354
|
+
|
|
355
|
+
## References
|
|
356
|
+
|
|
357
|
+
- [faceting-and-fuzzy.md](references/faceting-and-fuzzy.md) — faceted filter UIs (autocomplete + range slider) with `createFacetedRowModel`/`createFacetedUniqueValues`/`createFacetedMinMaxValues`, fuzzy global search via `@tanstack/match-sorter-utils`, plus MEDIUM-priority failure modes: `state` + `initialState` collision, `filterFromLeafRows` semantics, `'auto'` filter misdetection on null first row
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# Faceting and fuzzy filtering — extended patterns
|
|
2
|
+
|
|
3
|
+
Extended filtering patterns extracted from `SKILL.md`. The SKILL keeps simple column filter, global filter, server-side, and tree-data patterns inline; this file covers faceted UIs and fuzzy filtering with `@tanstack/match-sorter-utils`.
|
|
4
|
+
|
|
5
|
+
## Faceted filter UIs (autocomplete + range slider)
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import {
|
|
9
|
+
columnFacetingFeature,
|
|
10
|
+
createFacetedRowModel,
|
|
11
|
+
createFacetedUniqueValues,
|
|
12
|
+
createFacetedMinMaxValues,
|
|
13
|
+
} from '@tanstack/table-core'
|
|
14
|
+
|
|
15
|
+
const _features = tableFeatures({
|
|
16
|
+
columnFacetingFeature,
|
|
17
|
+
columnFilteringFeature,
|
|
18
|
+
rowPaginationFeature,
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
const table = constructTable({
|
|
22
|
+
_features,
|
|
23
|
+
_rowModels: {
|
|
24
|
+
filteredRowModel: createFilteredRowModel(filterFns),
|
|
25
|
+
paginatedRowModel: createPaginatedRowModel(),
|
|
26
|
+
facetedRowModel: createFacetedRowModel(), // REQUIRED base
|
|
27
|
+
facetedMinMaxValues: createFacetedMinMaxValues(),
|
|
28
|
+
facetedUniqueValues: createFacetedUniqueValues(),
|
|
29
|
+
},
|
|
30
|
+
columns,
|
|
31
|
+
data,
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
// In a Filter component:
|
|
35
|
+
const uniqueValues = column.getFacetedUniqueValues() // Map<value, count>
|
|
36
|
+
const [min, max] = column.getFacetedMinMaxValues() ?? [0, 0]
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Fuzzy global search with match-sorter-utils
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import {
|
|
43
|
+
rankItem,
|
|
44
|
+
compareItems,
|
|
45
|
+
type RankingInfo,
|
|
46
|
+
} from '@tanstack/match-sorter-utils'
|
|
47
|
+
import type { FilterFn, SortFn } from '@tanstack/table-core'
|
|
48
|
+
|
|
49
|
+
declare module '@tanstack/react-table' {
|
|
50
|
+
interface FilterFns {
|
|
51
|
+
fuzzy: FilterFn<typeof _features, Person>
|
|
52
|
+
}
|
|
53
|
+
interface FilterMeta {
|
|
54
|
+
itemRank?: RankingInfo
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const fuzzyFilter: FilterFn<typeof _features, Person> = (
|
|
59
|
+
row,
|
|
60
|
+
columnId,
|
|
61
|
+
value,
|
|
62
|
+
addMeta,
|
|
63
|
+
) => {
|
|
64
|
+
const itemRank = rankItem(row.getValue(columnId), value)
|
|
65
|
+
addMeta?.({ itemRank })
|
|
66
|
+
return itemRank.passed
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const fuzzySort: SortFn<typeof _features, Person> = (rowA, rowB, columnId) => {
|
|
70
|
+
let dir = 0
|
|
71
|
+
if (rowA.columnFiltersMeta[columnId]) {
|
|
72
|
+
dir = compareItems(
|
|
73
|
+
rowA.columnFiltersMeta[columnId].itemRank!,
|
|
74
|
+
rowB.columnFiltersMeta[columnId].itemRank!,
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
return dir === 0 ? sortFns.alphanumeric(rowA, rowB, columnId) : dir
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const table = constructTable({
|
|
81
|
+
_features,
|
|
82
|
+
_rowModels: {
|
|
83
|
+
filteredRowModel: createFilteredRowModel({
|
|
84
|
+
...filterFns,
|
|
85
|
+
fuzzy: fuzzyFilter,
|
|
86
|
+
}),
|
|
87
|
+
sortedRowModel: createSortedRowModel(sortFns),
|
|
88
|
+
},
|
|
89
|
+
columns,
|
|
90
|
+
data,
|
|
91
|
+
globalFilterFn: 'fuzzy',
|
|
92
|
+
})
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Additional MEDIUM-priority failure modes
|
|
96
|
+
|
|
97
|
+
### Using `state.columnFilters` AND `initialState.columnFilters` simultaneously
|
|
98
|
+
|
|
99
|
+
Wrong:
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
|
|
103
|
+
const table = useTable({
|
|
104
|
+
initialState: { columnFilters: [{ id: 'name', value: 'John' }] }, // IGNORED
|
|
105
|
+
state: { columnFilters }, // wins, starts empty
|
|
106
|
+
onColumnFiltersChange: setColumnFilters,
|
|
107
|
+
})
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Correct:
|
|
111
|
+
|
|
112
|
+
```tsx
|
|
113
|
+
// Seed the controlled state at useState time, NOT in initialState
|
|
114
|
+
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([
|
|
115
|
+
{ id: 'name', value: 'John' },
|
|
116
|
+
])
|
|
117
|
+
const table = useTable({
|
|
118
|
+
state: { columnFilters },
|
|
119
|
+
onColumnFiltersChange: setColumnFilters,
|
|
120
|
+
})
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`state` always overrides `initialState`. Seed your controlled state instead.
|
|
124
|
+
|
|
125
|
+
Source: docs/guide/column-filtering.md
|
|
126
|
+
|
|
127
|
+
### Expecting `filterFromLeafRows` to keep ALL children of a matching parent visible
|
|
128
|
+
|
|
129
|
+
Wrong:
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
// filterFromLeafRows hides children that don't match individually
|
|
133
|
+
const table = useTable({
|
|
134
|
+
_features: tableFeatures({ columnFilteringFeature, rowExpandingFeature }),
|
|
135
|
+
_rowModels: {
|
|
136
|
+
filteredRowModel: createFilteredRowModel(filterFns),
|
|
137
|
+
expandedRowModel: createExpandedRowModel(),
|
|
138
|
+
},
|
|
139
|
+
columns,
|
|
140
|
+
data,
|
|
141
|
+
getSubRows: (r) => r.subRows,
|
|
142
|
+
filterFromLeafRows: true,
|
|
143
|
+
// expectation: parent matches "John" → all children visible
|
|
144
|
+
// reality: only children that also match "John" stay visible
|
|
145
|
+
})
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Correct:
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
// Filter root-only to preserve all sub-rows under a matching parent
|
|
152
|
+
const table = useTable({
|
|
153
|
+
_features: tableFeatures({ columnFilteringFeature, rowExpandingFeature }),
|
|
154
|
+
_rowModels: {
|
|
155
|
+
filteredRowModel: createFilteredRowModel(filterFns),
|
|
156
|
+
expandedRowModel: createExpandedRowModel(),
|
|
157
|
+
},
|
|
158
|
+
columns,
|
|
159
|
+
data,
|
|
160
|
+
getSubRows: (r) => r.subRows,
|
|
161
|
+
maxLeafRowFilterDepth: 0,
|
|
162
|
+
})
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`filterFromLeafRows: true` is bottom-up. The mutually exclusive top-down default is what preserves descendants under a matching parent.
|
|
166
|
+
|
|
167
|
+
Source: packages/table-core/src/features/column-filtering/filterRowsUtils.ts
|
|
168
|
+
|
|
169
|
+
### Auto filter type misdetects when first row has `null`/`undefined`
|
|
170
|
+
|
|
171
|
+
Wrong:
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
const data = [
|
|
175
|
+
{ id: 1, name: null }, // first row
|
|
176
|
+
{ id: 2, name: 'Alice' },
|
|
177
|
+
]
|
|
178
|
+
// Column filter returns 0 results — auto picked wrong filter from null
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Correct:
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
columnHelper.accessor('name', {
|
|
185
|
+
filterFn: 'includesString', // explicit, don't rely on auto
|
|
186
|
+
})
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
The default `'auto'` `filterFn` infers from the first row's value. If it's null/undefined, type detection fails.
|
|
190
|
+
|
|
191
|
+
Source: https://github.com/TanStack/table/issues/4711
|