@jielga/tmdatagrid 2.1.0 → 2.1.2
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.js +1293 -1258
- package/dist/index.js.map +1 -1
- package/docs/column-layout.md +1 -1
- package/docs/column-menu.md +1 -1
- package/docs/localization.md +1 -1
- package/docs/row-details.md +15 -0
- package/docs/row-selection.md +5 -0
- package/docs/testing.md +5 -1
- package/docs/use-tm-data-grid.md +2 -2
- package/package.json +14 -14
- package/skills/appearance/SKILL.md +2 -2
- package/skills/cell-selection/SKILL.md +1 -1
- package/skills/columns/SKILL.md +1 -1
- package/skills/data/SKILL.md +1 -1
- package/skills/editing/SKILL.md +1 -1
- package/skills/filtering/SKILL.md +1 -1
- package/skills/getting-started/SKILL.md +1 -1
- package/skills/grouping/SKILL.md +1 -1
- package/skills/migrating-to-2/SKILL.md +1 -1
- package/skills/options/SKILL.md +2 -2
- package/skills/rows/SKILL.md +1 -1
- package/skills/server-side/SKILL.md +1 -1
- package/skills/testing/SKILL.md +1 -1
- package/skills/testing-components/SKILL.md +1 -1
- package/skills/testing-editing/SKILL.md +1 -1
- package/src/components/TMDataGridDetailsColumn.tsx +3 -0
- package/src/components/TMDataGridSelectColumn.tsx +15 -1
- package/src/components/TMDataGridTable.tsx +42 -9
- package/src/components/generatedColumns.tsx +8 -8
- package/src/core/expanding.ts +4 -1
- package/src/core/labels.ts +3 -3
- package/src/core/labelsSv.ts +22 -22
- package/src/core/quickSearch.ts +52 -0
- package/src/useTMDataGrid.tsx +37 -21
package/docs/column-layout.md
CHANGED
|
@@ -160,7 +160,7 @@ const { resetSettings } = useTMDataGrid({ data, columns });
|
|
|
160
160
|
| Name | Kind | Type | Default | What it does |
|
|
161
161
|
| --- | --- | --- | --- | --- |
|
|
162
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. |
|
|
163
|
+
| `enableColumnPinning` | Table option | `boolean` | `true` | `false` removes the pin menu items. The generated lanes stay pinned. |
|
|
164
164
|
| `enablePinning` | Column option | `boolean` | `true` | `false` for one column. |
|
|
165
165
|
| `enableColumnOrdering` | Option | `boolean` | `true` | Header dragging and the move menu items. Grid-defined. |
|
|
166
166
|
| `meta.enableOrdering` | Column meta | `boolean` | `true` | `false` keeps one column where it is. |
|
package/docs/column-menu.md
CHANGED
|
@@ -14,7 +14,7 @@ The menu shows each group only when the column supports it:
|
|
|
14
14
|
|
|
15
15
|
| Item | Shown when |
|
|
16
16
|
| --- | --- |
|
|
17
|
-
| Sort
|
|
17
|
+
| Sort ascending · Sort descending | The column can sort. See [Sorting](/docs/sorting) |
|
|
18
18
|
| Filter | The column can filter and `filters.inHeader` is off. See [Filtering](/docs/filtering) |
|
|
19
19
|
| Group by · Ungroup | The column can group. See [Grouping](/docs/grouping) |
|
|
20
20
|
| Expand all groups · Collapse all groups | Grouping is active |
|
package/docs/localization.md
CHANGED
package/docs/row-details.md
CHANGED
|
@@ -44,6 +44,20 @@ every panel at once.
|
|
|
44
44
|
|
|
45
45
|
Group rows get no chevron: they expand into their children from the tree lane.
|
|
46
46
|
|
|
47
|
+
To give only some rows a panel, set `getRowCanExpand`:
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
const grid = useTMDataGrid({
|
|
51
|
+
data,
|
|
52
|
+
columns,
|
|
53
|
+
renderDetails: ({ row }) => <Notes notes={row.original.notes} />,
|
|
54
|
+
getRowCanExpand: (row) => row.original.notes.length > 0,
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
A row it turns down gets no chevron, and the header control skips it.
|
|
59
|
+
It never applies to a group row.
|
|
60
|
+
|
|
47
61
|
## Opening a row from elsewhere
|
|
48
62
|
|
|
49
63
|
Which rows are open is TanStack's own `expanded` state, so anything can open
|
|
@@ -113,6 +127,7 @@ Group rows have no panel. Expanding one opens its children.
|
|
|
113
127
|
| --- | --- | --- | --- | --- |
|
|
114
128
|
| `renderDetails` | Option | `({ row, table }) => ReactNode` | – | Contents of the panel. Setting it adds the lane. |
|
|
115
129
|
| `TMDataGridDetailsArgs` | Type | `{ row, table }` | – | What `renderDetails` receives. |
|
|
130
|
+
| `getRowCanExpand` | Table option | `(row) => boolean` | – | Determines which data rows have a panel. If not set, every data row has one. Group rows always expand. |
|
|
116
131
|
| `renderDetailsEstHeight` | Option | `number` | `160` | Height the virtualizer assumes for an unmeasured panel. |
|
|
117
132
|
| `detailsColumnPosition` | Option | `"left" \| "right"` | `"left"` | Which edge the lane is pinned to. `"right"` places it after every column, inside the edit lane. |
|
|
118
133
|
| `initialState.expanded` | Table option | `ExpandedState` | `{}` | Rows open at mount. A data slice, so it persists. |
|
package/docs/row-selection.md
CHANGED
|
@@ -40,6 +40,11 @@ focusable in this mode, and Space or Enter toggles the focused row.
|
|
|
40
40
|
selection in any mode. It has no effect under `"highlight"`, which selects
|
|
41
41
|
nothing.
|
|
42
42
|
|
|
43
|
+
As a predicate, `enableRowSelection` decides row by row:
|
|
44
|
+
|
|
45
|
+
- a row it turns down has a disabled checkbox, and the header checkbox does not tick it
|
|
46
|
+
- unticking the header checkbox clears every row the filters show, including a turned-down row ticked through `initialState` or `setRowSelection`
|
|
47
|
+
|
|
43
48
|
## The highlighted row
|
|
44
49
|
|
|
45
50
|
The highlighted row is state of its own rather than a slice of `rowSelection`,
|
package/docs/testing.md
CHANGED
|
@@ -310,7 +310,11 @@ export class DataGrid {
|
|
|
310
310
|
await this.part("search").fill(text);
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
-
/**
|
|
313
|
+
/**
|
|
314
|
+
* Clicks a sortable header once. Each click steps the sort: off, first
|
|
315
|
+
* direction, the other direction, off. The first direction is ascending for
|
|
316
|
+
* text and descending for numbers, unless the column sets `sortDescFirst`.
|
|
317
|
+
*/
|
|
314
318
|
async sortBy(columnId: string): Promise<void> {
|
|
315
319
|
// The header, not its `header-sort` arrow: the arrow is display: none
|
|
316
320
|
// until the header is hovered, and a click on it also reaches the
|
package/docs/use-tm-data-grid.md
CHANGED
|
@@ -36,7 +36,7 @@ rather than forwarded to TanStack.
|
|
|
36
36
|
| `enableSorting` | `boolean` | `true` | Enables sorting for the table. |
|
|
37
37
|
| `enableColumnFilters` | `boolean` | `true` | Enables filtering for the table. |
|
|
38
38
|
| `enableHiding` | `boolean` | `true` | Enables column visibility for the table. |
|
|
39
|
-
| `enableColumnPinning` | `boolean` | `true` | Enables pinning for the table. |
|
|
39
|
+
| `enableColumnPinning` | `boolean` | `true` | Enables pinning for the table. `false` removes the pin menu items; the generated lanes stay pinned. |
|
|
40
40
|
| `enableColumnResizing` | `boolean` | `true` | Enables resizing for the table. |
|
|
41
41
|
| `enableColumnOrdering` | `boolean` | `true` | Enables header dragging and the move menu items. Defined by the grid, see [Column layout](/docs/column-layout#ordering). |
|
|
42
42
|
| `enablePagination` | `boolean` | `false` | Enables client-side paging and the `Footer` pager. Implied by `manualPagination`. Defined by the grid, see [Pagination](/docs/pagination). |
|
|
@@ -134,7 +134,7 @@ where its grammar requires:
|
|
|
134
134
|
|
|
135
135
|
```tsx
|
|
136
136
|
labels: {
|
|
137
|
-
groupBy: (column) => `Gruppera
|
|
137
|
+
groupBy: (column) => `Gruppera efter ${column}`,
|
|
138
138
|
pageRange: ({ from, to, total }) => `${from}–${to} av ${total}`,
|
|
139
139
|
}
|
|
140
140
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jielga/tmdatagrid",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
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",
|
|
@@ -76,31 +76,31 @@
|
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
78
|
"@babel/core": "^7.29.7",
|
|
79
|
-
"@mantine/core": "^9.4.
|
|
80
|
-
"@rolldown/plugin-babel": "^0.2.
|
|
79
|
+
"@mantine/core": "^9.4.2",
|
|
80
|
+
"@rolldown/plugin-babel": "^0.2.4",
|
|
81
81
|
"@tabler/icons-react": "^3.46.0",
|
|
82
82
|
"@tanstack/intent": "0.3.6",
|
|
83
|
-
"@tanstack/react-form": "^1.33.
|
|
84
|
-
"@tanstack/react-store": "^0.11.
|
|
83
|
+
"@tanstack/react-form": "^1.33.5",
|
|
84
|
+
"@tanstack/react-store": "^0.11.2",
|
|
85
85
|
"@tanstack/react-table": "^9.2.4",
|
|
86
|
-
"@tanstack/react-virtual": "^3.14.
|
|
87
|
-
"@tanstack/store": "^0.11.
|
|
86
|
+
"@tanstack/react-virtual": "^3.14.14",
|
|
87
|
+
"@tanstack/store": "^0.11.2",
|
|
88
88
|
"@tanstack/table-core": "^9.2.4",
|
|
89
89
|
"@testing-library/jest-dom": "^7.0.0",
|
|
90
90
|
"@testing-library/react": "^16.3.2",
|
|
91
|
-
"@testing-library/user-event": "^14.6.
|
|
91
|
+
"@testing-library/user-event": "^14.6.7",
|
|
92
92
|
"@types/babel__core": "^7.20.5",
|
|
93
|
-
"@types/react": "^19.2.
|
|
94
|
-
"@types/react-dom": "^19.2.
|
|
95
|
-
"@vitejs/plugin-react": "^6.0.
|
|
93
|
+
"@types/react": "^19.2.18",
|
|
94
|
+
"@types/react-dom": "^19.2.7",
|
|
95
|
+
"@vitejs/plugin-react": "^6.0.5",
|
|
96
96
|
"babel-plugin-react-compiler": "^1.0.0",
|
|
97
97
|
"jsdom": "^29.1.1",
|
|
98
|
-
"react": "^19.2.
|
|
99
|
-
"react-dom": "^19.2.
|
|
98
|
+
"react": "^19.2.8",
|
|
99
|
+
"react-dom": "^19.2.8",
|
|
100
100
|
"rolldown": "~1.1.5",
|
|
101
101
|
"rolldown-plugin-dts": "^0.27.14",
|
|
102
102
|
"typescript": "~7.0.2",
|
|
103
|
-
"vite": "^8.1.
|
|
103
|
+
"vite": "^8.1.6",
|
|
104
104
|
"vitest": "^4.1.10",
|
|
105
105
|
"zod": "^4.4.3"
|
|
106
106
|
}
|
|
@@ -18,7 +18,7 @@ description: >
|
|
|
18
18
|
metadata:
|
|
19
19
|
type: core
|
|
20
20
|
library: '@jielga/tmdatagrid'
|
|
21
|
-
library_version: '2.1.
|
|
21
|
+
library_version: '2.1.2'
|
|
22
22
|
sources:
|
|
23
23
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/styling.md'
|
|
24
24
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/toolbar.md'
|
|
@@ -242,7 +242,7 @@ where its grammar requires:
|
|
|
242
242
|
|
|
243
243
|
```tsx
|
|
244
244
|
const labels = {
|
|
245
|
-
groupBy: (column) => `Gruppera
|
|
245
|
+
groupBy: (column) => `Gruppera efter ${column}`,
|
|
246
246
|
pageRange: ({ from, to, total }) => `${from}–${to} av ${total}`,
|
|
247
247
|
} satisfies TMDataGridLabelsOverride;
|
|
248
248
|
```
|
|
@@ -14,7 +14,7 @@ description: >
|
|
|
14
14
|
metadata:
|
|
15
15
|
type: core
|
|
16
16
|
library: '@jielga/tmdatagrid'
|
|
17
|
-
library_version: '2.1.
|
|
17
|
+
library_version: '2.1.2'
|
|
18
18
|
sources:
|
|
19
19
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/cell-selection.md'
|
|
20
20
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/src/core/cellNavigation.ts'
|
package/skills/columns/SKILL.md
CHANGED
|
@@ -16,7 +16,7 @@ description: >
|
|
|
16
16
|
metadata:
|
|
17
17
|
type: core
|
|
18
18
|
library: '@jielga/tmdatagrid'
|
|
19
|
-
library_version: '2.1.
|
|
19
|
+
library_version: '2.1.2'
|
|
20
20
|
sources:
|
|
21
21
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/columns.md'
|
|
22
22
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/column-layout.md'
|
package/skills/data/SKILL.md
CHANGED
|
@@ -18,7 +18,7 @@ description: >
|
|
|
18
18
|
metadata:
|
|
19
19
|
type: core
|
|
20
20
|
library: '@jielga/tmdatagrid'
|
|
21
|
-
library_version: '2.1.
|
|
21
|
+
library_version: '2.1.2'
|
|
22
22
|
sources:
|
|
23
23
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/pagination.md'
|
|
24
24
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/scrolling.md'
|
package/skills/editing/SKILL.md
CHANGED
|
@@ -18,7 +18,7 @@ description: >
|
|
|
18
18
|
metadata:
|
|
19
19
|
type: core
|
|
20
20
|
library: '@jielga/tmdatagrid'
|
|
21
|
-
library_version: '2.1.
|
|
21
|
+
library_version: '2.1.2'
|
|
22
22
|
sources:
|
|
23
23
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/editing.md'
|
|
24
24
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/draft-store.md'
|
|
@@ -18,7 +18,7 @@ description: >
|
|
|
18
18
|
metadata:
|
|
19
19
|
type: core
|
|
20
20
|
library: '@jielga/tmdatagrid'
|
|
21
|
-
library_version: '2.1.
|
|
21
|
+
library_version: '2.1.2'
|
|
22
22
|
sources:
|
|
23
23
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/filtering.md'
|
|
24
24
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/quick-search.md'
|
|
@@ -13,7 +13,7 @@ description: >
|
|
|
13
13
|
metadata:
|
|
14
14
|
type: core
|
|
15
15
|
library: '@jielga/tmdatagrid'
|
|
16
|
-
library_version: '2.1.
|
|
16
|
+
library_version: '2.1.2'
|
|
17
17
|
sources:
|
|
18
18
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/getting-started.md'
|
|
19
19
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/anatomy.md'
|
package/skills/grouping/SKILL.md
CHANGED
|
@@ -14,7 +14,7 @@ description: >
|
|
|
14
14
|
metadata:
|
|
15
15
|
type: core
|
|
16
16
|
library: '@jielga/tmdatagrid'
|
|
17
|
-
library_version: '2.1.
|
|
17
|
+
library_version: '2.1.2'
|
|
18
18
|
sources:
|
|
19
19
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/grouping.md'
|
|
20
20
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/summary-row.md'
|
|
@@ -15,7 +15,7 @@ description: >
|
|
|
15
15
|
metadata:
|
|
16
16
|
type: lifecycle
|
|
17
17
|
library: '@jielga/tmdatagrid'
|
|
18
|
-
library_version: '2.1.
|
|
18
|
+
library_version: '2.1.2'
|
|
19
19
|
sources:
|
|
20
20
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/migrating-to-2.md'
|
|
21
21
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/src/index.ts'
|
package/skills/options/SKILL.md
CHANGED
|
@@ -14,7 +14,7 @@ description: >
|
|
|
14
14
|
metadata:
|
|
15
15
|
type: core
|
|
16
16
|
library: '@jielga/tmdatagrid'
|
|
17
|
-
library_version: '2.1.
|
|
17
|
+
library_version: '2.1.2'
|
|
18
18
|
sources:
|
|
19
19
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/use-tm-data-grid.md'
|
|
20
20
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/persistence.md'
|
|
@@ -57,7 +57,7 @@ rather than forwarded to TanStack.
|
|
|
57
57
|
| `enableSorting` | `boolean` | `true` | Enables sorting for the table. |
|
|
58
58
|
| `enableColumnFilters` | `boolean` | `true` | Enables filtering for the table. |
|
|
59
59
|
| `enableHiding` | `boolean` | `true` | Enables column visibility for the table. |
|
|
60
|
-
| `enableColumnPinning` | `boolean` | `true` | Enables pinning for the table. |
|
|
60
|
+
| `enableColumnPinning` | `boolean` | `true` | Enables pinning for the table. `false` removes the pin menu items; the generated lanes stay pinned. |
|
|
61
61
|
| `enableColumnResizing` | `boolean` | `true` | Enables resizing for the table. |
|
|
62
62
|
| `enableColumnOrdering` | `boolean` | `true` | Enables header dragging and the move menu items. Defined by the grid. |
|
|
63
63
|
| `enablePagination` | `boolean` | `false` | Enables client-side paging and the `Footer` pager. Implied by `manualPagination`. Defined by the grid. |
|
package/skills/rows/SKILL.md
CHANGED
|
@@ -17,7 +17,7 @@ description: >
|
|
|
17
17
|
metadata:
|
|
18
18
|
type: core
|
|
19
19
|
library: '@jielga/tmdatagrid'
|
|
20
|
-
library_version: '2.1.
|
|
20
|
+
library_version: '2.1.2'
|
|
21
21
|
sources:
|
|
22
22
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/row-selection.md'
|
|
23
23
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/row-interaction.md'
|
|
@@ -15,7 +15,7 @@ description: >
|
|
|
15
15
|
metadata:
|
|
16
16
|
type: core
|
|
17
17
|
library: '@jielga/tmdatagrid'
|
|
18
|
-
library_version: '2.1.
|
|
18
|
+
library_version: '2.1.2'
|
|
19
19
|
sources:
|
|
20
20
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/server-side.md'
|
|
21
21
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/server-query.md'
|
package/skills/testing/SKILL.md
CHANGED
|
@@ -12,7 +12,7 @@ description: >
|
|
|
12
12
|
metadata:
|
|
13
13
|
type: core
|
|
14
14
|
library: '@jielga/tmdatagrid'
|
|
15
|
-
library_version: '2.1.
|
|
15
|
+
library_version: '2.1.2'
|
|
16
16
|
sources:
|
|
17
17
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/testing.md'
|
|
18
18
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/test/gallery/main.tsx'
|
|
@@ -12,7 +12,7 @@ description: >
|
|
|
12
12
|
metadata:
|
|
13
13
|
type: core
|
|
14
14
|
library: '@jielga/tmdatagrid'
|
|
15
|
-
library_version: '2.1.
|
|
15
|
+
library_version: '2.1.2'
|
|
16
16
|
sources:
|
|
17
17
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/testing.md'
|
|
18
18
|
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/editing.md'
|
|
@@ -33,6 +33,9 @@ export function DetailsCell<TData extends RowData>({
|
|
|
33
33
|
// `showsDetails`. Their cells are aggregated, so this lane is already blank
|
|
34
34
|
// on them; the guard is what makes that a decision rather than a side effect.
|
|
35
35
|
if (row.getIsGrouped()) return null;
|
|
36
|
+
// A record the consumer's `getRowCanExpand` turns down has no panel, and
|
|
37
|
+
// TanStack refuses to expand it - a chevron here would do nothing.
|
|
38
|
+
if (!row.getCanExpand()) return null;
|
|
36
39
|
|
|
37
40
|
return (
|
|
38
41
|
<UnstyledButton
|
|
@@ -50,7 +50,21 @@ function SelectAllCheckbox<TData extends RowData>({
|
|
|
50
50
|
data-dg-part="select-all"
|
|
51
51
|
checked={allSelected}
|
|
52
52
|
indeterminate={someSelected && !allSelected}
|
|
53
|
-
onChange={
|
|
53
|
+
onChange={(event) => {
|
|
54
|
+
if (event.currentTarget.checked) {
|
|
55
|
+
table.toggleAllRowsSelected(true);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// Not `toggleAllRowsSelected(false)`: since TanStack 9.2 it keeps a
|
|
59
|
+
// ticked row that `enableRowSelection` turns down, so the box could
|
|
60
|
+
// never clear. Every row the filters show is unticked; rows a filter
|
|
61
|
+
// hides keep their tick, as they always have.
|
|
62
|
+
const next = { ...table.store.state.rowSelection };
|
|
63
|
+
for (const row of table.getPreGroupedRowModel().flatRows) {
|
|
64
|
+
delete next[row.id];
|
|
65
|
+
}
|
|
66
|
+
table.setRowSelection(next);
|
|
67
|
+
}}
|
|
54
68
|
/>
|
|
55
69
|
);
|
|
56
70
|
}
|
|
@@ -159,9 +159,9 @@ function keepColumnInView({
|
|
|
159
159
|
* | ---- | ------- |
|
|
160
160
|
* | On a data row | the column's `cell`, as always |
|
|
161
161
|
* | Placeholder - a grouped column other than this row's own | nothing |
|
|
162
|
-
* |
|
|
163
|
-
* |
|
|
164
|
-
* |
|
|
162
|
+
* | Group summary, column declares `aggregatedCell` | that |
|
|
163
|
+
* | Group summary, column declares an `aggregationFn` | the column's `cell`, over the aggregate |
|
|
164
|
+
* | Group summary, column declares neither | nothing |
|
|
165
165
|
*
|
|
166
166
|
* That last row is the one worth spelling out. Without an aggregation function
|
|
167
167
|
* `getValue()` is `undefined` on a group row, so the column's own renderer
|
|
@@ -174,17 +174,31 @@ function renderCellContent(
|
|
|
174
174
|
cell: Cell<TMDataGridFeatures, TMDataGridRowData, unknown>,
|
|
175
175
|
) {
|
|
176
176
|
if (cell.getIsPlaceholder()) return null;
|
|
177
|
-
if (!cell
|
|
177
|
+
if (!isGroupSummaryCell(cell)) {
|
|
178
178
|
return flexRender(cell.column.columnDef.cell, cell.getContext());
|
|
179
179
|
}
|
|
180
|
-
const { aggregatedCell
|
|
180
|
+
const { aggregatedCell } = cell.column.columnDef;
|
|
181
181
|
if (aggregatedCell !== undefined) {
|
|
182
182
|
return flexRender(aggregatedCell, cell.getContext());
|
|
183
183
|
}
|
|
184
|
-
if (
|
|
184
|
+
if (!cell.getIsAggregated()) return null;
|
|
185
185
|
return flexRender(cell.column.columnDef.cell, cell.getContext());
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
/**
|
|
189
|
+
* A cell on a group row in any column but the one the row groups by - the
|
|
190
|
+
* cells that summarise the group rather than show a record.
|
|
191
|
+
*
|
|
192
|
+
* Not `cell.getIsAggregated()`: since TanStack Table 9.2 that is true only
|
|
193
|
+
* when the column has an aggregation function, so it cannot tell a group
|
|
194
|
+
* row's blank cell from a data row's cell.
|
|
195
|
+
*/
|
|
196
|
+
function isGroupSummaryCell(
|
|
197
|
+
cell: Cell<TMDataGridFeatures, TMDataGridRowData, unknown>,
|
|
198
|
+
): boolean {
|
|
199
|
+
return cell.row.getIsGrouped() && !cell.getIsGrouped();
|
|
200
|
+
}
|
|
201
|
+
|
|
188
202
|
/**
|
|
189
203
|
* What a cell needs to take part in cell selection, or `undefined` while the
|
|
190
204
|
* feature is off - which is what keeps a plain grid's cells exactly as they
|
|
@@ -401,7 +415,7 @@ function TMDataGridBodyCell({
|
|
|
401
415
|
draftValues !== undefined &&
|
|
402
416
|
contentOverride === undefined &&
|
|
403
417
|
!cell.getIsPlaceholder() &&
|
|
404
|
-
!cell
|
|
418
|
+
!isGroupSummaryCell(cell)
|
|
405
419
|
? draftCellContext(cell, draftValues)
|
|
406
420
|
: undefined;
|
|
407
421
|
// Highlighting reproduces the *default* renderer, value then
|
|
@@ -412,7 +426,7 @@ function TMDataGridBodyCell({
|
|
|
412
426
|
highlightNeedles !== undefined &&
|
|
413
427
|
contentOverride === undefined &&
|
|
414
428
|
!cell.getIsPlaceholder() &&
|
|
415
|
-
!cell
|
|
429
|
+
!isGroupSummaryCell(cell) &&
|
|
416
430
|
cell.column.columnDef.cell === table.getDefaultColumnDef().cell
|
|
417
431
|
) {
|
|
418
432
|
const value =
|
|
@@ -1517,6 +1531,24 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
|
|
|
1517
1531
|
const trailingGuardRef = useRef<HTMLDivElement>(null);
|
|
1518
1532
|
const guardHopRef = useRef(false);
|
|
1519
1533
|
|
|
1534
|
+
/**
|
|
1535
|
+
* Keeps both guards at the scrollport's top-left corner as the body scrolls.
|
|
1536
|
+
*
|
|
1537
|
+
* A guard is out of flow, so left alone it sits at the top of the scrolled
|
|
1538
|
+
* content. Tab from outside focuses it without `preventScroll`, and the
|
|
1539
|
+
* browser then scrolls the body back to the top to show it - which unmounts
|
|
1540
|
+
* the cursor row the guard is about to hand the focus to, and drops the
|
|
1541
|
+
* focus on `<body>`. A guard already inside the scrollport is never
|
|
1542
|
+
* scrolled to. Written straight to the style, so a scroll costs no render.
|
|
1543
|
+
*/
|
|
1544
|
+
const placeTabGuards = (container: HTMLElement) => {
|
|
1545
|
+
for (const guard of [leadingGuardRef.current, trailingGuardRef.current]) {
|
|
1546
|
+
if (guard === null) continue;
|
|
1547
|
+
guard.style.top = `${container.scrollTop}px`;
|
|
1548
|
+
guard.style.left = `${container.scrollLeft}px`;
|
|
1549
|
+
}
|
|
1550
|
+
};
|
|
1551
|
+
|
|
1520
1552
|
// O(n) per keystroke and per render while a cell is focused. Fine at any row
|
|
1521
1553
|
// count a grid actually holds, and the alternative - an id→index map rebuilt
|
|
1522
1554
|
// whenever sorting, filtering or grouping changes - costs more than it saves.
|
|
@@ -2434,8 +2466,9 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
|
|
|
2434
2466
|
* zoom, where a "fully scrolled" position can land at 799.5 of 800.
|
|
2435
2467
|
*/
|
|
2436
2468
|
const handleScroll =
|
|
2437
|
-
contextMenuTarget || hasEdgeCallbacks
|
|
2469
|
+
contextMenuTarget || hasEdgeCallbacks || cellSelection
|
|
2438
2470
|
? (event: UIEvent<HTMLDivElement>) => {
|
|
2471
|
+
if (cellSelection) placeTabGuards(event.currentTarget);
|
|
2439
2472
|
if (contextMenuTarget) closeContextMenu();
|
|
2440
2473
|
if (!hasEdgeCallbacks) return;
|
|
2441
2474
|
const el = event.currentTarget;
|
|
@@ -48,8 +48,8 @@ export function createSelectColumn<TData extends RowData>(
|
|
|
48
48
|
enablePinning: false,
|
|
49
49
|
header: ({ table }) => <SelectAllHeader table={table} />,
|
|
50
50
|
cell: ({ row }) => <SelectRowCheckbox row={row} />,
|
|
51
|
-
// Every cell on a group row that is not the grouped column
|
|
52
|
-
//
|
|
51
|
+
// Every cell on a group row that is not the grouped column is a group
|
|
52
|
+
// summary cell, this lane included, and a summary cell with nothing
|
|
53
53
|
// declared renders blank. Without this the checkbox would disappear from
|
|
54
54
|
// exactly the rows that select a whole group. See renderCellContent.
|
|
55
55
|
aggregatedCell: ({ row }) => <SelectRowCheckbox row={row} />,
|
|
@@ -90,10 +90,10 @@ export function createGroupColumn<TData extends RowData>(
|
|
|
90
90
|
// Structurally pinned to the left; users shouldn't be able to move it.
|
|
91
91
|
enablePinning: false,
|
|
92
92
|
cell: ({ row }) => <GroupCell row={row} />,
|
|
93
|
-
//
|
|
94
|
-
//
|
|
95
|
-
//
|
|
96
|
-
//
|
|
93
|
+
// Every cell on a group row that is not the grouped column is a group
|
|
94
|
+
// summary cell - this lane included. Without an `aggregatedCell` the body
|
|
95
|
+
// would take that as "nothing to summarise" and render the tree lane
|
|
96
|
+
// blank on exactly the rows it exists for. See renderCellContent.
|
|
97
97
|
aggregatedCell: ({ row }) => <GroupCell row={row} />,
|
|
98
98
|
header: ({ table }) => <GroupHeader table={table} />,
|
|
99
99
|
};
|
|
@@ -142,7 +142,7 @@ export function createDetailsColumn<TData extends RowData>(
|
|
|
142
142
|
header: ({ table }) => <DetailsHeader table={table} />,
|
|
143
143
|
cell: ({ row }) => <DetailsCell row={row} />,
|
|
144
144
|
// Deliberately no `aggregatedCell`: on a group row every cell outside the
|
|
145
|
-
// grouped column
|
|
145
|
+
// grouped column is a summary cell, and blank is the right answer here -
|
|
146
146
|
// groups expand into their rows, not into a panel.
|
|
147
147
|
};
|
|
148
148
|
}
|
|
@@ -182,7 +182,7 @@ export function createEditColumn<TData extends RowData>(
|
|
|
182
182
|
header: () => null,
|
|
183
183
|
cell: ({ row }) => <EditLaneCell row={row} />,
|
|
184
184
|
// Group rows: same reasoning as the checkbox lane - without this the
|
|
185
|
-
// cell renders blank on
|
|
185
|
+
// cell renders blank on group rows, but here blank is also correct,
|
|
186
186
|
// so the aggregated cell renders the same (null for groups).
|
|
187
187
|
aggregatedCell: ({ row }) => <EditLaneCell row={row} />,
|
|
188
188
|
};
|
package/src/core/expanding.ts
CHANGED
|
@@ -20,7 +20,10 @@ function isTarget<TData extends RowData>(
|
|
|
20
20
|
row: Row<TMDataGridFeatures, TData>,
|
|
21
21
|
target: TMDataGridExpandTarget,
|
|
22
22
|
): boolean {
|
|
23
|
-
|
|
23
|
+
// A record a consumer's `getRowCanExpand` turns down has no panel to open.
|
|
24
|
+
return target === "groups"
|
|
25
|
+
? row.getIsGrouped()
|
|
26
|
+
: !row.getIsGrouped() && row.getCanExpand();
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
/**
|
package/src/core/labels.ts
CHANGED
|
@@ -236,8 +236,8 @@ export const TMDATAGRID_LABELS_EN: TMDataGridLabels = {
|
|
|
236
236
|
activeFilters: "Active filters",
|
|
237
237
|
clearFilter: (column) => `Clear ${column} filter`,
|
|
238
238
|
|
|
239
|
-
sortAsc: "Sort
|
|
240
|
-
sortDesc: "Sort
|
|
239
|
+
sortAsc: "Sort ascending",
|
|
240
|
+
sortDesc: "Sort descending",
|
|
241
241
|
filterMenuItem: "Filter",
|
|
242
242
|
groupBy: (column) => `Group by ${column}`,
|
|
243
243
|
ungroup: (column) => `Ungroup ${column}`,
|
|
@@ -260,7 +260,7 @@ export const TMDATAGRID_LABELS_EN: TMDataGridLabels = {
|
|
|
260
260
|
pageCount < 0 ? `Page ${page}` : `Page ${page} of ${pageCount}`,
|
|
261
261
|
groupedAllRows: (total) => `Grouped · all ${total} rows`,
|
|
262
262
|
pagingSuspendedHint:
|
|
263
|
-
"Paging is off while the rows are grouped
|
|
263
|
+
"Paging is off while the rows are grouped, and every row is shown. Ungroup to page again.",
|
|
264
264
|
previousPage: "Previous page",
|
|
265
265
|
nextPage: "Next page",
|
|
266
266
|
|