@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,575 @@
1
+ import {
2
+ Column,
3
+ Header,
4
+ HeaderGroup,
5
+ TableGenerics,
6
+ TableInstance,
7
+ } from '../types'
8
+ import { memo } from '../utils'
9
+ import { TableFeature } from './instance'
10
+
11
+ export type CoreHeaderGroup<TGenerics extends TableGenerics> = {
12
+ id: string
13
+ depth: number
14
+ headers: Header<TGenerics>[]
15
+ }
16
+
17
+ export type CoreHeader<TGenerics extends TableGenerics> = {
18
+ id: string
19
+ index: number
20
+ depth: number
21
+ column: Column<TGenerics>
22
+ headerGroup: HeaderGroup<TGenerics>
23
+ subHeaders: Header<TGenerics>[]
24
+ colSpan: number
25
+ rowSpan: number
26
+ getLeafHeaders: () => Header<TGenerics>[]
27
+ isPlaceholder: boolean
28
+ placeholderId?: string
29
+ renderHeader: (options?: {
30
+ renderPlaceholder?: boolean
31
+ }) => string | null | TGenerics['Rendered']
32
+ renderFooter: (options?: {
33
+ renderPlaceholder?: boolean
34
+ }) => string | null | TGenerics['Rendered']
35
+ }
36
+
37
+ export type HeadersInstance<TGenerics extends TableGenerics> = {
38
+ getHeaderGroups: () => HeaderGroup<TGenerics>[]
39
+ getLeftHeaderGroups: () => HeaderGroup<TGenerics>[]
40
+ getCenterHeaderGroups: () => HeaderGroup<TGenerics>[]
41
+ getRightHeaderGroups: () => HeaderGroup<TGenerics>[]
42
+
43
+ getFooterGroups: () => HeaderGroup<TGenerics>[]
44
+ getLeftFooterGroups: () => HeaderGroup<TGenerics>[]
45
+ getCenterFooterGroups: () => HeaderGroup<TGenerics>[]
46
+ getRightFooterGroups: () => HeaderGroup<TGenerics>[]
47
+
48
+ getFlatHeaders: () => Header<TGenerics>[]
49
+ getLeftFlatHeaders: () => Header<TGenerics>[]
50
+ getCenterFlatHeaders: () => Header<TGenerics>[]
51
+ getRightFlatHeaders: () => Header<TGenerics>[]
52
+
53
+ getLeafHeaders: () => Header<TGenerics>[]
54
+ getLeftLeafHeaders: () => Header<TGenerics>[]
55
+ getCenterLeafHeaders: () => Header<TGenerics>[]
56
+ getRightLeafHeaders: () => Header<TGenerics>[]
57
+ }
58
+
59
+ //
60
+
61
+ function createHeader<TGenerics extends TableGenerics>(
62
+ instance: TableInstance<TGenerics>,
63
+ column: Column<TGenerics>,
64
+ options: {
65
+ id?: string
66
+ isPlaceholder?: boolean
67
+ placeholderId?: string
68
+ index: number
69
+ depth: number
70
+ }
71
+ ) {
72
+ const id = options.id ?? column.id
73
+
74
+ let header: CoreHeader<TGenerics> = {
75
+ id,
76
+ column,
77
+ index: options.index,
78
+ isPlaceholder: !!options.isPlaceholder,
79
+ placeholderId: options.placeholderId,
80
+ depth: options.depth,
81
+ subHeaders: [],
82
+ colSpan: 0,
83
+ rowSpan: 0,
84
+ headerGroup: null!,
85
+ getLeafHeaders: (): Header<TGenerics>[] => {
86
+ const leafHeaders: CoreHeader<TGenerics>[] = []
87
+
88
+ const recurseHeader = (h: CoreHeader<TGenerics>) => {
89
+ if (h.subHeaders && h.subHeaders.length) {
90
+ h.subHeaders.map(recurseHeader)
91
+ }
92
+ leafHeaders.push(h)
93
+ }
94
+
95
+ recurseHeader(header)
96
+
97
+ return leafHeaders as Header<TGenerics>[]
98
+ },
99
+ renderHeader: () =>
100
+ column.columnDef.header
101
+ ? instance._render(column.columnDef.header, {
102
+ instance,
103
+ header: header as Header<TGenerics>,
104
+ column,
105
+ })
106
+ : null,
107
+ renderFooter: () =>
108
+ column.columnDef.footer
109
+ ? instance._render(column.columnDef.footer, {
110
+ instance,
111
+ header: header as Header<TGenerics>,
112
+ column,
113
+ })
114
+ : null,
115
+ }
116
+
117
+ instance._features.forEach(feature => {
118
+ Object.assign(header, feature.createHeader?.(header, instance))
119
+ })
120
+
121
+ return header as Header<TGenerics>
122
+ }
123
+
124
+ export const Headers: TableFeature = {
125
+ createInstance: <TGenerics extends TableGenerics>(
126
+ instance: TableInstance<TGenerics>
127
+ ): HeadersInstance<TGenerics> => {
128
+ return {
129
+ // Header Groups
130
+
131
+ getHeaderGroups: memo(
132
+ () => [
133
+ instance.getAllColumns(),
134
+ instance.getVisibleLeafColumns(),
135
+ instance.getState().columnPinning.left,
136
+ instance.getState().columnPinning.right,
137
+ ],
138
+ (allColumns, leafColumns, left, right) => {
139
+ const leftColumns =
140
+ left
141
+ ?.map(columnId => leafColumns.find(d => d.id === columnId)!)
142
+ .filter(Boolean) ?? []
143
+
144
+ const rightColumns =
145
+ right
146
+ ?.map(columnId => leafColumns.find(d => d.id === columnId)!)
147
+ .filter(Boolean) ?? []
148
+
149
+ const centerColumns = leafColumns.filter(
150
+ column => !left?.includes(column.id) && !right?.includes(column.id)
151
+ )
152
+
153
+ const headerGroups = buildHeaderGroups(
154
+ allColumns,
155
+ [...leftColumns, ...centerColumns, ...rightColumns],
156
+ instance
157
+ )
158
+
159
+ return headerGroups
160
+ },
161
+ {
162
+ key: process.env.NODE_ENV === 'development' && 'getHeaderGroups',
163
+ debug: () =>
164
+ instance.options.debugAll ?? instance.options.debugHeaders,
165
+ }
166
+ ),
167
+
168
+ getCenterHeaderGroups: memo(
169
+ () => [
170
+ instance.getAllColumns(),
171
+ instance.getVisibleLeafColumns(),
172
+ instance.getState().columnPinning.left,
173
+ instance.getState().columnPinning.right,
174
+ ],
175
+ (allColumns, leafColumns, left, right) => {
176
+ leafColumns = leafColumns.filter(
177
+ column => !left?.includes(column.id) && !right?.includes(column.id)
178
+ )
179
+ return buildHeaderGroups(allColumns, leafColumns, instance, 'center')
180
+ },
181
+ {
182
+ key:
183
+ process.env.NODE_ENV === 'development' && 'getCenterHeaderGroups',
184
+ debug: () =>
185
+ instance.options.debugAll ?? instance.options.debugHeaders,
186
+ }
187
+ ),
188
+
189
+ getLeftHeaderGroups: memo(
190
+ () => [
191
+ instance.getAllColumns(),
192
+ instance.getVisibleLeafColumns(),
193
+ instance.getState().columnPinning.left,
194
+ ],
195
+ (allColumns, leafColumns, left) => {
196
+ const orderedLeafColumns =
197
+ left
198
+ ?.map(columnId => leafColumns.find(d => d.id === columnId)!)
199
+ .filter(Boolean) ?? []
200
+
201
+ return buildHeaderGroups(
202
+ allColumns,
203
+ orderedLeafColumns,
204
+ instance,
205
+ 'left'
206
+ )
207
+ },
208
+ {
209
+ key: process.env.NODE_ENV === 'development' && 'getLeftHeaderGroups',
210
+ debug: () =>
211
+ instance.options.debugAll ?? instance.options.debugHeaders,
212
+ }
213
+ ),
214
+
215
+ getRightHeaderGroups: memo(
216
+ () => [
217
+ instance.getAllColumns(),
218
+ instance.getVisibleLeafColumns(),
219
+ instance.getState().columnPinning.right,
220
+ ],
221
+ (allColumns, leafColumns, right) => {
222
+ const orderedLeafColumns =
223
+ right
224
+ ?.map(columnId => leafColumns.find(d => d.id === columnId)!)
225
+ .filter(Boolean) ?? []
226
+
227
+ return buildHeaderGroups(
228
+ allColumns,
229
+ orderedLeafColumns,
230
+ instance,
231
+ 'right'
232
+ )
233
+ },
234
+ {
235
+ key: process.env.NODE_ENV === 'development' && 'getRightHeaderGroups',
236
+ debug: () =>
237
+ instance.options.debugAll ?? instance.options.debugHeaders,
238
+ }
239
+ ),
240
+
241
+ // Footer Groups
242
+
243
+ getFooterGroups: memo(
244
+ () => [instance.getHeaderGroups()],
245
+ headerGroups => {
246
+ return [...headerGroups].reverse()
247
+ },
248
+ {
249
+ key: process.env.NODE_ENV === 'development' && 'getFooterGroups',
250
+ debug: () =>
251
+ instance.options.debugAll ?? instance.options.debugHeaders,
252
+ }
253
+ ),
254
+
255
+ getLeftFooterGroups: memo(
256
+ () => [instance.getLeftHeaderGroups()],
257
+ headerGroups => {
258
+ return [...headerGroups].reverse()
259
+ },
260
+ {
261
+ key: process.env.NODE_ENV === 'development' && 'getLeftFooterGroups',
262
+ debug: () =>
263
+ instance.options.debugAll ?? instance.options.debugHeaders,
264
+ }
265
+ ),
266
+
267
+ getCenterFooterGroups: memo(
268
+ () => [instance.getCenterHeaderGroups()],
269
+ headerGroups => {
270
+ return [...headerGroups].reverse()
271
+ },
272
+ {
273
+ key:
274
+ process.env.NODE_ENV === 'development' && 'getCenterFooterGroups',
275
+ debug: () =>
276
+ instance.options.debugAll ?? instance.options.debugHeaders,
277
+ }
278
+ ),
279
+
280
+ getRightFooterGroups: memo(
281
+ () => [instance.getRightHeaderGroups()],
282
+ headerGroups => {
283
+ return [...headerGroups].reverse()
284
+ },
285
+ {
286
+ key: process.env.NODE_ENV === 'development' && 'getRightFooterGroups',
287
+ debug: () =>
288
+ instance.options.debugAll ?? instance.options.debugHeaders,
289
+ }
290
+ ),
291
+
292
+ // Flat Headers
293
+
294
+ getFlatHeaders: memo(
295
+ () => [instance.getHeaderGroups()],
296
+ headerGroups => {
297
+ return headerGroups
298
+ .map(headerGroup => {
299
+ return headerGroup.headers
300
+ })
301
+ .flat()
302
+ },
303
+ {
304
+ key: process.env.NODE_ENV === 'development' && 'getFlatHeaders',
305
+ debug: () =>
306
+ instance.options.debugAll ?? instance.options.debugHeaders,
307
+ }
308
+ ),
309
+
310
+ getLeftFlatHeaders: memo(
311
+ () => [instance.getLeftHeaderGroups()],
312
+ left => {
313
+ return left
314
+ .map(headerGroup => {
315
+ return headerGroup.headers
316
+ })
317
+ .flat()
318
+ },
319
+ {
320
+ key: process.env.NODE_ENV === 'development' && 'getLeftFlatHeaders',
321
+ debug: () =>
322
+ instance.options.debugAll ?? instance.options.debugHeaders,
323
+ }
324
+ ),
325
+
326
+ getCenterFlatHeaders: memo(
327
+ () => [instance.getCenterHeaderGroups()],
328
+ left => {
329
+ return left
330
+ .map(headerGroup => {
331
+ return headerGroup.headers
332
+ })
333
+ .flat()
334
+ },
335
+ {
336
+ key: process.env.NODE_ENV === 'development' && 'getCenterFlatHeaders',
337
+ debug: () =>
338
+ instance.options.debugAll ?? instance.options.debugHeaders,
339
+ }
340
+ ),
341
+
342
+ getRightFlatHeaders: memo(
343
+ () => [instance.getRightHeaderGroups()],
344
+ left => {
345
+ return left
346
+ .map(headerGroup => {
347
+ return headerGroup.headers
348
+ })
349
+ .flat()
350
+ },
351
+ {
352
+ key: process.env.NODE_ENV === 'development' && 'getRightFlatHeaders',
353
+ debug: () =>
354
+ instance.options.debugAll ?? instance.options.debugHeaders,
355
+ }
356
+ ),
357
+
358
+ // Leaf Headers
359
+
360
+ getCenterLeafHeaders: memo(
361
+ () => [instance.getCenterFlatHeaders()],
362
+ flatHeaders => {
363
+ return flatHeaders.filter(header => !header.subHeaders?.length)
364
+ },
365
+ {
366
+ key: process.env.NODE_ENV === 'development' && 'getCenterLeafHeaders',
367
+ debug: () =>
368
+ instance.options.debugAll ?? instance.options.debugHeaders,
369
+ }
370
+ ),
371
+
372
+ getLeftLeafHeaders: memo(
373
+ () => [instance.getLeftFlatHeaders()],
374
+ flatHeaders => {
375
+ return flatHeaders.filter(header => !header.subHeaders?.length)
376
+ },
377
+ {
378
+ key: process.env.NODE_ENV === 'development' && 'getLeftLeafHeaders',
379
+ debug: () =>
380
+ instance.options.debugAll ?? instance.options.debugHeaders,
381
+ }
382
+ ),
383
+
384
+ getRightLeafHeaders: memo(
385
+ () => [instance.getRightFlatHeaders()],
386
+ flatHeaders => {
387
+ return flatHeaders.filter(header => !header.subHeaders?.length)
388
+ },
389
+ {
390
+ key: process.env.NODE_ENV === 'development' && 'getRightLeafHeaders',
391
+ debug: () =>
392
+ instance.options.debugAll ?? instance.options.debugHeaders,
393
+ }
394
+ ),
395
+
396
+ getLeafHeaders: memo(
397
+ () => [
398
+ instance.getLeftHeaderGroups(),
399
+ instance.getCenterHeaderGroups(),
400
+ instance.getRightHeaderGroups(),
401
+ ],
402
+ (left, center, right) => {
403
+ return [
404
+ ...(left[0]?.headers ?? []),
405
+ ...(center[0]?.headers ?? []),
406
+ ...(right[0]?.headers ?? []),
407
+ ]
408
+ .map(header => {
409
+ return header.getLeafHeaders()
410
+ })
411
+ .flat()
412
+ },
413
+ {
414
+ key: process.env.NODE_ENV === 'development' && 'getLeafHeaders',
415
+ debug: () =>
416
+ instance.options.debugAll ?? instance.options.debugHeaders,
417
+ }
418
+ ),
419
+ }
420
+ },
421
+ }
422
+
423
+ export function buildHeaderGroups<TGenerics extends TableGenerics>(
424
+ allColumns: Column<TGenerics>[],
425
+ columnsToGroup: Column<TGenerics>[],
426
+ instance: TableInstance<TGenerics>,
427
+ headerFamily?: 'center' | 'left' | 'right'
428
+ ) {
429
+ // Find the max depth of the columns:
430
+ // build the leaf column row
431
+ // build each buffer row going up
432
+ // placeholder for non-existent level
433
+ // real column for existing level
434
+
435
+ let maxDepth = 0
436
+
437
+ const findMaxDepth = (columns: Column<TGenerics>[], depth = 1) => {
438
+ maxDepth = Math.max(maxDepth, depth)
439
+
440
+ columns
441
+ .filter(column => column.getIsVisible())
442
+ .forEach(column => {
443
+ if (column.columns?.length) {
444
+ findMaxDepth(column.columns, depth + 1)
445
+ }
446
+ }, 0)
447
+ }
448
+
449
+ findMaxDepth(allColumns)
450
+
451
+ let headerGroups: HeaderGroup<TGenerics>[] = []
452
+
453
+ const createHeaderGroup = (
454
+ headersToGroup: Header<TGenerics>[],
455
+ depth: number
456
+ ) => {
457
+ // The header group we are creating
458
+ const headerGroup: HeaderGroup<TGenerics> = {
459
+ depth,
460
+ id: [headerFamily, `${depth}`].filter(Boolean).join('_'),
461
+ headers: [],
462
+ }
463
+
464
+ // The parent columns we're going to scan next
465
+ const pendingParentHeaders: Header<TGenerics>[] = []
466
+
467
+ // Scan each column for parents
468
+ headersToGroup.forEach(headerToGroup => {
469
+ // What is the latest (last) parent column?
470
+
471
+ const latestPendingParentHeader = [...pendingParentHeaders].reverse()[0]
472
+
473
+ const isLeafHeader = headerToGroup.column.depth === headerGroup.depth
474
+
475
+ let column: Column<TGenerics>
476
+ let isPlaceholder = false
477
+
478
+ if (isLeafHeader && headerToGroup.column.parent) {
479
+ // The parent header is new
480
+ column = headerToGroup.column.parent
481
+ } else {
482
+ // The parent header is repeated
483
+ column = headerToGroup.column
484
+ isPlaceholder = true
485
+ }
486
+
487
+ if (latestPendingParentHeader?.column === column) {
488
+ // This column is repeated. Add it as a sub header to the next batch
489
+ latestPendingParentHeader.subHeaders.push(headerToGroup)
490
+ } else {
491
+ // This is a new header. Let's create it
492
+ const header = createHeader(instance, column, {
493
+ id: [headerFamily, depth, column.id, headerToGroup?.id]
494
+ .filter(Boolean)
495
+ .join('_'),
496
+ isPlaceholder,
497
+ placeholderId: isPlaceholder
498
+ ? `${pendingParentHeaders.filter(d => d.column === column).length}`
499
+ : undefined,
500
+ depth,
501
+ index: pendingParentHeaders.length,
502
+ })
503
+
504
+ // Add the headerToGroup as a subHeader of the new header
505
+ header.subHeaders.push(headerToGroup)
506
+ // Add the new header to the pendingParentHeaders to get grouped
507
+ // in the next batch
508
+ pendingParentHeaders.push(header)
509
+ }
510
+
511
+ headerGroup.headers.push(headerToGroup)
512
+ headerToGroup.headerGroup = headerGroup
513
+ })
514
+
515
+ headerGroups.push(headerGroup)
516
+
517
+ if (depth > 0) {
518
+ createHeaderGroup(pendingParentHeaders, depth - 1)
519
+ }
520
+ }
521
+
522
+ const bottomHeaders = columnsToGroup.map((column, index) =>
523
+ createHeader(instance, column, {
524
+ depth: maxDepth,
525
+ index,
526
+ })
527
+ )
528
+
529
+ createHeaderGroup(bottomHeaders, maxDepth - 1)
530
+
531
+ headerGroups.reverse()
532
+
533
+ // headerGroups = headerGroups.filter(headerGroup => {
534
+ // return !headerGroup.headers.every(header => header.isPlaceholder)
535
+ // })
536
+
537
+ const recurseHeadersForSpans = (
538
+ headers: Header<TGenerics>[]
539
+ ): { colSpan: number; rowSpan: number }[] => {
540
+ const filteredHeaders = headers.filter(header =>
541
+ header.column.getIsVisible()
542
+ )
543
+
544
+ return filteredHeaders.map(header => {
545
+ let colSpan = 0
546
+ let rowSpan = 0
547
+ let childRowSpans = [0]
548
+
549
+ if (header.subHeaders && header.subHeaders.length) {
550
+ childRowSpans = []
551
+
552
+ recurseHeadersForSpans(header.subHeaders).forEach(
553
+ ({ colSpan: childColSpan, rowSpan: childRowSpan }) => {
554
+ colSpan += childColSpan
555
+ childRowSpans.push(childRowSpan)
556
+ }
557
+ )
558
+ } else {
559
+ colSpan = 1
560
+ }
561
+
562
+ const minChildRowSpan = Math.min(...childRowSpans)
563
+ rowSpan = rowSpan + minChildRowSpan
564
+
565
+ header.colSpan = colSpan
566
+ header.rowSpan = rowSpan
567
+
568
+ return { colSpan, rowSpan }
569
+ })
570
+ }
571
+
572
+ recurseHeadersForSpans(headerGroups[0]?.headers ?? [])
573
+
574
+ return headerGroups
575
+ }