@jielga/tmdatagrid 2.1.4 → 2.3.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/dist/index.d.ts +78 -5
- package/dist/index.js +2194 -1992
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/docs/cell-selection.md +1 -1
- package/docs/column-layout.md +13 -8
- package/docs/columns.md +59 -3
- package/docs/components.md +1 -0
- package/docs/export.md +2 -2
- package/docs/filtering.md +108 -15
- package/docs/getting-started.md +40 -0
- package/docs/grouping.md +9 -6
- package/docs/loading-and-empty.md +29 -9
- package/docs/localization.md +130 -3
- package/docs/menu.md +1 -1
- package/docs/pagination.md +26 -7
- package/docs/persistence.md +101 -2
- package/docs/row-details.md +41 -4
- package/docs/row-interaction.md +2 -2
- package/docs/row-selection.md +6 -7
- package/docs/row-styling.md +17 -0
- package/docs/scrolling.md +1 -1
- package/docs/server-side.md +3 -1
- package/docs/testing.md +18 -0
- package/docs/use-tm-data-grid.md +75 -36
- package/package.json +1 -1
- package/skills/appearance/SKILL.md +6 -4
- package/skills/appearance/references/labels.md +126 -0
- package/skills/cell-selection/SKILL.md +2 -2
- package/skills/columns/SKILL.md +44 -43
- package/skills/columns/references/columns-api.md +16 -1
- package/skills/data/SKILL.md +77 -50
- package/skills/editing/SKILL.md +1 -1
- package/skills/filtering/SKILL.md +94 -60
- package/skills/filtering/references/custom-filters.md +118 -0
- package/skills/getting-started/SKILL.md +37 -2
- package/skills/grouping/SKILL.md +16 -9
- package/skills/migrating-to-2/SKILL.md +1 -1
- package/skills/options/SKILL.md +206 -55
- package/skills/rows/SKILL.md +70 -39
- package/skills/server-side/SKILL.md +1 -1
- package/skills/testing/SKILL.md +12 -1
- package/skills/testing-components/SKILL.md +1 -1
- package/skills/testing-editing/SKILL.md +1 -1
- package/src/components/TMDataGridFilterPills.module.css +9 -7
- package/src/components/TMDataGridTable.module.css +15 -6
- package/src/components/TMDataGridTable.tsx +253 -41
- package/src/components/sticky.module.css +27 -7
- package/src/core/autosize.ts +19 -7
- package/src/core/cellRange.ts +11 -2
- package/src/core/colSpan.ts +78 -0
- package/src/core/columnUtils.ts +7 -0
- package/src/core/filterControls.ts +8 -0
- package/src/core/filterOperators.ts +29 -1
- package/src/core/persistence.ts +322 -26
- package/src/index.ts +5 -0
- package/src/useTMDataGrid.tsx +133 -14
package/skills/columns/SKILL.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
name: columns
|
|
3
3
|
description: >
|
|
4
4
|
Define and arrange TMDataGrid columns. Covers createTMDataGridColumnHelper,
|
|
5
|
-
every column meta field (label, type, options, flex, align, autoSize,
|
|
5
|
+
every column meta field (label, type, options, flex, align, colSpan, autoSize,
|
|
6
6
|
enableOrdering, and the meta.filter and meta.edit namespaces holding
|
|
7
|
-
operators, defaultOperator, control, enabled, field, editor, validate and
|
|
7
|
+
operators, defaultOperator, control, url, enabled, field, editor, validate and
|
|
8
8
|
mapValue), the six column types, fluid minmax sizing versus fixed width with
|
|
9
9
|
minSize / maxSize / size, autosizing and autosizeColumn, hiding through
|
|
10
10
|
enableHiding and the columns panel, pinning and why a pinned column becomes
|
|
@@ -16,7 +16,7 @@ description: >
|
|
|
16
16
|
metadata:
|
|
17
17
|
type: core
|
|
18
18
|
library: '@jielga/tmdatagrid'
|
|
19
|
-
library_version: '2.
|
|
19
|
+
library_version: '2.3.0'
|
|
20
20
|
sources:
|
|
21
21
|
- 'Jielga/react:packages/tmdatagrid/docs/columns.md'
|
|
22
22
|
- 'Jielga/react:packages/tmdatagrid/docs/column-layout.md'
|
|
@@ -84,6 +84,7 @@ columnHelper.group({
|
|
|
84
84
|
| `options` | `TMDataGridOptionsSource` | – | Choices for a `select` / `multiSelect` column: an array, `"faceted"`, or a function. One declaration feeds the filter panel and the editor. |
|
|
85
85
|
| `flex` | `number` | `1` | Share of the remaining width. |
|
|
86
86
|
| `align` | `"left" \| "right" \| "center"` | `"left"` | Applied to both header and cells. |
|
|
87
|
+
| `colSpan` | `number \| ({ row, table }) => number` | `1` | Columns the cell covers on a row, counting itself; the covered cells do not render there. See below. |
|
|
87
88
|
| `autoSize` | `boolean` | `false` | Size to the widest mounted content once, after the first rows render. |
|
|
88
89
|
| `enableOrdering` | `boolean` | `true` | `false` keeps the column where it is. |
|
|
89
90
|
| `filter` | `TMDataGridColumnFilterOptions` | – | How this column filters. See below. |
|
|
@@ -93,7 +94,7 @@ What the column **is** stays flat; what the filter panel and the edit engine do
|
|
|
93
94
|
with it sits in their namespaces. `type` and `options` are read by both stages,
|
|
94
95
|
which is why they are in neither.
|
|
95
96
|
|
|
96
|
-
`meta.filter` holds `operators`, `defaultOperator` and `
|
|
97
|
+
`meta.filter` holds `operators`, `defaultOperator`, `control` and `url`; `meta.edit`
|
|
97
98
|
holds `enabled`, `field`, `editor`, `validate` and `mapValue`. Their fields are
|
|
98
99
|
in [references/columns-api.md](references/columns-api.md).
|
|
99
100
|
|
|
@@ -117,6 +118,11 @@ annotation. A column written without the helper keeps the untyped row,
|
|
|
117
118
|
TanStack defines no column option for. `meta.edit` only acts once `editing` is
|
|
118
119
|
set: see the `editing` skill. `meta.filter` belongs to the `filtering` skill.
|
|
119
120
|
|
|
121
|
+
`colSpan` (args `TMDataGridColSpanArgs`, `{ row, table }`) is display only, never
|
|
122
|
+
covers a generated lane or leaves its pinned block, and is ignored on group rows,
|
|
123
|
+
on rows in row edit mode, and on a row whose open cell editor a span would cover.
|
|
124
|
+
Source: `packages/tmdatagrid/docs/columns.md` (Spanning columns).
|
|
125
|
+
|
|
120
126
|
### Column types
|
|
121
127
|
|
|
122
128
|
`meta.type` is one of `"string"`, `"number"`, `"boolean"`, `"date"`,
|
|
@@ -163,10 +169,11 @@ Columns are fluid. Each track is `minmax(minSize, flex fr)`.
|
|
|
163
169
|
|
|
164
170
|
| Option | Effect |
|
|
165
171
|
| --- | --- |
|
|
166
|
-
| `minSize` | Minimum width, and the column's contribution to the grid minimum width. Defaults to `80`. |
|
|
172
|
+
| `minSize` | Minimum width, and the column's contribution to the grid minimum width. Also the floor of a resize and of a pinned width. Defaults to `80`, through `defaultColumn.minSize`. |
|
|
173
|
+
| `maxSize` | Ceiling of a resize, an autosize and a pinned width. Does not cap a fluid track. No default. |
|
|
167
174
|
| `meta.flex` | Share of the remaining width. Defaults to `1`. |
|
|
168
175
|
| `minSize === maxSize` | Fixed width. The column is never fluid. |
|
|
169
|
-
| `size` |
|
|
176
|
+
| `size` | Width of a column pinned at mount, clamped by `minSize` and `maxSize`. Ignored on a fluid column; a resize or an interactive pin stores the rendered width instead. Defaults to `150`. |
|
|
170
177
|
|
|
171
178
|
```tsx
|
|
172
179
|
// Fixed 64px action column that never flexes.
|
|
@@ -191,21 +198,23 @@ consumer code.
|
|
|
191
198
|
|
|
192
199
|
All three write state that persists together, so a grid comes back arranged the
|
|
193
200
|
way it was left. `resetSettings()` from the hook clears visibility, order,
|
|
194
|
-
pinning and
|
|
195
|
-
layout**.
|
|
201
|
+
pinning, widths and grouping in one go, and the column chooser offers it as
|
|
202
|
+
**Reset layout**.
|
|
196
203
|
|
|
197
204
|
**Hiding** is `columnVisibility`, driven by "Hide column" in a column menu and by
|
|
198
|
-
the column chooser
|
|
199
|
-
|
|
200
|
-
|
|
205
|
+
the column chooser, which comes in three forms (see the `appearance` skill):
|
|
206
|
+
|
|
207
|
+
- `TMDataGrid.Menu.Columns` in the grid menu.
|
|
208
|
+
- **Manage columns**, a submenu of every column menu.
|
|
209
|
+
- `TMDataGrid.ColumnsPanel`, plain controls for a host that is not a menu.
|
|
201
210
|
|
|
202
211
|
**Pinning** is "Pin to left" / "Pin to right" in the column menu. A pinned
|
|
203
212
|
column also becomes fixed-width: sticky offsets are computed from `getSize()`,
|
|
204
213
|
which cannot resolve an `fr` value, so the grid stores the rendered width in
|
|
205
214
|
`columnSizing` at the moment it is pinned and nothing jumps. A column pinned
|
|
206
215
|
from `initialState.columnPinning` has no rendered width to store, so it takes
|
|
207
|
-
its `size` - TanStack's default of `150` where none is set -
|
|
208
|
-
|
|
216
|
+
its `size` - TanStack's default of `150` where none is set - clamped by
|
|
217
|
+
`minSize` and `maxSize`.
|
|
209
218
|
|
|
210
219
|
**Ordering** is header dragging plus "Move left" / "Move right". A column can
|
|
211
220
|
only move **within its own pinned region** - pinning splits the grid into left,
|
|
@@ -253,24 +262,18 @@ const grid = useTMDataGrid({
|
|
|
253
262
|
```
|
|
254
263
|
|
|
255
264
|
`sortFn` on a column takes any registered name or a
|
|
256
|
-
`(rowA, rowB, columnId) => number` function
|
|
257
|
-
`sortingFn
|
|
265
|
+
`(rowA, rowB, columnId) => number` function. `sortFn` is v9's name for v8's
|
|
266
|
+
`sortingFn`. Sorting writes
|
|
258
267
|
TanStack's `sorting` state, an array of `{ id, desc }` in priority order. It is
|
|
259
268
|
a **data** slice, persisted under `dataKey`, while the column layout below is a
|
|
260
269
|
settings slice under `settingsKey`.
|
|
261
270
|
|
|
262
271
|
## Column-level feature options
|
|
263
272
|
|
|
264
|
-
Standard TanStack column options
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
| `enableSorting` | No sort indicator, no sort menu items, no click-to-sort. |
|
|
269
|
-
| `enableColumnFilter` | No filter menu item. Excluded from the filter panel's column list, and its header filter cell is empty. |
|
|
270
|
-
| `enableHiding` | No hide menu item. Checkbox disabled in the column manager. |
|
|
271
|
-
| `enablePinning` | No pin menu items. |
|
|
272
|
-
| `enableResizing` | The divider is displayed but cannot be dragged. |
|
|
273
|
-
| `enableGrouping` | No "Group by" menu item. |
|
|
273
|
+
Standard TanStack column options, each removing its interface when `false`:
|
|
274
|
+
`enableSorting`, `enableMultiSort`, `enableColumnFilter`, `enableHiding`,
|
|
275
|
+
`enablePinning`, `enableResizing` and `enableGrouping`. What each one removes is
|
|
276
|
+
in [references/columns-api.md](references/columns-api.md#column-level-feature-options).
|
|
274
277
|
|
|
275
278
|
`meta.enableOrdering: false` belongs to the same set. A column whose menu has no
|
|
276
279
|
remaining items renders no menu button and takes no right-click, so the
|
|
@@ -294,16 +297,17 @@ columns and edit.
|
|
|
294
297
|
They are structural: fixed width, no column menu, and they cannot be sorted,
|
|
295
298
|
filtered, resized, re-pinned or moved. The checkbox lane anchors the left pinned
|
|
296
299
|
region, so no column can be placed in front of it. `isControlColumn(columnId)`
|
|
297
|
-
identifies them.
|
|
300
|
+
identifies them. To locate a lane in a test, use the constant with
|
|
301
|
+
`data-column-id`; see the `testing` skill.
|
|
298
302
|
|
|
299
303
|
## Common mistakes
|
|
300
304
|
|
|
301
305
|
### CRITICAL Setting `size` to control width
|
|
302
306
|
|
|
303
|
-
`size`
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
+
`size` applies only to a column pinned at mount. On a fluid column it is
|
|
308
|
+
ignored - the track is `minmax(minSize, flex fr)` - so a column given
|
|
309
|
+
`size: 200` renders at whatever the flex share works out to. A resize or an
|
|
310
|
+
interactive pin stores the rendered width, not `size`.
|
|
307
311
|
|
|
308
312
|
Wrong:
|
|
309
313
|
|
|
@@ -322,29 +326,28 @@ columnHelper.accessor("email", {
|
|
|
322
326
|
});
|
|
323
327
|
```
|
|
324
328
|
|
|
325
|
-
|
|
326
|
-
column that is pinned needs one.
|
|
329
|
+
A column pinned at mount is fixed-width and does use `size`, so give it one.
|
|
327
330
|
|
|
328
331
|
Source: `packages/tmdatagrid/docs/column-layout.md` (Sizing).
|
|
329
332
|
|
|
330
|
-
### HIGH Pinning a column at mount without
|
|
333
|
+
### HIGH Pinning a column at mount without a width
|
|
331
334
|
|
|
332
335
|
A column pinned interactively keeps the width it was rendering, which the grid
|
|
333
336
|
writes into `columnSizing`. A column pinned from `initialState.columnPinning`
|
|
334
|
-
has no rendered width, so it takes `size`
|
|
335
|
-
none is set
|
|
337
|
+
has no rendered width, so it takes `size` clamped by `minSize` / `maxSize`:
|
|
338
|
+
TanStack's `150` when none is set, whatever the content needs.
|
|
336
339
|
|
|
337
340
|
Wrong:
|
|
338
341
|
|
|
339
342
|
```tsx
|
|
340
|
-
columnHelper.accessor("name", { header: "Name"
|
|
343
|
+
columnHelper.accessor("name", { header: "Name" });
|
|
341
344
|
initialState: { columnPinning: { start: ["name"], end: [] } },
|
|
342
345
|
```
|
|
343
346
|
|
|
344
347
|
Correct:
|
|
345
348
|
|
|
346
349
|
```tsx
|
|
347
|
-
columnHelper.accessor("name", { header: "Name",
|
|
350
|
+
columnHelper.accessor("name", { header: "Name", size: 220 });
|
|
348
351
|
initialState: { columnPinning: { start: ["name"], end: [] } },
|
|
349
352
|
```
|
|
350
353
|
|
|
@@ -399,8 +402,7 @@ Source: `packages/tmdatagrid/src/core/columnUtils.ts`.
|
|
|
399
402
|
|
|
400
403
|
`getColumnType(column)` defaults to `"string"`, so a numeric column that omits
|
|
401
404
|
`meta: { type: "number" }` offers only the string operators, and comparisons run
|
|
402
|
-
as text - `"9"` above `"10"`. The column still sorts and filters
|
|
403
|
-
it is easy to miss.
|
|
405
|
+
as text - `"9"` above `"10"`. The column still sorts and filters.
|
|
404
406
|
|
|
405
407
|
Source: `packages/tmdatagrid/src/core/filterOperators.ts`.
|
|
406
408
|
|
|
@@ -421,10 +423,9 @@ Source: `packages/tmdatagrid/docs/column-layout.md` (Regions).
|
|
|
421
423
|
|
|
422
424
|
### HIGH Reaching for the v8 name of a v9 option
|
|
423
425
|
|
|
424
|
-
TanStack v9 renamed the column comparator to `sortFn`. `sortingFn` is
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
custom ordering never appears.
|
|
426
|
+
TanStack v9 renamed the column comparator to `sortFn`. `sortingFn` is an
|
|
427
|
+
unknown key in v9; TypeScript does not always report it, and the column keeps
|
|
428
|
+
its automatic comparator, so the custom ordering never appears.
|
|
428
429
|
|
|
429
430
|
Wrong:
|
|
430
431
|
|
|
@@ -11,6 +11,7 @@ Reference for the `columns` skill.
|
|
|
11
11
|
| `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. |
|
|
12
12
|
| `defaultOperator` | `TMDataGridFilterOperator` | The type's default, else the first offered | The operator a fresh filter on this column starts with. |
|
|
13
13
|
| `control` | `TMDataGridFilterControlComponent` | By `meta.type` | Replaces the value control in this column's filter row. Module scope. |
|
|
14
|
+
| `url` | `boolean` | `true` | Whether the column's filter is written to the URL under `persist.urlKey`. `false` keeps it out of the link, and out of storage. |
|
|
14
15
|
|
|
15
16
|
`meta.edit` belongs to the `editing` skill, and only acts once `editing` is set:
|
|
16
17
|
|
|
@@ -22,6 +23,20 @@ Reference for the `columns` skill.
|
|
|
22
23
|
| `validate` | `TMDataGridFieldValidate` | – | Field-level validation. A bare schema means `onChange`. |
|
|
23
24
|
| `mapValue` | `TMDataGridEditValueMap` | – | Maps each value an editor writes, on every keystroke. |
|
|
24
25
|
|
|
26
|
+
## Column-level feature options
|
|
27
|
+
|
|
28
|
+
Standard TanStack column options. Each also removes the corresponding interface.
|
|
29
|
+
|
|
30
|
+
| Option | Effect when `false` |
|
|
31
|
+
| --- | --- |
|
|
32
|
+
| `enableSorting` | No sort indicator, no sort menu items, no click-to-sort. |
|
|
33
|
+
| `enableMultiSort` | Shift+click on this header replaces the sort instead of adding to it. |
|
|
34
|
+
| `enableColumnFilter` | No filter menu item. Excluded from the filter panel's column list, and its header filter cell is empty. |
|
|
35
|
+
| `enableHiding` | No hide menu item. Checkbox disabled in the column manager. |
|
|
36
|
+
| `enablePinning` | No pin menu items. |
|
|
37
|
+
| `enableResizing` | The divider is displayed but cannot be dragged. |
|
|
38
|
+
| `enableGrouping` | No "Group by" menu item. |
|
|
39
|
+
|
|
25
40
|
## Exports and options
|
|
26
41
|
|
|
27
42
|
| Name | Kind | Type | Default | What it does |
|
|
@@ -34,7 +49,7 @@ Reference for the `columns` skill.
|
|
|
34
49
|
| `TMDataGridOptionsArgs` | Type | `{ table, column, row? }` | – | What a `meta.options` function receives. `row` is absent when the filter panel asks. |
|
|
35
50
|
| `resolveColumnOptions` | Export | `({ table, column, row?, fallback? }) => Array<TMDataGridOption>` | – | Normalises all three `meta.options` forms. Empty when the column declares none. |
|
|
36
51
|
| `optionsToComboboxData` | Export | `(options) => ComboboxData` | – | Options as Mantine `Select` / `MultiSelect` data, groups folded in. |
|
|
37
|
-
| `minSize` / `maxSize` / `size` | Column options | `number` | `80` / – /
|
|
52
|
+
| `minSize` / `maxSize` / `size` | Column options | `number` | `80` / – / `150` | Floor of the fluid track, a resize and a pinned width; ceiling of a resize and a pinned width; width of a column pinned at mount. |
|
|
38
53
|
| `enableSorting` · `enableColumnFilter` · `enableHiding` · `enablePinning` · `enableResizing` · `enableGrouping` | Column options | `boolean` | `true` | Per-column switches, each removing its interface. |
|
|
39
54
|
| `enableColumnOrdering` | Option | `boolean` | `true` | Header dragging and the move menu items. Grid-defined. |
|
|
40
55
|
| `enableMultiSort` · `maxMultiSortColCount` · `isMultiSortEvent` | Table options | – | Shift held | Multi-column sorting. |
|
package/skills/data/SKILL.md
CHANGED
|
@@ -8,7 +8,7 @@ description: >
|
|
|
8
8
|
canPaginate, always-on virtualization with overscan and meta.rowHeight,
|
|
9
9
|
scrollToRow, the edge callbacks onScrollToBottom / onScrollToRight and why
|
|
10
10
|
onReachEnd is better for loading more, the header and pinned-lane depth
|
|
11
|
-
shadows, and the
|
|
11
|
+
shadows, and the five empty states in precedence order with meta.loading,
|
|
12
12
|
renderEmptyState, hasActiveFilters, TMDataGrid.LoadingIndicator and
|
|
13
13
|
TMDataGrid.SummaryCount, and export: TMDataGrid.Menu.Export and
|
|
14
14
|
Menu.ExportSelected, useTMDataGridExport, exportGrid, exportOptions, the
|
|
@@ -18,7 +18,7 @@ description: >
|
|
|
18
18
|
metadata:
|
|
19
19
|
type: core
|
|
20
20
|
library: '@jielga/tmdatagrid'
|
|
21
|
-
library_version: '2.
|
|
21
|
+
library_version: '2.3.0'
|
|
22
22
|
sources:
|
|
23
23
|
- 'Jielga/react:packages/tmdatagrid/docs/pagination.md'
|
|
24
24
|
- 'Jielga/react:packages/tmdatagrid/docs/scrolling.md'
|
|
@@ -56,8 +56,14 @@ const grid = useTMDataGrid({
|
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
Initial page size is 25, through `initialState.pagination`. `enablePagination`
|
|
59
|
-
is defined by the grid rather than by TanStack
|
|
60
|
-
|
|
59
|
+
is defined by the grid rather than by TanStack.
|
|
60
|
+
|
|
61
|
+
The Footer renders a rows-per-page select, the range (`1–25 of 300`, from
|
|
62
|
+
`table.getRowCount()`) and previous and next buttons; there are no numbered page
|
|
63
|
+
buttons. The select offers `pageSizeOptions`, by default `[10, 25, 50, 100]`,
|
|
64
|
+
with the current size folded in when it is not in the list. Pass a module-scope
|
|
65
|
+
array: the select is memoized on it, and an inline literal remounts it on every
|
|
66
|
+
render.
|
|
61
67
|
|
|
62
68
|
`TMDataGrid.Footer` takes a `renderPagination` slot handed three things: the
|
|
63
69
|
`state` the pager shows, the `actions` it can take, and `Controls`, the built-in
|
|
@@ -82,22 +88,26 @@ pieces, already wired.
|
|
|
82
88
|
|
|
83
89
|
`Controls.PageSize`, `Controls.Range` and `Controls.Pager` are what the default
|
|
84
90
|
footer renders, in that order, so a custom layout can keep the parts it wants
|
|
85
|
-
instead of rebuilding them. They behave
|
|
86
|
-
|
|
87
|
-
server-paged grid usually shows in place of
|
|
88
|
-
not in the default footer;
|
|
89
|
-
hand.
|
|
91
|
+
instead of rebuilding them. They behave as in the default footer, including
|
|
92
|
+
greying out while paging is suspended. `Controls.PageNumber` renders
|
|
93
|
+
"Page 3 of 200", the label a server-paged grid usually shows in place of the
|
|
94
|
+
row range. It is not in the default footer; add it through the slot.
|
|
90
95
|
|
|
91
96
|
`state` carries `pageIndex`, `pageSize`, `pageCount`, `rowCount`,
|
|
92
97
|
`canPreviousPage`, `canNextPage`, `from`, `to` and `isPagingActive`. `actions`
|
|
93
98
|
carries `setPageIndex`, `setPageSize`, `previousPage`, `nextPage`, `firstPage`
|
|
94
|
-
and `lastPage`.
|
|
95
|
-
`
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
and `lastPage`. Outside the Footer,
|
|
100
|
+
`getTMDataGridPaginationApi(table, isPagingActive(table, grid.features))`
|
|
101
|
+
returns the same `{ state, actions }`. Without the second argument
|
|
102
|
+
`state.isPagingActive` is `true`, also while the rows are grouped. `Controls`
|
|
103
|
+
is bound to the grid context, so those components work only inside the slot.
|
|
104
|
+
|
|
105
|
+
Grouping suspends the pager: the built-in controls grey out and the range
|
|
106
|
+
becomes `Grouped · all N rows`. The default footer also carries
|
|
107
|
+
`data-paging-suspended` on its bar and shows `labels.pagingSuspendedHint` as a
|
|
108
|
+
tooltip; a footer with `renderPagination` has neither. There is no option to
|
|
109
|
+
keep the built-in pager active while grouped. `isPagingActive(table, features)`
|
|
110
|
+
is the live state, whether the pager is slicing anything right now, while
|
|
101
111
|
`getGridCapabilities(...).canPaginate` is the configuration. The two differ
|
|
102
112
|
while a grouping is active.
|
|
103
113
|
|
|
@@ -141,14 +151,13 @@ arrival rather than on every scroll event. For loading more rows use
|
|
|
141
151
|
`onReachEnd` (the `server-side` skill) instead: it fires a number of rows before
|
|
142
152
|
the bottom, and latches per row count so a pending fetch is not requested twice.
|
|
143
153
|
|
|
144
|
-
Two depth cues
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
content.
|
|
154
|
+
Two depth cues run as scroll-driven CSS animations, with no scroll listener and
|
|
155
|
+
no React render. A shadow appears under the sticky header once rows scroll
|
|
156
|
+
beneath it. A band appears beside a pinned lane while it covers content.
|
|
148
157
|
|
|
149
158
|
## Empty states
|
|
150
159
|
|
|
151
|
-
There are
|
|
160
|
+
There are five ways to have nothing to show, and an empty body shows exactly one
|
|
152
161
|
of them, in this order:
|
|
153
162
|
|
|
154
163
|
1. **Loading** - `meta.loading` is true: a centred loader. A grid that is
|
|
@@ -156,9 +165,23 @@ of them, in this order:
|
|
|
156
165
|
2. **Entry rows** - an open entry row from `edit.addRow()`: the entry block
|
|
157
166
|
only, with no message beside the form.
|
|
158
167
|
3. **`renderEmptyState`** - your node, centred where the message would be.
|
|
159
|
-
4. **Filtered-empty** - a filter
|
|
160
|
-
|
|
161
|
-
|
|
168
|
+
4. **Filtered-empty** - a column filter is active (`isFilterActive`) or the
|
|
169
|
+
quick search is not blank: `labels.noResults`, since clearing the filter
|
|
170
|
+
will bring rows back.
|
|
171
|
+
5. **Truly-empty** - no column filter is active and the quick search is blank:
|
|
172
|
+
`labels.noRows`.
|
|
173
|
+
|
|
174
|
+
"Empty" means no displayed row and no pinned row. States 4 and 5 are decided by
|
|
175
|
+
the filter state alone, so an empty `data` array shows `noResults` while a
|
|
176
|
+
filter is active. A half-typed filter, such as
|
|
177
|
+
`{ operator: "contains", value: "" }`, is not active, so it does not count.
|
|
178
|
+
|
|
179
|
+
The loader is the only "no data yet" signal, so set `meta.loading` during the
|
|
180
|
+
first fetch too; without it the empty message shows until the rows arrive.
|
|
181
|
+
`renderEmptyState` is called only once `meta.loading` is not `true`: during a
|
|
182
|
+
refetch that returns no rows the loader mounts when `loading` turns `true`,
|
|
183
|
+
`renderEmptyState` mounts when it turns `false`, and unmounts again on the next
|
|
184
|
+
refetch.
|
|
162
185
|
|
|
163
186
|
`renderEmptyState` replaces the last two with one render prop, and
|
|
164
187
|
`hasActiveFilters` says which it is standing in for:
|
|
@@ -177,15 +200,14 @@ of them, in this order:
|
|
|
177
200
|
/>
|
|
178
201
|
```
|
|
179
202
|
|
|
180
|
-
An empty grid is a good place to offer the action that fills it, such as
|
|
181
|
-
clearing the filters or creating the first record.
|
|
182
|
-
|
|
183
203
|
The body's loading state only appears while the grid is **empty**. A
|
|
184
204
|
server-driven grid refetching with rows still on screen keeps showing them.
|
|
185
205
|
`TMDataGrid.LoadingIndicator` covers that case: a small spinner while
|
|
186
206
|
`meta.loading` is true. `TMDataGrid.SummaryCount` shows visible rows out of
|
|
187
|
-
total
|
|
188
|
-
count
|
|
207
|
+
total. The total is `meta.totalRowCount` when provided, otherwise the
|
|
208
|
+
pre-filtered count on a client-side grid; a server-driven grid
|
|
209
|
+
(`manualFiltering` or `manualPagination`) without `meta.totalRowCount` shows the
|
|
210
|
+
visible count alone, with no total.
|
|
189
211
|
|
|
190
212
|
## Export
|
|
191
213
|
|
|
@@ -214,15 +236,19 @@ function ExportButton() {
|
|
|
214
236
|
}
|
|
215
237
|
```
|
|
216
238
|
|
|
217
|
-
What is written:
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
239
|
+
What is written:
|
|
240
|
+
|
|
241
|
+
- **Columns** - the data columns in render order. Never the generated lanes,
|
|
242
|
+
never a column with `meta.enableExport: false`.
|
|
243
|
+
- **Rows** - every row after filtering and sorting. A grouped grid writes the
|
|
244
|
+
records under every group, never the group rows.
|
|
245
|
+
- **Values** - each cell's **value** rather than what it renders.
|
|
246
|
+
`meta.exportValue: ({ value, row, column }) => unknown` substitutes one.
|
|
247
|
+
|
|
222
248
|
`columns` on `exportOptions`, the items and the functions is `"visible"` (the
|
|
223
|
-
default), `"all"` (hidden columns too) or a list of ids
|
|
224
|
-
|
|
225
|
-
ticked, Export and Cancel
|
|
249
|
+
default), `"all"` (hidden columns too) or a list of ids. `columns="custom"` on a
|
|
250
|
+
menu item opens a picker instead: every exportable column, the visible ones
|
|
251
|
+
ticked, Export and Cancel. The picker is driven by `ui.state.exportPicker` and
|
|
226
252
|
`ui.actions.openExportPicker`. `TMDataGrid.Menu.ExportSelected` counts and
|
|
227
253
|
writes the ticked rows of the current view, in grid order; it renders nothing
|
|
228
254
|
when row selection is off.
|
|
@@ -303,10 +329,11 @@ a pending fetch is not requested twice.
|
|
|
303
329
|
|
|
304
330
|
Source: `packages/tmdatagrid/docs/scrolling.md` (Edge callbacks).
|
|
305
331
|
|
|
306
|
-
### HIGH `SummaryCount`
|
|
332
|
+
### HIGH `SummaryCount` without a total under manual pagination
|
|
307
333
|
|
|
308
|
-
The client
|
|
309
|
-
|
|
334
|
+
The client holds one page, so a server-driven grid has no total of its own.
|
|
335
|
+
Without `meta.totalRowCount`, `SummaryCount` shows the visible count alone, with
|
|
336
|
+
no total, over a table of thousands.
|
|
310
337
|
|
|
311
338
|
Correct:
|
|
312
339
|
|
|
@@ -334,7 +361,7 @@ Correct:
|
|
|
334
361
|
useTMDataGrid({ data, columns, meta: { loading: isFetching } });
|
|
335
362
|
```
|
|
336
363
|
|
|
337
|
-
Source: `packages/tmdatagrid/docs/loading-and-empty.md` (
|
|
364
|
+
Source: `packages/tmdatagrid/docs/loading-and-empty.md` (Precedence).
|
|
338
365
|
|
|
339
366
|
### MEDIUM Trusting the pager while grouped
|
|
340
367
|
|
|
@@ -342,7 +369,7 @@ Source: `packages/tmdatagrid/docs/loading-and-empty.md` (What wins).
|
|
|
342
369
|
grid is rendering the whole tree. A custom pager must read
|
|
343
370
|
`isPagingActive(table, features)` rather than the page count.
|
|
344
371
|
|
|
345
|
-
Source: `packages/tmdatagrid/docs/pagination.md` (Grouping
|
|
372
|
+
Source: `packages/tmdatagrid/docs/pagination.md` (Grouping).
|
|
346
373
|
|
|
347
374
|
## Reference
|
|
348
375
|
|
|
@@ -351,31 +378,31 @@ Source: `packages/tmdatagrid/docs/pagination.md` (Grouping suspends it).
|
|
|
351
378
|
| `enablePagination` | Option | `boolean` | `false` | Client-side paging and the Footer's pager. Grid-defined. |
|
|
352
379
|
| `manualPagination` | Table option | `boolean` | `false` | The server pages. Implies `enablePagination`. |
|
|
353
380
|
| `rowCount` | Table option | `number` | – | The true total, required under `manualPagination`. |
|
|
354
|
-
| `initialState.pagination` | Table option | `{ pageIndex, pageSize }` | `{ 0, 25 }` | Where paging starts. A `data` slice, so it persists. |
|
|
381
|
+
| `initialState.pagination` | Table option | `{ pageIndex, pageSize }` | `{ pageIndex: 0, pageSize: 25 }` | Where paging starts. A `data` slice, so it persists. |
|
|
355
382
|
| `onPaginationChange` | Table option | `OnChangeFn` | – | Controls the pagination state. |
|
|
356
|
-
| `TMDataGrid.Footer` | Component | `pageSizeOptions`, `renderPagination`, Mantine `BoxProps` | `[10, 25, 50, 100]` | The footer bar. Renders nothing when paging is off. Style props set on the bar. |
|
|
383
|
+
| `TMDataGrid.Footer` | Component | `pageSizeOptions`, `renderPagination`, Mantine `BoxProps` | `pageSizeOptions`: `[10, 25, 50, 100]` | The footer bar. Renders nothing when paging is off. Style props set on the bar. |
|
|
357
384
|
| `TMDataGridFooterProps` | Type | – | – | The props of `TMDataGrid.Footer`. |
|
|
358
385
|
| `Footer` `renderPagination` | Slot | `(args: TMDataGridPaginationSlotArgs) => ReactNode` | Built-in pager | Replaces the pager, and hands over its pieces. |
|
|
359
386
|
| `TMDataGridPaginationSlotArgs` | Type | `TMDataGridPaginationApi & { Controls }` | – | What `renderPagination` receives: `{ state, actions, Controls }`. |
|
|
360
|
-
| `getTMDataGridPaginationApi` | Export | `(table, isPaging?) => TMDataGridPaginationApi` | `isPaging`: `true` | The pager API, outside the Footer. |
|
|
387
|
+
| `getTMDataGridPaginationApi` | Export | `(table, isPaging?) => TMDataGridPaginationApi` | `isPaging`: `true` | The pager API, outside the Footer. Pass `isPagingActive(table, features)` as `isPaging`. |
|
|
361
388
|
| `TMDataGridPaginationApi` | Type | `{ state, actions }` | – | What `getTMDataGridPaginationApi` returns. |
|
|
362
389
|
| `TMDataGridPaginationState` · `TMDataGridPaginationActions` · `TMDataGridPaginationControls` | Exports | types | – | The three parts of the slot argument. |
|
|
363
390
|
| `isPagingActive` | Export | `(table, features) => boolean` | – | Whether the pager is slicing anything right now. |
|
|
364
391
|
| `overscan` | Option | `number` | `6` | Rows kept mounted beyond each edge of the viewport. |
|
|
365
|
-
| `meta.rowHeight` | Option | `number` |
|
|
392
|
+
| `meta.rowHeight` | Option | `number` | `52` at the default `md` size; see the `size` scale in the `appearance` skill | Row height in pixels. The virtualizer needs a number. |
|
|
366
393
|
| `scrollToRow` | Hook return | `({ rowId, align? }) => boolean` | `align: "auto"` | Scrolls a row into view, mounted or not. |
|
|
367
394
|
| `TMDataGridScrollToRowArgs` | Export | `{ rowId, align? }` | – | What `scrollToRow` takes. |
|
|
368
395
|
| `onScrollToTop` · `onScrollToBottom` · `onScrollToLeft` · `onScrollToRight` | Table props | `() => void` | – | Fire once on arriving at that edge. |
|
|
369
396
|
| `TMDataGridScrollAlign` | Export | `"start" \| "center" \| "end" \| "auto"` | – | The `align` argument. |
|
|
370
|
-
| `meta.loading` | Option | `boolean` | `false` | A fetch is in flight.
|
|
397
|
+
| `meta.loading` | Option | `boolean` | `false` | A fetch is in flight. While `true` and the view is empty, the loader replaces every empty message and `renderEmptyState` is not called. |
|
|
371
398
|
| `meta.noResultsLabel` | Option | `string` | `labels.noResults` | The filtered-empty message, without a render prop. |
|
|
372
|
-
| `meta.totalRowCount` | Option | `number` | Pre-filtered count | The total `SummaryCount` reports. |
|
|
373
|
-
| `renderEmptyState` | Table prop | `({ hasActiveFilters, table }) => ReactNode` | – | Replaces both built-in empty messages. |
|
|
399
|
+
| `meta.totalRowCount` | Option | `number` | Pre-filtered count; none on a server-driven grid | The total `SummaryCount` reports. |
|
|
400
|
+
| `renderEmptyState` | Table prop | `({ hasActiveFilters, table }) => ReactNode` | – | Replaces both built-in empty messages. `hasActiveFilters` is `true` when a column filter is active (`isFilterActive`) or the quick search is not blank. |
|
|
374
401
|
| `TMDataGrid.LoadingIndicator` | Component | – | – | Spinner while `meta.loading`, for when the body has rows. |
|
|
375
402
|
| `TMDataGrid.SummaryCount` | Component | `children` replaces the text | – | Visible rows out of total. |
|
|
376
403
|
| `--dg-header-shadow-color` | CSS variable | colour | Themed | The shadow under the sticky header. |
|
|
377
404
|
| `--dg-sticky-edge-range` | CSS variable | length | `20px` | How far the pinned-lane band takes to fade in. |
|
|
378
|
-
| `exportOptions` | Option | `TMDataGridExportOptions` | `
|
|
405
|
+
| `exportOptions` | Option | `TMDataGridExportOptions` | `csvExcelFormat()`, `"export"`, headers on, `"visible"` columns | Format, file name and header row for every export of the grid. |
|
|
379
406
|
| `meta.enableExport` | Column meta | `boolean` | `true` | `false` leaves the column out of every export and of Ctrl+C. |
|
|
380
407
|
| `meta.exportValue` | Column meta | `TMDataGridExportValueGetter`: `({ value, row, column }) => unknown` | – | The value written in place of `row.getValue`. |
|
|
381
408
|
| `TMDataGrid.Menu.Export` · `TMDataGrid.Menu.ExportSelected` | Components | `TMDataGridMenuExportProps` | – | Menu items: every filtered row, and the selected rows. `columns="custom"` opens the picker. |
|
package/skills/editing/SKILL.md
CHANGED