@tanstack/table-core 8.0.0-alpha.63 → 8.0.0-alpha.67

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.
Files changed (114) hide show
  1. package/build/cjs/core.js +7 -4
  2. package/build/cjs/core.js.map +1 -1
  3. package/build/cjs/features/Cells.js +2 -2
  4. package/build/cjs/features/Cells.js.map +1 -1
  5. package/build/cjs/features/ColumnSizing.js +68 -143
  6. package/build/cjs/features/ColumnSizing.js.map +1 -1
  7. package/build/cjs/features/Columns.js +7 -7
  8. package/build/cjs/features/Columns.js.map +1 -1
  9. package/build/cjs/features/Expanding.js +52 -90
  10. package/build/cjs/features/Expanding.js.map +1 -1
  11. package/build/cjs/features/Filters.js +213 -191
  12. package/build/cjs/features/Filters.js.map +1 -1
  13. package/build/cjs/features/Grouping.js +54 -80
  14. package/build/cjs/features/Grouping.js.map +1 -1
  15. package/build/cjs/features/Headers.js +16 -40
  16. package/build/cjs/features/Headers.js.map +1 -1
  17. package/build/cjs/features/Ordering.js +6 -5
  18. package/build/cjs/features/Ordering.js.map +1 -1
  19. package/build/cjs/features/Pagination.js +5 -5
  20. package/build/cjs/features/Pagination.js.map +1 -1
  21. package/build/cjs/features/Pinning.js +82 -168
  22. package/build/cjs/features/Pinning.js.map +1 -1
  23. package/build/cjs/features/RowSelection.js +67 -119
  24. package/build/cjs/features/RowSelection.js.map +1 -1
  25. package/build/cjs/features/Sorting.js +41 -91
  26. package/build/cjs/features/Sorting.js.map +1 -1
  27. package/build/cjs/features/Visibility.js +20 -43
  28. package/build/cjs/features/Visibility.js.map +1 -1
  29. package/build/cjs/filterFns.js +51 -108
  30. package/build/cjs/filterFns.js.map +1 -1
  31. package/build/cjs/index.js +5 -4
  32. package/build/cjs/index.js.map +1 -1
  33. package/build/cjs/utils/filterRowsUtils.js +21 -0
  34. package/build/cjs/utils/filterRowsUtils.js.map +1 -1
  35. package/build/cjs/utils/getCoreRowModelAsync.js +1 -1
  36. package/build/cjs/utils/getCoreRowModelAsync.js.map +1 -1
  37. package/build/cjs/utils/getCoreRowModelSync.js +1 -1
  38. package/build/cjs/utils/getCoreRowModelSync.js.map +1 -1
  39. package/build/cjs/utils/getExpandedRowModel.js +2 -2
  40. package/build/cjs/utils/getExpandedRowModel.js.map +1 -1
  41. package/build/cjs/utils/getFilteredRowModelSync.js +125 -0
  42. package/build/cjs/utils/getFilteredRowModelSync.js.map +1 -0
  43. package/build/cjs/utils/getGroupedRowModel.js +1 -1
  44. package/build/cjs/utils/getGroupedRowModel.js.map +1 -1
  45. package/build/cjs/utils/getPaginationRowModel.js +1 -1
  46. package/build/cjs/utils/getPaginationRowModel.js.map +1 -1
  47. package/build/cjs/utils/getSortedRowModelSync.js +3 -3
  48. package/build/cjs/utils/getSortedRowModelSync.js.map +1 -1
  49. package/build/cjs/utils.js +2 -6
  50. package/build/cjs/utils.js.map +1 -1
  51. package/build/esm/index.js +899 -1357
  52. package/build/esm/index.js.map +1 -1
  53. package/build/stats-html.html +1 -1
  54. package/build/stats-react.json +404 -418
  55. package/build/types/features/ColumnSizing.d.ts +2 -13
  56. package/build/types/features/Expanding.d.ts +3 -13
  57. package/build/types/features/Filters.d.ts +38 -42
  58. package/build/types/features/Grouping.d.ts +3 -18
  59. package/build/types/features/Ordering.d.ts +2 -6
  60. package/build/types/features/Pinning.d.ts +2 -19
  61. package/build/types/features/RowSelection.d.ts +4 -15
  62. package/build/types/features/Sorting.d.ts +5 -22
  63. package/build/types/features/Visibility.d.ts +2 -15
  64. package/build/types/filterFns.d.ts +10 -52
  65. package/build/types/index.d.ts +1 -2
  66. package/build/types/types.d.ts +2 -4
  67. package/build/types/utils/filterRowsUtils.d.ts +1 -0
  68. package/build/types/utils/{getColumnFilteredRowModelAsync.d.ts → getFilteredRowModelAsync.d.ts} +1 -1
  69. package/build/types/utils/getFilteredRowModelSync.d.ts +2 -0
  70. package/build/types/utils.d.ts +2 -2
  71. package/build/umd/index.development.js +867 -1323
  72. package/build/umd/index.development.js.map +1 -1
  73. package/build/umd/index.production.js +1 -1
  74. package/build/umd/index.production.js.map +1 -1
  75. package/package.json +2 -1
  76. package/src/core.ts +5 -5
  77. package/src/features/Cells.ts +4 -2
  78. package/src/features/ColumnSizing.ts +69 -126
  79. package/src/features/Columns.ts +12 -7
  80. package/src/features/Expanding.ts +62 -107
  81. package/src/features/Filters.ts +293 -243
  82. package/src/features/Grouping.ts +59 -81
  83. package/src/features/Headers.ts +18 -40
  84. package/src/features/Ordering.ts +7 -9
  85. package/src/features/Pagination.ts +4 -3
  86. package/src/features/Pinning.ts +77 -164
  87. package/src/features/RowSelection.ts +76 -123
  88. package/src/features/Sorting.ts +48 -106
  89. package/src/features/Visibility.ts +25 -52
  90. package/src/filterFns.ts +74 -147
  91. package/src/index.ts +1 -2
  92. package/src/types.ts +2 -2
  93. package/src/utils/filterRowsUtils.ts +24 -0
  94. package/src/utils/getCoreRowModelAsync.ts +1 -1
  95. package/src/utils/getCoreRowModelSync.ts +1 -1
  96. package/src/utils/getExpandedRowModel.ts +2 -2
  97. package/src/utils/getFilteredRowModelAsync.ts +157 -0
  98. package/src/utils/getFilteredRowModelSync.ts +141 -0
  99. package/src/utils/getGroupedRowModel.ts +1 -1
  100. package/src/utils/getPaginationRowModel.ts +1 -1
  101. package/src/utils/getSortedRowModelAsync.ts +1 -1
  102. package/src/utils/getSortedRowModelSync.ts +4 -4
  103. package/src/utils.ts +2 -4
  104. package/build/cjs/utils/getColumnFilteredRowModelSync.js +0 -115
  105. package/build/cjs/utils/getColumnFilteredRowModelSync.js.map +0 -1
  106. package/build/cjs/utils/getGlobalFilteredRowModelSync.js +0 -91
  107. package/build/cjs/utils/getGlobalFilteredRowModelSync.js.map +0 -1
  108. package/build/types/utils/getColumnFilteredRowModelSync.d.ts +0 -2
  109. package/build/types/utils/getGlobalFilteredRowModelAsync.d.ts +0 -4
  110. package/build/types/utils/getGlobalFilteredRowModelSync.d.ts +0 -2
  111. package/src/utils/getColumnFilteredRowModelAsync.ts +0 -118
  112. package/src/utils/getColumnFilteredRowModelSync.ts +0 -102
  113. package/src/utils/getGlobalFilteredRowModelAsync.ts +0 -96
  114. package/src/utils/getGlobalFilteredRowModelSync.ts +0 -79
@@ -7,6 +7,7 @@ import {
7
7
  TableInstance,
8
8
  Row,
9
9
  Updater,
10
+ TableFeature,
10
11
  } from '../types'
11
12
  import {
12
13
  functionalUpdate,
@@ -15,6 +16,7 @@ import {
15
16
  memo,
16
17
  Overwrite,
17
18
  } from '../utils'
19
+ import { filterRows } from '../utils/filterRowsUtils'
18
20
 
19
21
  export type FiltersTableState = {
20
22
  columnFilters: ColumnFiltersState
@@ -30,17 +32,25 @@ export type ColumnFilter = {
30
32
  value: unknown
31
33
  }
32
34
 
33
- /*
34
- A filter function is any function that takes an array of rows and returns an array of rows. Because filter functions can be used for both column and global filters, they are passed an array of columnIds to filter on.
35
- */
35
+ export type ResolvedColumnFilter<TGenerics extends TableGenerics> = {
36
+ id: string
37
+ resolvedValue: unknown
38
+ filterFn: FilterFn<TGenerics>
39
+ }
36
40
 
37
41
  export type FilterFn<TGenerics extends TableGenerics> = {
38
- (rows: Row<TGenerics>[], columnIds: string[], filterValue: any): any
42
+ (row: Row<TGenerics>, columnId: string, filterValue: any): boolean
43
+ resolveFilterValue?: TransformFilterValueFn<TGenerics>
39
44
  autoRemove?: ColumnFilterAutoRemoveTestFn<TGenerics>
40
45
  }
41
46
 
47
+ export type TransformFilterValueFn<TGenerics extends TableGenerics> = (
48
+ value: any,
49
+ column?: Column<TGenerics>
50
+ ) => unknown
51
+
42
52
  export type ColumnFilterAutoRemoveTestFn<TGenerics extends TableGenerics> = (
43
- value: unknown,
53
+ value: any,
44
54
  column?: Column<TGenerics>
45
55
  ) => boolean
46
56
 
@@ -57,82 +67,75 @@ export type FilterFnOption<TGenerics extends TableGenerics> =
57
67
 
58
68
  export type FiltersColumnDef<TGenerics extends TableGenerics> = {
59
69
  filterFn?: FilterFnOption<Overwrite<TGenerics, { Value: any }>>
60
- enableAllFilters?: boolean
61
70
  enableColumnFilter?: boolean
62
71
  enableGlobalFilter?: boolean
63
- defaultCanFilter?: boolean
64
- defaultCanColumnFilter?: boolean
65
- defaultCanGlobalFilter?: boolean
72
+ enableFaceting?: boolean
66
73
  }
67
74
 
68
75
  export type FiltersColumn<TGenerics extends TableGenerics> = {
69
76
  filterFn: FilterFnOption<Overwrite<TGenerics, { Value: any }>>
70
- getCanColumnFilter: () => boolean
77
+ getAutoFilterFn: () => FilterFn<TGenerics> | undefined
78
+ getFilterFn: () => FilterFn<TGenerics> | undefined
79
+ setFilterValue: (updater: Updater<any>) => void
80
+ getCanFilter: () => boolean
71
81
  getCanGlobalFilter: () => boolean
72
- getColumnFilterIndex: () => number
73
- getColumnIsFiltered: () => boolean
74
- getColumnFilterValue: () => unknown
75
- setColumnFilterValue: (updater: Updater<any>) => void
76
- getPreFilteredRows: () => Row<TGenerics>[] | undefined
77
- getPreFilteredUniqueValues: () => Map<any, number>
78
- getPreFilteredMinMaxValues: () => [any, any]
82
+ getFacetedRowModel: () => RowModel<TGenerics>
83
+ getIsFiltered: () => boolean
84
+ getFilterValue: () => unknown
85
+ getFilterIndex: () => number
86
+ getFacetedUniqueValues: () => Map<any, number>
87
+ getFacetedMinMaxValues: () => [any, any]
88
+ }
89
+
90
+ export type FiltersRow<TGenerics extends TableGenerics> = {
91
+ columnFilterMap: Record<string, boolean>
92
+ subRowsByFacetId: Record<string, Row<TGenerics>[]>
79
93
  }
80
94
 
81
95
  export type FiltersOptions<TGenerics extends TableGenerics> = {
96
+ enableFilters?: boolean
97
+ manualFiltering?: boolean
82
98
  filterFromLeafRows?: boolean
83
99
  filterFns?: TGenerics['FilterFns']
84
- enableFilters?: boolean
100
+
85
101
  // Column
86
- manualColumnFiltering?: boolean
87
102
  onColumnFiltersChange?: OnChangeFn<ColumnFiltersState>
88
103
  enableColumnFilters?: boolean
89
- getColumnFilteredRowModel?: (
104
+ getFilteredRowModel?: (
90
105
  instance: TableInstance<TGenerics>
91
106
  ) => () => RowModel<TGenerics>
107
+
92
108
  // Global
93
- manualGlobalFiltering?: boolean
94
109
  globalFilterFn?: FilterFnOption<TGenerics>
95
110
  onGlobalFilterChange?: OnChangeFn<any>
96
111
  enableGlobalFilter?: boolean
97
- getGlobalFilteredRowModel?: (
98
- instance: TableInstance<TGenerics>
99
- ) => () => RowModel<TGenerics>
100
- getColumnCanGlobalFilterFn?: (column: Column<TGenerics>) => boolean
112
+ getColumnCanGlobalFilter?: (column: Column<TGenerics>) => boolean
101
113
  }
102
114
 
103
115
  export type FiltersInstance<TGenerics extends TableGenerics> = {
104
- getColumnAutoFilterFn: (columnId: string) => FilterFn<TGenerics> | undefined
105
-
106
- getColumnFilterFn: (columnId: string) => FilterFn<TGenerics> | undefined
107
-
108
116
  setColumnFilters: (updater: Updater<ColumnFiltersState>) => void
109
- setColumnFilterValue: (columnId: string, updater: Updater<any>) => void
110
- resetColumnFilters: () => void
111
- getColumnCanColumnFilter: (columnId: string) => boolean
112
117
 
113
- getColumnIsFiltered: (columnId: string) => boolean
114
- getColumnFilterValue: (columnId: string) => unknown
115
- getColumnFilterIndex: (columnId: string) => number
118
+ resetColumnFilters: () => void
116
119
 
117
120
  // Column Filters
118
- getPreColumnFilteredRowModel: () => RowModel<TGenerics>
119
- getColumnFilteredRowModel: () => RowModel<TGenerics>
120
- _getColumnFilteredRowModel?: () => RowModel<TGenerics>
121
+ getPreFilteredRowModel: () => RowModel<TGenerics>
122
+ getFilteredRowModel: () => RowModel<TGenerics>
123
+ _getFilteredRowModel?: () => RowModel<TGenerics>
121
124
 
122
125
  // Global Filters
123
126
  setGlobalFilter: (updater: Updater<any>) => void
124
127
  resetGlobalFilter: () => void
125
128
  getGlobalAutoFilterFn: () => FilterFn<TGenerics> | undefined
126
129
  getGlobalFilterFn: () => FilterFn<TGenerics> | undefined
127
- getColumnCanGlobalFilter: (columnId: string) => boolean
128
- getPreGlobalFilteredRowModel: () => RowModel<TGenerics>
129
- getGlobalFilteredRowModel: () => RowModel<TGenerics>
130
- _getGlobalFilteredRowModel?: () => RowModel<TGenerics>
130
+
131
+ getGlobalFacetedRowModel: () => RowModel<TGenerics>
132
+ getGlobalFacetedUniqueValues: () => Map<any, number>
133
+ getGlobalFacetedMinMaxValues: () => [number, number]
131
134
  }
132
135
 
133
136
  //
134
137
 
135
- export const Filters = {
138
+ export const Filters: TableFeature = {
136
139
  getDefaultColumn: <
137
140
  TGenerics extends TableGenerics
138
141
  >(): FiltersColumnDef<TGenerics> => {
@@ -141,12 +144,13 @@ export const Filters = {
141
144
  }
142
145
  },
143
146
 
144
- getInitialState: (): FiltersTableState => {
147
+ getInitialState: (state): FiltersTableState => {
145
148
  return {
146
149
  columnFilters: [],
147
150
  globalFilter: undefined,
148
151
  columnFiltersProgress: 1,
149
152
  globalFilterProgress: 1,
153
+ ...state,
150
154
  }
151
155
  },
152
156
 
@@ -158,7 +162,7 @@ export const Filters = {
158
162
  onGlobalFilterChange: makeStateUpdater('globalFilter', instance),
159
163
  filterFromLeafRows: true,
160
164
  globalFilterFn: 'auto',
161
- getColumnCanGlobalFilterFn: column => {
165
+ getColumnCanGlobalFilter: column => {
162
166
  const value = instance
163
167
  .getCoreRowModel()
164
168
  .flatRows[0]?.getAllCellsByColumnId()[column.id]?.value
@@ -172,76 +176,19 @@ export const Filters = {
172
176
  column: Column<TGenerics>,
173
177
  instance: TableInstance<TGenerics>
174
178
  ): FiltersColumn<TGenerics> => {
175
- const getFacetInfo = memo(
176
- () => [column.getPreFilteredRows()],
177
- (rows = []) => {
178
- let preFilteredUniqueValues = new Map<any, number>()
179
-
180
- let preFilteredMinMaxValues: [any, any] = [
181
- rows[0]?.values[column.id] ?? null,
182
- rows[0]?.values[column.id] ?? null,
183
- ]
184
-
185
- for (let i = 0; i < rows.length; i++) {
186
- const value = rows[i]?.values[column.id]
187
-
188
- if (preFilteredUniqueValues.has(value)) {
189
- preFilteredUniqueValues.set(
190
- value,
191
- (preFilteredUniqueValues.get(value) ?? 0) + 1
192
- )
193
- } else {
194
- preFilteredUniqueValues.set(value, 1)
195
- }
196
-
197
- if (value < preFilteredMinMaxValues[0]) {
198
- preFilteredMinMaxValues[0] = value
199
- } else if (value > preFilteredMinMaxValues[1]) {
200
- preFilteredMinMaxValues[1] = value
201
- }
202
- }
203
-
204
- return {
205
- preFilteredUniqueValues,
206
- preFilteredMinMaxValues,
207
- }
208
- },
209
- {
210
- key: 'column.getFacetInfo',
211
- debug: () => instance.options.debugAll ?? instance.options.debugColumns,
212
- }
213
- )
214
-
215
179
  return {
216
180
  filterFn: column.filterFn,
217
- getCanColumnFilter: () => instance.getColumnCanColumnFilter(column.id),
218
- getCanGlobalFilter: () => instance.getColumnCanGlobalFilter(column.id),
219
- getColumnFilterIndex: () => instance.getColumnFilterIndex(column.id),
220
- getColumnIsFiltered: () => instance.getColumnIsFiltered(column.id),
221
- getColumnFilterValue: () => instance.getColumnFilterValue(column.id),
222
- setColumnFilterValue: val =>
223
- instance.setColumnFilterValue(column.id, val),
224
- getPreFilteredUniqueValues: () => getFacetInfo().preFilteredUniqueValues,
225
- getPreFilteredMinMaxValues: () => getFacetInfo().preFilteredMinMaxValues,
226
- getPreFilteredRows: () => undefined,
227
- }
228
- },
229
-
230
- createInstance: <TGenerics extends TableGenerics>(
231
- instance: TableInstance<TGenerics>
232
- ): FiltersInstance<TGenerics> => {
233
- return {
234
- getColumnAutoFilterFn: columnId => {
181
+ getAutoFilterFn: () => {
235
182
  const firstRow = instance.getCoreRowModel().flatRows[0]
236
183
 
237
- const value = firstRow?.values[columnId]
184
+ const value = firstRow?.values[column.id]
238
185
 
239
186
  if (typeof value === 'string') {
240
187
  return filterFns.includesString
241
188
  }
242
189
 
243
190
  if (typeof value === 'number') {
244
- return filterFns.betweenNumberRange
191
+ return filterFns.inNumberRange
245
192
  }
246
193
 
247
194
  if (value !== null && typeof value === 'object') {
@@ -254,21 +201,13 @@ export const Filters = {
254
201
 
255
202
  return filterFns.weakEquals
256
203
  },
257
- getGlobalAutoFilterFn: () => {
258
- return filterFns.includesString
259
- },
260
- getColumnFilterFn: columnId => {
261
- const column = instance.getColumn(columnId)
204
+ getFilterFn: () => {
262
205
  const userFilterFns = instance.options.filterFns
263
206
 
264
- if (!column) {
265
- throw new Error()
266
- }
267
-
268
207
  return isFunction(column.filterFn)
269
208
  ? column.filterFn
270
209
  : column.filterFn === 'auto'
271
- ? instance.getColumnAutoFilterFn(columnId)
210
+ ? column.getAutoFilterFn()
272
211
  : (userFilterFns as Record<string, any>)?.[
273
212
  column.filterFn as string
274
213
  ] ??
@@ -276,118 +215,38 @@ export const Filters = {
276
215
  column.filterFn as BuiltInFilterFn
277
216
  ] as FilterFn<TGenerics>)
278
217
  },
279
-
280
- getGlobalFilterFn: () => {
281
- const { filterFns: userFilterFns, globalFilterFn: globalFilterFn } =
282
- instance.options
283
-
284
- return isFunction(globalFilterFn)
285
- ? globalFilterFn
286
- : globalFilterFn === 'auto'
287
- ? instance.getGlobalAutoFilterFn()
288
- : (userFilterFns as Record<string, any>)?.[
289
- globalFilterFn as string
290
- ] ??
291
- (filterFns[
292
- globalFilterFn as BuiltInFilterFn
293
- ] as FilterFn<TGenerics>)
294
- },
295
-
296
- setColumnFilters: (updater: Updater<ColumnFiltersState>) => {
297
- const leafColumns = instance.getAllLeafColumns()
298
-
299
- const updateFn = (old: ColumnFiltersState) => {
300
- return functionalUpdate(updater, old)?.filter(filter => {
301
- const column = leafColumns.find(d => d.id === filter.id)
302
-
303
- if (column) {
304
- const filterFn = instance.getColumnFilterFn(column.id)
305
-
306
- if (shouldAutoRemoveFilter(filterFn, filter.value, column)) {
307
- return false
308
- }
309
- }
310
-
311
- return true
312
- })
313
- }
314
-
315
- instance.options.onColumnFiltersChange?.(updateFn)
316
- },
317
-
318
- setGlobalFilter: updater => {
319
- instance.options.onGlobalFilterChange?.(updater)
320
- },
321
-
322
- resetGlobalFilter: () => {
323
- instance.setGlobalFilter(instance.initialState.globalFilter)
324
- },
325
-
326
- getColumnCanColumnFilter: columnId => {
327
- const column = instance.getColumn(columnId)
328
-
329
- if (!column) {
330
- throw new Error()
331
- }
332
-
218
+ getCanFilter: () => {
333
219
  return (
334
- column.enableAllFilters ??
335
- column.enableColumnFilter ??
336
- instance.options.enableFilters ??
337
- instance.options.enableColumnFilters ??
338
- column.defaultCanColumnFilter ??
339
- column.defaultCanFilter ??
220
+ (column.enableColumnFilter ?? true) &&
221
+ (instance.options.enableColumnFilters ?? true) &&
222
+ (instance.options.enableFilters ?? true) &&
340
223
  !!column.accessorFn
341
224
  )
342
225
  },
343
226
 
344
- getColumnCanGlobalFilter: columnId => {
345
- const column = instance.getColumn(columnId)
346
-
347
- if (!column) {
348
- throw new Error()
349
- }
350
-
227
+ getCanGlobalFilter: () => {
351
228
  return (
352
- ((instance.options.enableFilters ??
353
- instance.options.enableGlobalFilter ??
354
- column.enableAllFilters ??
355
- column.enableGlobalFilter ??
356
- column.defaultCanGlobalFilter ??
357
- column.defaultCanFilter ??
358
- !!column.accessorFn) &&
359
- instance.options.getColumnCanGlobalFilterFn?.(column)) ??
360
- true
229
+ (column.enableGlobalFilter ?? true) &&
230
+ (instance.options.enableGlobalFilter ?? true) &&
231
+ (instance.options.enableFilters ?? true) &&
232
+ (instance.options.getColumnCanGlobalFilter?.(column) ?? true) &&
233
+ !!column.accessorFn
361
234
  )
362
235
  },
363
236
 
364
- getColumnIsFiltered: columnId =>
365
- instance.getColumnFilterIndex(columnId) > -1,
237
+ getIsFiltered: () => column.getFilterIndex() > -1,
366
238
 
367
- getColumnFilterValue: columnId =>
368
- instance.getState().columnFilters?.find(d => d.id === columnId)?.value,
239
+ getFilterValue: () =>
240
+ instance.getState().columnFilters?.find(d => d.id === column.id)?.value,
369
241
 
370
- getColumnFilterIndex: columnId =>
371
- instance.getState().columnFilters?.findIndex(d => d.id === columnId) ??
242
+ getFilterIndex: () =>
243
+ instance.getState().columnFilters?.findIndex(d => d.id === column.id) ??
372
244
  -1,
373
245
 
374
- setColumnFilterValue: (columnId, value) => {
375
- if (!columnId) return
376
-
246
+ setFilterValue: value => {
377
247
  instance.setColumnFilters(old => {
378
- const column = instance.getColumn(columnId)
379
-
380
- if (!column) {
381
- if (process.env.NODE_ENV !== 'production') {
382
- console.warn(
383
- `Table: Could not find a column with id: ${columnId}`
384
- )
385
- }
386
- throw new Error()
387
- }
388
-
389
- const filterFn = instance.getColumnFilterFn(column.id)
390
- const previousfilter = old?.find(d => d.id === columnId)
248
+ const filterFn = column.getFilterFn()
249
+ const previousfilter = old?.find(d => d.id === column.id)
391
250
 
392
251
  const newFilter = functionalUpdate(
393
252
  value,
@@ -402,15 +261,15 @@ export const Filters = {
402
261
  column
403
262
  )
404
263
  ) {
405
- return old?.filter(d => d.id !== columnId) ?? []
264
+ return old?.filter(d => d.id !== column.id) ?? []
406
265
  }
407
266
 
408
- const newFilterObj = { id: columnId, value: newFilter }
267
+ const newFilterObj = { id: column.id, value: newFilter }
409
268
 
410
269
  if (previousfilter) {
411
270
  return (
412
271
  old?.map(d => {
413
- if (d.id === columnId) {
272
+ if (d.id === column.id) {
414
273
  return newFilterObj
415
274
  }
416
275
  return d
@@ -425,49 +284,199 @@ export const Filters = {
425
284
  return [newFilterObj]
426
285
  })
427
286
  },
287
+ getFacetedRowModel: memo(
288
+ () => [
289
+ instance.getPreFilteredRowModel(),
290
+ instance.getState().columnFilters,
291
+ instance.getState().globalFilter,
292
+ // Include this to force the filtered facet info to be calculated
293
+ instance.getFilteredRowModel(),
294
+ ],
295
+ (rowModel, columnFilters, globalFilter, _) => {
296
+ if (!columnFilters?.length && !globalFilter) {
297
+ return rowModel
298
+ }
428
299
 
429
- resetColumnFilters: () => {
430
- instance.setColumnFilters(instance.initialState?.columnFilters ?? [])
300
+ return filterRows(
301
+ rowModel.rows,
302
+ [
303
+ ...columnFilters.map(d => d.id).filter(d => d !== column.id),
304
+ globalFilter ? '__global__' : undefined,
305
+ ].filter(Boolean) as string[],
306
+ instance
307
+ )
308
+ },
309
+ {
310
+ key:
311
+ process.env.NODE_ENV === 'production' &&
312
+ 'getFacetedRowModel_' + column.id,
313
+ debug: () =>
314
+ instance.options.debugAll ?? instance.options.debugColumns,
315
+ }
316
+ ),
317
+ getFacetedUniqueValues: memo(
318
+ () => [column.getFacetedRowModel()],
319
+ facetedRowModel => getRowModelUniqueValues(facetedRowModel, column.id),
320
+ {
321
+ key:
322
+ process.env.NODE_ENV === 'production' &&
323
+ 'column.getFacetedUniqueValues',
324
+ debug: () =>
325
+ instance.options.debugAll ?? instance.options.debugColumns,
326
+ }
327
+ ),
328
+ getFacetedMinMaxValues: memo(
329
+ () => [column.getFacetedRowModel()],
330
+ facetedRowModel => getRowModelMinMaxValues(facetedRowModel, column.id),
331
+ {
332
+ key:
333
+ process.env.NODE_ENV === 'production' &&
334
+ 'column.getFacetedMinMaxValues',
335
+ debug: () =>
336
+ instance.options.debugAll ?? instance.options.debugColumns,
337
+ }
338
+ ),
339
+ }
340
+ },
341
+
342
+ createRow: <TGenerics extends TableGenerics>(
343
+ row: Row<TGenerics>,
344
+ instance: TableInstance<TGenerics>
345
+ ): FiltersRow<TGenerics> => {
346
+ return {
347
+ columnFilterMap: {},
348
+ subRowsByFacetId: {},
349
+ }
350
+ },
351
+
352
+ createInstance: <TGenerics extends TableGenerics>(
353
+ instance: TableInstance<TGenerics>
354
+ ): FiltersInstance<TGenerics> => {
355
+ return {
356
+ getGlobalAutoFilterFn: () => {
357
+ return filterFns.includesString
431
358
  },
432
359
 
433
- getPreColumnFilteredRowModel: () => instance.getCoreRowModel(),
434
- getColumnFilteredRowModel: () => {
435
- if (
436
- !instance._getColumnFilteredRowModel &&
437
- instance.options.getColumnFilteredRowModel
438
- ) {
439
- instance._getColumnFilteredRowModel =
440
- instance.options.getColumnFilteredRowModel(instance)
441
- }
360
+ getGlobalFilterFn: () => {
361
+ const { filterFns: userFilterFns, globalFilterFn: globalFilterFn } =
362
+ instance.options
442
363
 
443
- if (
444
- instance.options.manualColumnFiltering ||
445
- !instance._getColumnFilteredRowModel
446
- ) {
447
- return instance.getPreColumnFilteredRowModel()
364
+ return isFunction(globalFilterFn)
365
+ ? globalFilterFn
366
+ : globalFilterFn === 'auto'
367
+ ? instance.getGlobalAutoFilterFn()
368
+ : (userFilterFns as Record<string, any>)?.[
369
+ globalFilterFn as string
370
+ ] ??
371
+ (filterFns[
372
+ globalFilterFn as BuiltInFilterFn
373
+ ] as FilterFn<TGenerics>)
374
+ },
375
+
376
+ setColumnFilters: (updater: Updater<ColumnFiltersState>) => {
377
+ const leafColumns = instance.getAllLeafColumns()
378
+
379
+ const updateFn = (old: ColumnFiltersState) => {
380
+ return functionalUpdate(updater, old)?.filter(filter => {
381
+ const column = leafColumns.find(d => d.id === filter.id)
382
+
383
+ if (column) {
384
+ const filterFn = column.getFilterFn()
385
+
386
+ if (shouldAutoRemoveFilter(filterFn, filter.value, column)) {
387
+ return false
388
+ }
389
+ }
390
+
391
+ return true
392
+ })
448
393
  }
449
394
 
450
- return instance._getColumnFilteredRowModel()
395
+ instance.options.onColumnFiltersChange?.(updateFn)
396
+ },
397
+
398
+ setGlobalFilter: updater => {
399
+ instance.options.onGlobalFilterChange?.(updater)
400
+ },
401
+
402
+ resetGlobalFilter: () => {
403
+ instance.setGlobalFilter(instance.initialState.globalFilter)
404
+ },
405
+
406
+ resetColumnFilters: () => {
407
+ instance.setColumnFilters(instance.initialState?.columnFilters ?? [])
451
408
  },
452
- getPreGlobalFilteredRowModel: () => instance.getColumnFilteredRowModel(),
453
- getGlobalFilteredRowModel: () => {
409
+
410
+ getPreFilteredRowModel: () => instance.getCoreRowModel(),
411
+ getFilteredRowModel: () => {
454
412
  if (
455
- !instance._getGlobalFilteredRowModel &&
456
- instance.options.getGlobalFilteredRowModel
413
+ !instance._getFilteredRowModel &&
414
+ instance.options.getFilteredRowModel
457
415
  ) {
458
- instance._getGlobalFilteredRowModel =
459
- instance.options.getGlobalFilteredRowModel(instance)
416
+ instance._getFilteredRowModel =
417
+ instance.options.getFilteredRowModel(instance)
460
418
  }
461
419
 
462
420
  if (
463
- instance.options.manualGlobalFiltering ||
464
- !instance._getGlobalFilteredRowModel
421
+ instance.options.manualFiltering ||
422
+ !instance._getFilteredRowModel
465
423
  ) {
466
- return instance.getPreGlobalFilteredRowModel()
424
+ return instance.getPreFilteredRowModel()
467
425
  }
468
426
 
469
- return instance._getGlobalFilteredRowModel()
427
+ return instance._getFilteredRowModel()
470
428
  },
429
+
430
+ getGlobalFacetedRowModel: memo(
431
+ () => [
432
+ instance.getPreFilteredRowModel(),
433
+ instance.getState().columnFilters,
434
+ instance.getState().globalFilter,
435
+ // Include this to force the filtered facet info to be calculated
436
+ instance.getFilteredRowModel(),
437
+ ],
438
+ (rowModel, columnFilters, globalFilter, _) => {
439
+ if (!columnFilters?.length && !globalFilter) {
440
+ return rowModel
441
+ }
442
+
443
+ return filterRows(
444
+ rowModel.rows,
445
+ columnFilters.map(d => d.id),
446
+ instance
447
+ )
448
+ },
449
+ {
450
+ key:
451
+ process.env.NODE_ENV === 'production' && 'getGlobalFacetedRowModel',
452
+ debug: () =>
453
+ instance.options.debugAll ?? instance.options.debugColumns,
454
+ }
455
+ ),
456
+ getGlobalFacetedUniqueValues: memo(
457
+ () => [instance.getGlobalFacetedRowModel()],
458
+ facetedRowModel =>
459
+ getRowModelUniqueValues(facetedRowModel, '__global__'),
460
+ {
461
+ key:
462
+ process.env.NODE_ENV === 'production' &&
463
+ 'getGlobalFacetedUniqueValues',
464
+ debug: () =>
465
+ instance.options.debugAll ?? instance.options.debugColumns,
466
+ }
467
+ ),
468
+ getGlobalFacetedMinMaxValues: memo(
469
+ () => [instance.getGlobalFacetedRowModel()],
470
+ facetedRowModel =>
471
+ getRowModelMinMaxValues(facetedRowModel, '__global__'),
472
+ {
473
+ key:
474
+ process.env.NODE_ENV === 'production' &&
475
+ 'getGlobalFacetedMinMaxValues',
476
+ debug: () =>
477
+ instance.options.debugAll ?? instance.options.debugColumns,
478
+ }
479
+ ),
471
480
  }
472
481
  },
473
482
  }
@@ -485,3 +494,44 @@ export function shouldAutoRemoveFilter<TGenerics extends TableGenerics>(
485
494
  (typeof value === 'string' && !value)
486
495
  )
487
496
  }
497
+
498
+ export function getRowModelMinMaxValues<TGenerics extends TableGenerics>(
499
+ rowModel: RowModel<TGenerics>,
500
+ columnId: string
501
+ ) {
502
+ let facetedMinMaxValues: [any, any] = [
503
+ rowModel.flatRows[0]?.values[columnId] ?? null,
504
+ rowModel.flatRows[0]?.values[columnId] ?? null,
505
+ ]
506
+
507
+ for (let i = 0; i < rowModel.flatRows.length; i++) {
508
+ const value = rowModel.flatRows[i]?.values[columnId]
509
+
510
+ if (value < facetedMinMaxValues[0]) {
511
+ facetedMinMaxValues[0] = value
512
+ } else if (value > facetedMinMaxValues[1]) {
513
+ facetedMinMaxValues[1] = value
514
+ }
515
+ }
516
+
517
+ return facetedMinMaxValues
518
+ }
519
+
520
+ export function getRowModelUniqueValues<TGenerics extends TableGenerics>(
521
+ rowModel: RowModel<TGenerics>,
522
+ columnId: string
523
+ ) {
524
+ let facetedUniqueValues = new Map<any, number>()
525
+
526
+ for (let i = 0; i < rowModel.flatRows.length; i++) {
527
+ const value = rowModel.flatRows[i]?.values[columnId]
528
+
529
+ if (facetedUniqueValues.has(value)) {
530
+ facetedUniqueValues.set(value, (facetedUniqueValues.get(value) ?? 0) + 1)
531
+ } else {
532
+ facetedUniqueValues.set(value, 1)
533
+ }
534
+ }
535
+
536
+ return facetedUniqueValues
537
+ }