@tanstack/table-core 8.0.0-alpha.30 → 8.0.0-alpha.32

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 (120) hide show
  1. package/build/cjs/aggregationTypes.js +1 -0
  2. package/build/cjs/aggregationTypes.js.map +1 -1
  3. package/build/cjs/core.js +22 -78
  4. package/build/cjs/core.js.map +1 -1
  5. package/build/cjs/createTable.js.map +1 -1
  6. package/build/cjs/features/ColumnSizing.js.map +1 -1
  7. package/build/cjs/features/Expanding.js +12 -16
  8. package/build/cjs/features/Expanding.js.map +1 -1
  9. package/build/cjs/features/Filters.js +28 -81
  10. package/build/cjs/features/Filters.js.map +1 -1
  11. package/build/cjs/features/Grouping.js +10 -16
  12. package/build/cjs/features/Grouping.js.map +1 -1
  13. package/build/cjs/features/Headers.js.map +1 -1
  14. package/build/cjs/features/Ordering.js.map +1 -1
  15. package/build/cjs/features/Pagination.js +8 -13
  16. package/build/cjs/features/Pagination.js.map +1 -1
  17. package/build/cjs/features/Pinning.js.map +1 -1
  18. package/build/cjs/features/RowSelection.js.map +1 -1
  19. package/build/cjs/features/Sorting.js +10 -16
  20. package/build/cjs/features/Sorting.js.map +1 -1
  21. package/build/cjs/features/Visibility.js.map +1 -1
  22. package/build/cjs/filterTypes.js.map +1 -1
  23. package/build/cjs/index.js +19 -12
  24. package/build/cjs/index.js.map +1 -1
  25. package/build/cjs/sortTypes.js.map +1 -1
  26. package/build/cjs/utils/filterRowsUtils.js.map +1 -1
  27. package/build/cjs/utils/getColumnFilteredRowModelSync.js +113 -0
  28. package/build/cjs/utils/getColumnFilteredRowModelSync.js.map +1 -0
  29. package/build/cjs/utils/getCoreRowModelAsync.js +125 -0
  30. package/build/cjs/utils/getCoreRowModelAsync.js.map +1 -0
  31. package/build/cjs/utils/getCoreRowModelSync.js +102 -0
  32. package/build/cjs/utils/getCoreRowModelSync.js.map +1 -0
  33. package/build/cjs/utils/getExpandedRowModel.js +61 -0
  34. package/build/cjs/utils/getExpandedRowModel.js.map +1 -0
  35. package/build/cjs/utils/getGlobalFilteredRowModelSync.js +89 -0
  36. package/build/cjs/utils/getGlobalFilteredRowModelSync.js.map +1 -0
  37. package/build/cjs/utils/getGroupedRowModel.js +174 -0
  38. package/build/cjs/utils/getGroupedRowModel.js.map +1 -0
  39. package/build/cjs/utils/getPaginationRowModel.js +61 -0
  40. package/build/cjs/utils/getPaginationRowModel.js.map +1 -0
  41. package/build/cjs/utils/getSortedRowModelSync.js +116 -0
  42. package/build/cjs/utils/getSortedRowModelSync.js.map +1 -0
  43. package/build/cjs/utils.js +155 -16
  44. package/build/cjs/utils.js.map +1 -1
  45. package/build/esm/index.js +841 -491
  46. package/build/esm/index.js.map +1 -1
  47. package/build/stats-html.html +1 -1
  48. package/build/stats-react.json +406 -298
  49. package/build/types/aggregationTypes.d.ts +1 -1
  50. package/build/types/core.d.ts +7 -1
  51. package/build/types/features/Expanding.d.ts +2 -1
  52. package/build/types/features/Filters.d.ts +6 -2
  53. package/build/types/features/Grouping.d.ts +3 -2
  54. package/build/types/features/Pagination.d.ts +2 -1
  55. package/build/types/features/Sorting.d.ts +2 -1
  56. package/build/types/index.d.ts +8 -6
  57. package/build/types/types.d.ts +2 -2
  58. package/build/types/utils/getColumnFilteredRowModelAsync.d.ts +4 -0
  59. package/build/types/utils/getColumnFilteredRowModelSync.d.ts +2 -0
  60. package/build/types/utils/getCoreRowModelAsync.d.ts +4 -0
  61. package/build/types/utils/getCoreRowModelSync.d.ts +2 -0
  62. package/build/types/utils/getExpandedRowModel.d.ts +7 -0
  63. package/build/types/utils/getGlobalFilteredRowModelAsync.d.ts +4 -0
  64. package/build/types/utils/getGlobalFilteredRowModelSync.d.ts +2 -0
  65. package/build/types/utils/getGroupedRowModel.d.ts +2 -0
  66. package/build/types/utils/getPaginationRowModel.d.ts +4 -0
  67. package/build/types/utils/{sortRowsQuicksortFn.d.ts → getSortedRowModelAsync.d.ts} +3 -1
  68. package/build/types/utils/getSortedRowModelSync.d.ts +2 -0
  69. package/build/types/utils.d.ts +16 -0
  70. package/build/umd/index.development.js +851 -496
  71. package/build/umd/index.development.js.map +1 -1
  72. package/build/umd/index.production.js +1 -1
  73. package/build/umd/index.production.js.map +1 -1
  74. package/package.json +1 -1
  75. package/src/aggregationTypes.ts +1 -1
  76. package/src/core.tsx +33 -97
  77. package/src/features/Expanding.ts +19 -27
  78. package/src/features/Filters.ts +52 -99
  79. package/src/features/Grouping.ts +19 -21
  80. package/src/features/Pagination.ts +17 -20
  81. package/src/features/Sorting.ts +19 -23
  82. package/src/index.tsx +8 -6
  83. package/src/types.ts +3 -1
  84. package/src/utils/getColumnFilteredRowModelAsync.ts +117 -0
  85. package/src/utils/getColumnFilteredRowModelSync.ts +97 -0
  86. package/src/utils/getCoreRowModelAsync.ts +103 -0
  87. package/src/utils/getCoreRowModelSync.ts +105 -0
  88. package/src/utils/getExpandedRowModel.ts +58 -0
  89. package/src/utils/getGlobalFilteredRowModelAsync.ts +95 -0
  90. package/src/utils/getGlobalFilteredRowModelSync.ts +74 -0
  91. package/src/utils/getGroupedRowModel.ts +187 -0
  92. package/src/utils/getPaginationRowModel.ts +45 -0
  93. package/src/utils/getSortedRowModelAsync.ts +199 -0
  94. package/src/utils/getSortedRowModelSync.ts +116 -0
  95. package/src/utils.tsx +189 -16
  96. package/build/cjs/utils/columnFilterRowsFn.js +0 -73
  97. package/build/cjs/utils/columnFilterRowsFn.js.map +0 -1
  98. package/build/cjs/utils/expandRowsFn.js +0 -37
  99. package/build/cjs/utils/expandRowsFn.js.map +0 -1
  100. package/build/cjs/utils/globalFilterRowsFn.js +0 -49
  101. package/build/cjs/utils/globalFilterRowsFn.js.map +0 -1
  102. package/build/cjs/utils/groupRowsFn.js +0 -155
  103. package/build/cjs/utils/groupRowsFn.js.map +0 -1
  104. package/build/cjs/utils/paginateRowsFn.js +0 -44
  105. package/build/cjs/utils/paginateRowsFn.js.map +0 -1
  106. package/build/cjs/utils/sortRowsFn.js +0 -94
  107. package/build/cjs/utils/sortRowsFn.js.map +0 -1
  108. package/build/types/utils/columnFilterRowsFn.d.ts +0 -2
  109. package/build/types/utils/expandRowsFn.d.ts +0 -2
  110. package/build/types/utils/globalFilterRowsFn.d.ts +0 -2
  111. package/build/types/utils/groupRowsFn.d.ts +0 -2
  112. package/build/types/utils/paginateRowsFn.d.ts +0 -2
  113. package/build/types/utils/sortRowsFn.d.ts +0 -2
  114. package/src/utils/columnFilterRowsFn.ts +0 -56
  115. package/src/utils/expandRowsFn.ts +0 -34
  116. package/src/utils/globalFilterRowsFn.ts +0 -39
  117. package/src/utils/groupRowsFn.ts +0 -174
  118. package/src/utils/paginateRowsFn.ts +0 -28
  119. package/src/utils/sortRowsFn.ts +0 -99
  120. package/src/utils/sortRowsQuicksortFn.ts +0 -174
@@ -84,10 +84,9 @@ export type SortingOptions<TGenerics extends AnyGenerics> = {
84
84
  enableMultiRemove?: boolean
85
85
  enableMultiSort?: boolean
86
86
  sortDescFirst?: boolean
87
- sortRowsFn?: (
88
- instance: TableInstance<TGenerics>,
89
- rowModel: RowModel<TGenerics>
90
- ) => RowModel<TGenerics>
87
+ getSortedRowModel?: (
88
+ instance: TableInstance<TGenerics>
89
+ ) => () => RowModel<TGenerics>
91
90
  maxMultiSortColCount?: number
92
91
  isMultiSortEvent?: (e: MouseEvent | TouchEvent) => boolean
93
92
  }
@@ -121,6 +120,7 @@ export type SortingInstance<TGenerics extends AnyGenerics> = {
121
120
  ) => undefined | PropGetterValue<ToggleSortingProps, TGetter>
122
121
  getPreSortedRowModel: () => RowModel<TGenerics>
123
122
  getSortedRowModel: () => RowModel<TGenerics>
123
+ _getSortedRowModel?: () => RowModel<TGenerics>
124
124
  }
125
125
 
126
126
  //
@@ -177,6 +177,8 @@ export const Sorting = {
177
177
 
178
178
  return {
179
179
  _notifySortingReset: () => {
180
+ instance._notifyGroupingReset()
181
+
180
182
  if (!registered) {
181
183
  registered = true
182
184
  return
@@ -443,27 +445,21 @@ export const Sorting = {
443
445
  },
444
446
 
445
447
  getPreSortedRowModel: () => instance.getGlobalFilteredRowModel(),
446
- getSortedRowModel: memo(
447
- () => [
448
- instance.getState().sorting,
449
- instance.getGlobalFilteredRowModel(),
450
- instance.options.sortRowsFn,
451
- ],
452
- (sorting, rowModel, sortingFn) => {
453
- if (!sortingFn || !sorting?.length) {
454
- return rowModel
455
- }
448
+ getSortedRowModel: () => {
449
+ if (
450
+ !instance._getSortedRowModel &&
451
+ instance.options.getSortedRowModel
452
+ ) {
453
+ instance._getSortedRowModel =
454
+ instance.options.getSortedRowModel(instance)
455
+ }
456
456
 
457
- return sortingFn(instance, rowModel)
458
- },
459
- {
460
- key: 'getSortedRowModel',
461
- debug: () => instance.options.debugAll ?? instance.options.debugTable,
462
- onChange: () => {
463
- instance._notifyGroupingReset()
464
- },
457
+ if (!instance._getSortedRowModel) {
458
+ return instance.getPreSortedRowModel()
465
459
  }
466
- ),
460
+
461
+ return instance._getSortedRowModel()
462
+ },
467
463
  }
468
464
  },
469
465
  }
package/src/index.tsx CHANGED
@@ -15,9 +15,11 @@ export * from './features/Sorting'
15
15
  export * from './features/Visibility'
16
16
  export * from './features/Expanding'
17
17
  export * from './utils'
18
- export * from './utils/columnFilterRowsFn'
19
- export * from './utils/globalFilterRowsFn'
20
- export * from './utils/sortRowsFn'
21
- export * from './utils/groupRowsFn'
22
- export * from './utils/expandRowsFn'
23
- export * from './utils/paginateRowsFn'
18
+ export * from './utils/getCoreRowModelSync'
19
+ export * from './utils/getCoreRowModelAsync'
20
+ export * from './utils/getColumnFilteredRowModelSync'
21
+ export * from './utils/getGlobalFilteredRowModelSync'
22
+ export * from './utils/getSortedRowModelSync'
23
+ export * from './utils/getGroupedRowModel'
24
+ export * from './utils/getExpandedRowModel'
25
+ export * from './utils/getPaginationRowModel'
package/src/types.ts CHANGED
@@ -3,6 +3,7 @@ import {
3
3
  CoreColumnDef,
4
4
  CoreOptions,
5
5
  CoreRow,
6
+ CoreTableState,
6
7
  TableCore,
7
8
  } from './core'
8
9
  import {
@@ -139,7 +140,8 @@ export type Options<TGenerics extends AnyGenerics> = CoreOptions<TGenerics> &
139
140
  export type Updater<T> = T | ((old: T) => T)
140
141
  export type OnChangeFn<T> = (updaterOrValue: Updater<T>, value: T) => void
141
142
 
142
- export type TableState = VisibilityTableState &
143
+ export type TableState = CoreTableState &
144
+ VisibilityTableState &
143
145
  ColumnOrderTableState &
144
146
  ColumnPinningTableState &
145
147
  FiltersTableState &
@@ -0,0 +1,117 @@
1
+ import { TableInstance, RowModel, AnyGenerics, Row } from '../types'
2
+ import { incrementalMemo, memo } from '../utils'
3
+ import {
4
+ filterRowModelFromLeafs,
5
+ filterRowModelFromRoot,
6
+ } from './filterRowsUtils'
7
+
8
+ export function getColumnFilteredRowModelAsync<
9
+ TGenerics extends AnyGenerics
10
+ >(opts?: {
11
+ initialSync?: boolean
12
+ }): (instance: TableInstance<TGenerics>) => () => RowModel<TGenerics> {
13
+ return instance =>
14
+ incrementalMemo(
15
+ () => [instance.getState().columnFilters, instance.getCoreRowModel()],
16
+ (_sorting, rowModel): RowModel<TGenerics> => {
17
+ return {
18
+ rows: rowModel.rows.slice(),
19
+ flatRows: [],
20
+ rowsById: rowModel.rowsById,
21
+ }
22
+ },
23
+ (columnFilters, rowModel) => rowModelRef => scheduleTask => {
24
+ // TODO: Figure out how to do scheduled filtering
25
+ // The trick will be batching those tasks in a way
26
+ // that makes them fast. JS work loops don't tend to do well with
27
+ // a high number of tasks that do one thing. Instead, shoot for each
28
+ // task to have a few thousand opts (or whatever amount is generally
29
+ // fast for most devices).
30
+ throw new Error('')
31
+
32
+ // if (!rowModel.rows.length || !columnFilters) {
33
+ // rowModelRef.current = rowModel
34
+ // } else {
35
+ // const filterFromLeafRows = instance.options.filterFromLeafRows
36
+
37
+ // const filterRows = (
38
+ // rowsToFilter: Row<TGenerics>[],
39
+ // depth: number
40
+ // ) => {
41
+ // for (let i = 0; i < columnFilters.length; i++) {
42
+ // const { id: columnId, value: filterValue } = columnFilters[i]
43
+ // // Find the columnFilters column
44
+ // const column = instance.getColumn(columnId)
45
+
46
+ // if (!column) {
47
+ // if (process.env.NODE_ENV !== 'production') {
48
+ // console.warn(
49
+ // `Table: Could not find a column with id: ${columnId}`
50
+ // )
51
+ // }
52
+ // throw new Error()
53
+ // }
54
+
55
+ // if (depth === 0) {
56
+ // const preFilteredRows = [...rowsToFilter]
57
+ // column.getPreFilteredRows = () => preFilteredRows
58
+ // }
59
+
60
+ // const filterFn = instance.getColumnFilterFn(column.id)
61
+
62
+ // if (!filterFn) {
63
+ // if (process.env.NODE_ENV !== 'production') {
64
+ // console.warn(
65
+ // `Could not find a valid 'column.filterType' for column with the ID: ${column.id}.`
66
+ // )
67
+ // }
68
+ // continue
69
+ // }
70
+
71
+ // // Pass the rows, id, filterValue and column to the filterFn
72
+ // // to get the filtered rows back
73
+ // rowsToFilter = filterFn(rowsToFilter, [columnId], filterValue)
74
+ // }
75
+
76
+ // return rowsToFilter
77
+ // }
78
+
79
+ // if (filterFromLeafRows) {
80
+ // return filterRowModelFromLeafs(rowModel.rows, filterRows, instance)
81
+ // }
82
+
83
+ // return filterRowModelFromRoot(rowModel.rows, filterRows, instance)
84
+ // }
85
+
86
+ // // Now that each filtered column has it's partially filtered rows,
87
+ // // lets assign the final filtered rows to all of the other columns
88
+ // const nonFilteredColumns = instance
89
+ // .getAllLeafColumns()
90
+ // .filter(
91
+ // column =>
92
+ // !instance.getState().columnFilters?.find(d => d.id === column.id)
93
+ // )
94
+
95
+ // // This essentially enables faceted filter options to be built easily
96
+ // // using every column's preFilteredRows value
97
+
98
+ // nonFilteredColumns.forEach(column => {
99
+ // column.getPreFilteredRows = () => rowModelRef.current.rows
100
+ // })
101
+ },
102
+ {
103
+ key: 'getColumnFilteredRowModelAsync',
104
+ initialSync: opts?.initialSync,
105
+ onProgress: progress => {
106
+ instance.setState(old => ({
107
+ ...old,
108
+ columnFiltersProgress: progress,
109
+ }))
110
+ },
111
+ debug: () => instance.options.debugAll ?? instance.options.debugTable,
112
+ onChange: () => {
113
+ instance._notifySortingReset()
114
+ },
115
+ }
116
+ )
117
+ }
@@ -0,0 +1,97 @@
1
+ import { TableInstance, RowModel, AnyGenerics, Row } from '../types'
2
+ import { memo } from '../utils'
3
+ import {
4
+ filterRowModelFromLeafs,
5
+ filterRowModelFromRoot,
6
+ } from './filterRowsUtils'
7
+
8
+ export function getColumnFilteredRowModelSync<
9
+ TGenerics extends AnyGenerics
10
+ >(): (instance: TableInstance<TGenerics>) => () => RowModel<TGenerics> {
11
+ return instance =>
12
+ memo(
13
+ () => [instance.getState().columnFilters, instance.getCoreRowModel()],
14
+ (columnFilters, rowModel) => {
15
+ const columnFilteredRowModel: RowModel<TGenerics> = (() => {
16
+ if (!rowModel.rows.length || !columnFilters) {
17
+ return rowModel
18
+ }
19
+
20
+ const filterFromLeafRows = instance.options.filterFromLeafRows
21
+
22
+ const filterRows = (
23
+ rowsToFilter: Row<TGenerics>[],
24
+ depth: number
25
+ ) => {
26
+ for (let i = 0; i < columnFilters.length; i++) {
27
+ const { id: columnId, value: filterValue } = columnFilters[i]
28
+ // Find the columnFilters column
29
+ const column = instance.getColumn(columnId)
30
+
31
+ if (!column) {
32
+ if (process.env.NODE_ENV !== 'production') {
33
+ console.warn(
34
+ `Table: Could not find a column with id: ${columnId}`
35
+ )
36
+ }
37
+ throw new Error()
38
+ }
39
+
40
+ if (depth === 0) {
41
+ const preFilteredRows = [...rowsToFilter]
42
+ column.getPreFilteredRows = () => preFilteredRows
43
+ }
44
+
45
+ const filterFn = instance.getColumnFilterFn(column.id)
46
+
47
+ if (!filterFn) {
48
+ if (process.env.NODE_ENV !== 'production') {
49
+ console.warn(
50
+ `Could not find a valid 'column.filterType' for column with the ID: ${column.id}.`
51
+ )
52
+ }
53
+ continue
54
+ }
55
+
56
+ // Pass the rows, id, filterValue and column to the filterFn
57
+ // to get the filtered rows back
58
+ rowsToFilter = filterFn(rowsToFilter, [columnId], filterValue)
59
+ }
60
+
61
+ return rowsToFilter
62
+ }
63
+
64
+ if (filterFromLeafRows) {
65
+ return filterRowModelFromLeafs(rowModel.rows, filterRows, instance)
66
+ }
67
+
68
+ return filterRowModelFromRoot(rowModel.rows, filterRows, instance)
69
+ })()
70
+
71
+ // Now that each filtered column has it's partially filtered rows,
72
+ // lets assign the final filtered rows to all of the other columns
73
+ const nonFilteredColumns = instance
74
+ .getAllLeafColumns()
75
+ .filter(
76
+ column =>
77
+ !instance.getState().columnFilters?.find(d => d.id === column.id)
78
+ )
79
+
80
+ // This essentially enables faceted filter options to be built easily
81
+ // using every column's preFilteredRows value
82
+
83
+ nonFilteredColumns.forEach(column => {
84
+ column.getPreFilteredRows = () => columnFilteredRowModel.rows
85
+ })
86
+
87
+ return columnFilteredRowModel
88
+ },
89
+ {
90
+ key: 'getColumnFilteredRowModelSync',
91
+ debug: () => instance.options.debugAll ?? instance.options.debugTable,
92
+ onChange: () => {
93
+ instance._notifySortingReset()
94
+ },
95
+ }
96
+ )
97
+ }
@@ -0,0 +1,103 @@
1
+ import { TableInstance, Row, RowModel, AnyGenerics } from '../types'
2
+ import { getBatchGroups, incrementalMemo } from '../utils'
3
+
4
+ export function getCoreRowModelAsync<TGenerics extends AnyGenerics>(opts?: {
5
+ initialSync: boolean
6
+ }): (instance: TableInstance<TGenerics>) => () => RowModel<TGenerics> {
7
+ return instance =>
8
+ incrementalMemo(
9
+ () => [instance.options.data, instance.getAllLeafColumns()],
10
+ () => {
11
+ const rows: Row<TGenerics>[] = []
12
+ const flatRows: Row<TGenerics>[] = []
13
+ const rowsById: Record<string, Row<TGenerics>> = {}
14
+
15
+ return { rows, flatRows, rowsById }
16
+ },
17
+ (data, leafColumns) => rowModelRef => scheduleTask => {
18
+ const accessRows = (
19
+ originalRows: TGenerics['Row'][],
20
+ depth = 0,
21
+ parent?: Row<TGenerics>
22
+ ) => {
23
+ const batchGroups = getBatchGroups(originalRows, 2000)
24
+
25
+ for (let i = 0; i < batchGroups.length; i++) {
26
+ const batchGroup = batchGroups[i]
27
+ scheduleTask(() => {
28
+ for (let i = 0; i < batchGroup.items.length; i++) {
29
+ const originalRow = batchGroup.items[i]
30
+ const rowIndex = batchGroup.start + i
31
+ const id = instance.getRowId(originalRow, rowIndex, parent)
32
+
33
+ if (!id) {
34
+ if (process.env.NODE_ENV !== 'production') {
35
+ throw new Error(`getRowId expected an ID, but got ${id}`)
36
+ }
37
+ }
38
+
39
+ const values: Record<string, any> = {}
40
+
41
+ for (let i = 0; i < leafColumns.length; i++) {
42
+ const column = leafColumns[i]
43
+ if (column && column.accessorFn) {
44
+ values[column.id] = column.accessorFn(originalRow, rowIndex)
45
+ }
46
+ }
47
+
48
+ // Make the row
49
+ const row = instance.createRow(
50
+ id,
51
+ originalRow,
52
+ rowIndex,
53
+ depth,
54
+ values
55
+ )
56
+
57
+ // Push instance row into the parentRows array
58
+ if (parent) {
59
+ parent.subRows.push(row)
60
+ } else {
61
+ rowModelRef.current.rows.push(row)
62
+ }
63
+ // Keep track of every row in a flat array
64
+ rowModelRef.current.flatRows.push(row)
65
+ // Also keep track of every row by its ID
66
+ rowModelRef.current.rowsById[id] = row
67
+
68
+ // Get the original subrows
69
+ if (instance.options.getSubRows) {
70
+ const originalSubRows = instance.options.getSubRows(
71
+ originalRow,
72
+ rowIndex
73
+ )
74
+
75
+ // Then recursively access them
76
+ if (originalSubRows?.length) {
77
+ row.originalSubRows = originalSubRows
78
+ row.subRows = []
79
+
80
+ accessRows(row.originalSubRows, depth + 1, row)
81
+ }
82
+ }
83
+ }
84
+ })
85
+ }
86
+ }
87
+
88
+ accessRows(data)
89
+ },
90
+ {
91
+ key: 'getRowModel',
92
+ initialSync: opts?.initialSync,
93
+ onProgress: progress => {
94
+ instance.setState(old => ({ ...old, coreProgress: progress }))
95
+ },
96
+ debug: () => instance.options.debugAll ?? instance.options.debugTable,
97
+ onChange: () => {
98
+ instance._notifyFiltersReset()
99
+ instance._notifyRowSelectionReset()
100
+ },
101
+ }
102
+ )
103
+ }
@@ -0,0 +1,105 @@
1
+ import { TableInstance, Row, RowModel, AnyGenerics } from '../types'
2
+ import { memo } from '../utils'
3
+
4
+ export function getCoreRowModelSync<TGenerics extends AnyGenerics>(): (
5
+ instance: TableInstance<TGenerics>
6
+ ) => () => RowModel<TGenerics> {
7
+ return instance =>
8
+ memo(
9
+ () => [instance.options.data],
10
+ (
11
+ data
12
+ ): {
13
+ rows: Row<TGenerics>[]
14
+ flatRows: Row<TGenerics>[]
15
+ rowsById: Record<string, Row<TGenerics>>
16
+ } => {
17
+ // Access the row model using initial columns
18
+ const rows: Row<TGenerics>[] = []
19
+ const flatRows: Row<TGenerics>[] = []
20
+ const rowsById: Record<string, Row<TGenerics>> = {}
21
+
22
+ const leafColumns = instance.getAllLeafColumns()
23
+
24
+ const accessRow = (
25
+ originalRow: TGenerics['Row'],
26
+ rowIndex: number,
27
+ depth = 0,
28
+ parentRows: Row<TGenerics>[],
29
+ parent?: Row<TGenerics>
30
+ ) => {
31
+ const id = instance.getRowId(originalRow, rowIndex, parent)
32
+
33
+ if (!id) {
34
+ if (process.env.NODE_ENV !== 'production') {
35
+ throw new Error(`getRowId expected an ID, but got ${id}`)
36
+ }
37
+ }
38
+
39
+ const values: Record<string, any> = {}
40
+
41
+ for (let i = 0; i < leafColumns.length; i++) {
42
+ const column = leafColumns[i]
43
+ if (column && column.accessorFn) {
44
+ values[column.id] = column.accessorFn(originalRow, rowIndex)
45
+ }
46
+ }
47
+
48
+ // Make the row
49
+ const row = instance.createRow(
50
+ id,
51
+ originalRow,
52
+ rowIndex,
53
+ depth,
54
+ values
55
+ )
56
+
57
+ // Push instance row into the parentRows array
58
+ parentRows.push(row)
59
+ // Keep track of every row in a flat array
60
+ flatRows.push(row)
61
+ // Also keep track of every row by its ID
62
+ rowsById[id] = row
63
+
64
+ // Get the original subrows
65
+ if (instance.options.getSubRows) {
66
+ const originalSubRows = instance.options.getSubRows(
67
+ originalRow,
68
+ rowIndex
69
+ )
70
+
71
+ // Then recursively access them
72
+ if (originalSubRows?.length) {
73
+ row.originalSubRows = originalSubRows
74
+ const subRows: Row<TGenerics>[] = []
75
+
76
+ for (let i = 0; i < row.originalSubRows.length; i++) {
77
+ accessRow(
78
+ row.originalSubRows[i] as TGenerics['Row'],
79
+ i,
80
+ depth + 1,
81
+ subRows,
82
+ row
83
+ )
84
+ }
85
+ row.subRows = subRows
86
+ }
87
+ }
88
+ }
89
+
90
+ for (let i = 0; i < data.length; i++) {
91
+ accessRow(data[i] as TGenerics['Row'], i, 0, rows)
92
+ }
93
+
94
+ return { rows, flatRows, rowsById }
95
+ },
96
+ {
97
+ key: 'getRowModel',
98
+ debug: () => instance.options.debugAll ?? instance.options.debugTable,
99
+ onChange: () => {
100
+ instance._notifyFiltersReset()
101
+ instance._notifyRowSelectionReset()
102
+ },
103
+ }
104
+ )
105
+ }
@@ -0,0 +1,58 @@
1
+ import { TableInstance, Row, RowModel, AnyGenerics } from '../types'
2
+ import { memo } from '../utils'
3
+
4
+ export function getExpandedRowModel<TGenerics extends AnyGenerics>(): (
5
+ instance: TableInstance<TGenerics>
6
+ ) => () => RowModel<TGenerics> {
7
+ return instance =>
8
+ memo(
9
+ () => [
10
+ instance.getState().expanded,
11
+ instance.getGroupedRowModel(),
12
+ instance.options.paginateExpandedRows,
13
+ ],
14
+ (expanded, rowModel, paginateExpandedRows) => {
15
+ if (
16
+ !rowModel.rows.length ||
17
+ // Do not expand if rows are not included in pagination
18
+ !paginateExpandedRows ||
19
+ (expanded !== true && !Object.keys(expanded ?? {}).length)
20
+ ) {
21
+ return rowModel
22
+ }
23
+
24
+ return expandRows(rowModel, instance)
25
+ },
26
+ {
27
+ key: 'getExpandedRowModel',
28
+ debug: () => instance.options.debugAll ?? instance.options.debugTable,
29
+ }
30
+ )
31
+ }
32
+
33
+ export function expandRows<TGenerics extends AnyGenerics>(
34
+ rowModel: RowModel<TGenerics>,
35
+ instance: TableInstance<TGenerics>
36
+ ) {
37
+ const expandedRows: Row<TGenerics>[] = []
38
+
39
+ const handleRow = (row: Row<TGenerics>) => {
40
+ expandedRows.push(row)
41
+
42
+ if (
43
+ instance.options.expandSubRows &&
44
+ row.subRows?.length &&
45
+ instance.getIsRowExpanded(row.id)
46
+ ) {
47
+ row.subRows.forEach(handleRow)
48
+ }
49
+ }
50
+
51
+ rowModel.rows.forEach(handleRow)
52
+
53
+ return {
54
+ rows: expandedRows,
55
+ flatRows: rowModel.flatRows,
56
+ rowsById: rowModel.rowsById,
57
+ }
58
+ }
@@ -0,0 +1,95 @@
1
+ import { TableInstance, RowModel, AnyGenerics, Row } from '../types'
2
+ import { incrementalMemo, memo } from '../utils'
3
+ import {
4
+ filterRowModelFromLeafs,
5
+ filterRowModelFromRoot,
6
+ } from './filterRowsUtils'
7
+
8
+ export function getGlobalFilteredRowModelAsync<
9
+ TGenerics extends AnyGenerics
10
+ >(opts?: {
11
+ initialSync?: boolean
12
+ }): (instance: TableInstance<TGenerics>) => () => RowModel<TGenerics> {
13
+ return instance =>
14
+ incrementalMemo(
15
+ () => [instance.getState().globalFilter, instance.getCoreRowModel()],
16
+ (_globalFilter, rowModel): RowModel<TGenerics> => {
17
+ return {
18
+ rows: rowModel.rows.slice(),
19
+ flatRows: [],
20
+ rowsById: rowModel.rowsById,
21
+ }
22
+ },
23
+ (globalFilter, rowModel) => rowModelRef => scheduleTask => {
24
+ // TODO: Figure out how to do scheduled filtering
25
+ // The trick will be batching those tasks in a way
26
+ // that makes them fast. JS work loops don't tend to do well with
27
+ // a high number of tasks that do one thing. Instead, shoot for each
28
+ // task to have a few thousand opts (or whatever amount is generally
29
+ // fast for most devices).
30
+ throw new Error('')
31
+
32
+ // const globalFilteredRowModel: RowModel<TGenerics> = (() => {
33
+ // if (!rowModel.rows.length || !globalFilter) {
34
+ // return rowModel
35
+ // }
36
+
37
+ // const filterFromLeafRows = instance.options.filterFromLeafRows
38
+
39
+ // const filterFn = instance.getGlobalFilterFn()
40
+
41
+ // if (!filterFn) {
42
+ // if (process.env.NODE_ENV !== 'production') {
43
+ // console.warn(`Could not find a valid 'globalFilterType'`)
44
+ // }
45
+ // return rowModel
46
+ // }
47
+
48
+ // const filterableColumns = instance
49
+ // .getAllLeafColumns()
50
+ // .filter(column => column.getCanGlobalFilter())
51
+
52
+ // const filterableColumnIds = filterableColumns.map(d => d.id)
53
+
54
+ // const filterRows = (rows: Row<TGenerics>[]) => {
55
+ // return filterFn(rows, filterableColumnIds, globalFilter)
56
+ // }
57
+
58
+ // if (filterFromLeafRows) {
59
+ // filterRowModelFromLeafs(rowModel.rows, filterRows, instance)
60
+ // }
61
+
62
+ // return filterRowModelFromRoot(rowModel.rows, filterRows, instance)
63
+ // })()
64
+
65
+ // // Now that each filtered column has it's partially filtered rows,
66
+ // // lets assign the final filtered rows to all of the other columns
67
+ // const nonFilteredColumns = instance
68
+ // .getAllLeafColumns()
69
+ // .filter(
70
+ // column =>
71
+ // !instance.getState().columnFilters?.find(d => d.id === column.id)
72
+ // )
73
+
74
+ // // This essentially enables faceted filter options to be built easily
75
+ // // using every column's preFilteredRows value
76
+
77
+ // nonFilteredColumns.forEach(column => {
78
+ // column.getPreFilteredRows = () => globalFilteredRowModel.rows
79
+ // })
80
+
81
+ // return globalFilteredRowModel
82
+ },
83
+ {
84
+ key: 'getGlobalFilteredRowModelAsync',
85
+ initialSync: opts?.initialSync,
86
+ onProgress: progress => {
87
+ instance.setState(old => ({ ...old, globalFilterProgress: progress }))
88
+ },
89
+ debug: () => instance.options.debugAll ?? instance.options.debugTable,
90
+ onChange: () => {
91
+ instance._notifySortingReset()
92
+ },
93
+ }
94
+ )
95
+ }