@jielga/tmdatagrid 2.0.0-beta.8 → 2.0.0
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 +1323 -796
- package/dist/index.js +4719 -3193
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/docs/adding-rows.md +132 -0
- package/docs/anatomy.md +119 -0
- package/docs/card-view.md +108 -0
- package/docs/cell-selection.md +194 -0
- package/docs/column-layout.md +182 -0
- package/docs/column-menu.md +66 -0
- package/docs/columns.md +268 -0
- package/docs/components.md +311 -0
- package/docs/draft-store.md +242 -0
- package/docs/editing.md +303 -0
- package/docs/editors.md +250 -0
- package/docs/export.md +319 -0
- package/docs/filtering.md +362 -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/migrating-to-2.md +163 -0
- package/docs/pagination.md +144 -0
- package/docs/persistence.md +114 -0
- package/docs/portfolio-rebalancer.md +94 -0
- package/docs/query-builder.md +179 -0
- package/docs/quick-search.md +84 -0
- package/docs/row-details.md +115 -0
- package/docs/row-interaction.md +149 -0
- package/docs/row-pinning.md +132 -0
- package/docs/row-selection.md +136 -0
- package/docs/row-styling.md +133 -0
- package/docs/scrolling.md +112 -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 +744 -0
- package/docs/toolbar.md +161 -0
- package/docs/use-tm-data-grid.md +361 -0
- package/package.json +22 -46
- package/skills/appearance/SKILL.md +72 -19
- package/skills/cell-selection/SKILL.md +69 -78
- package/skills/columns/SKILL.md +90 -34
- package/skills/data/SKILL.md +86 -16
- package/skills/editing/SKILL.md +83 -50
- package/skills/editing/references/common-mistakes.md +77 -69
- package/skills/editing/references/editing-api.md +31 -23
- package/skills/editing/references/editors-and-validation.md +24 -17
- package/skills/filtering/SKILL.md +148 -40
- package/skills/getting-started/SKILL.md +17 -15
- package/skills/grouping/SKILL.md +31 -16
- package/skills/options/SKILL.md +8 -8
- package/skills/rows/SKILL.md +22 -18
- package/skills/server-side/SKILL.md +170 -17
- package/skills/testing/SKILL.md +150 -32
- package/skills/testing-components/SKILL.md +230 -0
- package/skills/testing-editing/SKILL.md +240 -0
- 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 +38 -21
- package/src/{tmdatagrid/components → components}/TMDataGridCellEditor.tsx +73 -7
- 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 +9 -55
- package/src/{tmdatagrid/components → components}/TMDataGridDraftActions.tsx +41 -24
- package/src/{tmdatagrid/components → components}/TMDataGridEditColumn.tsx +23 -63
- package/src/components/TMDataGridEntryRows.tsx +354 -0
- 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 +15 -8
- package/src/components/TMDataGridFilterSurface.module.css +54 -0
- package/src/components/TMDataGridFilterSurface.tsx +167 -0
- package/src/{tmdatagrid/components → components}/TMDataGridFooter.tsx +53 -90
- package/src/{tmdatagrid/components → components}/TMDataGridGroupColumn.tsx +9 -72
- package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.module.css +12 -2
- package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.tsx +58 -21
- package/src/components/TMDataGridHeaderFilterRow.module.css +51 -0
- package/src/components/TMDataGridHeaderFilterRow.tsx +301 -0
- package/src/components/TMDataGridMenu.tsx +357 -0
- package/src/{tmdatagrid/components → components}/TMDataGridSelectColumn.tsx +15 -53
- package/src/{tmdatagrid/components → components}/TMDataGridTable.module.css +88 -65
- package/src/{tmdatagrid/components → components}/TMDataGridTable.tsx +579 -165
- package/src/{tmdatagrid/components → components}/TMDataGridToolbar.module.css +5 -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/{tmdatagrid/components → components}/editors/TMDataGridNumberEditor.tsx +3 -3
- 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 +16 -2
- 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/components/generatedColumns.tsx +187 -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 +5 -5
- package/src/{tmdatagrid/core → core}/columnOptions.ts +60 -8
- package/src/{tmdatagrid/core → core}/columnOrdering.ts +33 -14
- package/src/{tmdatagrid/core → core}/columnUtils.ts +44 -5
- package/src/core/controlledStateSync.ts +108 -0
- package/src/core/deletedRows.ts +34 -0
- package/src/core/dom.ts +74 -0
- package/src/{tmdatagrid/core → core}/editEngine.ts +1172 -388
- package/src/{tmdatagrid/core → core}/editorFocus.ts +8 -4
- package/src/core/export.ts +704 -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}/grouping.ts +21 -0
- package/src/{tmdatagrid/core → core}/labels.ts +51 -6
- package/src/{tmdatagrid/core → core}/labelsSv.ts +27 -6
- package/src/core/pageReset.ts +120 -0
- package/src/core/pagination.ts +81 -0
- package/src/{tmdatagrid/core → core}/persistence.ts +22 -5
- package/src/{tmdatagrid/core → core}/summary.ts +20 -4
- package/src/{tmdatagrid/index.ts → index.ts} +70 -36
- package/src/{tmdatagrid/useTMDataGrid.tsx → useTMDataGrid.tsx} +534 -123
- package/src/useTMDataGridExport.ts +78 -0
- package/src/tmdatagrid/components/TMDataGridEntryRows.tsx +0 -298
- package/src/tmdatagrid/components/TMDataGridFilterPanel.module.css +0 -35
- package/src/tmdatagrid/components/TMDataGridFilterPanel.tsx +0 -354
- package/src/tmdatagrid/components/TMDataGridToolbar.tsx +0 -161
- package/src/tmdatagrid/core/cellExport.ts +0 -320
- /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}/controlledState.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}/matchHighlight.ts +0 -0
- /package/src/{tmdatagrid/core → core}/quickSearch.ts +0 -0
- /package/src/{tmdatagrid/core → core}/resizePreview.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
- /package/src/{tmdatagrid/core → core}/useSettledTableState.ts +0 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# Visibility, pinning, ordering and size
|
|
2
|
+
|
|
3
|
+
Four things a user can change about the layout of the grid, and one button that
|
|
4
|
+
resets them. All four write state that
|
|
5
|
+
[persists](/docs/use-tm-data-grid#persist) together, so a grid comes back
|
|
6
|
+
arranged the way it was left. Each is also an item in the
|
|
7
|
+
[column header menu](/docs/column-menu).
|
|
8
|
+
|
|
9
|
+
```demo
|
|
10
|
+
file: columns/ColumnLayout.tsx
|
|
11
|
+
hint: Drag a header to reorder · pin or hide from a column menu · drag a divider to resize, or double-click it to fit the content.
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Hiding
|
|
15
|
+
|
|
16
|
+
**Hide column** in any column menu, and the column chooser for the whole list at once: a search field, one checkbox per column, show/hide all, and **Reset layout**.
|
|
17
|
+
The chooser is `TMDataGrid.Menu.Columns` in the [grid menu](/docs/menu), **Manage columns** in every column menu (a submenu of the same items), and `TMDataGrid.ColumnsPanel` as plain controls for a host that is not a menu.
|
|
18
|
+
|
|
19
|
+
`enableHiding: false` removes all of it; on a column it removes that column's
|
|
20
|
+
menu item and leaves it out of the panel, which lists what can be hidden and
|
|
21
|
+
nothing else. Show/hide all covers the same list, so a column switched off this
|
|
22
|
+
way keeps whatever visibility it was given. The state is TanStack's
|
|
23
|
+
`columnVisibility`.
|
|
24
|
+
|
|
25
|
+
The generated lanes are all `enableHiding: false` and never appear in the
|
|
26
|
+
panel. Each follows the feature that adds it rather than a setting of its own.
|
|
27
|
+
|
|
28
|
+
## Pinning
|
|
29
|
+
|
|
30
|
+
**Pin to left** and **Pin to right** are in each column menu. The current
|
|
31
|
+
position is marked, and choosing it again unpins. Pinned columns are sticky
|
|
32
|
+
within the scroll container. The boundary is marked with a divider and a short
|
|
33
|
+
gradient band, which fades in only while it is covering content.
|
|
34
|
+
|
|
35
|
+
Headers, cells and grid tracks are ordered left, centre, right from the same
|
|
36
|
+
source, so pinning does not change a column's position relative to its group.
|
|
37
|
+
|
|
38
|
+
A pinned column also becomes fixed-width, since sticky offsets cannot be
|
|
39
|
+
computed from an `fr` value. The grid writes the column's rendered width into
|
|
40
|
+
`columnSizing` as it is pinned, so nothing jumps.
|
|
41
|
+
|
|
42
|
+
To start pinned, set `initialState.columnPinning`. The slice is TanStack's
|
|
43
|
+
full `ColumnPinningState`, so a partial does not compile - name both sides.
|
|
44
|
+
A column pinned at mount has no rendered width to store, so it takes its
|
|
45
|
+
`size` - TanStack's default of `150` where none is set - and `minSize` does
|
|
46
|
+
not apply. Give such a column an explicit `size`:
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
columnHelper.accessor("registration", { header: "Registration", size: 220 });
|
|
50
|
+
|
|
51
|
+
initialState: { columnPinning: { start: ["registration"], end: [] } }
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The generated lanes stay outside both pinned lanes: pinning a column right puts
|
|
55
|
+
it to the left of the edit lane, so the row's Save, Cancel and Delete remain
|
|
56
|
+
last in the row.
|
|
57
|
+
|
|
58
|
+
## Ordering
|
|
59
|
+
|
|
60
|
+
Drag a column header sideways to move it. The header being dragged dims, and a
|
|
61
|
+
bar marks the edge the column will land against. **Move left** and **Move
|
|
62
|
+
right** in the column menu do the same one step at a time, without a pointer.
|
|
63
|
+
Both move the header, its cells and its filter entry together.
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
const grid = useTMDataGrid({ data, columns, enableColumnOrdering: false });
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`enableColumnOrdering` is defined by the grid rather than by TanStack, which
|
|
70
|
+
ships the ordering state and APIs but no `enable` option. The per-column form is
|
|
71
|
+
`meta.enableOrdering`.
|
|
72
|
+
|
|
73
|
+
### Regions
|
|
74
|
+
|
|
75
|
+
A column can only move **within its own pinned region**; a header in another
|
|
76
|
+
region does not accept the drop. This follows TanStack's ordering pipeline:
|
|
77
|
+
pinning splits the grid into left, centre and right, then `columnOrder`
|
|
78
|
+
sequences the centre while `columnPinning.start` and `.end` sequence the
|
|
79
|
+
pinned lanes. Unpin a column first to move it out of one.
|
|
80
|
+
|
|
81
|
+
A neighbour that cannot be moved blocks the move; it is not stepped over. The
|
|
82
|
+
checkbox column sets `meta.enableOrdering: false`, so nothing can be placed in
|
|
83
|
+
front of it.
|
|
84
|
+
|
|
85
|
+
Columns inside a header group cannot be moved either, in either direction:
|
|
86
|
+
`columnOrder` sequences leaf columns, so moving one would leave the group header
|
|
87
|
+
spanning columns that no longer belong to it.
|
|
88
|
+
|
|
89
|
+
### Moving from your own code
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
import { moveColumn, moveColumnByStep } from "@jielga/tmdatagrid";
|
|
93
|
+
|
|
94
|
+
moveColumn({ table, columnId: "salary", targetId: "age", side: "before" });
|
|
95
|
+
moveColumnByStep({ table, columnId: "salary", direction: 1 });
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Both are no-ops for a move that is not allowed, including one across regions.
|
|
99
|
+
`getStepTargetColumn({ table, columnId, direction })` returns the column a step
|
|
100
|
+
would swap with, or `null` at the edge of a region. The menu items use it to
|
|
101
|
+
decide whether to disable themselves.
|
|
102
|
+
|
|
103
|
+
### State
|
|
104
|
+
|
|
105
|
+
Ordering writes `columnOrder` as the **complete** leaf order, including hidden
|
|
106
|
+
and pinned columns, so a column keeps its position when it is later shown or
|
|
107
|
+
unpinned. Moving a pinned column also rewrites its `columnPinning` array. A
|
|
108
|
+
column added to the definitions later is not in the stored order and is appended
|
|
109
|
+
at the end until it is moved.
|
|
110
|
+
|
|
111
|
+
## Sizing
|
|
112
|
+
|
|
113
|
+
Columns are fluid by default. Each track is `minmax(minSize, flex fr)`.
|
|
114
|
+
|
|
115
|
+
| Column option | Effect |
|
|
116
|
+
| --- | --- |
|
|
117
|
+
| `minSize` | Minimum width, and the column's contribution to the grid minimum width. Defaults to `80`. |
|
|
118
|
+
| `meta.flex` | Share of the remaining width. Defaults to `1`. |
|
|
119
|
+
| `minSize === maxSize` | Fixed width. The column is never fluid. |
|
|
120
|
+
| `size` | Applied once the column becomes fixed by resizing or pinning. |
|
|
121
|
+
|
|
122
|
+
Drag a divider to resize. A column switches to a fixed pixel width the moment
|
|
123
|
+
it is resized or pinned, and the width is stored in `columnSizing`. The drag
|
|
124
|
+
starts from the width the column is rendered with, and the grid paints it on
|
|
125
|
+
its own column tracks while the pointer moves; the width reaches `columnSizing`
|
|
126
|
+
when the pointer is released. `columnResizeMode: "onChange"` publishes it on
|
|
127
|
+
every move instead, at the cost of a render of the grid for each one.
|
|
128
|
+
|
|
129
|
+
### Autosizing
|
|
130
|
+
|
|
131
|
+
Double-click a column's resize divider to size it to its widest mounted
|
|
132
|
+
content. **Autosize column** in the column menu does the same without a
|
|
133
|
+
pointer, and `meta.autoSize: true` runs it once after the first rows render,
|
|
134
|
+
unless a persisted or user-set width already applies to the column.
|
|
135
|
+
|
|
136
|
+
**Mounted content only.** Under virtualization the unmounted rows cannot be
|
|
137
|
+
measured, so the width fits the visible window plus overscan. The result is
|
|
138
|
+
clamped to `minSize`/`maxSize` and written into `columnSizing`, so it persists
|
|
139
|
+
with the other widths and a later drag overrides it.
|
|
140
|
+
|
|
141
|
+
`meta.autoSize` waits for content: on a grid whose rows are fetched, the first
|
|
142
|
+
render has a header and no cells, so the column is sized on the render its
|
|
143
|
+
first cells appear in.
|
|
144
|
+
|
|
145
|
+
`autosizeColumn({ table, columnId, container })` is exported for menus and
|
|
146
|
+
consumer code; `container` is the grid's scroll container, or any ancestor of
|
|
147
|
+
the column's cells.
|
|
148
|
+
|
|
149
|
+
## Reset the layout
|
|
150
|
+
|
|
151
|
+
`resetSettings()` from the hook clears visibility, order, pinning and widths in
|
|
152
|
+
one call. The columns panel offers it as **Reset layout**.
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
const { resetSettings } = useTMDataGrid({ data, columns });
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Reference
|
|
159
|
+
|
|
160
|
+
| Name | Kind | Type | Default | What it does |
|
|
161
|
+
| --- | --- | --- | --- | --- |
|
|
162
|
+
| `enableHiding` | Table option | `boolean` | `true` | Also a column option. `false` removes hiding entirely. |
|
|
163
|
+
| `enableColumnPinning` | Table option | `boolean` | `true` | `false` removes the pin menu items. |
|
|
164
|
+
| `enablePinning` | Column option | `boolean` | `true` | `false` for one column. |
|
|
165
|
+
| `enableColumnOrdering` | Option | `boolean` | `true` | Header dragging and the move menu items. Grid-defined. |
|
|
166
|
+
| `meta.enableOrdering` | Column meta | `boolean` | `true` | `false` keeps one column where it is. |
|
|
167
|
+
| `enableColumnResizing` | Table option | `boolean` | `true` | `false` leaves the divider as a separator only. |
|
|
168
|
+
| `enableResizing` | Column option | `boolean` | `true` | `false` for one column. |
|
|
169
|
+
| `meta.flex` | Column meta | `number` | `1` | Share of the remaining width. |
|
|
170
|
+
| `meta.autoSize` | Column meta | `boolean` | `false` | Autosize once, on the render the column's first cells appear in. |
|
|
171
|
+
| `minSize` / `maxSize` / `size` | Column options | `number` | `80` / – / – | Width bounds, and the fixed width once one applies. |
|
|
172
|
+
| `resetSettings` | Hook return | `() => void` | – | Clears visibility, order, pinning and widths. |
|
|
173
|
+
| `moveColumn` | Export | `({ table, columnId, targetId, side }) => void` | – | Moves a column beside another. |
|
|
174
|
+
| `moveColumnByStep` | Export | `({ table, columnId, direction }) => void` | – | Moves it one place. |
|
|
175
|
+
| `MoveColumnArgs` · `ColumnStepArgs` | Types | – | – | What `moveColumn` takes, and what `moveColumnByStep` and `getStepTargetColumn` take. |
|
|
176
|
+
| `TMDataGridDropSide` | Type | `"before" \| "after"` | – | The `side` of `MoveColumnArgs`: which edge of the target column the moved column lands on. |
|
|
177
|
+
| `getStepTargetColumn` | Export | `(args) => Column \| null` | – | What a step would swap with, or `null` at a region edge. |
|
|
178
|
+
| `keepGeneratedColumnsOutermost` | Export | `(columnPinning) => ColumnPinningState` | – | Puts the generated lanes back on the outside of both pinned lanes. The grid runs it after every pin. |
|
|
179
|
+
| `getColumnRegion` | Export | `(columnPinning, columnId) => "start" \| "center" \| "end"` | – | Which pinned region a column is in. |
|
|
180
|
+
| `TMDataGridColumnRegion` | Type | `"start" \| "center" \| "end"` | – | What `getColumnRegion` returns. |
|
|
181
|
+
| `autosizeColumn` | Export | `({ table, columnId, container }) => void` | – | Fits a column to its mounted content. |
|
|
182
|
+
| `TMDataGrid.Menu.Columns` · `TMDataGrid.ColumnsPanel` | Components | – | – | The column chooser, as menu items and as plain controls. See [Grid menu](/docs/menu). |
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Column header menu
|
|
2
|
+
|
|
3
|
+
The menu on every column header.
|
|
4
|
+
It opens from the header's menu button and from a right-click on the header.
|
|
5
|
+
|
|
6
|
+
```demo
|
|
7
|
+
file: columns/ColumnMenuItems.tsx
|
|
8
|
+
hint: The ID column has no menu; every other menu ends with Column statistics.
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Items
|
|
12
|
+
|
|
13
|
+
The menu shows each group only when the column supports it:
|
|
14
|
+
|
|
15
|
+
| Item | Shown when |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| Sort by ASC · Sort by DESC | The column can sort. See [Sorting](/docs/sorting) |
|
|
18
|
+
| Filter | The column can filter and `filters.inHeader` is off. See [Filtering](/docs/filtering) |
|
|
19
|
+
| Group by · Ungroup | The column can group. See [Grouping](/docs/grouping) |
|
|
20
|
+
| Expand all groups · Collapse all groups | Grouping is active |
|
|
21
|
+
| Pin to left · Pin to right · Unpin | The column can pin. Unpin only on a pinned column. See [Column layout](/docs/column-layout#pinning) |
|
|
22
|
+
| Move left · Move right | The column can be reordered and has a neighbour in its region. See [Column layout](/docs/column-layout#ordering) |
|
|
23
|
+
| Autosize column | The column can resize. See [Column layout](/docs/column-layout#autosizing) |
|
|
24
|
+
| Hide column | The column can hide |
|
|
25
|
+
| Manage columns | Any column can hide |
|
|
26
|
+
|
|
27
|
+
A divider separates the groups.
|
|
28
|
+
Each option that turns a feature off also removes its items; the full list is in [What each switch removes](/docs/use-tm-data-grid#what-each-switch-removes).
|
|
29
|
+
A column whose menu would be empty has no menu button.
|
|
30
|
+
Group headers and the generated columns (checkbox, details, edit, row number) have no menu.
|
|
31
|
+
The item texts come from `labels`; see [Localization](/docs/localization).
|
|
32
|
+
|
|
33
|
+
## Change the items
|
|
34
|
+
|
|
35
|
+
`renderColumnMenuItems` on `TMDataGrid.Table` sets the contents of every column's menu.
|
|
36
|
+
It receives the items the grid would render and returns the list to render:
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
<TMDataGrid.Table<Employee>
|
|
40
|
+
renderColumnMenuItems={({ column, internalItems }) => [
|
|
41
|
+
...internalItems,
|
|
42
|
+
<Menu.Divider key="stats-divider" />,
|
|
43
|
+
<Menu.Item key="stats" onClick={() => showStats(column.id)}>
|
|
44
|
+
Column statistics
|
|
45
|
+
</Menu.Item>,
|
|
46
|
+
]}
|
|
47
|
+
/>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
- `internalItems` - the built-in items in order, dividers included
|
|
51
|
+
- return `internalItems` unchanged to keep the default menu
|
|
52
|
+
- add items around it to extend the menu
|
|
53
|
+
- return other items to replace it
|
|
54
|
+
- return `[]` to remove the menu button
|
|
55
|
+
|
|
56
|
+
The function runs for every column that has a menu; branch on `column.id` for a per-column menu.
|
|
57
|
+
A trailing divider is dropped.
|
|
58
|
+
Give every item a `key`.
|
|
59
|
+
|
|
60
|
+
## Reference
|
|
61
|
+
|
|
62
|
+
| Name | Kind | Type | Default | What it does |
|
|
63
|
+
| --- | --- | --- | --- | --- |
|
|
64
|
+
| `renderColumnMenuItems` | Table prop | `TMDataGridColumnMenuItemsRenderer` | – | Sets the column menu's contents. An empty list removes the menu button. |
|
|
65
|
+
| `TMDataGridColumnMenuItemsRenderer` | Type | `(args: TMDataGridColumnMenuItemsArgs) => ReactNode[]` | – | The function `renderColumnMenuItems` takes. |
|
|
66
|
+
| `TMDataGridColumnMenuItemsArgs` | Type | `{ column, table, internalItems }` | – | What the function receives. |
|
package/docs/columns.md
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# Defining columns
|
|
2
|
+
|
|
3
|
+
A column declares where its value comes from, what kind of value it is, and how
|
|
4
|
+
to render it. Which filter operators it offers, which editor it opens and how
|
|
5
|
+
it sorts all follow from `meta.type`.
|
|
6
|
+
|
|
7
|
+
## The column helper
|
|
8
|
+
|
|
9
|
+
`createTMDataGridColumnHelper<TData>()` returns a TanStack column helper bound
|
|
10
|
+
to the grid's feature set, so that `meta` and `filterFn` are correctly typed.
|
|
11
|
+
The `meta.options` and `meta.edit.enabled` callbacks receive rows typed as
|
|
12
|
+
`TData`, so `row.original` needs no cast.
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
const columnHelper = createTMDataGridColumnHelper<Employee>();
|
|
16
|
+
|
|
17
|
+
const columns = columnHelper.columns([
|
|
18
|
+
columnHelper.accessor("salary", {
|
|
19
|
+
header: "Salary",
|
|
20
|
+
minSize: 130,
|
|
21
|
+
meta: { type: "number", align: "right" },
|
|
22
|
+
cell: (info) => formatSek(info.getValue()),
|
|
23
|
+
}),
|
|
24
|
+
columnHelper.accessor((row) => `${row.firstName} ${row.lastName}`, {
|
|
25
|
+
id: "fullName",
|
|
26
|
+
header: "Full name",
|
|
27
|
+
meta: { label: "Full name" },
|
|
28
|
+
}),
|
|
29
|
+
]);
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Define columns at module scope.** A new array on every render rebuilds the
|
|
33
|
+
table's column model and discards the user's column widths and order.
|
|
34
|
+
|
|
35
|
+
```demo
|
|
36
|
+
file: getting-started/ColumnDefinitions.tsx
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
An accessor may be a key of the row or a function over it. A function needs an
|
|
40
|
+
explicit `id`, and a `meta.label` for the name shown in menus and the columns
|
|
41
|
+
panel.
|
|
42
|
+
|
|
43
|
+
A dotted `accessorKey` reads a nested field, and the column id it derives
|
|
44
|
+
replaces the dots: `accessorKey: "address.city"` makes column id
|
|
45
|
+
`address_city`, while the edit path stays `"address.city"`. Anything that
|
|
46
|
+
addresses the column by id - `initialState`, `editing.columns`, `moveColumn`,
|
|
47
|
+
a test selector - takes the underscore form; the dotted form silently matches
|
|
48
|
+
nothing.
|
|
49
|
+
|
|
50
|
+
### Columns derived from the other rows
|
|
51
|
+
|
|
52
|
+
`accessorFn` is handed one row, so a value that depends on the rest - a share
|
|
53
|
+
of a total, a rank, a running total - cannot be an accessor. Derive the
|
|
54
|
+
collection once and hand the grid the finished shape; the column is then a
|
|
55
|
+
plain `accessorKey`:
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
const rows = useMemo(() => {
|
|
59
|
+
const total = holdings.reduce((sum, holding) => sum + holding.value, 0);
|
|
60
|
+
|
|
61
|
+
return holdings.map((holding) => ({
|
|
62
|
+
...holding,
|
|
63
|
+
pctOfTotal: (holding.value / total) * 100,
|
|
64
|
+
}));
|
|
65
|
+
}, [holdings]);
|
|
66
|
+
|
|
67
|
+
columnHelper.accessor("pctOfTotal", {
|
|
68
|
+
header: "Share",
|
|
69
|
+
meta: { type: "number", align: "right" },
|
|
70
|
+
cell: (info) => `${info.getValue().toFixed(1)}%`,
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
[A portfolio rebalancer](/docs/portfolio-rebalancer) works one through, from
|
|
75
|
+
the derived rows to a validator that reads them all.
|
|
76
|
+
|
|
77
|
+
## meta
|
|
78
|
+
|
|
79
|
+
`meta` carries what a TanStack column definition has no field for. What the
|
|
80
|
+
column is sits at the top level; what the filter panel and the edit engine do
|
|
81
|
+
with it sits in the `filter` and `edit` namespaces.
|
|
82
|
+
Its type is `TMDataGridColumnMeta`.
|
|
83
|
+
|
|
84
|
+
| Field | Type | Default | Description |
|
|
85
|
+
| --- | --- | --- | --- |
|
|
86
|
+
| `label` | `string` | String header, or column id | Name used in menus and the column manager. Required when `header` is a component. |
|
|
87
|
+
| `type` | `"string" \| "number" \| "boolean" \| "date" \| "select" \| "multiSelect"` | `"string"` | What the values are. Selects the filter operators, the filter control and the cell editor. |
|
|
88
|
+
| `options` | `TMDataGridOptionsSource` | - | The choices of a `select` / `multiSelect` column. See [Options](#options). |
|
|
89
|
+
| `flex` | `number` | `1` | Share of the remaining width. |
|
|
90
|
+
| `align` | `"left" \| "right" \| "center"` | `"left"` | Alignment, applied to both header and cells. |
|
|
91
|
+
| `autoSize` | `boolean` | `false` | Fit the column to its content once, on the render its first cells appear in. |
|
|
92
|
+
| `enableOrdering` | `boolean` | `true` | `false` keeps the column where it is. |
|
|
93
|
+
| `filter` | `TMDataGridColumnFilterOptions` | - | How this column filters. See [meta.filter](#metafilter). |
|
|
94
|
+
| `edit` | `TMDataGridColumnEditOptions` | - | How this column is edited. See [meta.edit](#metaedit). |
|
|
95
|
+
|
|
96
|
+
### meta.filter
|
|
97
|
+
|
|
98
|
+
| Field | Type | Default | Description |
|
|
99
|
+
| --- | --- | --- | --- |
|
|
100
|
+
| `defaultOperator` | `TMDataGridFilterOperator` | The type's default | The operator a fresh filter starts with. See [Filtering](/docs/filtering#operators). |
|
|
101
|
+
| `control` | `TMDataGridFilterControlComponent` | By type and operator | Replaces the filter panel's value control. See [Filtering](/docs/filtering#replacing-the-value-control). |
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
meta: {
|
|
105
|
+
type: "number",
|
|
106
|
+
filter: { defaultOperator: "between", control: DgRangeSliderFilter },
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### meta.edit
|
|
111
|
+
|
|
112
|
+
| Field | Type | Default | Description |
|
|
113
|
+
| --- | --- | --- | --- |
|
|
114
|
+
| `enabled` | `boolean \| (row) => boolean` | `true` | Whether cells in this column may be edited. See [Editing](/docs/editing#which-cells-edit). |
|
|
115
|
+
| `field` | `string` | The `accessorKey` | The data path an edit writes to, for a column built on `accessorFn`. |
|
|
116
|
+
| `editor` | `TMDataGridEditorComponent` | By `type` | Replaces the cell editor. See [Editors](/docs/editors#writing-your-own). |
|
|
117
|
+
| `validate` | `TMDataGridFieldValidate` | - | Per-cell validation. See [Validation](/docs/editors#validation). |
|
|
118
|
+
| `mapValue` | `TMDataGridEditValueMap` | - | Maps each value an editor writes. See [Mapping the value](/docs/editors#mapping-the-value-as-it-is-typed). |
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
meta: {
|
|
122
|
+
type: "string",
|
|
123
|
+
edit: {
|
|
124
|
+
enabled: (row) => row.original.status !== "Terminated",
|
|
125
|
+
validate: z.string().min(2, "At least two characters"),
|
|
126
|
+
mapValue: ({ value }) =>
|
|
127
|
+
typeof value === "string" ? value.toUpperCase() : value,
|
|
128
|
+
},
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Omit both namespaces to get the defaults: any column mapping to a data path is
|
|
133
|
+
editable once `editing` is set, and every column filters by its type.
|
|
134
|
+
|
|
135
|
+
## Column types
|
|
136
|
+
|
|
137
|
+
`meta.type` declares what a column's values are. The filter panel offers that
|
|
138
|
+
type's operators and renders a matching value control: a date input for `date`,
|
|
139
|
+
a Yes/No dropdown for `boolean`, a multi-select of the column's options for
|
|
140
|
+
`select` and `multiSelect`. With editing on, the same declaration picks the
|
|
141
|
+
editor.
|
|
142
|
+
|
|
143
|
+
Dates may be `Date` instances or ISO `YYYY-MM-DD` strings in the data; the
|
|
144
|
+
comparison is by calendar day either way, and filter values always travel as ISO
|
|
145
|
+
strings. The date control is the native `<input type="date">`; `@mantine/dates`
|
|
146
|
+
is not used.
|
|
147
|
+
|
|
148
|
+
A column whose value is none of the six types - an object such as a
|
|
149
|
+
`{ from, to }` range - renders through its own `cell`, but sorting, the filter
|
|
150
|
+
panel and quick search operate on the raw value. Set `enableSorting`,
|
|
151
|
+
`enableColumnFilter` and `enableGlobalFilter` to `false` on such a column.
|
|
152
|
+
|
|
153
|
+
### Options
|
|
154
|
+
|
|
155
|
+
`select` and `multiSelect` columns declare their choices once, in `meta.options`,
|
|
156
|
+
and every consumer of them (the filter panel, the cell editor) reads the same
|
|
157
|
+
source:
|
|
158
|
+
|
|
159
|
+
```tsx
|
|
160
|
+
// A fixed set, strings or full options:
|
|
161
|
+
meta: {
|
|
162
|
+
type: "select",
|
|
163
|
+
options: [
|
|
164
|
+
"Pending",
|
|
165
|
+
{ value: "Paid", label: "Paid in full", color: "green" },
|
|
166
|
+
],
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// The distinct values present in the data (low-cardinality columns):
|
|
170
|
+
meta: { type: "select", options: "faceted" }
|
|
171
|
+
|
|
172
|
+
// Computed. `row` is set when a cell editor asks and absent for the filter
|
|
173
|
+
// panel, so row-dependent options can branch on it:
|
|
174
|
+
meta: {
|
|
175
|
+
type: "select",
|
|
176
|
+
options: ({ row }) => (row ? citiesFor(row.original.country) : allCities),
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
`resolveColumnOptions({ table, column, row? })` normalises all three forms and is
|
|
181
|
+
exported for custom controls; `optionsToComboboxData` turns the result into what
|
|
182
|
+
Mantine's `Select` and `MultiSelect` take, `group` fields included.
|
|
183
|
+
|
|
184
|
+
A select column that declares no options still filters: the panel falls back to
|
|
185
|
+
the faceted values. Mantine's dropdowns are not virtualized, so use the function
|
|
186
|
+
form for very large sets.
|
|
187
|
+
|
|
188
|
+
## Header groups
|
|
189
|
+
|
|
190
|
+
`columnHelper.group` nests columns under a shared header. The group is a header
|
|
191
|
+
row, not a column - the leaves keep all the behaviour. `columns` takes another
|
|
192
|
+
`columnHelper.columns` call, not a bare array:
|
|
193
|
+
|
|
194
|
+
```tsx
|
|
195
|
+
columnHelper.group({
|
|
196
|
+
id: "person",
|
|
197
|
+
header: "Person",
|
|
198
|
+
columns: columnHelper.columns([
|
|
199
|
+
columnHelper.accessor("firstName", { header: "First" }),
|
|
200
|
+
columnHelper.accessor("lastName", { header: "Last" }),
|
|
201
|
+
]),
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
```demo
|
|
206
|
+
file: getting-started/HeaderGroups.tsx
|
|
207
|
+
hint: Sort, filter and resize the leaves; the group header follows them.
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Columns inside a group cannot be reordered, regardless of `meta.enableOrdering`:
|
|
211
|
+
`columnOrder` sequences leaf columns, so moving one would leave the group header
|
|
212
|
+
spanning columns that no longer belong to it.
|
|
213
|
+
|
|
214
|
+
## Per-column feature switches
|
|
215
|
+
|
|
216
|
+
Standard TanStack column options. Each removes the corresponding interface for
|
|
217
|
+
that column alone.
|
|
218
|
+
|
|
219
|
+
| Option | Effect when `false` |
|
|
220
|
+
| --- | --- |
|
|
221
|
+
| `enableSorting` | No sort indicator and no sort menu items. See [Sorting](/docs/sorting). |
|
|
222
|
+
| `enableColumnFilter` | No filter menu item, and no entry in the panel's column list. |
|
|
223
|
+
| `enableHiding` | No hide menu item, and no checkbox in the column manager. |
|
|
224
|
+
| `enablePinning` | No pin menu items. |
|
|
225
|
+
| `enableResizing` | The divider stays as a separator but cannot be dragged. |
|
|
226
|
+
| `meta.enableOrdering` | No header dragging and no move menu items. |
|
|
227
|
+
|
|
228
|
+
Sizing, pinning, ordering and visibility are covered on
|
|
229
|
+
[Visibility, pinning, ordering and size](/docs/column-layout).
|
|
230
|
+
|
|
231
|
+
## The generated columns
|
|
232
|
+
|
|
233
|
+
Five lanes the grid adds when a feature needs them. All are **system lanes**:
|
|
234
|
+
fixed width, no column menu, no resize handle, never exported, never hidden and
|
|
235
|
+
never listed in the columns panel.
|
|
236
|
+
|
|
237
|
+
| Id | Appears when | Where |
|
|
238
|
+
| --- | --- | --- |
|
|
239
|
+
| `ROW_NUMBER_COLUMN_ID` | `enableRowNumbers` | Outermost left, before everything. See [Row pinning and numbering](/docs/row-pinning#numbering-rows). |
|
|
240
|
+
| `SELECT_COLUMN_ID` | A checkbox selection mode | First, pinned left. See [Row selection](/docs/row-selection). |
|
|
241
|
+
| `GROUP_COLUMN_ID` | A column is grouped | Front, beside the checkbox lane. See [Grouping](/docs/grouping). |
|
|
242
|
+
| `DETAILS_COLUMN_ID` | `renderDetails` is set | Left, after checkbox and tree. See [Row details](/docs/row-details). |
|
|
243
|
+
| `EDIT_COLUMN_ID` | `editing.mode: "row"`, `editing.draft`, or `editing.onRowDelete` | Appended, pinned right, and stays outside anything the user pins right. See [Editing](/docs/editing). |
|
|
244
|
+
|
|
245
|
+
The checkbox lane cannot be moved: it anchors the left pinned region, and no
|
|
246
|
+
column can be placed in front of it.
|
|
247
|
+
|
|
248
|
+
## Reference
|
|
249
|
+
|
|
250
|
+
| Name | Kind | Type | Default | What it does |
|
|
251
|
+
| --- | --- | --- | --- | --- |
|
|
252
|
+
| `createTMDataGridColumnHelper` | Export | `<TData>() => TMDataGridColumnHelper<TData>` | – | A TanStack column helper typed against the grid's features, with `meta` callbacks typed against `TData`. |
|
|
253
|
+
| `TMDataGridColumnHelper` | Type | – | – | The helper's type. |
|
|
254
|
+
| `TMDataGridColumnMeta` | Type | – | – | The type of `meta`. Typed against the row when the column is declared with `createTMDataGridColumnHelper`. |
|
|
255
|
+
| `TMDataGridRowData` | Type | `Record<string, unknown>` | – | The row type where none is given: the default `TData` of the column meta types, and the rows `useTMDataGridContext` returns. |
|
|
256
|
+
| `meta.label` | Column meta | `string` | Header or id | Name in menus and the columns panel. |
|
|
257
|
+
| `meta.type` | Column meta | six types | `"string"` | What the values are; drives filters and editors. |
|
|
258
|
+
| `TMDataGridColumnType` | Type | – | – | The six values of `meta.type`. |
|
|
259
|
+
| `meta.options` | Column meta | array \| `"faceted"` \| `(args) => …` | – | The choices of an option column. |
|
|
260
|
+
| `TMDataGridOptionsArgs` | Type | – | – | What a `meta.options` function receives: `{ table, column, row? }`. `row` is absent when the filter panel asks. |
|
|
261
|
+
| `meta.align` | Column meta | `"left" \| "right" \| "center"` | `"left"` | Header and cell alignment. |
|
|
262
|
+
| `meta.filter` | Column meta | `TMDataGridColumnFilterOptions` | – | How the column filters: `defaultOperator`, `control`. |
|
|
263
|
+
| `meta.edit` | Column meta | `TMDataGridColumnEditOptions` | – | How the column edits: `enabled`, `field`, `editor`, `validate`, `mapValue`. |
|
|
264
|
+
| `resolveColumnOptions` | Export | `({ table, column, row? }) => options` | – | Normalises all three `meta.options` forms. |
|
|
265
|
+
| `optionsToComboboxData` | Export | `(options) => ComboboxData` | – | Options as Mantine `Select` data. |
|
|
266
|
+
| `getColumnLabel` · `getColumnType` · `isControlColumn` | Exports | `(column) => …` | – | How the built-in controls read a column. |
|
|
267
|
+
| `isGeneratedColumn` | Export | `(columnId) => boolean` | – | Whether the grid generated the column - the four control lanes plus the tree column. |
|
|
268
|
+
| `SELECT_COLUMN_ID` · `GROUP_COLUMN_ID` · `DETAILS_COLUMN_ID` · `EDIT_COLUMN_ID` · `ROW_NUMBER_COLUMN_ID` | Exports | `string` | – | Ids of the five generated lanes. |
|