@tanstack/table-core 8.0.0-alpha.54 → 8.0.0-alpha.58

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 (74) hide show
  1. package/build/cjs/core.js +9 -384
  2. package/build/cjs/core.js.map +1 -1
  3. package/build/cjs/features/Cells.js +122 -0
  4. package/build/cjs/features/Cells.js.map +1 -0
  5. package/build/cjs/features/ColumnSizing.js +90 -37
  6. package/build/cjs/features/ColumnSizing.js.map +1 -1
  7. package/build/cjs/features/Columns.js +216 -0
  8. package/build/cjs/features/Columns.js.map +1 -0
  9. package/build/cjs/features/Expanding.js +2 -2
  10. package/build/cjs/features/Expanding.js.map +1 -1
  11. package/build/cjs/features/Filters.js +3 -3
  12. package/build/cjs/features/Filters.js.map +1 -1
  13. package/build/cjs/features/Grouping.js +2 -2
  14. package/build/cjs/features/Grouping.js.map +1 -1
  15. package/build/cjs/features/Headers.js +78 -153
  16. package/build/cjs/features/Headers.js.map +1 -1
  17. package/build/cjs/features/Ordering.js +1 -1
  18. package/build/cjs/features/Ordering.js.map +1 -1
  19. package/build/cjs/features/Pagination.js +2 -2
  20. package/build/cjs/features/Pagination.js.map +1 -1
  21. package/build/cjs/features/Pinning.js +172 -2
  22. package/build/cjs/features/Pinning.js.map +1 -1
  23. package/build/cjs/features/RowSelection.js +1 -1
  24. package/build/cjs/features/RowSelection.js.map +1 -1
  25. package/build/cjs/features/Rows.js +99 -0
  26. package/build/cjs/features/Rows.js.map +1 -0
  27. package/build/cjs/features/Sorting.js +2 -2
  28. package/build/cjs/features/Sorting.js.map +1 -1
  29. package/build/cjs/features/Visibility.js +51 -17
  30. package/build/cjs/features/Visibility.js.map +1 -1
  31. package/build/cjs/utils.js.map +1 -1
  32. package/build/esm/index.js +881 -695
  33. package/build/esm/index.js.map +1 -1
  34. package/build/stats-html.html +1 -1
  35. package/build/stats-react.json +418 -316
  36. package/build/types/core.d.ts +2 -79
  37. package/build/types/features/Cells.d.ts +14 -0
  38. package/build/types/features/ColumnSizing.d.ts +26 -18
  39. package/build/types/features/Columns.d.ts +54 -0
  40. package/build/types/features/Expanding.d.ts +2 -1
  41. package/build/types/features/Filters.d.ts +3 -1
  42. package/build/types/features/Grouping.d.ts +2 -1
  43. package/build/types/features/Headers.d.ts +3 -11
  44. package/build/types/features/Ordering.d.ts +1 -1
  45. package/build/types/features/Pagination.d.ts +2 -1
  46. package/build/types/features/Pinning.d.ts +18 -4
  47. package/build/types/features/RowSelection.d.ts +1 -1
  48. package/build/types/features/Rows.d.ts +29 -0
  49. package/build/types/features/Sorting.d.ts +2 -1
  50. package/build/types/features/Visibility.d.ts +7 -2
  51. package/build/types/types.d.ts +18 -10
  52. package/build/types/utils.d.ts +0 -1
  53. package/build/umd/index.development.js +882 -696
  54. package/build/umd/index.development.js.map +1 -1
  55. package/build/umd/index.production.js +1 -1
  56. package/build/umd/index.production.js.map +1 -1
  57. package/package.json +1 -1
  58. package/src/core.ts +28 -550
  59. package/src/features/Cells.ts +156 -0
  60. package/src/features/ColumnSizing.ts +103 -51
  61. package/src/features/Columns.ts +290 -0
  62. package/src/features/Expanding.ts +7 -3
  63. package/src/features/Filters.ts +11 -3
  64. package/src/features/Grouping.ts +3 -2
  65. package/src/features/Headers.ts +48 -138
  66. package/src/features/Ordering.ts +1 -1
  67. package/src/features/Pagination.ts +6 -2
  68. package/src/features/Pinning.ts +194 -3
  69. package/src/features/RowSelection.ts +1 -1
  70. package/src/features/Rows.ts +151 -0
  71. package/src/features/Sorting.ts +3 -2
  72. package/src/features/Visibility.ts +67 -20
  73. package/src/types.ts +25 -37
  74. package/src/utils.ts +1 -3
@@ -0,0 +1,156 @@
1
+ import {
2
+ Cell,
3
+ TableGenerics,
4
+ TableInstance,
5
+ Row,
6
+ Column,
7
+ CoreCell,
8
+ Getter,
9
+ CellProps,
10
+ PropGetterValue,
11
+ } from '../types'
12
+ import { memo, propGetter } from '../utils'
13
+
14
+ export type CellsRow<TGenerics extends TableGenerics> = {
15
+ getAllCells: () => Cell<TGenerics>[]
16
+ getAllCellsByColumnId: () => Record<string, Cell<TGenerics>>
17
+ }
18
+
19
+ export type CellsInstance<TGenerics extends TableGenerics> = {
20
+ createCell: (
21
+ row: Row<TGenerics>,
22
+ column: Column<TGenerics>,
23
+ value: any
24
+ ) => Cell<TGenerics>
25
+ getCell: (rowId: string, columnId: string) => Cell<TGenerics>
26
+ getCellProps: <TGetter extends Getter<CellProps>>(
27
+ rowId: string,
28
+ columnId: string,
29
+ userProps?: TGetter
30
+ ) => undefined | PropGetterValue<CellProps, TGetter>
31
+ }
32
+
33
+ //
34
+
35
+ export const Cells = {
36
+ createRow: <TGenerics extends TableGenerics>(
37
+ row: Row<TGenerics>,
38
+ instance: TableInstance<TGenerics>
39
+ ): CellsRow<TGenerics> => {
40
+ return {
41
+ getAllCells: memo(
42
+ () => [instance.getAllLeafColumns()],
43
+ leafColumns => {
44
+ return leafColumns.map(column => {
45
+ return instance.createCell(
46
+ row as Row<TGenerics>,
47
+ column,
48
+ row.values[column.id]
49
+ )
50
+ })
51
+ },
52
+ {
53
+ key: process.env.NODE_ENV !== 'production' ? 'row.getAllCells' : '',
54
+ debug: () => instance.options.debugAll ?? instance.options.debugRows,
55
+ }
56
+ ),
57
+
58
+ getAllCellsByColumnId: memo(
59
+ () => [row.getAllCells()],
60
+ allCells => {
61
+ return allCells.reduce((acc, cell) => {
62
+ acc[cell.columnId] = cell
63
+ return acc
64
+ }, {} as Record<string, Cell<TGenerics>>)
65
+ },
66
+ {
67
+ key: 'row.getAllCellsByColumnId',
68
+ debug: () => instance.options.debugAll ?? instance.options.debugRows,
69
+ }
70
+ ),
71
+ }
72
+ },
73
+
74
+ createInstance: <TGenerics extends TableGenerics>(
75
+ instance: TableInstance<TGenerics>
76
+ ): CellsInstance<TGenerics> => {
77
+ return {
78
+ createCell: (row, column, value) => {
79
+ const cell: CoreCell<TGenerics> = {
80
+ id: `${row.id}_${column.id}`,
81
+ rowId: row.id,
82
+ columnId: column.id,
83
+ row,
84
+ column,
85
+ value,
86
+ getCellProps: userProps =>
87
+ instance.getCellProps(row.id, column.id, userProps)!,
88
+ renderCell: () =>
89
+ column.cell
90
+ ? instance.render(column.cell, {
91
+ instance,
92
+ column,
93
+ row,
94
+ cell: cell as Cell<TGenerics>,
95
+ value,
96
+ })
97
+ : null,
98
+ }
99
+
100
+ instance._features.forEach(feature => {
101
+ Object.assign(
102
+ cell,
103
+ feature.createCell?.(
104
+ cell as Cell<TGenerics>,
105
+ column,
106
+ row as Row<TGenerics>,
107
+ instance
108
+ )
109
+ )
110
+ }, {})
111
+
112
+ return cell as Cell<TGenerics>
113
+ },
114
+
115
+ getCell: (rowId: string, columnId: string) => {
116
+ const row = instance.getRow(rowId)
117
+
118
+ if (!row) {
119
+ if (process.env.NODE_ENV !== 'production') {
120
+ throw new Error(`[Table] could not find row with id ${rowId}`)
121
+ }
122
+ throw new Error()
123
+ }
124
+
125
+ const cell = row.getAllCellsByColumnId()[columnId]
126
+
127
+ if (!cell) {
128
+ if (process.env.NODE_ENV !== 'production') {
129
+ throw new Error(
130
+ `[Table] could not find cell ${columnId} in row ${rowId}`
131
+ )
132
+ }
133
+ throw new Error()
134
+ }
135
+
136
+ return cell
137
+ },
138
+
139
+ getCellProps: (rowId, columnId, userProps) => {
140
+ const cell = instance.getCell(rowId, columnId)
141
+
142
+ if (!cell) {
143
+ return
144
+ }
145
+
146
+ return propGetter(
147
+ {
148
+ key: cell.id,
149
+ role: 'gridcell',
150
+ },
151
+ userProps
152
+ )
153
+ },
154
+ }
155
+ },
156
+ }
@@ -9,10 +9,16 @@ import {
9
9
  Updater,
10
10
  } from '../types'
11
11
  import { makeStateUpdater, propGetter } from '../utils'
12
+ import { ColumnPinningPosition } from './Pinning'
12
13
 
13
14
  //
14
15
 
15
- export type ColumnSizing = Record<string, number>
16
+ export type ColumnSizingTableState = {
17
+ columnSizing: ColumnSizingState
18
+ columnSizingInfo: ColumnSizingInfoState
19
+ }
20
+
21
+ export type ColumnSizingState = Record<string, number>
16
22
 
17
23
  export type ColumnSizingInfoState = {
18
24
  startOffset: null | number
@@ -23,23 +29,18 @@ export type ColumnSizingInfoState = {
23
29
  columnSizingStart: [string, number][]
24
30
  }
25
31
 
26
- export type ColumnSizingTableState = {
27
- columnSizing: ColumnSizing
28
- columnSizingInfo: ColumnSizingInfoState
29
- }
30
-
31
32
  export type ColumnResizeMode = 'onChange' | 'onEnd'
32
33
 
33
34
  export type ColumnSizingOptions = {
34
35
  enableColumnResizing?: boolean
35
36
  columnResizeMode?: ColumnResizeMode
36
- onColumnSizingChange?: OnChangeFn<ColumnSizing>
37
+ onColumnSizingChange?: OnChangeFn<ColumnSizingState>
37
38
  onColumnSizingInfoChange?: OnChangeFn<ColumnSizingInfoState>
38
39
  }
39
40
 
40
41
  export type ColumnSizingDefaultOptions = {
41
42
  columnResizeMode: ColumnResizeMode
42
- onColumnSizingChange: OnChangeFn<ColumnSizing>
43
+ onColumnSizingChange: OnChangeFn<ColumnSizingState>
43
44
  onColumnSizingInfoChange: OnChangeFn<ColumnSizingInfoState>
44
45
  }
45
46
 
@@ -52,8 +53,9 @@ export type ColumnResizerProps = {
52
53
  }
53
54
 
54
55
  export type ColumnSizingInstance<TGenerics extends TableGenerics> = {
55
- getColumnWidth: (columnId: string) => number
56
- setColumnSizing: (updater: Updater<ColumnSizing>) => void
56
+ getColumnSize: (columnId: string) => number
57
+ getColumnStart: (columnId: string, position?: ColumnPinningPosition) => number
58
+ setColumnSizing: (updater: Updater<ColumnSizingState>) => void
57
59
  setColumnSizingInfo: (updater: Updater<ColumnSizingInfoState>) => void
58
60
  resetColumnSizing: () => void
59
61
  resetColumnSize: (columnId: string) => void
@@ -67,17 +69,23 @@ export type ColumnSizingInstance<TGenerics extends TableGenerics> = {
67
69
  ) => undefined | PropGetterValue<ColumnResizerProps, TGetter>
68
70
  getColumnIsResizing: (columnId: string) => boolean
69
71
  getHeaderIsResizing: (headerId: string) => boolean
72
+ getTotalSize: () => number
73
+ getLeftTotalSize: () => number
74
+ getCenterTotalSize: () => number
75
+ getRightTotalSize: () => number
70
76
  }
71
77
 
72
78
  export type ColumnSizingColumnDef = {
73
79
  enableResizing?: boolean
74
80
  defaultCanResize?: boolean
75
- width?: number
76
- minWidth?: number
77
- maxWidth?: number
81
+ size?: number
82
+ minSize?: number
83
+ maxSize?: number
78
84
  }
79
85
 
80
86
  export type ColumnSizingColumn<TGenerics extends TableGenerics> = {
87
+ getSize: () => number
88
+ getStart: (position?: ColumnPinningPosition) => number
81
89
  getCanResize: () => boolean
82
90
  getIsResizing: () => boolean
83
91
  resetSize: () => void
@@ -95,9 +103,9 @@ export type ColumnSizingHeader<TGenerics extends TableGenerics> = {
95
103
  //
96
104
 
97
105
  export const defaultColumnSizing = {
98
- width: 150,
99
- minWidth: 20,
100
- maxWidth: Number.MAX_SAFE_INTEGER,
106
+ size: 150,
107
+ minSize: 20,
108
+ maxSize: Number.MAX_SAFE_INTEGER,
101
109
  }
102
110
 
103
111
  export const ColumnSizing = {
@@ -128,11 +136,37 @@ export const ColumnSizing = {
128
136
  }
129
137
  },
130
138
 
131
- getInstance: <TGenerics extends TableGenerics>(
139
+ createColumn: <TGenerics extends TableGenerics>(
140
+ column: Column<TGenerics>,
141
+ instance: TableInstance<TGenerics>
142
+ ): ColumnSizingColumn<TGenerics> => {
143
+ return {
144
+ getSize: () => instance.getColumnSize(column.id),
145
+ getStart: position => instance.getColumnStart(column.id, position),
146
+ getIsResizing: () => instance.getColumnIsResizing(column.id),
147
+ getCanResize: () => instance.getColumnCanResize(column.id),
148
+ resetSize: () => instance.resetColumnSize(column.id),
149
+ }
150
+ },
151
+
152
+ createHeader: <TGenerics extends TableGenerics>(
153
+ header: Header<TGenerics>,
154
+ instance: TableInstance<TGenerics>
155
+ ): ColumnSizingHeader<TGenerics> => {
156
+ return {
157
+ getIsResizing: () => instance.getColumnIsResizing(header.column.id),
158
+ getCanResize: () => instance.getColumnCanResize(header.column.id),
159
+ resetSize: () => instance.resetColumnSize(header.column.id),
160
+ getResizerProps: userProps =>
161
+ instance.getHeaderResizerProps(header.id, userProps),
162
+ }
163
+ },
164
+
165
+ createInstance: <TGenerics extends TableGenerics>(
132
166
  instance: TableInstance<TGenerics>
133
167
  ): ColumnSizingInstance<TGenerics> => {
134
168
  return {
135
- getColumnWidth: (columnId: string) => {
169
+ getColumnSize: (columnId: string) => {
136
170
  const column = instance.getColumn(columnId)
137
171
 
138
172
  if (!column) {
@@ -143,12 +177,38 @@ export const ColumnSizing = {
143
177
 
144
178
  return Math.min(
145
179
  Math.max(
146
- column.minWidth ?? defaultColumnSizing.minWidth,
147
- columnSize ?? column.width ?? defaultColumnSizing.width
180
+ column.minSize ?? defaultColumnSizing.minSize,
181
+ columnSize ?? column.size ?? defaultColumnSizing.size
148
182
  ),
149
- column.maxWidth ?? defaultColumnSizing.maxWidth
183
+ column.maxSize ?? defaultColumnSizing.maxSize
150
184
  )
151
185
  },
186
+ getColumnStart: (columnId, position) => {
187
+ const column = instance.getColumn(columnId)
188
+
189
+ if (!column) {
190
+ throw new Error()
191
+ }
192
+
193
+ const columns = !position
194
+ ? instance.getVisibleLeafColumns()
195
+ : position === 'left'
196
+ ? instance.getLeftVisibleLeafColumns()
197
+ : instance.getRightVisibleLeafColumns()
198
+
199
+ const index = columns.findIndex(d => d.id === columnId)
200
+
201
+ if (index > 0) {
202
+ const prevSiblingColumn = columns[index - 1]
203
+
204
+ return (
205
+ instance.getColumnStart(prevSiblingColumn.id, position) +
206
+ prevSiblingColumn.getSize()
207
+ )
208
+ }
209
+
210
+ return 0
211
+ },
152
212
  setColumnSizing: updater =>
153
213
  instance.options.onColumnSizingChange?.(updater),
154
214
  setColumnSizingInfo: updater =>
@@ -231,11 +291,11 @@ export const ColumnSizing = {
231
291
 
232
292
  const header = headerId ? instance.getHeader(headerId) : undefined
233
293
 
234
- const startSize = header ? header.getWidth() : column.getWidth()
294
+ const startSize = header ? header.getSize() : column.getSize()
235
295
 
236
296
  const columnSizingStart: [string, number][] = header
237
- ? header.getLeafHeaders().map(d => [d.column.id, d.getWidth()])
238
- : [[column.id, column.getWidth()]]
297
+ ? header.getLeafHeaders().map(d => [d.column.id, d.getSize()])
298
+ : [[column.id, column.getSize()]]
239
299
 
240
300
  const clientX = isTouchStartEvent(e)
241
301
  ? Math.round(e.touches[0].clientX)
@@ -249,7 +309,7 @@ export const ColumnSizing = {
249
309
  return
250
310
  }
251
311
 
252
- let newColumnSizing: ColumnSizing = {}
312
+ let newColumnSizing: ColumnSizingState = {}
253
313
 
254
314
  instance.setColumnSizingInfo(old => {
255
315
  const deltaOffset = clientXPos - (old?.startOffset ?? 0)
@@ -258,11 +318,10 @@ export const ColumnSizing = {
258
318
  -0.999999
259
319
  )
260
320
 
261
- old.columnSizingStart.forEach(([columnId, headerWidth]) => {
321
+ old.columnSizingStart.forEach(([columnId, headerSize]) => {
262
322
  newColumnSizing[columnId] =
263
323
  Math.round(
264
- Math.max(headerWidth + headerWidth * deltaPercentage, 0) *
265
- 100
324
+ Math.max(headerSize + headerSize * deltaPercentage, 0) * 100
266
325
  ) / 100
267
326
  })
268
327
 
@@ -387,30 +446,23 @@ export const ColumnSizing = {
387
446
 
388
447
  return propGetter(initialProps, userProps)
389
448
  },
390
- }
391
- },
392
449
 
393
- createColumn: <TGenerics extends TableGenerics>(
394
- column: Column<TGenerics>,
395
- instance: TableInstance<TGenerics>
396
- ): ColumnSizingColumn<TGenerics> => {
397
- return {
398
- getIsResizing: () => instance.getColumnIsResizing(column.id),
399
- getCanResize: () => instance.getColumnCanResize(column.id),
400
- resetSize: () => instance.resetColumnSize(column.id),
401
- }
402
- },
403
-
404
- createHeader: <TGenerics extends TableGenerics>(
405
- header: Header<TGenerics>,
406
- instance: TableInstance<TGenerics>
407
- ): ColumnSizingHeader<TGenerics> => {
408
- return {
409
- getIsResizing: () => instance.getColumnIsResizing(header.column.id),
410
- getCanResize: () => instance.getColumnCanResize(header.column.id),
411
- resetSize: () => instance.resetColumnSize(header.column.id),
412
- getResizerProps: userProps =>
413
- instance.getHeaderResizerProps(header.id, userProps),
450
+ getTotalSize: () =>
451
+ instance.getHeaderGroups()[0]?.headers.reduce((sum, header) => {
452
+ return sum + header.getSize()
453
+ }, 0) ?? 0,
454
+ getLeftTotalSize: () =>
455
+ instance.getLeftHeaderGroups()[0]?.headers.reduce((sum, header) => {
456
+ return sum + header.getSize()
457
+ }, 0) ?? 0,
458
+ getCenterTotalSize: () =>
459
+ instance.getCenterHeaderGroups()[0]?.headers.reduce((sum, header) => {
460
+ return sum + header.getSize()
461
+ }, 0) ?? 0,
462
+ getRightTotalSize: () =>
463
+ instance.getRightHeaderGroups()[0]?.headers.reduce((sum, header) => {
464
+ return sum + header.getSize()
465
+ }, 0) ?? 0,
414
466
  }
415
467
  },
416
468
  }
@@ -0,0 +1,290 @@
1
+ import { features } from 'process'
2
+ import {
3
+ Cell,
4
+ Column,
5
+ Header,
6
+ TableGenerics,
7
+ TableInstance,
8
+ Row,
9
+ AccessorFn,
10
+ ColumnDef,
11
+ Renderable,
12
+ HeaderRenderProps,
13
+ } from '../types'
14
+ import { memo } from '../utils'
15
+ import { ColumnPinningPosition } from './Pinning'
16
+
17
+ export type CoreColumnDefType = 'data' | 'display' | 'group'
18
+
19
+ export type CoreColumnDef<TGenerics extends TableGenerics> = {
20
+ id: string
21
+ accessorKey?: string & keyof TGenerics['Row']
22
+ accessorFn?: AccessorFn<TGenerics['Row']>
23
+ columns?: ColumnDef<TGenerics>[]
24
+ header?: Renderable<
25
+ TGenerics,
26
+ {
27
+ instance: TableInstance<TGenerics>
28
+ header: Header<TGenerics>
29
+ column: Column<TGenerics>
30
+ }
31
+ >
32
+ footer?: Renderable<
33
+ TGenerics,
34
+ {
35
+ instance: TableInstance<TGenerics>
36
+ header: Header<TGenerics>
37
+ column: Column<TGenerics>
38
+ }
39
+ >
40
+ cell?: Renderable<
41
+ TGenerics,
42
+ {
43
+ instance: TableInstance<TGenerics>
44
+ row: Row<TGenerics>
45
+ column: Column<TGenerics>
46
+ cell: Cell<TGenerics>
47
+ value: TGenerics['Value']
48
+ }
49
+ >
50
+ meta?: TGenerics['ColumnMeta']
51
+ }
52
+
53
+ export type CoreColumn<TGenerics extends TableGenerics> = {
54
+ id: string
55
+ depth: number
56
+ accessorFn?: AccessorFn<TGenerics['Row']>
57
+ columnDef: ColumnDef<TGenerics>
58
+ columnDefType: CoreColumnDefType
59
+ columns: Column<TGenerics>[]
60
+ parent?: Column<TGenerics>
61
+ getFlatColumns: () => Column<TGenerics>[]
62
+ getLeafColumns: () => Column<TGenerics>[]
63
+ }
64
+
65
+ export type ColumnsOptions<TGenerics extends TableGenerics> = {
66
+ columns: ColumnDef<TGenerics>[]
67
+ defaultColumn?: Partial<ColumnDef<TGenerics>>
68
+ }
69
+
70
+ export type ColumnsInstance<TGenerics extends TableGenerics> = {
71
+ getDefaultColumn: () => Partial<ColumnDef<TGenerics>>
72
+ getColumnDefs: () => ColumnDef<TGenerics>[]
73
+ createColumn: (
74
+ columnDef: ColumnDef<TGenerics>,
75
+ depth: number,
76
+ parent?: Column<TGenerics>
77
+ ) => Column<TGenerics>
78
+ getAllColumns: () => Column<TGenerics>[]
79
+ getAllFlatColumns: () => Column<TGenerics>[]
80
+ getAllFlatColumnsById: () => Record<string, Column<TGenerics>>
81
+ getAllLeafColumns: () => Column<TGenerics>[]
82
+ getColumn: (columnId: string) => Column<TGenerics>
83
+ }
84
+
85
+ //
86
+
87
+ export const Columns = {
88
+ createInstance: <TGenerics extends TableGenerics>(
89
+ instance: TableInstance<TGenerics>
90
+ ): ColumnsInstance<TGenerics> => {
91
+ return {
92
+ getDefaultColumn: memo(
93
+ () => [instance.options.defaultColumn],
94
+ defaultColumn => {
95
+ defaultColumn = (defaultColumn ?? {}) as Partial<ColumnDef<TGenerics>>
96
+
97
+ return {
98
+ header: (props: HeaderRenderProps<Header<TGenerics>>) =>
99
+ props.header.column.id,
100
+ footer: (props: HeaderRenderProps<Header<TGenerics>>) =>
101
+ props.header.column.id,
102
+ cell: ({ value = '' }: { value: any }): JSX.Element =>
103
+ typeof value === 'boolean' ? value.toString() : value,
104
+ ...instance._features.reduce((obj, feature) => {
105
+ return Object.assign(obj, feature.getDefaultColumn?.())
106
+ }, {}),
107
+ ...defaultColumn,
108
+ } as Partial<ColumnDef<TGenerics>>
109
+ },
110
+ {
111
+ debug: () =>
112
+ instance.options.debugAll ?? instance.options.debugColumns,
113
+ key: 'getDefaultColumn',
114
+ }
115
+ ),
116
+
117
+ getColumnDefs: () => instance.options.columns,
118
+
119
+ createColumn: (
120
+ columnDef: ColumnDef<TGenerics> & { columnDefType?: CoreColumnDefType },
121
+ depth: number,
122
+ parent
123
+ ) => {
124
+ const defaultColumn = instance.getDefaultColumn()
125
+
126
+ let id =
127
+ columnDef.id ??
128
+ columnDef.accessorKey ??
129
+ (typeof columnDef.header === 'string' ? columnDef.header : undefined)
130
+
131
+ let accessorFn: AccessorFn<TGenerics['Row']> | undefined
132
+
133
+ if (columnDef.accessorFn) {
134
+ accessorFn = columnDef.accessorFn
135
+ } else if (columnDef.accessorKey) {
136
+ accessorFn = (originalRow?: TGenerics['Row']) =>
137
+ (originalRow as any)[columnDef.accessorKey]
138
+ }
139
+
140
+ if (!id) {
141
+ if (process.env.NODE_ENV !== 'production') {
142
+ throw new Error(
143
+ columnDef.accessorFn
144
+ ? `Columns require an id when using an accessorFn`
145
+ : `Columns require an id when using a non-string header`
146
+ )
147
+ }
148
+ throw new Error()
149
+ }
150
+
151
+ let column: CoreColumn<TGenerics> = {
152
+ ...defaultColumn,
153
+ ...columnDef,
154
+ id: `${id}`,
155
+ accessorFn,
156
+ parent: parent as any,
157
+ depth,
158
+ columnDef,
159
+ columnDefType: columnDef.columnDefType as CoreColumnDefType,
160
+ columns: [],
161
+ getFlatColumns: memo(
162
+ () => [true],
163
+ () => {
164
+ return [
165
+ column as Column<TGenerics>,
166
+ ...column.columns?.flatMap(d => d.getFlatColumns()),
167
+ ]
168
+ },
169
+ {
170
+ key: 'column.getFlatColumns',
171
+ debug: () =>
172
+ instance.options.debugAll ?? instance.options.debugColumns,
173
+ }
174
+ ),
175
+ getLeafColumns: memo(
176
+ () => [instance._getOrderColumnsFn()],
177
+ orderColumns => {
178
+ if (column.columns?.length) {
179
+ let leafColumns = column.columns.flatMap(column =>
180
+ column.getLeafColumns()
181
+ )
182
+
183
+ return orderColumns(leafColumns)
184
+ }
185
+
186
+ return [column as Column<TGenerics>]
187
+ },
188
+ {
189
+ key: 'column.getLeafColumns',
190
+ debug: () =>
191
+ instance.options.debugAll ?? instance.options.debugColumns,
192
+ }
193
+ ),
194
+ }
195
+
196
+ column = instance._features.reduce((obj, feature) => {
197
+ return Object.assign(obj, feature.createColumn?.(column, instance))
198
+ }, column)
199
+
200
+ // Yes, we have to convert instance to uknown, because we know more than the compiler here.
201
+ return column as Column<TGenerics>
202
+ },
203
+
204
+ getAllColumns: memo(
205
+ () => [instance.getColumnDefs()],
206
+ columnDefs => {
207
+ const recurseColumns = (
208
+ columnDefs: ColumnDef<TGenerics>[],
209
+ parent?: Column<TGenerics>,
210
+ depth = 0
211
+ ): Column<TGenerics>[] => {
212
+ return columnDefs.map(columnDef => {
213
+ const column = instance.createColumn(columnDef, depth, parent)
214
+
215
+ column.columns = columnDef.columns
216
+ ? recurseColumns(columnDef.columns, column, depth + 1)
217
+ : []
218
+
219
+ return column
220
+ })
221
+ }
222
+
223
+ return recurseColumns(columnDefs)
224
+ },
225
+ {
226
+ key: 'getAllColumns',
227
+ debug: () =>
228
+ instance.options.debugAll ?? instance.options.debugColumns,
229
+ }
230
+ ),
231
+
232
+ getAllFlatColumns: memo(
233
+ () => [instance.getAllColumns()],
234
+ allColumns => {
235
+ return allColumns.flatMap(column => {
236
+ return column.getFlatColumns()
237
+ })
238
+ },
239
+ {
240
+ key: 'getAllFlatColumns',
241
+ debug: () =>
242
+ instance.options.debugAll ?? instance.options.debugColumns,
243
+ }
244
+ ),
245
+
246
+ getAllFlatColumnsById: memo(
247
+ () => [instance.getAllFlatColumns()],
248
+ flatColumns => {
249
+ return flatColumns.reduce((acc, column) => {
250
+ acc[column.id] = column
251
+ return acc
252
+ }, {} as Record<string, Column<TGenerics>>)
253
+ },
254
+ {
255
+ key: 'getAllFlatColumnsById',
256
+ debug: () =>
257
+ instance.options.debugAll ?? instance.options.debugColumns,
258
+ }
259
+ ),
260
+
261
+ getAllLeafColumns: memo(
262
+ () => [instance.getAllColumns(), instance._getOrderColumnsFn()],
263
+ (allColumns, orderColumns) => {
264
+ let leafColumns = allColumns.flatMap(column =>
265
+ column.getLeafColumns()
266
+ )
267
+ return orderColumns(leafColumns)
268
+ },
269
+ {
270
+ key: 'getAllLeafColumns',
271
+ debug: () =>
272
+ instance.options.debugAll ?? instance.options.debugColumns,
273
+ }
274
+ ),
275
+
276
+ getColumn: columnId => {
277
+ const column = instance.getAllFlatColumnsById()[columnId]
278
+
279
+ if (!column) {
280
+ if (process.env.NODE_ENV !== 'production') {
281
+ console.warn(`[Table] Column with id ${columnId} does not exist.`)
282
+ }
283
+ throw new Error()
284
+ }
285
+
286
+ return column
287
+ },
288
+ }
289
+ },
290
+ }