@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.
Files changed (150) hide show
  1. package/README.md +5 -212
  2. package/dist/index.d.ts +1664 -632
  3. package/dist/index.js +5226 -3223
  4. package/dist/index.js.map +1 -1
  5. package/dist/styles.css +1 -1
  6. package/docs/anatomy.md +102 -0
  7. package/docs/cell-selection.md +154 -0
  8. package/docs/column-layout.md +204 -0
  9. package/docs/columns.md +262 -0
  10. package/docs/components.md +304 -0
  11. package/docs/editing.md +603 -0
  12. package/docs/editors.md +250 -0
  13. package/docs/export.md +326 -0
  14. package/docs/filtering.md +358 -0
  15. package/docs/getting-started.md +123 -0
  16. package/docs/grouping.md +165 -0
  17. package/docs/loading-and-empty.md +92 -0
  18. package/docs/localization.md +79 -0
  19. package/docs/menu.md +143 -0
  20. package/docs/pagination.md +144 -0
  21. package/docs/persistence.md +111 -0
  22. package/docs/portfolio-rebalancer.md +94 -0
  23. package/docs/query-builder.md +175 -0
  24. package/docs/quick-search.md +83 -0
  25. package/docs/row-details.md +113 -0
  26. package/docs/row-interaction.md +148 -0
  27. package/docs/row-pinning.md +132 -0
  28. package/docs/row-selection.md +134 -0
  29. package/docs/row-styling.md +133 -0
  30. package/docs/scrolling.md +111 -0
  31. package/docs/server-query.md +246 -0
  32. package/docs/server-side.md +206 -0
  33. package/docs/sorting.md +101 -0
  34. package/docs/styling.md +126 -0
  35. package/docs/summary-row.md +76 -0
  36. package/docs/testing.md +309 -0
  37. package/docs/toolbar.md +161 -0
  38. package/docs/use-tm-data-grid.md +361 -0
  39. package/package.json +21 -45
  40. package/skills/appearance/SKILL.md +70 -17
  41. package/skills/cell-selection/SKILL.md +70 -76
  42. package/skills/columns/SKILL.md +131 -32
  43. package/skills/data/SKILL.md +100 -23
  44. package/skills/editing/SKILL.md +217 -96
  45. package/skills/editing/references/common-mistakes.md +111 -24
  46. package/skills/editing/references/editing-api.md +63 -39
  47. package/skills/editing/references/editors-and-validation.md +77 -19
  48. package/skills/filtering/SKILL.md +148 -40
  49. package/skills/getting-started/SKILL.md +18 -16
  50. package/skills/grouping/SKILL.md +32 -15
  51. package/skills/options/SKILL.md +39 -9
  52. package/skills/rows/SKILL.md +22 -18
  53. package/skills/server-side/SKILL.md +170 -17
  54. package/skills/testing/SKILL.md +10 -7
  55. package/src/{tmdatagrid/TMDataGridContext.ts → TMDataGridContext.ts} +7 -19
  56. package/src/{tmdatagrid/components → components}/TMDataGrid.module.css +7 -1
  57. package/src/{tmdatagrid/components → components}/TMDataGrid.tsx +39 -23
  58. package/src/{tmdatagrid/components → components}/TMDataGridCellEditor.tsx +106 -38
  59. package/src/{tmdatagrid/components → components}/TMDataGridColumnsPanel.module.css +5 -1
  60. package/src/{tmdatagrid/components → components}/TMDataGridColumnsPanel.tsx +47 -55
  61. package/src/{tmdatagrid/components → components}/TMDataGridDetailsColumn.tsx +4 -4
  62. package/src/components/TMDataGridDraftActions.tsx +307 -0
  63. package/src/{tmdatagrid/components → components}/TMDataGridEditColumn.tsx +58 -50
  64. package/src/{tmdatagrid/components → components}/TMDataGridEntryRows.tsx +150 -115
  65. package/src/components/TMDataGridExportPicker.module.css +77 -0
  66. package/src/components/TMDataGridExportPicker.tsx +234 -0
  67. package/src/components/TMDataGridFilterPanel.module.css +54 -0
  68. package/src/components/TMDataGridFilterPanel.tsx +348 -0
  69. package/src/{tmdatagrid/components → components}/TMDataGridFilterPills.tsx +7 -5
  70. package/src/components/TMDataGridFilterSurface.module.css +54 -0
  71. package/src/components/TMDataGridFilterSurface.tsx +167 -0
  72. package/src/{tmdatagrid/components → components}/TMDataGridFooter.tsx +53 -13
  73. package/src/{tmdatagrid/components → components}/TMDataGridGroupColumn.tsx +4 -3
  74. package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.module.css +10 -0
  75. package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.tsx +100 -28
  76. package/src/components/TMDataGridHeaderFilterRow.module.css +51 -0
  77. package/src/components/TMDataGridHeaderFilterRow.tsx +301 -0
  78. package/src/components/TMDataGridMenu.tsx +354 -0
  79. package/src/{tmdatagrid/components → components}/TMDataGridSelectColumn.tsx +12 -7
  80. package/src/{tmdatagrid/components → components}/TMDataGridTable.module.css +90 -67
  81. package/src/{tmdatagrid/components → components}/TMDataGridTable.tsx +678 -156
  82. package/src/components/TMDataGridToolbar.module.css +21 -0
  83. package/src/components/TMDataGridToolbar.tsx +181 -0
  84. package/src/{tmdatagrid/components → components}/editors/TMDataGridBooleanEditor.tsx +3 -3
  85. package/src/{tmdatagrid/components → components}/editors/TMDataGridDateEditor.tsx +3 -3
  86. package/src/{tmdatagrid/components → components}/editors/TMDataGridMultiSelectEditor.tsx +3 -3
  87. package/src/components/editors/TMDataGridNumberEditor.tsx +70 -0
  88. package/src/{tmdatagrid/components → components}/editors/TMDataGridSelectEditor.tsx +3 -3
  89. package/src/{tmdatagrid/components → components}/editors/TMDataGridStringEditor.tsx +3 -3
  90. package/src/{tmdatagrid/components → components}/editors/editorShared.ts +17 -31
  91. package/src/{tmdatagrid/components → components}/filters/DgAutocompleteFilter.tsx +5 -4
  92. package/src/{tmdatagrid/components → components}/filters/DgDateRangeFilter.tsx +22 -5
  93. package/src/{tmdatagrid/components → components}/filters/DgRangeSliderFilter.tsx +5 -1
  94. package/src/{tmdatagrid/components → components}/filters/DgTriStateFilter.tsx +5 -1
  95. package/src/{tmdatagrid/components → components}/filters/TMDataGridFilterValueInput.tsx +44 -28
  96. package/src/components/filters/controlLayout.ts +32 -0
  97. package/src/components/filters/filterControlFor.ts +65 -0
  98. package/src/{tmdatagrid/components → components}/icons.ts +1 -0
  99. package/src/{tmdatagrid/components → components}/sticky.module.css +44 -0
  100. package/src/components/useHideableColumns.ts +52 -0
  101. package/src/{tmdatagrid/core → core}/autosize.ts +5 -2
  102. package/src/{tmdatagrid/core → core}/capabilities.ts +14 -6
  103. package/src/{tmdatagrid/core → core}/columnOptions.ts +46 -0
  104. package/src/{tmdatagrid/core → core}/columnOrdering.ts +33 -14
  105. package/src/{tmdatagrid/core → core}/columnUtils.ts +44 -5
  106. package/src/core/controlledState.ts +179 -0
  107. package/src/core/controlledStateSync.ts +108 -0
  108. package/src/core/deletedRows.ts +34 -0
  109. package/src/core/dom.ts +74 -0
  110. package/src/core/editEngine.ts +2476 -0
  111. package/src/{tmdatagrid/core → core}/editorFocus.ts +8 -4
  112. package/src/core/export.ts +843 -0
  113. package/src/{tmdatagrid/core → core}/filterControls.ts +38 -1
  114. package/src/{tmdatagrid/core → core}/filterOperators.ts +64 -1
  115. package/src/core/filterSurface.ts +99 -0
  116. package/src/{tmdatagrid/core → core}/labels.ts +66 -8
  117. package/src/{tmdatagrid/core → core}/labelsSv.ts +26 -3
  118. package/src/core/pageReset.ts +120 -0
  119. package/src/{tmdatagrid/core → core}/persistence.ts +22 -5
  120. package/src/core/resizePreview.ts +141 -0
  121. package/src/core/summary.ts +59 -0
  122. package/src/core/useSettledTableState.ts +36 -0
  123. package/src/{tmdatagrid/index.ts → index.ts} +75 -12
  124. package/src/{tmdatagrid/useTMDataGrid.tsx → useTMDataGrid.tsx} +734 -135
  125. package/src/useTMDataGridExport.ts +78 -0
  126. package/src/tmdatagrid/components/TMDataGridEditActions.tsx +0 -162
  127. package/src/tmdatagrid/components/TMDataGridFilterPanel.module.css +0 -35
  128. package/src/tmdatagrid/components/TMDataGridFilterPanel.tsx +0 -354
  129. package/src/tmdatagrid/components/TMDataGridToolbar.module.css +0 -12
  130. package/src/tmdatagrid/components/TMDataGridToolbar.tsx +0 -162
  131. package/src/tmdatagrid/components/editors/TMDataGridNumberEditor.tsx +0 -40
  132. package/src/tmdatagrid/core/cellExport.ts +0 -320
  133. package/src/tmdatagrid/core/editEngine.ts +0 -1006
  134. package/src/tmdatagrid/core/summary.ts +0 -35
  135. /package/src/{tmdatagrid/components → components}/TMDataGridDetailsColumn.module.css +0 -0
  136. /package/src/{tmdatagrid/components → components}/TMDataGridFilterPills.module.css +0 -0
  137. /package/src/{tmdatagrid/components → components}/TMDataGridFooter.module.css +0 -0
  138. /package/src/{tmdatagrid/components → components}/TMDataGridGroupColumn.module.css +0 -0
  139. /package/src/{tmdatagrid/components → components}/TMDataGridRowNumberColumn.tsx +0 -0
  140. /package/src/{tmdatagrid/components → components}/TMDataGridSearch.tsx +0 -0
  141. /package/src/{tmdatagrid/core → core}/cellNavigation.ts +0 -0
  142. /package/src/{tmdatagrid/core → core}/cellRange.ts +0 -0
  143. /package/src/{tmdatagrid/core → core}/draftCellContext.ts +0 -0
  144. /package/src/{tmdatagrid/core → core}/expanding.ts +0 -0
  145. /package/src/{tmdatagrid/core → core}/grouping.ts +0 -0
  146. /package/src/{tmdatagrid/core → core}/matchHighlight.ts +0 -0
  147. /package/src/{tmdatagrid/core → core}/quickSearch.ts +0 -0
  148. /package/src/{tmdatagrid/core → core}/rowPinning.ts +0 -0
  149. /package/src/{tmdatagrid/core → core}/rowSelection.ts +0 -0
  150. /package/src/{tmdatagrid/core → core}/sizes.ts +0 -0
@@ -0,0 +1,361 @@
1
+ # useTMDataGrid
2
+
3
+ Creates the table instance and the state used by the grid interface.
4
+
5
+ ```tsx
6
+ const grid = useTMDataGrid<TData>(options);
7
+ // { table, ui, features }
8
+ ```
9
+
10
+ Spread the result onto `TMDataGrid`.
11
+
12
+ ## Options
13
+
14
+ All TanStack `TableOptions` are supported and passed through unchanged,
15
+ including `data`, `columns`, `getRowId`, `state` and the `onXChange` callbacks
16
+ (see [Controlled state](#controlled-state)), the `manual*` flags and `rowCount`.
17
+ The `features` option is supplied internally and cannot be overridden.
18
+
19
+ `persist`, `enableColumnOrdering`, `enablePagination`, `selectionMode`,
20
+ `showSelectedBackground`, `defaultHighlightedRowId`, `onHighlightedRowChange`,
21
+ `renderDetails`, `renderDetailsEstHeight`, `overscan`, `cellSelection`,
22
+ `onFocusedCellChange`, `quickSearchMode`, `labels` and `editing`
23
+ (see [Editing](/docs/editing)) are the grid's own options and are consumed here
24
+ rather than forwarded to TanStack.
25
+
26
+ | Option | Type | Default | Description |
27
+ | --- | --- | --- | --- |
28
+ | `data` | `TData[]` | – | Row data. When the reference changes the table reprocesses the row models, so keep it stable with `useMemo`. |
29
+ | `columns` | `ColumnDef[]` | – | Created with `createTMDataGridColumnHelper`. |
30
+ | `getRowId` | `(row, index) => string` | Row index | Used by row selection and virtualization. |
31
+ | `enableRowSelection` | `boolean \| (row) => boolean` | `true` | `false` removes row selection and its checkbox column. |
32
+ | `selectionMode` | `"checkbox" \| "row" \| "checkboxAndHighlight" \| "highlight"` | `"checkbox"` | What selecting looks like and what a bare row click does. Defined by the grid, see [Row selection](/docs/row-selection). |
33
+ | `showSelectedBackground` | `boolean` | On for `"row"`, off for `"checkbox"` | Determines whether selected rows take a background tint, coloured by `--dg-row-selected-bg`. Defined by the grid, see [Row selection](/docs/row-selection). |
34
+ | `defaultHighlightedRowId` | `string \| null` | – | Row highlighted on mount, under a mode with a highlight. Read once, like `initialState`. |
35
+ | `onHighlightedRowChange` | `(rowId: string \| null) => void` | – | Follows the highlighted row, from clicks and from `ui.actions.setHighlightedRow`. |
36
+ | `enableSorting` | `boolean` | `true` | Enables sorting for the table. |
37
+ | `enableColumnFilters` | `boolean` | `true` | Enables filtering for the table. |
38
+ | `enableHiding` | `boolean` | `true` | Enables column visibility for the table. |
39
+ | `enableColumnPinning` | `boolean` | `true` | Enables pinning for the table. |
40
+ | `enableColumnResizing` | `boolean` | `true` | Enables resizing for the table. |
41
+ | `enableColumnOrdering` | `boolean` | `true` | Enables header dragging and the move menu items. Defined by the grid, see [Column layout](/docs/column-layout#ordering). |
42
+ | `enablePagination` | `boolean` | `false` | Enables client-side paging and the `Footer` pager. Implied by `manualPagination`. Defined by the grid, see [Pagination](/docs/pagination). |
43
+ | `enableRowNumbers` | `boolean` | `false` | The row-number gutter, outermost left. Defined by the grid, see [Row pinning and numbering](/docs/row-pinning). |
44
+ | `enableRowPinning` | `boolean \| (row) => boolean` | `false` | Rows can be pinned to sticky edge blocks with `row.pin()`. See [Row pinning and numbering](/docs/row-pinning). |
45
+ | `quickSearchMode` | `"fuzzy" \| "contains"` | `"fuzzy"` | How `Search` matches. Fuzzy forgives typos and orders unsorted results by match quality; `"contains"` is plain substring matching. Defined by the grid, see [Quick search](/docs/quick-search). |
46
+ | `enableMatchHighlighting` | `boolean` | `false` | Cells mark the matched text while a contains-family filter or the quick search is active. Defined by the grid, see [Quick search](/docs/quick-search#match-highlighting). |
47
+ | `renderDetails` | `({ row, table }) => ReactNode` | – | Panel rendered under an expanded row, spanning every column. Setting it turns row details on and adds the pinned chevron lane. Defined by the grid, see [Row details](/docs/row-details). |
48
+ | `renderDetailsEstHeight` | `number` | `160` | What the virtualizer assumes for a panel it has not measured yet. Panels are measured once mounted, so an approximation is enough. |
49
+ | `cellSelection` | `"none" \| "single" \| "range"` | `"none"` | Cell cursor and, under `"range"`, a selectable rectangle with Ctrl+C and CSV export. Defined by the grid, see [Cell selection](/docs/cell-selection). |
50
+ | `onFocusedCellChange` | `(cell: TMDataGridCellPosition \| null) => void` | – | Called whenever the focused cell moves, by key, click or `setFocusedCell`. |
51
+ | `overscan` | `number` | `6` | Rows the virtualizer keeps mounted above and below the viewport. Raise it if fast scrolling flashes blank rows, lower it when rows are expensive to render. |
52
+ | `columnResizeMode` | `"onChange" \| "onEnd"` | `"onEnd"` | When a resize drag writes `columnSizing`. The grid paints a running drag itself either way; `"onChange"` also publishes a width on every pointer move, which re-renders the grid with each of them. |
53
+ | `initialState` | `Partial<TableState>` | – | Starting state, read once on mount. Merged over the [grid defaults](#default-initial-state). |
54
+ | `state` | `Partial<TableState>` | – | Controlled state. Each slice requires its `onXChange`. See [Controlled state](#controlled-state). |
55
+ | `atoms` | `Partial<Record<slice, Atom>>` | – | External atoms owning state slices. No callback required. Takes precedence over `state`. |
56
+ | `meta` | `TMDataGridTableMeta` | `{}` | Grid configuration. See [meta](#meta). |
57
+ | `filters` | `TMDataGridFiltersOptions` | `{ surface: "popup" }` | Where the filter controls go - a popup, a sidebar, the column headers, or nowhere. See [Filtering](/docs/filtering#the-filters-option). |
58
+ | `persist` | `TMDataGridPersistence` | – | State persistence. See [persist](#persist). |
59
+ | `labels` | `TMDataGridLabelsOverride` | English | Overrides for the grid's strings, see [Localization](#localization). |
60
+
61
+ ### Default initial state
62
+
63
+ | Slice | Default |
64
+ | --- | --- |
65
+ | `pagination` | `{ pageIndex: 0, pageSize: 25 }`. Inert until pagination is enabled |
66
+ | `columnPinning.start` | The checkbox, tree and details columns, followed by any columns you provide |
67
+ | `globalFilterFn` | `"tmDataGridFuzzy"`, the fuzzy matcher behind `quickSearchMode`. `"includesString"` under `quickSearchMode: "contains"` |
68
+
69
+ ### Controlled state
70
+
71
+ `state` makes a slice controlled: the parent owns the value and the grid reads
72
+ it on every render. Each controlled slice requires its `onXChange` callback -
73
+ all writes go through it. Without the callback the slice cannot change; the
74
+ grid logs a console warning in development. For a starting value only, use
75
+ `initialState`.
76
+
77
+ ```tsx
78
+ const [columnVisibility, setColumnVisibility] = useState({ play: false });
79
+
80
+ const grid = useTMDataGrid({
81
+ data,
82
+ columns,
83
+ state: { columnVisibility },
84
+ onColumnVisibilityChange: setColumnVisibility,
85
+ });
86
+ ```
87
+
88
+ - Controllable slices: `columnFilters`, `columnOrder`, `columnPinning`,
89
+ `columnResizing`, `columnSizing`, `columnVisibility`, `expanded`,
90
+ `globalFilter`, `grouping`, `pagination`, `rowPinning`, `rowSelection`,
91
+ `sorting`. Each has a matching `onXChange`.
92
+ - A key set to `undefined` is ignored; the slice is uncontrolled.
93
+ - Slices are compared structurally between renders, so the `state` object can
94
+ be built inline. `Date` values compare by time. `Map`s and class instances
95
+ compare by identity; keep a slice containing one in `useState` or `useMemo`.
96
+ - `atoms` also controls a slice, with no callback: the table writes through the
97
+ atom. An atom takes precedence over `state` for the same slice.
98
+ - `columnVisibility` toggles user-defined columns only. Entries for the
99
+ generated columns (checkbox, details, edit, row number) are ignored; enable
100
+ or disable those through their feature options. The tree column's entry is
101
+ managed by the grid and follows `grouping`.
102
+ - `persist` restores through `initialState` and cannot restore a controlled
103
+ slice. It still writes the slice to storage on change.
104
+
105
+ ## meta
106
+
107
+ Grid configuration, passed through the `meta` option.
108
+
109
+ | Field | Type | Default | Description |
110
+ | --- | --- | --- | --- |
111
+ | `loading` | `boolean` | – | Displays a loader while the grid is empty. Takes precedence over every empty state. |
112
+ | `noResultsLabel` | `string` | `"No rows match your filters"` | The filtered-empty message. A grid with no data and no filters says `labels.noRows` instead; `renderEmptyState` on the Table replaces both. |
113
+ | `rowHeight` | `number` | From `size` | Row height in px. Overrides the size scale. |
114
+ | `totalRowCount` | `number` | – | Unfiltered total used by `SummaryCount`. Required for server-side data. |
115
+
116
+ ## Localization
117
+
118
+ Every string the grid renders - menu items, panels, tooltips, the pager and the
119
+ `aria-label`s - comes from one labels object, English by default. The `labels`
120
+ option takes any subset and merges it over the defaults:
121
+
122
+ ```tsx
123
+ const grid = useTMDataGrid({
124
+ data,
125
+ columns,
126
+ labels: { noResults: "Inga rader matchar dina filter" },
127
+ });
128
+ ```
129
+
130
+ Labels that carry a value are functions, so each language can place the value
131
+ where its grammar requires:
132
+
133
+ ```tsx
134
+ labels: {
135
+ groupBy: (column) => `Gruppera på ${column}`,
136
+ pageRange: ({ from, to, total }) => `${from}–${to} av ${total}`,
137
+ }
138
+ ```
139
+
140
+ Keep the object referentially stable (module scope or `useMemo`); the grid
141
+ re-renders when its identity changes.
142
+
143
+ The full dictionary type is `TMDataGridLabels`; the English defaults are
144
+ exported as `TMDATAGRID_LABELS_EN`, and a complete Swedish dictionary as
145
+ `TMDATAGRID_LABELS_SV`:
146
+
147
+ ```tsx
148
+ import { TMDATAGRID_LABELS_SV } from "@jielga/tmdatagrid";
149
+
150
+ const grid = useTMDataGrid({ data, columns, labels: TMDATAGRID_LABELS_SV });
151
+ ```
152
+
153
+ `meta.noResultsLabel` still works as a per-instance override of
154
+ `labels.noResults`.
155
+
156
+ The resolved dictionary is returned from the hook as `grid.labels`, so custom
157
+ toolbar components can read the same strings as the built-in parts.
158
+
159
+ ## persist
160
+
161
+ Restores table state on mount and writes it back on every change. State is
162
+ split across two keys: `settingsKey` for the column layout, `dataKey` for
163
+ filters, sorting and pagination. Either can be cleared without the other.
164
+
165
+ | Field | Type | Default | Description |
166
+ | --- | --- | --- | --- |
167
+ | `dataKey` | `string \| [string, DataSlice[]]` | – | Storage key for the data group. |
168
+ | `settingsKey` | `string \| [string, SettingsSlice[]]` | – | Storage key for the settings group. |
169
+ | `storageMode` | `"localStorage" \| "sessionStorage"` | `"localStorage"` | Storage area. Use `"sessionStorage"` for per-tab state. |
170
+ | `serialize` | `(value) => string` | `JSON.stringify` | Serializes a payload before storing. |
171
+ | `deserialize` | `(value: string) => unknown` | `JSON.parse` | Parses a stored payload. |
172
+
173
+ Both keys are optional.
174
+
175
+ ```tsx
176
+ // Defined at module scope: the object is a dependency of the write subscription.
177
+ const persist = {
178
+ dataKey: "employees.data",
179
+ settingsKey: "employees.settings",
180
+ } satisfies TMDataGridPersistence;
181
+
182
+ const grid = useTMDataGrid({ data, columns, persist });
183
+ ```
184
+
185
+ ### Selecting slices
186
+
187
+ Passing a key on its own persists every slice in its group. Pass a tuple of
188
+ `[key, slices]` to persist only some of them:
189
+
190
+ ```tsx
191
+ const persist = {
192
+ // Restore filters and sorting, but always start on the first page.
193
+ dataKey: ["employees.data", ["columnFilters", "sorting"]],
194
+ // Restore column layout but not widths.
195
+ settingsKey: ["employees.settings", ["columnVisibility", "columnOrder"]],
196
+ storageMode: "sessionStorage",
197
+ } satisfies TMDataGridPersistence;
198
+ ```
199
+
200
+ | Group | Available slices |
201
+ | --- | --- |
202
+ | `dataKey` | `columnFilters`, `globalFilter`, `sorting`, `pagination`, `expanded` |
203
+ | `settingsKey` | `columnVisibility`, `columnSizing`, `columnOrder`, `columnPinning`, `grouping` |
204
+
205
+ The exported `DATA_STATE_SLICES` and `SETTINGS_STATE_SLICES` arrays contain the
206
+ same values. Slice names are typed per group, so only valid names are accepted.
207
+
208
+ ### Behaviour
209
+
210
+ Restoring happens once on mount through `initialState`. Writing is implemented
211
+ as a subscription to the table store, so state changed directly through the
212
+ table API is persisted as well.
213
+
214
+ Only the selected slices are read back. A payload written before the selection
215
+ was narrowed cannot reintroduce slices you have since opted out of. Unrecognised
216
+ keys are ignored.
217
+
218
+ Payloads carry a version stamp, the exported `PERSIST_PAYLOAD_VERSION`. A
219
+ payload from a different version, including anything written by a 0.x build,
220
+ which had no stamp, is dropped whole rather than migrated.
221
+
222
+ Restored state is realigned against the columns that exist. Entries naming a
223
+ column removed between deploys are dropped: a stale id in the order, a width for
224
+ a column that no longer exists, or a sort or filter that would be active with no
225
+ column to show it. New columns need no handling, since TanStack appends columns
226
+ missing from `columnOrder` in definition order.
227
+
228
+ `resetSettings()` on the returned API puts the settings state back to what a
229
+ first visit with clean storage would have shown - your `initialState` plus the
230
+ structural lanes - and, with persistence configured, writes through to storage
231
+ like any other change. The columns panel's **Reset layout** button calls it.
232
+ TanStack's own `resetColumnX()` family cannot do it on a persisted grid: those
233
+ reset to `initialState`, which the mount built from the restored payload.
234
+
235
+ All storage access is guarded. If storage is unavailable, disabled or full,
236
+ persistence is skipped rather than throwing.
237
+
238
+ Storage keys are not namespaced automatically. Include a tenant or user
239
+ identifier if several users can share a browser profile.
240
+
241
+ ## Return value
242
+
243
+ | Field | Type | Description |
244
+ | --- | --- | --- |
245
+ | `table` | `Table<TMDataGridFeatures, TData>` | The TanStack table instance. |
246
+ | `ui` | `Store<TMDataGridUiState, TMDataGridUiActions>` | State of the filter and column panels. |
247
+ | `filters` | `TMDataGridFiltersSettings` | The `filters` option with its defaults filled in. See [Filtering](/docs/filtering#the-filters-option). |
248
+ | `edit` | `TMDataGridEditApi` | The edit engine, inert until `editing` is set. See [Editing](/docs/editing). |
249
+ | `features` | `TMDataGridFeatureFlags` | Table-level feature switches, re-read from options on each render. See [Toolbar](/docs/toolbar#reading-options-reactively). |
250
+ | `labels` | `TMDataGridLabels` | The resolved label set, overrides merged over English. See [Localization](/docs/localization). |
251
+ | `renderDetails` | `TMDataGridDetailsRenderer<TData> \| undefined` | The detail renderer, passed through for `TMDataGrid.Table` to call. |
252
+ | `renderDetailsEstHeight` | `number` | The estimate, resolved to its default when the option was not set. |
253
+ | `overscan` | `number` | The overscan, resolved to its default when the option was not set. |
254
+ | `resetSettings` | `() => void` | Puts the settings state back to a clean first visit. See [persist](#persist). |
255
+ | `scrollToRow` | `({ rowId, align? }) => boolean` | Scrolls a row into view; see below. |
256
+
257
+ ### scrollToRow
258
+
259
+ The grid is always virtualized, so a row far down the list has no element and
260
+ `scrollIntoView` has nothing to act on. `scrollToRow` moves the virtualizer
261
+ instead:
262
+
263
+ ```ts
264
+ grid.scrollToRow({ rowId: "42" });
265
+ grid.scrollToRow({ rowId: "42", align: "center" });
266
+ ```
267
+
268
+ `align` is TanStack Virtual's: `"auto"` (the default: nearest edge, leaving a
269
+ visible row where it is), `"start"`, `"center"` or `"end"`.
270
+
271
+ It returns whether the row could be reached. `false` means the row is not in the
272
+ current view - filtered out, on another page, or an id matching no row - and
273
+ nothing scrolled. A pinned row returns `true` without scrolling.
274
+
275
+ The identity is stable, so it is safe in a dependency array. Before
276
+ `TMDataGrid.Table` has mounted there is nothing to scroll and it returns
277
+ `false`.
278
+
279
+ Both stores are subscribable, so a parent component can react to grid state
280
+ without holding it:
281
+
282
+ ```tsx
283
+ import { useSelector } from "@tanstack/react-store";
284
+
285
+ const selectedCount = useSelector(
286
+ grid.table.store,
287
+ (state) => Object.keys(state.rowSelection).length,
288
+ );
289
+
290
+ const filterPanelOpen = useSelector(grid.ui, (state) => state.filterPanelOpen);
291
+ ```
292
+
293
+ Read state with `useSelector` rather than `grid.table.store.state`. A direct
294
+ read does not subscribe the component to the store.
295
+
296
+ ### ui actions
297
+
298
+ | Action | Signature |
299
+ | --- | --- |
300
+ | `openFilterPanel` | `(columnId?: string \| null) => void` |
301
+ | `closeFilterPanel` | `() => void` |
302
+ | `focusPanelFilter` | `(columnId: string \| null) => void` |
303
+ | `focusHeaderFilter` | `(columnId: string \| null) => void` |
304
+ | `startColumnDrag` | `(columnId: string) => void` |
305
+ | `endColumnDrag` | `() => void` |
306
+ | `setHighlightedRow` | `(rowId: string \| null) => void` |
307
+ | `setSelectionAnchor` | `(rowId: string \| null) => void` |
308
+ | `setFocusedCell` | `(cell: TMDataGridCellPosition \| null) => void` |
309
+ | `setCellRange` | `(range: TMDataGridCellRange \| null) => void` |
310
+
311
+ `setFocusedCell` and `setCellRange` move the cell cursor and the selected
312
+ rectangle under `cellSelection`. See [Cell selection](/docs/cell-selection). DOM
313
+ focus follows `focusedCell` while the grid holds it, scrolling the row into view
314
+ when it is off screen.
315
+
316
+ `startColumnDrag` and `endColumnDrag` are called by the header cells while a
317
+ column is being dragged. `ui.draggedColumnId` holds the column being moved,
318
+ since `dataTransfer` is unreadable until the drop.
319
+
320
+ `openColumnFilter(grid, columnId)` combines two steps used by the column menu:
321
+ it adds an empty filter row for the column if none exists, then sends the user
322
+ to that column's control. Which control that is follows the `filters` option -
323
+ the panel row, or, under `filters.inHeader`, the column's header control.
324
+
325
+ The two focus actions are the halves of that, and they write separate state
326
+ (`filterPanelColumnId` and `headerFilterColumnId`) so a grid showing both a
327
+ panel and header controls never has the two racing for the caret.
328
+
329
+ ## What each switch removes
330
+
331
+ Almost every control is bound to the TanStack capability check for its feature,
332
+ so setting the standard table or column option removes the corresponding
333
+ interface. Empty menus and inactive buttons are never rendered, except `TMDataGrid.Menu`, which cannot see what its children render; see [Grid menu](/docs/menu).
334
+
335
+ Column ordering and pagination are the two exceptions: TanStack ships state and
336
+ APIs for both but no `enable` option, so the grid defines `enableColumnOrdering`
337
+ (with `meta.enableOrdering`) and `enablePagination` itself. Pagination defaults
338
+ to off; ordering, like the options around it, defaults to on.
339
+
340
+ | Option | Level | Interface removed |
341
+ | --- | --- | --- |
342
+ | `enableSorting: false` | Table, column | Sort indicator, sort menu items, click-to-sort. See [Sorting](/docs/sorting) |
343
+ | `enableColumnFilters: false` | Table | Filter menu item, `FilterButton`, filter panel, header filter row. See [Filtering](/docs/filtering) |
344
+ | `enableColumnFilter: false` | Column | That column's filter menu item, panel entry and header control |
345
+ | `enableGlobalFilter: false` | Table, column | `Search`: the whole input at table level, one column's participation at column level |
346
+ | `enableHiding: false` | Table, column | Hide column, Manage columns, `TMDataGrid.Menu.Columns`. See [Column layout](/docs/column-layout) |
347
+ | `enableColumnPinning: false` | Table | Pin and unpin menu items. See [Column layout](/docs/column-layout) |
348
+ | `enablePinning: false` | Column | That column's pin menu items |
349
+ | `enableColumnResizing: false` | Table | Resize dragging, double-click autosize, the Autosize menu item. The divider remains as a separator |
350
+ | `enableResizing: false` | Column | That column's resize dragging and autosize |
351
+ | `enableColumnOrdering: false` | Table | Header dragging and the move menu items. See [Column layout](/docs/column-layout#ordering) |
352
+ | `meta.enableOrdering: false` | Column | That column's header dragging and move menu items |
353
+ | `enableRowSelection: false` | Table | The checkbox column |
354
+ | `selectionMode: "row"` / `"highlight"` | Table | The checkbox column. The row click selects instead. See [Row selection](/docs/row-selection) |
355
+ | `showSelectedBackground: false` | Table | The highlight background on selected rows. Follows the selection mode by default |
356
+ | `enablePagination: true` | Table | Opt-in: adds paging and the `Footer` pager. Off by default |
357
+ | `enableRowNumbers: true` | Table | Opt-in: the row-number gutter, outermost left. Numbers the current view: sorted, filtered, continuing across pages. Group rows take no number |
358
+ | `enableRowPinning: true` | Table | Opt-in: rows can be pinned to sticky edge blocks with `row.pin()`. Also takes a per-row predicate. See [Row pinning](/docs/row-pinning) |
359
+ | `enableMatchHighlighting: true` | Table | Opt-in: cells mark the matched text while a contains-family filter or the quick search is active. See [Quick search](/docs/quick-search#match-highlighting) |
360
+ | `enableGrouping: false` | Table, column | Group by and Ungroup menu items. See [Grouping](/docs/grouping) |
361
+ | `renderDetails` | Table | Opt-in: adds the details lane, and an expanded row opens a panel underneath it. See [Row details](/docs/row-details) |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jielga/tmdatagrid",
3
- "version": "2.0.0-beta.2",
3
+ "version": "2.0.0-beta.21",
4
4
  "description": "A React data grid built on TanStack Table v9 and Mantine - always virtualized, with resizable, reorderable, sortable, filterable, hideable and pinnable columns.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -9,7 +9,8 @@
9
9
  ],
10
10
  "repository": {
11
11
  "type": "git",
12
- "url": "git+https://github.com/Jielga/TMDataGrid.git"
12
+ "url": "git+https://github.com/Jielga/TMDataGrid.git",
13
+ "directory": "packages/tmdatagrid"
13
14
  },
14
15
  "homepage": "https://jielga.github.io/TMDataGrid/",
15
16
  "bugs": {
@@ -29,17 +30,13 @@
29
30
  "access": "public"
30
31
  },
31
32
  "intent": {
32
- "docs": "src/docs/",
33
- "skills": [
34
- "@tanstack/react-table",
35
- "@tanstack/table-core",
36
- "@tanstack/router-core"
37
- ]
33
+ "docs": "docs/"
38
34
  },
39
35
  "files": [
40
36
  "dist",
41
- "src/tmdatagrid",
42
- "!src/tmdatagrid/**/*.test.*",
37
+ "src",
38
+ "!src/**/*.test.*",
39
+ "docs",
43
40
  "skills",
44
41
  "!skills/_artifacts"
45
42
  ],
@@ -53,78 +50,57 @@
53
50
  },
54
51
  "./styles.css": "./dist/styles.css",
55
52
  "./styles.layer.css": "./dist/styles.layer.css",
53
+ "./docs/*": "./docs/*",
56
54
  "./package.json": "./package.json"
57
55
  },
58
56
  "scripts": {
59
- "dev": "vite",
60
- "build": "tsc -b && vite build",
61
- "build:lib": "vite build --config vite.lib.config.ts && tsc -p tsconfig.lib.json && rolldown -c rolldown.dts.config.mjs",
62
- "lint": "oxlint",
63
- "check:style": "node scripts/check-house-style.mjs",
57
+ "build": "vite build && tsc -p tsconfig.build.json && rolldown -c rolldown.dts.config.mjs",
64
58
  "test": "vitest run",
65
- "test:watch": "vitest",
66
- "preview": "vite preview",
67
- "changeset": "changeset",
68
- "version-packages": "changeset version && node scripts/sync-skill-version.mjs",
69
- "release": "changeset publish",
70
- "prepublishOnly": "npm run lint && npm run build:lib",
71
- "prepare": "husky"
59
+ "prepublishOnly": "oxlint && bun run build"
72
60
  },
73
61
  "peerDependencies": {
74
62
  "@mantine/core": "^9.4.0",
75
63
  "@tabler/icons-react": "^3.46.0",
76
64
  "@tanstack/react-form": "^1.33.0",
77
- "@tanstack/react-store": "^0.11.0",
78
- "@tanstack/react-table": "^9.0.0-beta.21",
65
+ "@tanstack/react-store": "^0.11.1",
66
+ "@tanstack/react-table": "^9.2.4",
79
67
  "@tanstack/react-virtual": "^3.14.4",
80
- "@tanstack/store": "^0.11.0",
81
- "@tanstack/table-core": "^9.0.0-beta.21",
68
+ "@tanstack/store": "^0.11.1",
69
+ "@tanstack/table-core": "^9.2.4",
82
70
  "react": "^19.1.0",
83
71
  "react-dom": "^19.1.0"
84
72
  },
73
+ "dependencies": {
74
+ "@tanstack/match-sorter-utils": "^8.19.4"
75
+ },
85
76
  "devDependencies": {
86
77
  "@babel/core": "^7.29.7",
87
- "@changesets/changelog-github": "^0.7.0",
88
- "@changesets/cli": "^2.31.1",
89
- "@mantine/code-highlight": "^9.4.1",
90
78
  "@mantine/core": "^9.4.0",
91
- "@mantine/hooks": "^9.4.1",
92
79
  "@rolldown/plugin-babel": "^0.2.3",
93
80
  "@tabler/icons-react": "^3.46.0",
94
81
  "@tanstack/intent": "0.3.6",
95
82
  "@tanstack/react-form": "^1.33.2",
96
- "@tanstack/react-router": "^1.170.17",
97
- "@tanstack/react-router-devtools": "^1.167.0",
98
- "@tanstack/react-store": "^0.11.0",
99
- "@tanstack/react-table": "^9.0.0-beta.21",
83
+ "@tanstack/react-store": "^0.11.1",
84
+ "@tanstack/react-table": "^9.2.4",
100
85
  "@tanstack/react-virtual": "^3.14.4",
101
- "@tanstack/store": "^0.11.0",
102
- "@tanstack/table-core": "^9.0.0-beta.21",
86
+ "@tanstack/store": "^0.11.1",
87
+ "@tanstack/table-core": "^9.2.4",
103
88
  "@testing-library/jest-dom": "^7.0.0",
104
89
  "@testing-library/react": "^16.3.2",
105
90
  "@testing-library/user-event": "^14.6.1",
106
91
  "@types/babel__core": "^7.20.5",
107
- "@types/node": "^24.13.2",
108
92
  "@types/react": "^19.2.17",
109
93
  "@types/react-dom": "^19.2.3",
110
94
  "@vitejs/plugin-react": "^6.0.4",
111
95
  "babel-plugin-react-compiler": "^1.0.0",
112
- "husky": "^9.1.7",
113
96
  "jsdom": "^29.1.1",
114
- "oxlint": "^1.69.0",
115
97
  "react": "^19.2.7",
116
98
  "react-dom": "^19.2.7",
117
- "react-markdown": "^10.1.0",
118
- "remark-gfm": "^4.0.1",
119
99
  "rolldown": "~1.1.5",
120
100
  "rolldown-plugin-dts": "^0.27.14",
121
- "shiki": "^4.4.3",
122
101
  "typescript": "~7.0.2",
123
102
  "vite": "^8.1.5",
124
103
  "vitest": "^4.1.10",
125
104
  "zod": "^4.4.3"
126
- },
127
- "dependencies": {
128
- "@tanstack/match-sorter-utils": "^8.19.4"
129
105
  }
130
106
  }
@@ -5,24 +5,27 @@ description: >
5
5
  xl) and what it drives, every --dg-* CSS variable for metrics, colours and the
6
6
  stacking ladder, the two stylesheets styles.css and styles.layer.css and why
7
7
  only one may be imported, the bounded-height layout rule with minHeight 0,
8
- toolbar composition through children and TMDataGrid.Spacer, writing a toolbar
8
+ toolbar composition through children and TMDataGrid.Spacer, Mantine BoxProps
9
+ (mb, px, hiddenFrom) and withBottomBorder on the toolbar, writing a toolbar
9
10
  button with useTMDataGridContext, hiding it the way the built-ins do with
10
11
  getGridCapabilities and getColumnCapabilities, why capabilities take a
11
12
  features argument under the React Compiler, and localization through the
12
13
  labels option, TMDATAGRID_LABELS_EN, TMDATAGRID_LABELS_SV, mergeLabels and
13
14
  grid.labels. Load when styling or theming the grid, choosing a density,
14
- building a toolbar, adding a button beside the built-in ones, or translating
15
- the interface.
15
+ building a toolbar, adding a button beside the built-in ones, filling the grid
16
+ menu (TMDataGrid.Menu, the column chooser as menu items), or translating the
17
+ interface.
16
18
  metadata:
17
19
  type: core
18
20
  library: '@jielga/tmdatagrid'
19
- library_version: '2.0.0-beta.2'
21
+ library_version: '2.0.0-beta.21'
20
22
  sources:
21
- - 'Jielga/TMDataGrid:src/docs/styling.md'
22
- - 'Jielga/TMDataGrid:src/docs/toolbar.md'
23
- - 'Jielga/TMDataGrid:src/docs/localization.md'
24
- - 'Jielga/TMDataGrid:src/tmdatagrid/core/capabilities.ts'
25
- - 'Jielga/TMDataGrid:src/tmdatagrid/core/labels.ts'
23
+ - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/styling.md'
24
+ - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/toolbar.md'
25
+ - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/menu.md'
26
+ - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/localization.md'
27
+ - 'Jielga/TMDataGrid:packages/tmdatagrid/src/core/capabilities.ts'
28
+ - 'Jielga/TMDataGrid:packages/tmdatagrid/src/core/labels.ts'
26
29
  ---
27
30
 
28
31
  # TMDataGrid - Appearance, toolbar and labels
@@ -118,7 +121,9 @@ element, and `TMDataGrid.Spacer` pushes what follows to the right.
118
121
  <TMDataGrid.LoadingIndicator />
119
122
  <ExportButton />
120
123
  <TMDataGrid.FilterButton />
121
- <TMDataGrid.ColumnsButton />
124
+ <TMDataGrid.Menu>
125
+ <TMDataGrid.Menu.Columns />
126
+ </TMDataGrid.Menu>
122
127
  </TMDataGrid.Toolbar>
123
128
  ```
124
129
 
@@ -126,6 +131,54 @@ Each built-in renders nothing when its feature is off, so a read-only grid needs
126
131
  no conditionals: `FilterButton` under `enableColumnFilters: false` renders
127
132
  nothing at all.
128
133
 
134
+ `TMDataGrid.Toolbar` and `TMDataGrid.Spacer` take Mantine's `BoxProps` - the
135
+ style props (`mb`, `px`, `h`, `hiddenFrom`), `className`, `style` and `mod` -
136
+ set on the element itself. `withBottomBorder` on the toolbar draws a 1px line in
137
+ the theme's default border colour under it, the same line the header draws;
138
+ default `false`. `TMDataGrid.Footer`, `FilterPanel`, `FilterPills` and
139
+ `ColumnsPanel` take the same `BoxProps` on top of their own props.
140
+
141
+ ```tsx
142
+ <TMDataGrid.Toolbar withBottomBorder px="sm" mb="xs">
143
+ <TMDataGrid.SummaryCount />
144
+ <TMDataGrid.Spacer hiddenFrom="sm" />
145
+ <TMDataGrid.FilterButton />
146
+ </TMDataGrid.Toolbar>
147
+ ```
148
+
149
+ ### The grid menu
150
+
151
+ `TMDataGrid.Menu` is the burger: a Mantine `Menu` whose children are the
152
+ dropdown, so your own `Menu.Item`s sit beside the built-in items. It takes
153
+ Mantine `MenuProps` (defaults `position="bottom-end"`, `shadow="md"`,
154
+ `width={260}`, `withinPortal`), `icon` and `label` (default `labels.menuButton`).
155
+
156
+ ```tsx
157
+ import { Menu } from "@mantine/core";
158
+
159
+ <TMDataGrid.Menu>
160
+ <Menu.Item onClick={exportCsv}>Export CSV</Menu.Item>
161
+ <Menu.Divider />
162
+ <Menu.Label>Columns</Menu.Label>
163
+ <TMDataGrid.Menu.Columns />
164
+ </TMDataGrid.Menu>
165
+ ```
166
+
167
+ `TMDataGrid.Menu.Columns` is the column chooser as menu items: `Menu.Search`,
168
+ one checkbox item per hideable column, show/hide all and reset layout;
169
+ it renders nothing when no column can be hidden. Its pieces
170
+ `TMDataGrid.Menu.ColumnToggles` (`search` narrows the list),
171
+ `.ShowHideAll` and `.ResetLayout` are exported for menus that want only some of
172
+ them. Every piece needs a Mantine `Menu` around it and reads the grid from
173
+ context, so it works in any Mantine menu rendered inside `TMDataGrid`, and in a
174
+ `Menu.Sub` (pass `searchable={false}` there: `Menu.Search` registers on the
175
+ root menu and switches off its type-ahead and arrow keys).
176
+
177
+ The menu always renders, since it cannot see what its children render; a menu
178
+ holding only `Menu.Columns` should be hidden with `canHideAny` under
179
+ `enableHiding: false`. `TMDataGrid.ColumnsPanel` is the same chooser as plain
180
+ controls, for a Popover, a Drawer or an inline layout.
181
+
129
182
  A button of your own reads the grid from context, which returns
130
183
  `{ table, ui, features, labels, controlSize, resetSettings }`:
131
184
 
@@ -206,7 +259,7 @@ own uses the same strings as the built-in parts.
206
259
  so an application that ordered its layers to put the grid underneath its own
207
260
  overrides silently gets the opposite.
208
261
 
209
- Source: `src/docs/styling.md` (The stylesheet).
262
+ Source: `packages/tmdatagrid/docs/styling.md` (The stylesheet).
210
263
 
211
264
  ### CRITICAL A grid with no bounded height
212
265
 
@@ -226,7 +279,7 @@ Correct:
226
279
  <TMDataGrid {...grid} style={{ flex: 1, minHeight: 0 }} />
227
280
  ```
228
281
 
229
- Source: `src/docs/styling.md` (Layout).
282
+ Source: `packages/tmdatagrid/docs/styling.md` (Layout).
230
283
 
231
284
  ### HIGH Setting `--dg-row-height` to change density
232
285
 
@@ -241,7 +294,7 @@ Correct:
241
294
  useTMDataGrid({ data, columns, meta: { rowHeight: 64 } });
242
295
  ```
243
296
 
244
- Source: `src/docs/styling.md` (The size scale).
297
+ Source: `packages/tmdatagrid/docs/styling.md` (The size scale).
245
298
 
246
299
  ### HIGH A capability check without `features`
247
300
 
@@ -264,7 +317,7 @@ const { canSort } = getColumnCapabilities(column, features);
264
317
  if (!canSort) return null;
265
318
  ```
266
319
 
267
- Source: `src/docs/toolbar.md` (Why `features` is a second argument).
320
+ Source: `packages/tmdatagrid/docs/toolbar.md` (Why `features` is a second argument).
268
321
 
269
322
  ### MEDIUM An inline `labels` object
270
323
 
@@ -286,7 +339,7 @@ const labels = { noResults: "Inga träffar" } satisfies TMDataGridLabelsOverride
286
339
  useTMDataGrid({ data, columns, labels });
287
340
  ```
288
341
 
289
- Source: `src/docs/localization.md` (Keep the object stable).
342
+ Source: `packages/tmdatagrid/docs/localization.md` (Keep the object stable).
290
343
 
291
344
  ### MEDIUM Conditionally rendering built-in toolbar parts
292
345
 
@@ -294,7 +347,7 @@ Each built-in already renders nothing when its feature is off. Wrapping them in
294
347
  your own checks duplicates the capability logic, and the two drift apart the
295
348
  first time an option changes.
296
349
 
297
- Source: `src/docs/toolbar.md` (The built-in parts).
350
+ Source: `packages/tmdatagrid/docs/toolbar.md` (The built-in parts).
298
351
 
299
352
  ## Reference
300
353
 
@@ -306,7 +359,7 @@ Source: `src/docs/toolbar.md` (The built-in parts).
306
359
  | `SIZE_ROW_HEIGHT` | Export | `Record<MantineSize, number>` | – | The row heights the scale table lists. |
307
360
  | `SIZE_CONTROL_SIZE` | Export | `Record<MantineSize, MantineSize>` | – | Which control size each grid size uses. |
308
361
  | `DEFAULT_TMDATAGRID_SIZE` | Export | `"md"` | – | The default size. |
309
- | `TMDataGrid.Toolbar` · `Spacer` | Components | `children` | – | The flex row, and the push-right. |
362
+ | `TMDataGrid.Toolbar` · `Spacer` | Components | `children`, `withBottomBorder`, Mantine `BoxProps` | `withBottomBorder: false` | The flex row, and the push-right. Style props set on the element. |
310
363
  | `useTMDataGridContext` | Hook | `() => TMDataGridContextValue` | – | `{ table, ui, features, labels, controlSize, resetSettings }`. |
311
364
  | `getGridCapabilities` | Export | `(table, features) => TMDataGridCapabilities` | – | What this grid can do, reactively. |
312
365
  | `getColumnCapabilities` | Export | `(column, features) => TMDataGridColumnCapabilities` | – | The same for one column. |