@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.
- package/build/cjs/core.js +9 -384
- package/build/cjs/core.js.map +1 -1
- package/build/cjs/features/Cells.js +122 -0
- package/build/cjs/features/Cells.js.map +1 -0
- package/build/cjs/features/ColumnSizing.js +90 -37
- package/build/cjs/features/ColumnSizing.js.map +1 -1
- package/build/cjs/features/Columns.js +216 -0
- package/build/cjs/features/Columns.js.map +1 -0
- package/build/cjs/features/Expanding.js +2 -2
- package/build/cjs/features/Expanding.js.map +1 -1
- package/build/cjs/features/Filters.js +3 -3
- package/build/cjs/features/Filters.js.map +1 -1
- package/build/cjs/features/Grouping.js +2 -2
- package/build/cjs/features/Grouping.js.map +1 -1
- package/build/cjs/features/Headers.js +78 -153
- package/build/cjs/features/Headers.js.map +1 -1
- package/build/cjs/features/Ordering.js +1 -1
- package/build/cjs/features/Ordering.js.map +1 -1
- package/build/cjs/features/Pagination.js +2 -2
- package/build/cjs/features/Pagination.js.map +1 -1
- package/build/cjs/features/Pinning.js +172 -2
- package/build/cjs/features/Pinning.js.map +1 -1
- package/build/cjs/features/RowSelection.js +1 -1
- package/build/cjs/features/RowSelection.js.map +1 -1
- package/build/cjs/features/Rows.js +99 -0
- package/build/cjs/features/Rows.js.map +1 -0
- package/build/cjs/features/Sorting.js +2 -2
- package/build/cjs/features/Sorting.js.map +1 -1
- package/build/cjs/features/Visibility.js +51 -17
- package/build/cjs/features/Visibility.js.map +1 -1
- package/build/cjs/utils.js.map +1 -1
- package/build/esm/index.js +881 -695
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +418 -316
- package/build/types/core.d.ts +2 -79
- package/build/types/features/Cells.d.ts +14 -0
- package/build/types/features/ColumnSizing.d.ts +26 -18
- package/build/types/features/Columns.d.ts +54 -0
- package/build/types/features/Expanding.d.ts +2 -1
- package/build/types/features/Filters.d.ts +3 -1
- package/build/types/features/Grouping.d.ts +2 -1
- package/build/types/features/Headers.d.ts +3 -11
- package/build/types/features/Ordering.d.ts +1 -1
- package/build/types/features/Pagination.d.ts +2 -1
- package/build/types/features/Pinning.d.ts +18 -4
- package/build/types/features/RowSelection.d.ts +1 -1
- package/build/types/features/Rows.d.ts +29 -0
- package/build/types/features/Sorting.d.ts +2 -1
- package/build/types/features/Visibility.d.ts +7 -2
- package/build/types/types.d.ts +18 -10
- package/build/types/utils.d.ts +0 -1
- package/build/umd/index.development.js +882 -696
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +1 -1
- package/build/umd/index.production.js.map +1 -1
- package/package.json +1 -1
- package/src/core.ts +28 -550
- package/src/features/Cells.ts +156 -0
- package/src/features/ColumnSizing.ts +103 -51
- package/src/features/Columns.ts +290 -0
- package/src/features/Expanding.ts +7 -3
- package/src/features/Filters.ts +11 -3
- package/src/features/Grouping.ts +3 -2
- package/src/features/Headers.ts +48 -138
- package/src/features/Ordering.ts +1 -1
- package/src/features/Pagination.ts +6 -2
- package/src/features/Pinning.ts +194 -3
- package/src/features/RowSelection.ts +1 -1
- package/src/features/Rows.ts +151 -0
- package/src/features/Sorting.ts +3 -2
- package/src/features/Visibility.ts +67 -20
- package/src/types.ts +25 -37
- 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
|
|
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<
|
|
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<
|
|
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
|
-
|
|
56
|
-
|
|
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
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
147
|
-
columnSize ?? column.
|
|
180
|
+
column.minSize ?? defaultColumnSizing.minSize,
|
|
181
|
+
columnSize ?? column.size ?? defaultColumnSizing.size
|
|
148
182
|
),
|
|
149
|
-
column.
|
|
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.
|
|
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.
|
|
238
|
-
: [[column.id, column.
|
|
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:
|
|
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,
|
|
321
|
+
old.columnSizingStart.forEach(([columnId, headerSize]) => {
|
|
262
322
|
newColumnSizing[columnId] =
|
|
263
323
|
Math.round(
|
|
264
|
-
Math.max(
|
|
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
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
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
|
+
}
|