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