@tanstack/table-core 8.0.0-alpha.9 → 8.0.0-beta.2

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 (186) hide show
  1. package/build/cjs/aggregationFns.js +120 -0
  2. package/build/cjs/aggregationFns.js.map +1 -0
  3. package/build/cjs/core/cell.js +40 -0
  4. package/build/cjs/core/cell.js.map +1 -0
  5. package/build/cjs/core/column.js +88 -0
  6. package/build/cjs/core/column.js.map +1 -0
  7. package/build/cjs/core/headers.js +403 -0
  8. package/build/cjs/core/headers.js.map +1 -0
  9. package/build/cjs/core/instance.js +255 -0
  10. package/build/cjs/core/instance.js.map +1 -0
  11. package/build/cjs/core/row.js +77 -0
  12. package/build/cjs/core/row.js.map +1 -0
  13. package/build/cjs/createTable.js +36 -29
  14. package/build/cjs/createTable.js.map +1 -1
  15. package/build/cjs/features/ColumnSizing.js +157 -189
  16. package/build/cjs/features/ColumnSizing.js.map +1 -1
  17. package/build/cjs/features/Expanding.js +103 -155
  18. package/build/cjs/features/Expanding.js.map +1 -1
  19. package/build/cjs/features/Filters.js +155 -304
  20. package/build/cjs/features/Filters.js.map +1 -1
  21. package/build/cjs/features/Grouping.js +97 -157
  22. package/build/cjs/features/Grouping.js.map +1 -1
  23. package/build/cjs/features/Ordering.js +30 -41
  24. package/build/cjs/features/Ordering.js.map +1 -1
  25. package/build/cjs/features/Pagination.js +102 -105
  26. package/build/cjs/features/Pagination.js.map +1 -1
  27. package/build/cjs/features/Pinning.js +131 -89
  28. package/build/cjs/features/Pinning.js.map +1 -1
  29. package/build/cjs/features/RowSelection.js +138 -267
  30. package/build/cjs/features/RowSelection.js.map +1 -1
  31. package/build/cjs/features/Sorting.js +82 -167
  32. package/build/cjs/features/Sorting.js.map +1 -1
  33. package/build/cjs/features/Visibility.js +69 -115
  34. package/build/cjs/features/Visibility.js.map +1 -1
  35. package/build/cjs/filterFns.js +107 -0
  36. package/build/cjs/filterFns.js.map +1 -0
  37. package/build/cjs/index.js +36 -23
  38. package/build/cjs/index.js.map +1 -1
  39. package/build/cjs/sortingFns.js +124 -0
  40. package/build/cjs/sortingFns.js.map +1 -0
  41. package/build/cjs/utils/filterRowsUtils.js +117 -0
  42. package/build/cjs/utils/filterRowsUtils.js.map +1 -0
  43. package/build/cjs/utils/getCoreRowModel.js +79 -0
  44. package/build/cjs/utils/getCoreRowModel.js.map +1 -0
  45. package/build/cjs/utils/getExpandedRowModel.js +57 -0
  46. package/build/cjs/utils/getExpandedRowModel.js.map +1 -0
  47. package/build/cjs/utils/getFacetedMinMaxValues.js +54 -0
  48. package/build/cjs/utils/getFacetedMinMaxValues.js.map +1 -0
  49. package/build/cjs/utils/getFacetedRowModel.js +50 -0
  50. package/build/cjs/utils/getFacetedRowModel.js.map +1 -0
  51. package/build/cjs/utils/getFacetedUniqueValues.js +48 -0
  52. package/build/cjs/utils/getFacetedUniqueValues.js.map +1 -0
  53. package/build/cjs/utils/getFilteredRowModel.js +139 -0
  54. package/build/cjs/utils/getFilteredRowModel.js.map +1 -0
  55. package/build/cjs/utils/getGroupedRowModel.js +161 -0
  56. package/build/cjs/utils/getGroupedRowModel.js.map +1 -0
  57. package/build/cjs/utils/getPaginationRowModel.js +61 -0
  58. package/build/cjs/utils/getPaginationRowModel.js.map +1 -0
  59. package/build/cjs/utils/getSortedRowModel.js +110 -0
  60. package/build/cjs/utils/getSortedRowModel.js.map +1 -0
  61. package/build/cjs/utils.js +38 -107
  62. package/build/cjs/utils.js.map +1 -1
  63. package/build/esm/index.js +2976 -3853
  64. package/build/esm/index.js.map +1 -1
  65. package/build/stats-html.html +1 -1
  66. package/build/stats-react.json +586 -408
  67. package/build/types/aggregationFns.d.ts +13 -0
  68. package/build/types/core/cell.d.ts +9 -0
  69. package/build/types/core/column.d.ts +40 -0
  70. package/build/types/core/headers.d.ts +46 -0
  71. package/build/types/core/instance.d.ts +57 -0
  72. package/build/types/core/row.d.ts +15 -0
  73. package/build/types/createTable.d.ts +47 -26
  74. package/build/types/features/ColumnSizing.d.ts +32 -44
  75. package/build/types/features/Expanding.d.ts +15 -26
  76. package/build/types/features/Filters.d.ts +64 -63
  77. package/build/types/features/Grouping.d.ts +32 -46
  78. package/build/types/features/Ordering.d.ts +7 -10
  79. package/build/types/features/Pagination.d.ts +16 -15
  80. package/build/types/features/Pinning.d.ts +16 -17
  81. package/build/types/features/RowSelection.d.ts +13 -33
  82. package/build/types/features/Sorting.d.ts +25 -44
  83. package/build/types/features/Visibility.d.ts +16 -25
  84. package/build/types/filterFns.d.ts +13 -0
  85. package/build/types/index.d.ts +16 -10
  86. package/build/types/sortingFns.d.ts +11 -0
  87. package/build/types/types.d.ts +37 -122
  88. package/build/types/utils/filterRowsUtils.d.ts +4 -0
  89. package/build/types/utils/getCoreRowModel.d.ts +2 -0
  90. package/build/types/utils/getExpandedRowModel.d.ts +7 -0
  91. package/build/types/utils/getFacetedMinMaxValues.d.ts +2 -0
  92. package/build/types/utils/getFacetedRowModel.d.ts +2 -0
  93. package/build/types/utils/getFacetedUniqueValues.d.ts +2 -0
  94. package/build/types/utils/getFilteredRowModel.d.ts +2 -0
  95. package/build/types/utils/getGroupedRowModel.d.ts +2 -0
  96. package/build/types/utils/getPaginationRowModel.d.ts +4 -0
  97. package/build/types/utils/getSortedRowModel.d.ts +2 -0
  98. package/build/types/utils.d.ts +7 -11
  99. package/build/umd/index.development.js +3024 -3893
  100. package/build/umd/index.development.js.map +1 -1
  101. package/build/umd/index.production.js +1 -1
  102. package/build/umd/index.production.js.map +1 -1
  103. package/package.json +9 -10
  104. package/src/aggregationFns.ts +123 -0
  105. package/src/core/cell.ts +48 -0
  106. package/src/core/column.ts +147 -0
  107. package/src/core/headers.ts +575 -0
  108. package/src/core/instance.ts +359 -0
  109. package/src/core/row.ts +85 -0
  110. package/src/createTable.ts +188 -0
  111. package/src/features/ColumnSizing.ts +170 -185
  112. package/src/features/Expanding.ts +120 -194
  113. package/src/features/Filters.ts +299 -381
  114. package/src/features/Grouping.ts +158 -220
  115. package/src/features/Ordering.ts +24 -25
  116. package/src/features/Pagination.ts +88 -73
  117. package/src/features/Pinning.ts +186 -63
  118. package/src/features/RowSelection.ts +107 -245
  119. package/src/features/Sorting.ts +125 -225
  120. package/src/features/Visibility.ts +116 -132
  121. package/src/filterFns.ts +135 -0
  122. package/src/index.ts +29 -0
  123. package/src/{sortTypes.ts → sortingFns.ts} +63 -85
  124. package/src/types.ts +62 -168
  125. package/src/utils/filterRowsUtils.ts +112 -0
  126. package/src/utils/getCoreRowModel.ts +84 -0
  127. package/src/utils/getExpandedRowModel.ts +54 -0
  128. package/src/utils/getFacetedMinMaxValues.ts +40 -0
  129. package/src/utils/getFacetedRowModel.ts +50 -0
  130. package/src/utils/getFacetedUniqueValues.ts +37 -0
  131. package/src/utils/getFilteredRowModel.ts +159 -0
  132. package/src/utils/getGroupedRowModel.ts +175 -0
  133. package/src/utils/getPaginationRowModel.ts +48 -0
  134. package/src/utils/getSortedRowModel.ts +116 -0
  135. package/src/utils.ts +126 -0
  136. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +0 -112
  137. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +0 -1
  138. package/build/cjs/aggregationTypes.js +0 -130
  139. package/build/cjs/aggregationTypes.js.map +0 -1
  140. package/build/cjs/core.js +0 -545
  141. package/build/cjs/core.js.map +0 -1
  142. package/build/cjs/features/Headers.js +0 -630
  143. package/build/cjs/features/Headers.js.map +0 -1
  144. package/build/cjs/filterTypes.js +0 -172
  145. package/build/cjs/filterTypes.js.map +0 -1
  146. package/build/cjs/sortTypes.js +0 -122
  147. package/build/cjs/sortTypes.js.map +0 -1
  148. package/build/cjs/types.js +0 -22
  149. package/build/cjs/types.js.map +0 -1
  150. package/build/cjs/utils/columnFilterRowsFn.js +0 -131
  151. package/build/cjs/utils/columnFilterRowsFn.js.map +0 -1
  152. package/build/cjs/utils/expandRowsFn.js +0 -38
  153. package/build/cjs/utils/expandRowsFn.js.map +0 -1
  154. package/build/cjs/utils/globalFilterRowsFn.js +0 -101
  155. package/build/cjs/utils/globalFilterRowsFn.js.map +0 -1
  156. package/build/cjs/utils/groupRowsFn.js +0 -155
  157. package/build/cjs/utils/groupRowsFn.js.map +0 -1
  158. package/build/cjs/utils/paginateRowsFn.js +0 -44
  159. package/build/cjs/utils/paginateRowsFn.js.map +0 -1
  160. package/build/cjs/utils/sortRowsFn.js +0 -94
  161. package/build/cjs/utils/sortRowsFn.js.map +0 -1
  162. package/build/types/aggregationTypes.d.ts +0 -22
  163. package/build/types/core.d.ts +0 -105
  164. package/build/types/features/Headers.d.ts +0 -43
  165. package/build/types/filterTypes.d.ts +0 -50
  166. package/build/types/sortTypes.d.ts +0 -18
  167. package/build/types/utils/columnFilterRowsFn.d.ts +0 -2
  168. package/build/types/utils/expandRowsFn.d.ts +0 -2
  169. package/build/types/utils/globalFilterRowsFn.d.ts +0 -2
  170. package/build/types/utils/groupRowsFn.d.ts +0 -2
  171. package/build/types/utils/paginateRowsFn.d.ts +0 -2
  172. package/build/types/utils/sortRowsFn.d.ts +0 -2
  173. package/src/.DS_Store +0 -0
  174. package/src/aggregationTypes.ts +0 -115
  175. package/src/core.tsx +0 -763
  176. package/src/createTable.tsx +0 -137
  177. package/src/features/Headers.ts +0 -747
  178. package/src/filterTypes.ts +0 -188
  179. package/src/index.tsx +0 -23
  180. package/src/utils/columnFilterRowsFn.ts +0 -113
  181. package/src/utils/expandRowsFn.ts +0 -30
  182. package/src/utils/globalFilterRowsFn.ts +0 -89
  183. package/src/utils/groupRowsFn.ts +0 -170
  184. package/src/utils/paginateRowsFn.ts +0 -28
  185. package/src/utils/sortRowsFn.ts +0 -95
  186. package/src/utils.tsx +0 -221
@@ -0,0 +1,37 @@
1
+ import { TableInstance, TableGenerics } from '../types'
2
+ import { memo } from '../utils'
3
+
4
+ export function getFacetedUniqueValues<TGenerics extends TableGenerics>(): (
5
+ instance: TableInstance<TGenerics>,
6
+ columnId: string
7
+ ) => () => Map<any, number> {
8
+ return (instance, columnId) =>
9
+ memo(
10
+ () => [instance.getColumn(columnId).getFacetedRowModel()],
11
+ facetedRowModel => {
12
+ let facetedUniqueValues = new Map<any, number>()
13
+
14
+ for (let i = 0; i < facetedRowModel.flatRows.length; i++) {
15
+ const value = facetedRowModel.flatRows[i]?.getValue(columnId)
16
+
17
+ if (facetedUniqueValues.has(value)) {
18
+ facetedUniqueValues.set(
19
+ value,
20
+ (facetedUniqueValues.get(value) ?? 0) + 1
21
+ )
22
+ } else {
23
+ facetedUniqueValues.set(value, 1)
24
+ }
25
+ }
26
+
27
+ return facetedUniqueValues
28
+ },
29
+ {
30
+ key:
31
+ process.env.NODE_ENV === 'development' &&
32
+ 'getFacetedUniqueValues_' + columnId,
33
+ debug: () => instance.options.debugAll ?? instance.options.debugTable,
34
+ onChange: () => {},
35
+ }
36
+ )
37
+ }
@@ -0,0 +1,159 @@
1
+ import { ResolvedColumnFilter } from '../features/Filters'
2
+ import { TableInstance, RowModel, TableGenerics, Row } from '../types'
3
+ import { memo } from '../utils'
4
+ import { filterRows } from './filterRowsUtils'
5
+
6
+ export function getFilteredRowModel<TGenerics extends TableGenerics>(): (
7
+ instance: TableInstance<TGenerics>
8
+ ) => () => RowModel<TGenerics> {
9
+ return instance =>
10
+ memo(
11
+ () => [
12
+ instance.getPreFilteredRowModel(),
13
+ instance.getState().columnFilters,
14
+ instance.getState().globalFilter,
15
+ ],
16
+ (rowModel, columnFilters, globalFilter) => {
17
+ if (
18
+ !rowModel.rows.length ||
19
+ (!columnFilters?.length && !globalFilter)
20
+ ) {
21
+ for (let i = 0; i < rowModel.flatRows.length; i++) {
22
+ rowModel.flatRows[i]!.columnFilters = {}
23
+ rowModel.flatRows[i]!.columnFiltersMeta = {}
24
+ }
25
+ return rowModel
26
+ }
27
+
28
+ const resolvedColumnFilters: ResolvedColumnFilter<TGenerics>[] = []
29
+ const resolvedGlobalFilters: ResolvedColumnFilter<TGenerics>[] = []
30
+
31
+ ;(columnFilters ?? []).forEach(d => {
32
+ const column = instance.getColumn(d.id)
33
+
34
+ if (!column) {
35
+ if (process.env.NODE_ENV !== 'production') {
36
+ console.warn(
37
+ `Table: Could not find a column to filter with columnId: ${d.id}`
38
+ )
39
+ }
40
+ }
41
+
42
+ const filterFn = column.getFilterFn()
43
+
44
+ if (!filterFn) {
45
+ if (process.env.NODE_ENV !== 'production') {
46
+ console.warn(
47
+ `Could not find a valid 'column.filterFn' for column with the ID: ${column.id}.`
48
+ )
49
+ }
50
+ return
51
+ }
52
+
53
+ resolvedColumnFilters.push({
54
+ id: d.id,
55
+ filterFn,
56
+ resolvedValue: filterFn.resolveFilterValue?.(d.value) ?? d.value,
57
+ })
58
+ })
59
+
60
+ const filterableIds = columnFilters.map(d => d.id)
61
+
62
+ const globalFilterFn = instance.getGlobalFilterFn()
63
+
64
+ const globallyFilterableColumns = instance
65
+ .getAllLeafColumns()
66
+ .filter(column => column.getCanGlobalFilter())
67
+
68
+ if (
69
+ globalFilter &&
70
+ globalFilterFn &&
71
+ globallyFilterableColumns.length
72
+ ) {
73
+ filterableIds.push('__global__')
74
+
75
+ globallyFilterableColumns.forEach(column => {
76
+ resolvedGlobalFilters.push({
77
+ id: column.id,
78
+ filterFn: globalFilterFn,
79
+ resolvedValue:
80
+ globalFilterFn.resolveFilterValue?.(globalFilter) ??
81
+ globalFilter,
82
+ })
83
+ })
84
+ }
85
+
86
+ let currentColumnFilter
87
+ let currentGlobalFilter
88
+
89
+ // Flag the prefiltered row model with each filter state
90
+ for (let j = 0; j < rowModel.flatRows.length; j++) {
91
+ const row = rowModel.flatRows[j]!
92
+
93
+ row.columnFilters = {}
94
+
95
+ if (resolvedColumnFilters.length) {
96
+ for (let i = 0; i < resolvedColumnFilters.length; i++) {
97
+ currentColumnFilter = resolvedColumnFilters[i]!
98
+ const id = currentColumnFilter.id
99
+
100
+ // Tag the row with the column filter state
101
+ row.columnFilters[id] = currentColumnFilter.filterFn(
102
+ row,
103
+ id,
104
+ currentColumnFilter.resolvedValue,
105
+ filterMeta => {
106
+ row.columnFiltersMeta[id] = filterMeta
107
+ }
108
+ )
109
+ }
110
+ }
111
+
112
+ if (resolvedGlobalFilters.length) {
113
+ for (let i = 0; i < resolvedGlobalFilters.length; i++) {
114
+ currentGlobalFilter = resolvedGlobalFilters[i]!
115
+ const id = currentGlobalFilter.id
116
+ // Tag the row with the first truthy global filter state
117
+ if (
118
+ currentGlobalFilter.filterFn(
119
+ row,
120
+ id,
121
+ currentGlobalFilter.resolvedValue,
122
+ filterMeta => {
123
+ row.columnFiltersMeta[id] = filterMeta
124
+ }
125
+ )
126
+ ) {
127
+ row.columnFilters.__global__ = true
128
+ break
129
+ }
130
+ }
131
+
132
+ if (row.columnFilters.__global__ !== true) {
133
+ row.columnFilters.__global__ = false
134
+ }
135
+ }
136
+ }
137
+
138
+ const filterRowsImpl = (row: Row<TGenerics>) => {
139
+ // Horizontally filter rows through each column
140
+ for (let i = 0; i < filterableIds.length; i++) {
141
+ if (row.columnFilters[filterableIds[i]!] === false) {
142
+ return false
143
+ }
144
+ }
145
+ return true
146
+ }
147
+
148
+ // Filter final rows using all of the active filters
149
+ return filterRows(rowModel.rows, filterRowsImpl, instance)
150
+ },
151
+ {
152
+ key: process.env.NODE_ENV === 'development' && 'getFilteredRowModel',
153
+ debug: () => instance.options.debugAll ?? instance.options.debugTable,
154
+ onChange: () => {
155
+ instance._autoResetPageIndex()
156
+ },
157
+ }
158
+ )
159
+ }
@@ -0,0 +1,175 @@
1
+ import { createRow } from '../core/row'
2
+ import { TableInstance, Row, RowModel, TableGenerics } from '../types'
3
+ import { flattenBy, memo } from '../utils'
4
+
5
+ export function getGroupedRowModel<TGenerics extends TableGenerics>(): (
6
+ instance: TableInstance<TGenerics>
7
+ ) => () => RowModel<TGenerics> {
8
+ return instance =>
9
+ memo(
10
+ () => [instance.getState().grouping, instance.getPreGroupedRowModel()],
11
+ (grouping, rowModel) => {
12
+ if (!rowModel.rows.length || !grouping.length) {
13
+ return rowModel
14
+ }
15
+
16
+ // Filter the grouping list down to columns that exist
17
+ const existingGrouping = grouping.filter(columnId =>
18
+ instance.getColumn(columnId)
19
+ )
20
+
21
+ const groupedFlatRows: Row<TGenerics>[] = []
22
+ const groupedRowsById: Record<string, Row<TGenerics>> = {}
23
+ // const onlyGroupedFlatRows: Row[] = [];
24
+ // const onlyGroupedRowsById: Record<RowId, Row> = {};
25
+ // const nonGroupedFlatRows: Row[] = [];
26
+ // const nonGroupedRowsById: Record<RowId, Row> = {};
27
+
28
+ // Recursively group the data
29
+ const groupUpRecursively = (
30
+ rows: Row<TGenerics>[],
31
+ depth = 0,
32
+ parentId: string
33
+ ) => {
34
+ // This is the last level, just return the rows
35
+ if (depth === existingGrouping.length) {
36
+ return rows
37
+ }
38
+
39
+ const columnId = existingGrouping[depth]!
40
+
41
+ // Group the rows together for this level
42
+ const rowGroupsMap = groupBy(rows, columnId)
43
+
44
+ // Peform aggregations for each group
45
+ const aggregatedGroupedRows = Array.from(rowGroupsMap.entries()).map(
46
+ ([groupingValue, groupedRows], index) => {
47
+ let id = `${columnId}:${groupingValue}`
48
+ id = parentId ? `${parentId}>${id}` : id
49
+
50
+ // First, Recurse to group sub rows before aggregation
51
+ const subRows = groupUpRecursively(groupedRows, depth + 1, id)
52
+
53
+ // Flatten the leaf rows of the rows in this group
54
+ const leafRows = depth
55
+ ? flattenBy(groupedRows, row => row.subRows)
56
+ : groupedRows
57
+
58
+ const row = createRow(instance, id, undefined, index, depth)
59
+
60
+ Object.assign(row, {
61
+ groupingColumnId: columnId,
62
+ groupingValue,
63
+ subRows,
64
+ leafRows,
65
+ getValue: (columnId: string) => {
66
+ // Don't aggregate columns that are in the grouping
67
+ if (existingGrouping.includes(columnId)) {
68
+ if (row._valuesCache.hasOwnProperty(columnId)) {
69
+ return row._valuesCache[columnId]
70
+ }
71
+
72
+ if (groupedRows[0]) {
73
+ row._valuesCache[columnId] =
74
+ groupedRows[0].getValue(columnId) ?? undefined
75
+ }
76
+
77
+ return row._valuesCache[columnId]
78
+ }
79
+
80
+ if (row._groupingValuesCache.hasOwnProperty(columnId)) {
81
+ return row._groupingValuesCache[columnId]
82
+ }
83
+
84
+ // Aggregate the values
85
+ const column = instance.getColumn(columnId)
86
+ const aggregateFn = column.getAggregationFn()
87
+
88
+ if (aggregateFn) {
89
+ row._groupingValuesCache[columnId] = aggregateFn(
90
+ columnId,
91
+ leafRows,
92
+ groupedRows
93
+ )
94
+
95
+ return row._groupingValuesCache[columnId]
96
+ } else if (column.aggregationFn) {
97
+ console.info({ column })
98
+ throw new Error(
99
+ process.env.NODE_ENV !== 'production'
100
+ ? `Table: Invalid column.aggregateType option for column listed above`
101
+ : ''
102
+ )
103
+ }
104
+ },
105
+ })
106
+
107
+ subRows.forEach(subRow => {
108
+ groupedFlatRows.push(subRow)
109
+ groupedRowsById[subRow.id] = subRow
110
+ // if (subRow.getIsGrouped?.()) {
111
+ // onlyGroupedFlatRows.push(subRow);
112
+ // onlyGroupedRowsById[subRow.id] = subRow;
113
+ // } else {
114
+ // nonGroupedFlatRows.push(subRow);
115
+ // nonGroupedRowsById[subRow.id] = subRow;
116
+ // }
117
+ })
118
+
119
+ return row
120
+ }
121
+ )
122
+
123
+ return aggregatedGroupedRows
124
+ }
125
+
126
+ const groupedRows = groupUpRecursively(rowModel.rows, 0, '')
127
+
128
+ groupedRows.forEach(subRow => {
129
+ groupedFlatRows.push(subRow)
130
+ groupedRowsById[subRow.id] = subRow
131
+ // if (subRow.getIsGrouped?.()) {
132
+ // onlyGroupedFlatRows.push(subRow);
133
+ // onlyGroupedRowsById[subRow.id] = subRow;
134
+ // } else {
135
+ // nonGroupedFlatRows.push(subRow);
136
+ // nonGroupedRowsById[subRow.id] = subRow;
137
+ // }
138
+ })
139
+
140
+ return {
141
+ rows: groupedRows,
142
+ flatRows: groupedFlatRows,
143
+ rowsById: groupedRowsById,
144
+ }
145
+ },
146
+ {
147
+ key: process.env.NODE_ENV === 'development' && 'getGroupedRowModel',
148
+ debug: () => instance.options.debugAll ?? instance.options.debugTable,
149
+ onChange: () => {
150
+ instance._queue(() => {
151
+ instance._autoResetExpanded()
152
+ instance._autoResetPageIndex()
153
+ })
154
+ },
155
+ }
156
+ )
157
+ }
158
+
159
+ function groupBy<TGenerics extends TableGenerics>(
160
+ rows: Row<TGenerics>[],
161
+ columnId: string
162
+ ) {
163
+ const groupMap = new Map<any, Row<TGenerics>[]>()
164
+
165
+ return rows.reduce((map, row) => {
166
+ const resKey = `${row.getValue(columnId)}`
167
+ const previous = map.get(resKey)
168
+ if (!previous) {
169
+ map.set(resKey, [row])
170
+ } else {
171
+ map.set(resKey, [...previous, row])
172
+ }
173
+ return map
174
+ }, groupMap)
175
+ }
@@ -0,0 +1,48 @@
1
+ import { TableInstance, RowModel, TableGenerics } from '../types'
2
+ import { memo } from '../utils'
3
+ import { expandRows } from './getExpandedRowModel'
4
+
5
+ export function getPaginationRowModel<TGenerics extends TableGenerics>(opts?: {
6
+ initialSync: boolean
7
+ }): (instance: TableInstance<TGenerics>) => () => RowModel<TGenerics> {
8
+ return instance =>
9
+ memo(
10
+ () => [
11
+ instance.getState().pagination,
12
+ instance.getPrePaginationRowModel(),
13
+ ],
14
+ (pagination, rowModel) => {
15
+ if (!rowModel.rows.length) {
16
+ return rowModel
17
+ }
18
+
19
+ const { pageSize, pageIndex } = pagination
20
+ let { rows, flatRows, rowsById } = rowModel
21
+ const pageStart = pageSize * pageIndex
22
+ const pageEnd = pageStart + pageSize
23
+
24
+ rows = rows.slice(pageStart, pageEnd)
25
+
26
+ if (!instance.options.paginateExpandedRows) {
27
+ return expandRows(
28
+ {
29
+ rows,
30
+ flatRows,
31
+ rowsById,
32
+ },
33
+ instance
34
+ )
35
+ }
36
+
37
+ return {
38
+ rows,
39
+ flatRows,
40
+ rowsById,
41
+ }
42
+ },
43
+ {
44
+ key: process.env.NODE_ENV === 'development' && 'getPaginationRowModel',
45
+ debug: () => instance.options.debugAll ?? instance.options.debugTable,
46
+ }
47
+ )
48
+ }
@@ -0,0 +1,116 @@
1
+ import { TableInstance, Row, RowModel, TableGenerics } from '../types'
2
+ import { SortingFn } from '../features/Sorting'
3
+ import { memo } from '../utils'
4
+
5
+ export function getSortedRowModel<TGenerics extends TableGenerics>(): (
6
+ instance: TableInstance<TGenerics>
7
+ ) => () => RowModel<TGenerics> {
8
+ return instance =>
9
+ memo(
10
+ () => [instance.getState().sorting, instance.getPreSortedRowModel()],
11
+ (sorting, rowModel) => {
12
+ if (!rowModel.rows.length || !sorting?.length) {
13
+ return rowModel
14
+ }
15
+
16
+ const sortingState = instance.getState().sorting
17
+
18
+ const sortedFlatRows: Row<TGenerics>[] = []
19
+
20
+ // Filter out sortings that correspond to non existing columns
21
+ const availableSorting = sortingState.filter(sort =>
22
+ instance.getColumn(sort.id).getCanSort()
23
+ )
24
+
25
+ const columnInfoById: Record<
26
+ string,
27
+ {
28
+ sortUndefined?: false | -1 | 1
29
+ invertSorting?: boolean
30
+ sortingFn: SortingFn<TGenerics>
31
+ }
32
+ > = {}
33
+
34
+ availableSorting.forEach(sortEntry => {
35
+ const column = instance.getColumn(sortEntry.id)
36
+
37
+ columnInfoById[sortEntry.id] = {
38
+ sortUndefined: column.columnDef.sortUndefined,
39
+ invertSorting: column.columnDef.invertSorting,
40
+ sortingFn: column.getSortingFn(),
41
+ }
42
+ })
43
+
44
+ const sortData = (rows: Row<TGenerics>[]) => {
45
+ // This will also perform a stable sorting using the row index
46
+ // if needed.
47
+ const sortedData = rows.slice()
48
+
49
+ sortedData.sort((rowA, rowB) => {
50
+ for (let i = 0; i < availableSorting.length; i += 1) {
51
+ const sortEntry = availableSorting[i]!
52
+ const columnInfo = columnInfoById[sortEntry.id]!
53
+ const isDesc = sortEntry?.desc ?? false
54
+
55
+ if (columnInfo.sortUndefined) {
56
+ const aValue = rowA.getValue(sortEntry.id)
57
+ const bValue = rowB.getValue(sortEntry.id)
58
+
59
+ const aUndefined = typeof aValue === 'undefined'
60
+ const bUndefined = typeof bValue === 'undefined'
61
+
62
+ if (aUndefined || bUndefined) {
63
+ return aUndefined && bUndefined
64
+ ? 0
65
+ : aUndefined
66
+ ? columnInfo.sortUndefined
67
+ : -columnInfo.sortUndefined
68
+ }
69
+ }
70
+
71
+ // This function should always return in ascending order
72
+ let sortInt = columnInfo.sortingFn(rowA, rowB, sortEntry.id)
73
+
74
+ if (sortInt !== 0) {
75
+ if (isDesc) {
76
+ sortInt *= -1
77
+ }
78
+
79
+ if (columnInfo.invertSorting) {
80
+ sortInt *= -1
81
+ }
82
+
83
+ return sortInt
84
+ }
85
+ }
86
+
87
+ return rowA.index - rowB.index
88
+ })
89
+
90
+ // If there are sub-rows, sort them
91
+ sortedData.forEach(row => {
92
+ sortedFlatRows.push(row)
93
+ if (!row.subRows || row.subRows.length <= 1) {
94
+ return
95
+ }
96
+ row.subRows = sortData(row.subRows)
97
+ })
98
+
99
+ return sortedData
100
+ }
101
+
102
+ return {
103
+ rows: sortData(rowModel.rows),
104
+ flatRows: sortedFlatRows,
105
+ rowsById: rowModel.rowsById,
106
+ }
107
+ },
108
+ {
109
+ key: process.env.NODE_ENV === 'development' && 'getSortedRowModel',
110
+ debug: () => instance.options.debugAll ?? instance.options.debugTable,
111
+ onChange: () => {
112
+ instance._autoResetPageIndex()
113
+ },
114
+ }
115
+ )
116
+ }
package/src/utils.ts ADDED
@@ -0,0 +1,126 @@
1
+ import { NoInfer, TableState, Updater } from './types'
2
+
3
+ export type PartialKeys<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>
4
+ export type RequiredKeys<T, K extends keyof T> = Omit<T, K> &
5
+ Required<Pick<T, K>>
6
+ export type Overwrite<T, U extends { [TKey in keyof T]?: any }> = Omit<
7
+ T,
8
+ keyof U
9
+ > &
10
+ U
11
+
12
+ export type IfDefined<T, N> = 0 extends 1 & T ? N : T extends {} ? T : N
13
+
14
+ export function functionalUpdate<T>(updater: Updater<T>, input: T): T {
15
+ return typeof updater === 'function'
16
+ ? (updater as (input: T) => T)(input)
17
+ : updater
18
+ }
19
+
20
+ export function noop() {
21
+ //
22
+ }
23
+
24
+ export function makeStateUpdater(key: keyof TableState, instance: unknown) {
25
+ return (updater: Updater<any>) => {
26
+ ;(instance as any).setState(<TTableState>(old: TTableState) => {
27
+ return {
28
+ ...old,
29
+ [key]: functionalUpdate(updater, (old as any)[key]),
30
+ }
31
+ })
32
+ }
33
+ }
34
+
35
+ type AnyFunction = (...args: any) => any
36
+
37
+ export function isFunction<T extends AnyFunction>(d: any): d is T {
38
+ return d instanceof Function
39
+ }
40
+
41
+ export function flattenBy<TNode>(
42
+ arr: TNode[],
43
+ getChildren: (item: TNode) => TNode[]
44
+ ) {
45
+ const flat: TNode[] = []
46
+
47
+ const recurse = (subArr: TNode[]) => {
48
+ subArr.forEach(item => {
49
+ flat.push(item)
50
+ const children = getChildren(item)
51
+ if (children?.length) {
52
+ recurse(children)
53
+ }
54
+ })
55
+ }
56
+
57
+ recurse(arr)
58
+
59
+ return flat
60
+ }
61
+
62
+ export function memo<TDeps extends readonly any[], TResult>(
63
+ getDeps: () => [...TDeps],
64
+ fn: (...args: NoInfer<[...TDeps]>) => TResult,
65
+ opts: {
66
+ key: any
67
+ debug?: () => any
68
+ onChange?: (result: TResult) => void
69
+ }
70
+ ): () => TResult {
71
+ let deps: any[] = []
72
+ let result: TResult | undefined
73
+
74
+ return () => {
75
+ let depTime: number
76
+ if (opts.key && opts.debug) depTime = Date.now()
77
+
78
+ const newDeps = getDeps()
79
+
80
+ const depsChanged =
81
+ newDeps.length !== deps.length ||
82
+ newDeps.some((dep: any, index: number) => deps[index] !== dep)
83
+
84
+ if (!depsChanged) {
85
+ return result!
86
+ }
87
+
88
+ deps = newDeps
89
+
90
+ let resultTime: number
91
+ if (opts.key && opts.debug) resultTime = Date.now()
92
+
93
+ result = fn(...newDeps)
94
+ opts?.onChange?.(result)
95
+
96
+ if (opts.key && opts.debug) {
97
+ if (opts?.debug()) {
98
+ const depEndTime = Math.round((Date.now() - depTime!) * 100) / 100
99
+ const resultEndTime = Math.round((Date.now() - resultTime!) * 100) / 100
100
+ const resultFpsPercentage = resultEndTime / 16
101
+
102
+ const pad = (str: number | string, num: number) => {
103
+ str = String(str)
104
+ while (str.length < num) {
105
+ str = ' ' + str
106
+ }
107
+ return str
108
+ }
109
+
110
+ console.info(
111
+ `%c⏱ ${pad(resultEndTime, 5)} /${pad(depEndTime, 5)} ms`,
112
+ `
113
+ font-size: .6rem;
114
+ font-weight: bold;
115
+ color: hsl(${Math.max(
116
+ 0,
117
+ Math.min(120 - 120 * resultFpsPercentage, 120)
118
+ )}deg 100% 31%);`,
119
+ opts?.key
120
+ )
121
+ }
122
+ }
123
+
124
+ return result!
125
+ }
126
+ }