-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Expand file tree
/
Copy pathcolumn.ts
More file actions
169 lines (154 loc) · 5.68 KB
/
column.ts
File metadata and controls
169 lines (154 loc) · 5.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
import {
Column,
Table,
AccessorFn,
ColumnDef,
RowData,
ColumnDefResolved,
} from '../types'
import { getMemoOptions, memo } from '../utils'
export interface CoreColumn<TData extends RowData, TValue> {
/**
* The resolved accessor function to use when extracting the value for the column from each row. Will only be defined if the column def has a valid accessor key or function defined.
* @link [API Docs](https://tanstack.com/table/v8/docs/api/core/column#accessorfn)
* @link [Guide](https://tanstack.com/table/v8/docs/guide/column-defs)
*/
accessorFn?: AccessorFn<TData, TValue>
/**
* The original column def used to create the column.
* @link [API Docs](https://tanstack.com/table/v8/docs/api/core/column#columndef)
* @link [Guide](https://tanstack.com/table/v8/docs/guide/column-defs)
*/
columnDef: ColumnDef<TData, TValue>
/**
* The child column (if the column is a group column). Will be an empty array if the column is not a group column.
* @link [API Docs](https://tanstack.com/table/v8/docs/api/core/column#columns)
* @link [Guide](https://tanstack.com/table/v8/docs/guide/column-defs)
*/
columns: Column<TData, TValue>[]
/**
* The depth of the column (if grouped) relative to the root column def array.
* @link [API Docs](https://tanstack.com/table/v8/docs/api/core/column#depth)
* @link [Guide](https://tanstack.com/table/v8/docs/guide/column-defs)
*/
depth: number
/**
* Returns the flattened array of this column and all child/grand-child columns for this column.
* @link [API Docs](https://tanstack.com/table/v8/docs/api/core/column#getflatcolumns)
* @link [Guide](https://tanstack.com/table/v8/docs/guide/column-defs)
*/
getFlatColumns: () => Column<TData, TValue>[]
/**
* Returns an array of all leaf-node columns for this column. If a column has no children, it is considered the only leaf-node column.
* @link [API Docs](https://tanstack.com/table/v8/docs/api/core/column#getleafcolumns)
* @link [Guide](https://tanstack.com/table/v8/docs/guide/column-defs)
*/
getLeafColumns: () => Column<TData, TValue>[]
/**
* The resolved unique identifier for the column resolved in this priority:
- A manual `id` property from the column def
- The accessor key from the column def
- The header string from the column def
* @link [API Docs](https://tanstack.com/table/v8/docs/api/core/column#id)
* @link [Guide](https://tanstack.com/table/v8/docs/guide/column-defs)
*/
id: string
/**
* The parent column for this column. Will be undefined if this is a root column.
* @link [API Docs](https://tanstack.com/table/v8/docs/api/core/column#parent)
* @link [Guide](https://tanstack.com/table/v8/docs/guide/column-defs)
*/
parent?: Column<TData, TValue>
}
export function createColumn<TData extends RowData, TValue>(
table: Table<TData>,
columnDef: ColumnDef<TData, TValue>,
depth: number,
parent?: Column<TData, TValue>
): Column<TData, TValue> {
const defaultColumn = table._getDefaultColumnDef()
const resolvedColumnDef = {
...defaultColumn,
...columnDef,
} as ColumnDefResolved<TData>
const accessorKey = resolvedColumnDef.accessorKey
let id =
resolvedColumnDef.id ??
(accessorKey
? typeof String.prototype.replaceAll === 'function'
? accessorKey.replaceAll('.', '_')
: accessorKey.replace(/\./g, '_')
: undefined) ??
(typeof resolvedColumnDef.header === 'string'
? resolvedColumnDef.header
: undefined)
let accessorFn: AccessorFn<TData> | undefined
if (resolvedColumnDef.accessorFn) {
accessorFn = resolvedColumnDef.accessorFn
} else if (accessorKey) {
// Support deep accessor keys
if (accessorKey.includes('.')) {
accessorFn = (originalRow: TData) => {
let result = originalRow as Record<string, any>
for (const key of accessorKey.split('.')) {
result = result?.[key]
if (process.env.NODE_ENV !== 'production' && result === undefined) {
console.warn(
`"${key}" in deeply nested key "${accessorKey}" returned undefined.`
)
}
}
return result
}
} else {
accessorFn = (originalRow: TData) =>
(originalRow as any)[resolvedColumnDef.accessorKey]
}
}
if (!id) {
if (process.env.NODE_ENV !== 'production') {
throw new Error(
resolvedColumnDef.accessorFn
? `Columns require an id when using an accessorFn`
: `Columns require an id when using a non-string header`
)
}
throw new Error()
}
let column: CoreColumn<TData, any> = {
id: `${String(id)}`,
accessorFn,
parent: parent as any,
depth,
columnDef: resolvedColumnDef as ColumnDef<TData, any>,
columns: [],
getFlatColumns: memo(
() => [true],
() => {
return [
column as Column<TData, TValue>,
...column.columns?.flatMap(d => d.getFlatColumns()),
]
},
getMemoOptions(table.options, 'debugColumns', 'column.getFlatColumns')
),
getLeafColumns: memo(
() => [table._getOrderColumnsFn()],
orderColumns => {
if (column.columns?.length) {
let leafColumns = column.columns.flatMap(column =>
column.getLeafColumns()
)
return orderColumns(leafColumns)
}
return [column as Column<TData, TValue>]
},
getMemoOptions(table.options, 'debugColumns', 'column.getLeafColumns')
),
}
for (const feature of table._features) {
feature.createColumn?.(column as Column<TData, TValue>, table)
}
// Yes, we have to convert table to unknown, because we know more than the compiler here.
return column as Column<TData, TValue>
}