@jielga/tmdatagrid 2.0.0-beta.2 → 2.0.0-beta.21
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/README.md +5 -212
- package/dist/index.d.ts +1664 -632
- package/dist/index.js +5226 -3223
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/docs/anatomy.md +102 -0
- package/docs/cell-selection.md +154 -0
- package/docs/column-layout.md +204 -0
- package/docs/columns.md +262 -0
- package/docs/components.md +304 -0
- package/docs/editing.md +603 -0
- package/docs/editors.md +250 -0
- package/docs/export.md +326 -0
- package/docs/filtering.md +358 -0
- package/docs/getting-started.md +123 -0
- package/docs/grouping.md +165 -0
- package/docs/loading-and-empty.md +92 -0
- package/docs/localization.md +79 -0
- package/docs/menu.md +143 -0
- package/docs/pagination.md +144 -0
- package/docs/persistence.md +111 -0
- package/docs/portfolio-rebalancer.md +94 -0
- package/docs/query-builder.md +175 -0
- package/docs/quick-search.md +83 -0
- package/docs/row-details.md +113 -0
- package/docs/row-interaction.md +148 -0
- package/docs/row-pinning.md +132 -0
- package/docs/row-selection.md +134 -0
- package/docs/row-styling.md +133 -0
- package/docs/scrolling.md +111 -0
- package/docs/server-query.md +246 -0
- package/docs/server-side.md +206 -0
- package/docs/sorting.md +101 -0
- package/docs/styling.md +126 -0
- package/docs/summary-row.md +76 -0
- package/docs/testing.md +309 -0
- package/docs/toolbar.md +161 -0
- package/docs/use-tm-data-grid.md +361 -0
- package/package.json +21 -45
- package/skills/appearance/SKILL.md +70 -17
- package/skills/cell-selection/SKILL.md +70 -76
- package/skills/columns/SKILL.md +131 -32
- package/skills/data/SKILL.md +100 -23
- package/skills/editing/SKILL.md +217 -96
- package/skills/editing/references/common-mistakes.md +111 -24
- package/skills/editing/references/editing-api.md +63 -39
- package/skills/editing/references/editors-and-validation.md +77 -19
- package/skills/filtering/SKILL.md +148 -40
- package/skills/getting-started/SKILL.md +18 -16
- package/skills/grouping/SKILL.md +32 -15
- package/skills/options/SKILL.md +39 -9
- package/skills/rows/SKILL.md +22 -18
- package/skills/server-side/SKILL.md +170 -17
- package/skills/testing/SKILL.md +10 -7
- package/src/{tmdatagrid/TMDataGridContext.ts → TMDataGridContext.ts} +7 -19
- package/src/{tmdatagrid/components → components}/TMDataGrid.module.css +7 -1
- package/src/{tmdatagrid/components → components}/TMDataGrid.tsx +39 -23
- package/src/{tmdatagrid/components → components}/TMDataGridCellEditor.tsx +106 -38
- package/src/{tmdatagrid/components → components}/TMDataGridColumnsPanel.module.css +5 -1
- package/src/{tmdatagrid/components → components}/TMDataGridColumnsPanel.tsx +47 -55
- package/src/{tmdatagrid/components → components}/TMDataGridDetailsColumn.tsx +4 -4
- package/src/components/TMDataGridDraftActions.tsx +307 -0
- package/src/{tmdatagrid/components → components}/TMDataGridEditColumn.tsx +58 -50
- package/src/{tmdatagrid/components → components}/TMDataGridEntryRows.tsx +150 -115
- package/src/components/TMDataGridExportPicker.module.css +77 -0
- package/src/components/TMDataGridExportPicker.tsx +234 -0
- package/src/components/TMDataGridFilterPanel.module.css +54 -0
- package/src/components/TMDataGridFilterPanel.tsx +348 -0
- package/src/{tmdatagrid/components → components}/TMDataGridFilterPills.tsx +7 -5
- package/src/components/TMDataGridFilterSurface.module.css +54 -0
- package/src/components/TMDataGridFilterSurface.tsx +167 -0
- package/src/{tmdatagrid/components → components}/TMDataGridFooter.tsx +53 -13
- package/src/{tmdatagrid/components → components}/TMDataGridGroupColumn.tsx +4 -3
- package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.module.css +10 -0
- package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.tsx +100 -28
- package/src/components/TMDataGridHeaderFilterRow.module.css +51 -0
- package/src/components/TMDataGridHeaderFilterRow.tsx +301 -0
- package/src/components/TMDataGridMenu.tsx +354 -0
- package/src/{tmdatagrid/components → components}/TMDataGridSelectColumn.tsx +12 -7
- package/src/{tmdatagrid/components → components}/TMDataGridTable.module.css +90 -67
- package/src/{tmdatagrid/components → components}/TMDataGridTable.tsx +678 -156
- package/src/components/TMDataGridToolbar.module.css +21 -0
- package/src/components/TMDataGridToolbar.tsx +181 -0
- package/src/{tmdatagrid/components → components}/editors/TMDataGridBooleanEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridDateEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridMultiSelectEditor.tsx +3 -3
- package/src/components/editors/TMDataGridNumberEditor.tsx +70 -0
- package/src/{tmdatagrid/components → components}/editors/TMDataGridSelectEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridStringEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/editorShared.ts +17 -31
- package/src/{tmdatagrid/components → components}/filters/DgAutocompleteFilter.tsx +5 -4
- package/src/{tmdatagrid/components → components}/filters/DgDateRangeFilter.tsx +22 -5
- package/src/{tmdatagrid/components → components}/filters/DgRangeSliderFilter.tsx +5 -1
- package/src/{tmdatagrid/components → components}/filters/DgTriStateFilter.tsx +5 -1
- package/src/{tmdatagrid/components → components}/filters/TMDataGridFilterValueInput.tsx +44 -28
- package/src/components/filters/controlLayout.ts +32 -0
- package/src/components/filters/filterControlFor.ts +65 -0
- package/src/{tmdatagrid/components → components}/icons.ts +1 -0
- package/src/{tmdatagrid/components → components}/sticky.module.css +44 -0
- package/src/components/useHideableColumns.ts +52 -0
- package/src/{tmdatagrid/core → core}/autosize.ts +5 -2
- package/src/{tmdatagrid/core → core}/capabilities.ts +14 -6
- package/src/{tmdatagrid/core → core}/columnOptions.ts +46 -0
- package/src/{tmdatagrid/core → core}/columnOrdering.ts +33 -14
- package/src/{tmdatagrid/core → core}/columnUtils.ts +44 -5
- package/src/core/controlledState.ts +179 -0
- package/src/core/controlledStateSync.ts +108 -0
- package/src/core/deletedRows.ts +34 -0
- package/src/core/dom.ts +74 -0
- package/src/core/editEngine.ts +2476 -0
- package/src/{tmdatagrid/core → core}/editorFocus.ts +8 -4
- package/src/core/export.ts +843 -0
- package/src/{tmdatagrid/core → core}/filterControls.ts +38 -1
- package/src/{tmdatagrid/core → core}/filterOperators.ts +64 -1
- package/src/core/filterSurface.ts +99 -0
- package/src/{tmdatagrid/core → core}/labels.ts +66 -8
- package/src/{tmdatagrid/core → core}/labelsSv.ts +26 -3
- package/src/core/pageReset.ts +120 -0
- package/src/{tmdatagrid/core → core}/persistence.ts +22 -5
- package/src/core/resizePreview.ts +141 -0
- package/src/core/summary.ts +59 -0
- package/src/core/useSettledTableState.ts +36 -0
- package/src/{tmdatagrid/index.ts → index.ts} +75 -12
- package/src/{tmdatagrid/useTMDataGrid.tsx → useTMDataGrid.tsx} +734 -135
- package/src/useTMDataGridExport.ts +78 -0
- package/src/tmdatagrid/components/TMDataGridEditActions.tsx +0 -162
- package/src/tmdatagrid/components/TMDataGridFilterPanel.module.css +0 -35
- package/src/tmdatagrid/components/TMDataGridFilterPanel.tsx +0 -354
- package/src/tmdatagrid/components/TMDataGridToolbar.module.css +0 -12
- package/src/tmdatagrid/components/TMDataGridToolbar.tsx +0 -162
- package/src/tmdatagrid/components/editors/TMDataGridNumberEditor.tsx +0 -40
- package/src/tmdatagrid/core/cellExport.ts +0 -320
- package/src/tmdatagrid/core/editEngine.ts +0 -1006
- package/src/tmdatagrid/core/summary.ts +0 -35
- /package/src/{tmdatagrid/components → components}/TMDataGridDetailsColumn.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridFilterPills.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridFooter.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridGroupColumn.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridRowNumberColumn.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridSearch.tsx +0 -0
- /package/src/{tmdatagrid/core → core}/cellNavigation.ts +0 -0
- /package/src/{tmdatagrid/core → core}/cellRange.ts +0 -0
- /package/src/{tmdatagrid/core → core}/draftCellContext.ts +0 -0
- /package/src/{tmdatagrid/core → core}/expanding.ts +0 -0
- /package/src/{tmdatagrid/core → core}/grouping.ts +0 -0
- /package/src/{tmdatagrid/core → core}/matchHighlight.ts +0 -0
- /package/src/{tmdatagrid/core → core}/quickSearch.ts +0 -0
- /package/src/{tmdatagrid/core → core}/rowPinning.ts +0 -0
- /package/src/{tmdatagrid/core → core}/rowSelection.ts +0 -0
- /package/src/{tmdatagrid/core → core}/sizes.ts +0 -0
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cell-selection
|
|
3
3
|
description: >
|
|
4
|
-
Cell cursor, ranges
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
context menu
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
4
|
+
Cell cursor, ranges and the clipboard in TMDataGrid. Covers the cellSelection
|
|
5
|
+
option and its none / single / range modes, the keyboard map (arrows,
|
|
6
|
+
Shift+arrows, PageUp/PageDown, Home/End, Enter, F2, Escape, Space, Ctrl+C),
|
|
7
|
+
the one-tab-stop rule and the in-row Tab walk over controls inside cells, the
|
|
8
|
+
role flip from table/cell to grid/gridcell, ui.state.focusedCell and
|
|
9
|
+
ui.state.cellRange keyed by id, onFocusedCellChange, and the Copy / Export
|
|
10
|
+
cells / Include headers context menu that writes the rectangle in the grid's
|
|
11
|
+
exportOptions format. Load when adding keyboard cell navigation, selecting
|
|
12
|
+
blocks of cells, copying to a spreadsheet, or when Tab walks through controls
|
|
13
|
+
inside the grid body. Exporting whole rows is the data skill.
|
|
14
14
|
metadata:
|
|
15
15
|
type: core
|
|
16
16
|
library: '@jielga/tmdatagrid'
|
|
17
|
-
library_version: '2.0.0-beta.
|
|
17
|
+
library_version: '2.0.0-beta.21'
|
|
18
18
|
sources:
|
|
19
|
-
- 'Jielga/TMDataGrid:
|
|
20
|
-
- 'Jielga/TMDataGrid:
|
|
21
|
-
- 'Jielga/TMDataGrid:
|
|
22
|
-
- 'Jielga/TMDataGrid:
|
|
19
|
+
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/cell-selection.md'
|
|
20
|
+
- 'Jielga/TMDataGrid:packages/tmdatagrid/src/core/cellNavigation.ts'
|
|
21
|
+
- 'Jielga/TMDataGrid:packages/tmdatagrid/src/core/cellRange.ts'
|
|
22
|
+
- 'Jielga/TMDataGrid:packages/tmdatagrid/src/core/export.ts'
|
|
23
23
|
---
|
|
24
24
|
|
|
25
25
|
# TMDataGrid - Cell selection
|
|
@@ -70,29 +70,21 @@ a cell's contents own their own keys.
|
|
|
70
70
|
|
|
71
71
|
## One tab stop
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
one per mounted row, and how many that is depends on the scroll position.
|
|
73
|
+
The body is one tab stop in each direction. Tab from a cell leaves the grid and
|
|
74
|
+
Shift+Tab leaves it backwards, however many rows are mounted and whatever those
|
|
75
|
+
rows hold.
|
|
77
76
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
A control inside a body cell needs no `tabIndex`. Enter or F2 steps into the
|
|
78
|
+
cell and onto its first control, Escape steps back out to the cell, and Space
|
|
79
|
+
ticks the row from any of its cells without stepping in.
|
|
81
80
|
|
|
82
|
-
|
|
81
|
+
Once the focus is on a control, Tab walks the rest of that row's controls - its
|
|
82
|
+
open editors, the buttons in its cells, and on an open row the edit lane's save
|
|
83
|
+
and cancel. Past the row's last control the cursor moves to the next row's first
|
|
84
|
+
cell, and Shift+Tab before its first control moves to the previous row's last
|
|
85
|
+
cell; neither opens the row it lands on. From the last row, Tab leaves the grid.
|
|
83
86
|
|
|
84
|
-
|
|
85
|
-
import { useCellControlTabIndex } from "@jielga/tmdatagrid";
|
|
86
|
-
|
|
87
|
-
const OpenButton = ({ row }) => (
|
|
88
|
-
<Button tabIndex={useCellControlTabIndex()} onClick={() => open(row.id)}>
|
|
89
|
-
Open
|
|
90
|
-
</Button>
|
|
91
|
-
);
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
The hook returns `-1` while cell selection is on and `0` otherwise, so the same
|
|
95
|
-
cell works either way.
|
|
87
|
+
Header controls are untouched - the header row is not part of cell navigation.
|
|
96
88
|
|
|
97
89
|
## Where the selection lives
|
|
98
90
|
|
|
@@ -123,57 +115,61 @@ Ctrl+C puts the block on the clipboard as tab-separated text with CRLF between
|
|
|
123
115
|
rows, the format Excel, Sheets and Numbers all produce themselves. Values only:
|
|
124
116
|
Excel's own copy carries no header row either.
|
|
125
117
|
|
|
126
|
-
Right-clicking inside the selection opens Copy, "Export
|
|
118
|
+
Right-clicking inside the selection opens Copy, "Export cells" and an
|
|
127
119
|
"Include headers" toggle. A right-click outside it moves the selection there
|
|
128
120
|
first, the way a spreadsheet does. Your own `renderRowContextMenu` items are appended
|
|
129
121
|
below a divider, so nothing is lost by turning cell selection on.
|
|
130
122
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
123
|
+
"Export cells" writes the rectangle in the grid's export format - by default a
|
|
124
|
+
CSV for a Nordic Excel: a `sep=;` first line, a UTF-8 BOM, CRLF endings,
|
|
125
|
+
semicolons between fields and a comma as the decimal mark. The format, the file
|
|
126
|
+
name and the header row are the grid's `exportOptions`:
|
|
134
127
|
|
|
135
128
|
```tsx
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
129
|
+
const grid = useTMDataGrid({
|
|
130
|
+
data,
|
|
131
|
+
columns,
|
|
132
|
+
cellSelection: "range",
|
|
133
|
+
exportOptions: { format: csvFormat(), fileName: "employees" },
|
|
134
|
+
});
|
|
139
135
|
```
|
|
140
136
|
|
|
141
|
-
What gets written is the cell's **value**, not what it renders
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
selected block, with the same options and defaults. There is no built-in button
|
|
146
|
-
for it:
|
|
137
|
+
What gets written is the cell's **value**, not what it renders, for the file and
|
|
138
|
+
for Ctrl+C alike; `meta.exportValue` substitutes a value and
|
|
139
|
+
`meta.enableExport: false` drops a column from both. Ctrl+C writes numbers with
|
|
140
|
+
the format's decimal mark, so what is pasted matches what is exported.
|
|
147
141
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
142
|
+
Exporting every filtered row rather than the rectangle is
|
|
143
|
+
`TMDataGrid.Menu.Export`, `TMDataGrid.Menu.ExportSelected` and
|
|
144
|
+
`useTMDataGridExport`, covered by the data skill. The `cellExport` Table prop is
|
|
145
|
+
deprecated: it is converted and merged over `exportOptions` for this menu only.
|
|
151
146
|
|
|
152
147
|
## Common mistakes
|
|
153
148
|
|
|
154
|
-
### CRITICAL A
|
|
149
|
+
### CRITICAL A cell control given a tab index of its own
|
|
155
150
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
151
|
+
The grid keeps every control in a body cell out of the page's tab order and
|
|
152
|
+
reaches them by stepping into the cell. A `<Button>` or `<Checkbox>` handed
|
|
153
|
+
`tabIndex={0}` puts one tab stop per mounted row back, and how many that is
|
|
154
|
+
depends on the scroll position, which makes the bug look intermittent.
|
|
159
155
|
|
|
160
156
|
Wrong:
|
|
161
157
|
|
|
162
158
|
```tsx
|
|
163
|
-
const OpenButton = ({ row }) =>
|
|
159
|
+
const OpenButton = ({ row }) => (
|
|
160
|
+
<Button tabIndex={0} onClick={() => open(row.id)}>
|
|
161
|
+
Open
|
|
162
|
+
</Button>
|
|
163
|
+
);
|
|
164
164
|
```
|
|
165
165
|
|
|
166
166
|
Correct:
|
|
167
167
|
|
|
168
168
|
```tsx
|
|
169
|
-
const OpenButton = ({ row }) => (
|
|
170
|
-
<Button tabIndex={useCellControlTabIndex()} onClick={() => open(row.id)}>
|
|
171
|
-
Open
|
|
172
|
-
</Button>
|
|
173
|
-
);
|
|
169
|
+
const OpenButton = ({ row }) => <Button onClick={() => open(row.id)}>Open</Button>;
|
|
174
170
|
```
|
|
175
171
|
|
|
176
|
-
Source: `
|
|
172
|
+
Source: `packages/tmdatagrid/docs/cell-selection.md` (One tab stop).
|
|
177
173
|
|
|
178
174
|
### HIGH Selectors written for `table` / `cell` roles
|
|
179
175
|
|
|
@@ -181,7 +177,7 @@ The grid reports `grid` and `gridcell` once cell selection is on, so a test or a
|
|
|
181
177
|
query written against `getByRole("cell")` stops resolving the moment the option
|
|
182
178
|
is set - including when `editing` turns it on implicitly.
|
|
183
179
|
|
|
184
|
-
Source: `
|
|
180
|
+
Source: `packages/tmdatagrid/docs/cell-selection.md`, and the `testing` skill.
|
|
185
181
|
|
|
186
182
|
### HIGH Reading the selection as row and column indices
|
|
187
183
|
|
|
@@ -196,23 +192,23 @@ const row = grid.table.getRow(focusedCell.rowId);
|
|
|
196
192
|
const value = row.getValue(focusedCell.columnId);
|
|
197
193
|
```
|
|
198
194
|
|
|
199
|
-
Source: `
|
|
195
|
+
Source: `packages/tmdatagrid/docs/cell-selection.md` (Where the selection lives).
|
|
200
196
|
|
|
201
197
|
### MEDIUM Expecting the export to match what the cells show
|
|
202
198
|
|
|
203
199
|
A cell renders React - often a badge, a link or a formatted string - and the
|
|
204
200
|
export writes the underlying value. A currency cell showing `32 000 kr` exports
|
|
205
|
-
`32000`.
|
|
206
|
-
if the file must match the screen.
|
|
201
|
+
`32000`. Set `meta.exportValue` on the column, or post-process the data from
|
|
202
|
+
`buildExportData`, if the file must match the screen.
|
|
207
203
|
|
|
208
|
-
Source: `
|
|
204
|
+
Source: `packages/tmdatagrid/docs/cell-selection.md` (The file).
|
|
209
205
|
|
|
210
206
|
### MEDIUM Expecting headers in the clipboard
|
|
211
207
|
|
|
212
208
|
Ctrl+C copies values only, matching Excel's own copy. Headers are an option of
|
|
213
|
-
the export menu and of `
|
|
209
|
+
the export menu and of `exportOptions`, not of the clipboard path.
|
|
214
210
|
|
|
215
|
-
Source: `
|
|
211
|
+
Source: `packages/tmdatagrid/docs/cell-selection.md` (Copy and export).
|
|
216
212
|
|
|
217
213
|
## Reference
|
|
218
214
|
|
|
@@ -220,16 +216,14 @@ Source: `src/docs/cell-selection.md` (Copy and export).
|
|
|
220
216
|
| --- | --- | --- | --- | --- |
|
|
221
217
|
| `cellSelection` | Option | `"none" \| "single" \| "range"` | `"none"`, or `"single"` under `editing` | Turns the cursor, and the rectangle, on. |
|
|
222
218
|
| `onFocusedCellChange` | Callback | `(cell \| null) => void` | – | Follows the cursor. |
|
|
223
|
-
| `
|
|
219
|
+
| `exportOptions` | Option | `TMDataGridExportOptions` | `DEFAULT_EXPORT_OPTIONS` | Format, file name and header row of the Export cells item. |
|
|
224
220
|
| `ui.state.focusedCell` | UI state | `{ rowId, columnId } \| null` | `null` | The cursor. |
|
|
225
221
|
| `ui.state.cellRange` | UI state | `{ anchor, focus } \| null` | `null` | The rectangle's two corners. |
|
|
226
222
|
| `ui.actions.setFocusedCell` · `setCellRange` | UI actions | – | – | Move either from your own code. |
|
|
227
|
-
| `
|
|
228
|
-
| `
|
|
229
|
-
| `
|
|
230
|
-
| `
|
|
231
|
-
| `formatExportValue` | Export | `(value, options) => string` | – | One value, formatted as the export would. |
|
|
232
|
-
| `DEFAULT_CELL_EXPORT_OPTIONS` | Export | object | – | The Nordic Excel defaults, to spread over. |
|
|
223
|
+
| `buildExportData` | Export | `({ table, rows, bounds }) => TMDataGridExportData` | – | The rectangle's values, with `bounds`; the whole grid without. |
|
|
224
|
+
| `toClipboardText` · `writeClipboardText` | Exports | – | – | The pieces behind Ctrl+C. |
|
|
225
|
+
| `formatExportValue` | Export | `(value, options) => string` | – | One value, formatted as the text formats would. |
|
|
226
|
+
| `cellExport` | Table prop | `TMDataGridCellExportOptions` | – | Deprecated; merged over `exportOptions` for the cell-range menu only. |
|
|
233
227
|
| `isSameCell` · `resolveCellMove` | Exports | – | – | The cursor arithmetic, for a custom navigator. |
|
|
234
228
|
| `resolveRangeBounds` · `isWithinBounds` · `boundsEdges` · `boundsCellCount` | Exports | – | – | The rectangle arithmetic. |
|
|
235
229
|
| `data-focused` | Data attribute | – | – | On the focused cell. |
|
package/skills/columns/SKILL.md
CHANGED
|
@@ -4,26 +4,26 @@ description: >
|
|
|
4
4
|
Define and arrange TMDataGrid columns. Covers createTMDataGridColumnHelper,
|
|
5
5
|
every column meta field (label, type, options, flex, align, autoSize,
|
|
6
6
|
enableOrdering, and the meta.filter and meta.edit namespaces holding
|
|
7
|
-
defaultOperator, control, enabled, field, editor, validate and
|
|
8
|
-
six column types, fluid minmax sizing versus fixed width with
|
|
9
|
-
maxSize / size, autosizing and autosizeColumn, hiding through
|
|
10
|
-
the columns panel, pinning and why a pinned column becomes
|
|
11
|
-
ordering with enableColumnOrdering, meta.enableOrdering,
|
|
12
|
-
moveColumnByStep, getStepTargetColumn and the pinned regions,
|
|
13
|
-
sorting with multi-sort through isMultiSortEvent and a custom
|
|
14
|
-
generated lanes. Load when adding or changing columns,
|
|
15
|
-
hiding, pinning, reordering or sorting them.
|
|
7
|
+
operators, defaultOperator, control, enabled, field, editor, validate and
|
|
8
|
+
mapValue), the six column types, fluid minmax sizing versus fixed width with
|
|
9
|
+
minSize / maxSize / size, autosizing and autosizeColumn, hiding through
|
|
10
|
+
enableHiding and the columns panel, pinning and why a pinned column becomes
|
|
11
|
+
fixed-width, ordering with enableColumnOrdering, meta.enableOrdering,
|
|
12
|
+
moveColumn, moveColumnByStep, getStepTargetColumn and the pinned regions,
|
|
13
|
+
resetSettings, sorting with multi-sort through isMultiSortEvent and a custom
|
|
14
|
+
sortFn, and the generated lanes. Load when adding or changing columns,
|
|
15
|
+
controlling widths, hiding, pinning, reordering or sorting them.
|
|
16
16
|
metadata:
|
|
17
17
|
type: core
|
|
18
18
|
library: '@jielga/tmdatagrid'
|
|
19
|
-
library_version: '2.0.0-beta.
|
|
19
|
+
library_version: '2.0.0-beta.21'
|
|
20
20
|
sources:
|
|
21
|
-
- 'Jielga/TMDataGrid:
|
|
22
|
-
- 'Jielga/TMDataGrid:
|
|
23
|
-
- 'Jielga/TMDataGrid:
|
|
24
|
-
- 'Jielga/TMDataGrid:
|
|
25
|
-
- 'Jielga/TMDataGrid:
|
|
26
|
-
- 'Jielga/TMDataGrid:
|
|
21
|
+
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/columns.md'
|
|
22
|
+
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/column-layout.md'
|
|
23
|
+
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/sorting.md'
|
|
24
|
+
- 'Jielga/TMDataGrid:packages/tmdatagrid/src/core/columnUtils.ts'
|
|
25
|
+
- 'Jielga/TMDataGrid:packages/tmdatagrid/src/core/columnOrdering.ts'
|
|
26
|
+
- 'Jielga/TMDataGrid:packages/tmdatagrid/src/core/autosize.ts'
|
|
27
27
|
---
|
|
28
28
|
|
|
29
29
|
# TMDataGrid - Columns
|
|
@@ -55,6 +55,26 @@ const columns = columnHelper.columns([
|
|
|
55
55
|
Define columns at module scope. A new array on every render rebuilds the table's
|
|
56
56
|
column model.
|
|
57
57
|
|
|
58
|
+
A dotted `accessorKey` reads a nested field, and the column id it derives
|
|
59
|
+
replaces the dots: `accessorKey: "address.city"` makes column id
|
|
60
|
+
`address_city`, while the edit path stays `"address.city"`. Anything that
|
|
61
|
+
addresses the column by id - `initialState`, `editing.columns`, `moveColumn`,
|
|
62
|
+
a test selector - takes the underscore form.
|
|
63
|
+
|
|
64
|
+
`columnHelper.group` nests columns under a shared header; `columns` takes
|
|
65
|
+
another `columnHelper.columns` call, not a bare array:
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
columnHelper.group({
|
|
69
|
+
id: "person",
|
|
70
|
+
header: "Person",
|
|
71
|
+
columns: columnHelper.columns([
|
|
72
|
+
columnHelper.accessor("firstName", { header: "First" }),
|
|
73
|
+
columnHelper.accessor("lastName", { header: "Last" }),
|
|
74
|
+
]),
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
58
78
|
## meta
|
|
59
79
|
|
|
60
80
|
| Field | Type | Default | Description |
|
|
@@ -77,7 +97,8 @@ which is why they are in neither.
|
|
|
77
97
|
|
|
78
98
|
| Field | Type | Default | What it does |
|
|
79
99
|
| --- | --- | --- | --- |
|
|
80
|
-
| `
|
|
100
|
+
| `operators` | `readonly TMDataGridFilterOperator[]` | The type's list | The operators this column offers, a subset of its type's. For a backend that answers only some. |
|
|
101
|
+
| `defaultOperator` | `TMDataGridFilterOperator` | The type's default, else the first offered | The operator a fresh filter on this column starts with. |
|
|
81
102
|
| `control` | `TMDataGridFilterControlComponent` | By `meta.type` | Replaces the value control in this column's filter row. Module scope. |
|
|
82
103
|
|
|
83
104
|
`meta.edit`:
|
|
@@ -154,21 +175,26 @@ consumer code.
|
|
|
154
175
|
|
|
155
176
|
All three write state that persists together, so a grid comes back arranged the
|
|
156
177
|
way it was left. `resetSettings()` from the hook clears visibility, order,
|
|
157
|
-
pinning and widths in one go, and the
|
|
178
|
+
pinning and widths in one go, and the column chooser offers it as **Reset
|
|
158
179
|
layout**.
|
|
159
180
|
|
|
160
181
|
**Hiding** is `columnVisibility`, driven by "Hide column" in a column menu and by
|
|
161
|
-
`TMDataGrid.
|
|
182
|
+
the column chooser: `TMDataGrid.Menu.Columns` in the grid menu, **Manage
|
|
183
|
+
columns** as a submenu of every column menu, and `TMDataGrid.ColumnsPanel` as
|
|
184
|
+
plain controls for a host that is not a menu. See the `appearance` skill.
|
|
162
185
|
|
|
163
186
|
**Pinning** is "Pin to left" / "Pin to right" in the column menu. A pinned
|
|
164
187
|
column also becomes fixed-width: sticky offsets are computed from `getSize()`,
|
|
165
188
|
which cannot resolve an `fr` value, so the grid stores the rendered width in
|
|
166
|
-
`columnSizing` at the moment it is pinned and nothing jumps.
|
|
189
|
+
`columnSizing` at the moment it is pinned and nothing jumps. A column pinned
|
|
190
|
+
from `initialState.columnPinning` has no rendered width to store, so it takes
|
|
191
|
+
its `size` - TanStack's default of `150` where none is set - and `minSize`
|
|
192
|
+
does not apply.
|
|
167
193
|
|
|
168
194
|
**Ordering** is header dragging plus "Move left" / "Move right". A column can
|
|
169
195
|
only move **within its own pinned region** - pinning splits the grid into left,
|
|
170
196
|
centre and right, then `columnOrder` sequences the centre while
|
|
171
|
-
`columnPinning.
|
|
197
|
+
`columnPinning.start` and `.end` sequence the pinned lanes. Unpin a column
|
|
172
198
|
first to move it out of one. A neighbour that cannot move acts as a wall rather
|
|
173
199
|
than being stepped over, and columns inside a header group are not movable in
|
|
174
200
|
either direction, because `columnOrder` sequences leaf columns.
|
|
@@ -224,7 +250,7 @@ Standard TanStack column options. Each also removes the corresponding interface.
|
|
|
224
250
|
| Option | Effect when `false` |
|
|
225
251
|
| --- | --- |
|
|
226
252
|
| `enableSorting` | No sort indicator, no sort menu items, no click-to-sort. |
|
|
227
|
-
| `enableColumnFilter` | No filter menu item. Excluded from the filter panel's column list. |
|
|
253
|
+
| `enableColumnFilter` | No filter menu item. Excluded from the filter panel's column list, and its header filter cell is empty. |
|
|
228
254
|
| `enableHiding` | No hide menu item. Checkbox disabled in the column manager. |
|
|
229
255
|
| `enablePinning` | No pin menu items. |
|
|
230
256
|
| `enableResizing` | The divider is displayed but cannot be dragged. |
|
|
@@ -246,7 +272,7 @@ asks for it.
|
|
|
246
272
|
| Checkbox | `SELECT_COLUMN_ID` | Selection is on and the mode has checkboxes |
|
|
247
273
|
| Tree | `GROUP_COLUMN_ID` | A column is grouped |
|
|
248
274
|
| Details | `DETAILS_COLUMN_ID` | `renderDetails` is set |
|
|
249
|
-
| Edit | `EDIT_COLUMN_ID` | Row mode, draft
|
|
275
|
+
| Edit | `EDIT_COLUMN_ID` | Row mode, `editing.draft`, or `editing.onRowDelete` |
|
|
250
276
|
|
|
251
277
|
They are structural: fixed width, no column menu, and they cannot be sorted,
|
|
252
278
|
filtered, resized, re-pinned or moved. The checkbox lane anchors the left pinned
|
|
@@ -279,7 +305,55 @@ columnHelper.accessor("email", {
|
|
|
279
305
|
});
|
|
280
306
|
```
|
|
281
307
|
|
|
282
|
-
|
|
308
|
+
The corollary is that a pinned column is fixed-width and does use `size`, so a
|
|
309
|
+
column that is pinned needs one.
|
|
310
|
+
|
|
311
|
+
Source: `packages/tmdatagrid/docs/column-layout.md` (Sizing).
|
|
312
|
+
|
|
313
|
+
### HIGH Pinning a column at mount without size
|
|
314
|
+
|
|
315
|
+
A column pinned interactively keeps the width it was rendering, which the grid
|
|
316
|
+
writes into `columnSizing`. A column pinned from `initialState.columnPinning`
|
|
317
|
+
has no rendered width, so it takes `size` - TanStack's default of `150` where
|
|
318
|
+
none is set - and `minSize` does not apply.
|
|
319
|
+
|
|
320
|
+
Wrong:
|
|
321
|
+
|
|
322
|
+
```tsx
|
|
323
|
+
columnHelper.accessor("name", { header: "Name", minSize: 220 });
|
|
324
|
+
initialState: { columnPinning: { start: ["name"], end: [] } },
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Correct:
|
|
328
|
+
|
|
329
|
+
```tsx
|
|
330
|
+
columnHelper.accessor("name", { header: "Name", minSize: 220, size: 220 });
|
|
331
|
+
initialState: { columnPinning: { start: ["name"], end: [] } },
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Source: `packages/tmdatagrid/docs/column-layout.md` (Pinning).
|
|
335
|
+
|
|
336
|
+
### HIGH Addressing a dotted column by its accessor key
|
|
337
|
+
|
|
338
|
+
A dotted `accessorKey` produces a column id with underscores, so state and
|
|
339
|
+
calls keyed by column id silently match nothing when given the dotted form.
|
|
340
|
+
|
|
341
|
+
Wrong:
|
|
342
|
+
|
|
343
|
+
```tsx
|
|
344
|
+
initialState: { columnVisibility: { "address.city": false } },
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Correct:
|
|
348
|
+
|
|
349
|
+
```tsx
|
|
350
|
+
initialState: { columnVisibility: { address_city: false } },
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
The edit path is the exception: `meta.edit.field` and validation issue paths
|
|
354
|
+
stay dotted, because they address the data, not the column.
|
|
355
|
+
|
|
356
|
+
Source: `packages/tmdatagrid/docs/columns.md` (The column helper).
|
|
283
357
|
|
|
284
358
|
### CRITICAL A component header without `meta.label`
|
|
285
359
|
|
|
@@ -302,7 +376,7 @@ columnHelper.accessor("fullName", {
|
|
|
302
376
|
});
|
|
303
377
|
```
|
|
304
378
|
|
|
305
|
-
Source: `
|
|
379
|
+
Source: `packages/tmdatagrid/src/core/columnUtils.ts`.
|
|
306
380
|
|
|
307
381
|
### HIGH A numeric column without `meta.type`
|
|
308
382
|
|
|
@@ -311,7 +385,7 @@ Source: `src/tmdatagrid/core/columnUtils.ts`.
|
|
|
311
385
|
as text - `"9"` above `"10"`. The column still sorts and filters, which is why
|
|
312
386
|
it is easy to miss.
|
|
313
387
|
|
|
314
|
-
Source: `
|
|
388
|
+
Source: `packages/tmdatagrid/src/core/filterOperators.ts`.
|
|
315
389
|
|
|
316
390
|
### HIGH Expecting a move across pinned regions to work
|
|
317
391
|
|
|
@@ -326,7 +400,7 @@ table.getColumn("salary")?.pin(false);
|
|
|
326
400
|
moveColumn({ table, columnId: "salary", targetId: "age", side: "before" });
|
|
327
401
|
```
|
|
328
402
|
|
|
329
|
-
Source: `
|
|
403
|
+
Source: `packages/tmdatagrid/docs/column-layout.md` (Regions).
|
|
330
404
|
|
|
331
405
|
### HIGH Reaching for the v8 name of a v9 option
|
|
332
406
|
|
|
@@ -348,7 +422,7 @@ columnHelper.accessor("priority", { header: "Priority", sortFn: byRank });
|
|
|
348
422
|
```
|
|
349
423
|
|
|
350
424
|
Source: `@tanstack/table-core` `rowSortingFeature.types.d.ts`, and
|
|
351
|
-
`
|
|
425
|
+
`packages/tmdatagrid/src/useTMDataGrid.tsx` (the registered `sortFns`).
|
|
352
426
|
|
|
353
427
|
### MEDIUM Expecting autosize to measure every row
|
|
354
428
|
|
|
@@ -356,7 +430,7 @@ Autosizing fits the **mounted** rows plus overscan, not every row, because
|
|
|
356
430
|
virtualization leaves the rest with no DOM to measure. A column autosized at the
|
|
357
431
|
top of a long list can be too narrow for a value further down.
|
|
358
432
|
|
|
359
|
-
Source: `
|
|
433
|
+
Source: `packages/tmdatagrid/docs/column-layout.md` (Autosizing).
|
|
360
434
|
|
|
361
435
|
### MEDIUM Reordering a column inside a header group
|
|
362
436
|
|
|
@@ -365,7 +439,32 @@ the group header spanning columns that no longer belong to it. Grouped-header
|
|
|
365
439
|
columns are therefore immovable in both directions, whatever `meta.enableOrdering`
|
|
366
440
|
says.
|
|
367
441
|
|
|
368
|
-
Source: `
|
|
442
|
+
Source: `packages/tmdatagrid/docs/column-layout.md` (Regions).
|
|
443
|
+
|
|
444
|
+
### MEDIUM Computing a cross-row value in accessorFn
|
|
445
|
+
|
|
446
|
+
`accessorFn` is handed one row, so a share of a total, a rank or a running
|
|
447
|
+
total has nothing to compute against. Derive the collection once and give the
|
|
448
|
+
grid the finished shape.
|
|
449
|
+
|
|
450
|
+
Wrong:
|
|
451
|
+
|
|
452
|
+
```tsx
|
|
453
|
+
columnHelper.accessor((row) => (row.value / total) * 100, { id: "pctOfTotal" });
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
Correct:
|
|
457
|
+
|
|
458
|
+
```tsx
|
|
459
|
+
const rows = useMemo(() => {
|
|
460
|
+
const total = holdings.reduce((sum, h) => sum + h.value, 0);
|
|
461
|
+
return holdings.map((h) => ({ ...h, pctOfTotal: (h.value / total) * 100 }));
|
|
462
|
+
}, [holdings]);
|
|
463
|
+
|
|
464
|
+
columnHelper.accessor("pctOfTotal", { header: "Share" });
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
Source: `packages/tmdatagrid/docs/columns.md` (Columns derived from the other rows).
|
|
369
468
|
|
|
370
469
|
## Reference
|
|
371
470
|
|
|
@@ -383,13 +482,13 @@ Source: `src/docs/column-layout.md` (Regions).
|
|
|
383
482
|
| `moveColumn` | Export | `({ table, columnId, targetId, side }) => void` | – | Moves a column beside another. |
|
|
384
483
|
| `moveColumnByStep` | Export | `({ table, columnId, direction }) => void` | – | Moves it one place. |
|
|
385
484
|
| `getStepTargetColumn` | Export | `(args) => Column \| null` | – | What a step would swap with, or `null` at a region edge. |
|
|
386
|
-
| `getColumnRegion` | Export | `(column) => "
|
|
485
|
+
| `getColumnRegion` | Export | `(column) => "start" \| "center" \| "end"` | – | Which pinned region a column is in. |
|
|
387
486
|
| `isColumnReorderable` | Export | `(column, features) => boolean` | – | Whether this column may move at all. |
|
|
388
487
|
| `autosizeColumn` | Export | `({ table, columnId, container }) => void` | – | Fits a column to its mounted content. |
|
|
389
488
|
| `measureColumnContentWidth` | Export | `(args) => number` | – | The measurement behind it. |
|
|
390
489
|
| `getColumnLabel` · `getColumnType` · `getColumnDefaultOperator` · `isControlColumn` | Exports | – | – | What the built-in controls read off a column. |
|
|
391
490
|
| `SELECT_COLUMN_ID` · `GROUP_COLUMN_ID` · `DETAILS_COLUMN_ID` · `EDIT_COLUMN_ID` · `ROW_NUMBER_COLUMN_ID` | Exports | ids | – | The generated lanes. |
|
|
392
|
-
| `TMDataGrid.
|
|
491
|
+
| `TMDataGrid.Menu.Columns` · `TMDataGrid.ColumnsPanel` | Components | `searchable` · Mantine `BoxProps` | – | The column chooser, as menu items and as plain controls. Style props set on the panel. |
|
|
393
492
|
|
|
394
493
|
See also: the `filtering` skill for operators and filter controls, the `editing`
|
|
395
494
|
skill for the editing meta fields, and the `grouping` skill for what grouping
|