@jielga/tmdatagrid 0.1.0 → 0.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/README.md +35 -2
- package/dist/index.d.ts +792 -327
- package/dist/index.js +1581 -892
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +15 -7
- package/skills/columns/SKILL.md +8 -7
- package/skills/features/SKILL.md +104 -16
- package/skills/getting-started/SKILL.md +78 -20
- package/skills/options/SKILL.md +12 -7
- package/skills/server-side/SKILL.md +5 -2
- package/src/tmdatagrid/TMDataGridContext.ts +1 -1
- package/src/tmdatagrid/components/TMDataGrid.module.css +73 -0
- package/src/tmdatagrid/{TMDataGrid.tsx → components/TMDataGrid.tsx} +15 -4
- package/src/tmdatagrid/components/TMDataGridColumnsPanel.module.css +25 -0
- package/src/tmdatagrid/{TMDataGridColumnsPanel.tsx → components/TMDataGridColumnsPanel.tsx} +10 -4
- package/src/tmdatagrid/components/TMDataGridFilterPanel.module.css +35 -0
- package/src/tmdatagrid/{TMDataGridFilterPanel.tsx → components/TMDataGridFilterPanel.tsx} +91 -14
- package/src/tmdatagrid/components/TMDataGridFilterPills.module.css +35 -0
- package/src/tmdatagrid/components/TMDataGridFilterPills.tsx +135 -0
- package/src/tmdatagrid/components/TMDataGridFooter.module.css +18 -0
- package/src/tmdatagrid/components/TMDataGridFooter.tsx +171 -0
- package/src/tmdatagrid/components/TMDataGridGroupColumn.module.css +48 -0
- package/src/tmdatagrid/components/TMDataGridGroupColumn.tsx +147 -0
- package/src/tmdatagrid/components/TMDataGridHeaderCell.module.css +159 -0
- package/src/tmdatagrid/{TMDataGridHeaderCell.tsx → components/TMDataGridHeaderCell.tsx} +99 -14
- package/src/tmdatagrid/components/TMDataGridSelectColumn.tsx +177 -0
- package/src/tmdatagrid/components/TMDataGridTable.module.css +137 -0
- package/src/tmdatagrid/components/TMDataGridTable.tsx +720 -0
- package/src/tmdatagrid/components/TMDataGridToolbar.module.css +12 -0
- package/src/tmdatagrid/{TMDataGridToolbar.tsx → components/TMDataGridToolbar.tsx} +8 -5
- package/src/tmdatagrid/{icons.ts → components/icons.ts} +5 -0
- package/src/tmdatagrid/components/sticky.module.css +45 -0
- package/src/tmdatagrid/core/capabilities.ts +215 -0
- package/src/tmdatagrid/{columnOrdering.ts → core/columnOrdering.ts} +2 -2
- package/src/tmdatagrid/{columnUtils.ts → core/columnUtils.ts} +1 -1
- package/src/tmdatagrid/{filterOperators.ts → core/filterOperators.ts} +25 -0
- package/src/tmdatagrid/core/grouping.ts +21 -0
- package/src/tmdatagrid/{persistence.ts → core/persistence.ts} +92 -2
- package/src/tmdatagrid/core/rowSelection.ts +202 -0
- package/src/tmdatagrid/index.ts +39 -9
- package/src/tmdatagrid/useTMDataGrid.tsx +318 -66
- package/src/tmdatagrid/TMDataGrid.module.css +0 -410
- package/src/tmdatagrid/TMDataGridFooter.tsx +0 -74
- package/src/tmdatagrid/TMDataGridTable.tsx +0 -297
- package/src/tmdatagrid/capabilities.ts +0 -117
- /package/src/tmdatagrid/{sizes.ts → core/sizes.ts} +0 -0
package/dist/styles.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
.
|
|
1
|
+
._root_13dg1_8[data-size=xs]{--dg-row-height:34px;--dg-header-height:32px;--dg-font-size:var(--mantine-font-size-xs);--dg-padding:6px}._root_13dg1_8[data-size=sm]{--dg-row-height:42px;--dg-header-height:38px;--dg-font-size:var(--mantine-font-size-sm);--dg-padding:8px}._root_13dg1_8[data-size=md]{--dg-row-height:52px;--dg-header-height:44px;--dg-font-size:var(--mantine-font-size-sm);--dg-padding:10px}._root_13dg1_8[data-size=lg]{--dg-row-height:62px;--dg-header-height:52px;--dg-font-size:var(--mantine-font-size-md);--dg-padding:14px}._root_13dg1_8[data-size=xl]{--dg-row-height:72px;--dg-header-height:60px;--dg-font-size:var(--mantine-font-size-lg);--dg-padding:18px}._root_13dg1_8{--dg-row-height:52px;--dg-header-height:44px;--dg-font-size:var(--mantine-font-size-sm);--dg-padding:10px;--dg-row-selected-bg:var(--mantine-primary-color-light);--dg-row-highlight-bg:var(--mantine-primary-color-light-hover);--dg-row-group-bg:var(--mantine-color-body);text-align:left;border:1px solid var(--mantine-color-default-border);border-radius:var(--mantine-radius-md);background-color:var(--mantine-color-body);flex-direction:column;min-height:0;display:flex;overflow:hidden}._columnsPanel_1492o_1{flex-direction:column;width:280px;display:flex}._columnsPanelSearch_1492o_7{padding:var(--mantine-spacing-sm)}._columnsPanelList_1492o_11{gap:var(--mantine-spacing-sm);padding:0 var(--mantine-spacing-sm) var(--mantine-spacing-sm);flex-direction:column;display:flex}._columnsPanelFooter_1492o_18{justify-content:space-between;align-items:center;gap:var(--mantine-spacing-sm);padding:var(--mantine-spacing-sm);border-top:1px solid var(--mantine-color-default-border);display:flex}._groupToggle_h06xv_4{width:100%;min-width:0;font-size:var(--dg-font-size);color:inherit;align-items:center;gap:6px;display:flex}._chevron_h06xv_14{color:var(--mantine-color-dimmed);flex:none;align-items:center;transition:transform .12s;display:flex}._chevron_h06xv_14[data-expanded=true]{transform:rotate(90deg)}@media (prefers-reduced-motion:reduce){._chevron_h06xv_14{transition:none}}._groupLabel_h06xv_34{white-space:nowrap;text-overflow:ellipsis;min-width:0;font-weight:600;overflow:hidden}._groupCount_h06xv_44{color:var(--mantine-color-dimmed);font-variant-numeric:tabular-nums;flex:none}._filterPanel_izakx_4{top:calc(var(--dg-header-height) + 2px);left:var(--mantine-spacing-md);z-index:5;padding:var(--mantine-spacing-sm);border-radius:var(--mantine-radius-md);border:1px solid var(--mantine-color-default-border);background-color:var(--mantine-color-body);box-shadow:var(--mantine-shadow-md);position:absolute}._filterRow_izakx_16{align-items:flex-end;gap:var(--mantine-spacing-xs);display:flex}._filterPanelHeader_izakx_22{justify-content:space-between;align-items:center;gap:var(--mantine-spacing-md);padding-bottom:var(--mantine-spacing-xs);display:flex}._filterPanelFooter_izakx_30{justify-content:space-between;align-items:center;gap:var(--mantine-spacing-md);display:flex}._filterPills_1yybb_3{align-items:center;gap:var(--mantine-spacing-xs);flex-wrap:wrap;display:flex}._filterPills_1yybb_3 ._pill_1yybb_15{background-color:var(--lightningcss-light,var(--mantine-color-gray-1))var(--lightningcss-dark,var(--mantine-color-dark-5));color:var(--lightningcss-light,var(--mantine-color-black))var(--lightningcss-dark,var(--mantine-color-dark-0));border:1px solid var(--lightningcss-light,var(--mantine-color-gray-3))var(--lightningcss-dark,var(--mantine-color-dark-3))}._pillLabel_1yybb_27{font:inherit;color:inherit;cursor:pointer}._pillLabel_1yybb_27:hover{text-decoration:underline}._footer_149ca_1{justify-content:flex-end;align-items:center;gap:var(--mantine-spacing-lg);padding:4px var(--mantine-spacing-sm);border-top:1px solid var(--mantine-color-default-border);flex-shrink:0;min-height:48px;display:flex}._footer_149ca_1[data-paging-suspended=true]{opacity:.55}._tableWrapper_chabz_2{flex-direction:column;flex:1;min-height:0;display:flex;position:relative}._scrollContainer_chabz_10{flex:1;min-height:0;position:relative;overflow:auto}._grid_chabz_18{display:grid}._headerRow_chabz_24{grid-column:1/-1;grid-template-columns:subgrid;z-index:3;display:grid;position:sticky;top:0}._bodyRow_chabz_33{--row-bg:var(--mantine-color-body);grid-column:1/-1;grid-template-columns:subgrid;align-items:stretch;display:grid}._bodyRow_chabz_33:hover{--row-bg:var(--mantine-color-default-hover)}._bodyRow_chabz_33[data-grouped=true]{--row-bg:var(--dg-row-group-bg)}._bodyRow_chabz_33[data-context-menu=true]{--row-bg:var(--mantine-color-default-hover)}._bodyRow_chabz_33[data-selected-bg=true]{--row-bg:var(--dg-row-selected-bg)}._bodyRow_chabz_33[data-highlighted=true]{--row-bg:var(--dg-row-highlight-bg)}._bodyRow_chabz_33[data-selects-on-click=true]{-webkit-user-select:none;user-select:none}._bodyRow_chabz_33:focus-visible{outline:2px solid var(--mantine-primary-color-filled);outline-offset:-2px}._bodyCell_chabz_91{padding:0 var(--dg-padding);border-bottom:1px solid var(--mantine-color-default-border);background-color:var(--row-bg);font-size:var(--dg-font-size);align-items:center;display:flex}._bodyCell_chabz_91[data-select-column=true]{padding:0}._cellContent_chabz_89{white-space:nowrap;text-overflow:ellipsis;min-width:0;overflow:hidden}._bodyCell_chabz_91[data-align=right]{justify-content:flex-end}._bodyCell_chabz_91[data-align=center]{justify-content:center}._bodyCell_chabz_91[data-align=left] ._cellContent_chabz_89{flex:auto}._messageRow_chabz_129{justify-content:center;align-items:center;gap:var(--mantine-spacing-xs);padding:var(--mantine-spacing-xl);flex-direction:column;grid-column:1/-1;display:flex}._stickyLeft_1iqrf_11{border-right:1px solid var(--mantine-color-default-border)}._stickyRight_1iqrf_15{border-left:1px solid var(--mantine-color-default-border)}._stickyLeft_1iqrf_11:after,._stickyRight_1iqrf_15:after{content:"";pointer-events:none;width:4px;position:absolute;top:0;bottom:0}._stickyLeft_1iqrf_11:after{background:linear-gradient(90deg,var(--lightningcss-light,#00000014)var(--lightningcss-dark,#00000047),#0000);left:100%}._stickyRight_1iqrf_15:after{background:linear-gradient(270deg,var(--lightningcss-light,#00000014)var(--lightningcss-dark,#00000047),#0000);right:100%}._headerCell_49xbo_1{padding:0 var(--dg-padding);min-width:0;min-height:var(--dg-header-height);font-weight:600;font-size:var(--dg-font-size);background-color:var(--mantine-color-body);border-bottom:1px solid var(--mantine-color-default-border);-webkit-user-select:none;user-select:none;align-items:center;gap:2px;display:flex;position:relative}._headerCell_49xbo_1[data-align=right]{justify-content:flex-end}._headerCell_49xbo_1[data-align=center]{justify-content:center}._headerCell_49xbo_1[data-select-column=true]{padding:0}._headerCell_49xbo_1[data-active=true] ._headerTitle_49xbo_31{color:var(--mantine-primary-color-filled)}._headerTitle_49xbo_31{text-overflow:ellipsis;white-space:nowrap;flex:auto;min-width:0;overflow:hidden}._headerCell_49xbo_1[data-align=right] ._headerTitle_49xbo_31{text-align:right}._headerCell_49xbo_1[data-align=center] ._headerTitle_49xbo_31{justify-content:center;display:flex}._headerActions_49xbo_54{flex-shrink:0;align-items:center;gap:0;margin-left:auto;display:flex}._headerCell_49xbo_1[data-align=right] ._headerActions_49xbo_54{order:-1;margin-left:0;margin-right:auto}._headerAction_49xbo_54{display:none}._headerCell_49xbo_1:hover ._headerAction_49xbo_54,._headerCell_49xbo_1:focus-within ._headerAction_49xbo_54,._headerAction_49xbo_54[data-pinned-visible=true]{display:flex}._headerCellSortable_49xbo_83{cursor:pointer}._headerCellDragging_49xbo_90{opacity:.4}._headerCellDropBefore_49xbo_94:before,._headerCellDropAfter_49xbo_95:before{content:"";background-color:var(--mantine-primary-color-filled);z-index:5;pointer-events:none;width:2px;position:absolute;top:0;bottom:0}._headerCellDropBefore_49xbo_94:before{left:0}._headerCellDropAfter_49xbo_95:before{right:0}._columnSeparator_49xbo_115{z-index:1;justify-content:center;width:10px;height:50%;display:flex;position:absolute;top:25%;right:0;transform:translate(50%)}._columnSeparatorResizable_49xbo_127{cursor:col-resize;touch-action:none}._columnSeparator_49xbo_115:after{content:"";background-color:#0000;width:1px;height:100%;transition:background-color .12s,width .12s}._headerCell_49xbo_1:hover ._columnSeparator_49xbo_115:after,._headerCell_49xbo_1:focus-within ._columnSeparator_49xbo_115:after{background-color:var(--mantine-color-default-border)}._columnSeparatorResizable_49xbo_127:hover:after,._columnSeparatorActive_49xbo_150:after{background-color:var(--mantine-primary-color-filled);width:2px}._menuItemActive_49xbo_156{background-color:var(--mantine-color-default-hover);font-weight:600}._toolbar_4my8t_1{align-items:center;gap:var(--mantine-spacing-xs);padding:6px var(--mantine-spacing-xs);flex-shrink:0;min-height:42px;display:flex}._toolbarSpacer_4my8t_10{flex:1}
|
|
2
2
|
/*$vite$:1*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jielga/tmdatagrid",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
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",
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"files": [
|
|
40
40
|
"dist",
|
|
41
41
|
"src/tmdatagrid",
|
|
42
|
+
"!src/tmdatagrid/**/*.test.*",
|
|
42
43
|
"skills",
|
|
43
44
|
"!skills/_artifacts"
|
|
44
45
|
],
|
|
@@ -56,8 +57,10 @@
|
|
|
56
57
|
"scripts": {
|
|
57
58
|
"dev": "vite",
|
|
58
59
|
"build": "tsc -b && vite build",
|
|
59
|
-
"build:lib": "vite build --config vite.lib.config.ts && tsc -p tsconfig.lib.json &&
|
|
60
|
+
"build:lib": "vite build --config vite.lib.config.ts && tsc -p tsconfig.lib.json && rolldown -c rolldown.dts.config.mjs",
|
|
60
61
|
"lint": "oxlint",
|
|
62
|
+
"test": "vitest run",
|
|
63
|
+
"test:watch": "vitest",
|
|
61
64
|
"preview": "vite preview",
|
|
62
65
|
"changeset": "changeset",
|
|
63
66
|
"version-packages": "changeset version && node scripts/sync-skill-version.mjs",
|
|
@@ -91,21 +94,26 @@
|
|
|
91
94
|
"@tanstack/react-virtual": "^3.14.4",
|
|
92
95
|
"@tanstack/store": "^0.11.0",
|
|
93
96
|
"@tanstack/table-core": "^9.0.0-beta.21",
|
|
97
|
+
"@testing-library/jest-dom": "^7.0.0",
|
|
98
|
+
"@testing-library/react": "^16.3.2",
|
|
99
|
+
"@testing-library/user-event": "^14.6.1",
|
|
94
100
|
"@types/babel__core": "^7.20.5",
|
|
95
101
|
"@types/node": "^24.13.2",
|
|
96
102
|
"@types/react": "^19.2.17",
|
|
97
103
|
"@types/react-dom": "^19.2.3",
|
|
98
|
-
"@vitejs/plugin-react": "^6.0.
|
|
104
|
+
"@vitejs/plugin-react": "^6.0.4",
|
|
99
105
|
"babel-plugin-react-compiler": "^1.0.0",
|
|
100
106
|
"husky": "^9.1.7",
|
|
107
|
+
"jsdom": "^29.1.1",
|
|
101
108
|
"oxlint": "^1.69.0",
|
|
102
109
|
"react": "^19.2.7",
|
|
103
110
|
"react-dom": "^19.2.7",
|
|
104
111
|
"react-markdown": "^10.1.0",
|
|
105
112
|
"remark-gfm": "^4.0.1",
|
|
106
|
-
"
|
|
107
|
-
"
|
|
108
|
-
"typescript": "~
|
|
109
|
-
"vite": "^8.1.
|
|
113
|
+
"rolldown": "~1.1.5",
|
|
114
|
+
"rolldown-plugin-dts": "^0.27.14",
|
|
115
|
+
"typescript": "~7.0.2",
|
|
116
|
+
"vite": "^8.1.5",
|
|
117
|
+
"vitest": "^4.1.10"
|
|
110
118
|
}
|
|
111
119
|
}
|
package/skills/columns/SKILL.md
CHANGED
|
@@ -11,11 +11,11 @@ description: >
|
|
|
11
11
|
metadata:
|
|
12
12
|
type: core
|
|
13
13
|
library: '@jielga/tmdatagrid'
|
|
14
|
-
library_version: '0.
|
|
14
|
+
library_version: '0.3.0'
|
|
15
15
|
sources:
|
|
16
16
|
- 'Jielga/TMDataGrid:src/docs/columns.md'
|
|
17
|
-
- 'Jielga/TMDataGrid:src/tmdatagrid/filterOperators.ts'
|
|
18
|
-
- 'Jielga/TMDataGrid:src/tmdatagrid/columnUtils.ts'
|
|
17
|
+
- 'Jielga/TMDataGrid:src/tmdatagrid/core/filterOperators.ts'
|
|
18
|
+
- 'Jielga/TMDataGrid:src/tmdatagrid/core/columnUtils.ts'
|
|
19
19
|
---
|
|
20
20
|
|
|
21
21
|
# TMDataGrid — Columns
|
|
@@ -105,10 +105,11 @@ A column whose menu has no remaining items renders no menu button.
|
|
|
105
105
|
|
|
106
106
|
## Checkbox column
|
|
107
107
|
|
|
108
|
-
Unless `enableRowSelection` is `false
|
|
109
|
-
is added as the first column and pinned to the
|
|
110
|
-
selection" in the column manager and can be
|
|
111
|
-
no column menu and cannot be sorted,
|
|
108
|
+
Unless `enableRowSelection` is `false` or `rowSelectionMode` is `"row"`, a column
|
|
109
|
+
with the id `SELECT_COLUMN_ID` is added as the first column and pinned to the
|
|
110
|
+
left. It is listed as "Checkbox selection" in the column manager and can be
|
|
111
|
+
hidden like any other column. It has no column menu and cannot be sorted,
|
|
112
|
+
filtered, resized, re-pinned or moved.
|
|
112
113
|
|
|
113
114
|
Because it cannot be moved, it also anchors the left pinned region: no column
|
|
114
115
|
can be placed in front of it.
|
package/skills/features/SKILL.md
CHANGED
|
@@ -4,20 +4,24 @@ description: >
|
|
|
4
4
|
Enable or disable TMDataGrid interface elements through standard TanStack
|
|
5
5
|
table and column options, and reuse the same checks in your own components.
|
|
6
6
|
Covers the enableSorting/enableColumnFilters/enableHiding/enableColumnPinning/
|
|
7
|
-
enableColumnResizing/enableColumnOrdering/enableRowSelection matrix,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
enableColumnResizing/enableColumnOrdering/enableRowSelection matrix, the
|
|
8
|
+
checkbox and row selection modes behind rowSelectionMode, the
|
|
9
|
+
highlightSelectedRows flag and the --dg-row-selected-bg colour, the
|
|
10
|
+
default-off enablePagination switch and its three modes (none, client,
|
|
11
|
+
manual), getGridCapabilities and getColumnCapabilities, why the features
|
|
12
|
+
argument is required for reactivity under the React Compiler, column pinning,
|
|
13
|
+
column ordering with moveColumn and moveColumnByStep, and always-on
|
|
14
|
+
virtualization. Load when building a read-only grid, hiding grid chrome,
|
|
15
|
+
enabling pagination, reordering columns from code, or writing a custom toolbar
|
|
16
|
+
button.
|
|
13
17
|
metadata:
|
|
14
18
|
type: core
|
|
15
19
|
library: '@jielga/tmdatagrid'
|
|
16
|
-
library_version: '0.
|
|
20
|
+
library_version: '0.3.0'
|
|
17
21
|
sources:
|
|
18
22
|
- 'Jielga/TMDataGrid:src/docs/features.md'
|
|
19
|
-
- 'Jielga/TMDataGrid:src/tmdatagrid/capabilities.ts'
|
|
20
|
-
- 'Jielga/TMDataGrid:src/tmdatagrid/columnOrdering.ts'
|
|
23
|
+
- 'Jielga/TMDataGrid:src/tmdatagrid/core/capabilities.ts'
|
|
24
|
+
- 'Jielga/TMDataGrid:src/tmdatagrid/core/columnOrdering.ts'
|
|
21
25
|
---
|
|
22
26
|
|
|
23
27
|
# TMDataGrid — Features and capabilities
|
|
@@ -26,10 +30,10 @@ Almost every control is bound to the TanStack capability check for that feature,
|
|
|
26
30
|
so setting the standard table or column option removes the corresponding
|
|
27
31
|
interface. Empty menus and inactive buttons are never rendered.
|
|
28
32
|
|
|
29
|
-
Column ordering
|
|
30
|
-
|
|
31
|
-
`
|
|
32
|
-
options around
|
|
33
|
+
Column ordering and pagination are the two exceptions. TanStack ships state and
|
|
34
|
+
APIs for both but no `enable` option, so the grid defines `enableColumnOrdering`
|
|
35
|
+
(with `meta.enableOrdering`) and `enablePagination` itself. Ordering behaves
|
|
36
|
+
like the options around it; pagination is the one switch that defaults to off.
|
|
33
37
|
|
|
34
38
|
## Option reference
|
|
35
39
|
|
|
@@ -46,6 +50,9 @@ options around them.
|
|
|
46
50
|
| `enableColumnOrdering: false` | Table | Header dragging and the move menu items |
|
|
47
51
|
| `meta.enableOrdering: false` | Column | That column's header dragging and move menu items |
|
|
48
52
|
| `enableRowSelection: false` | Table | The checkbox column |
|
|
53
|
+
| `rowSelectionMode: "row"` | Table | The checkbox column — the row itself selects instead. See Row selection |
|
|
54
|
+
| `highlightSelectedRows: false` | Table | The highlight background on selected rows. Follows the selection mode by default |
|
|
55
|
+
| `enablePagination: true` | Table | Opt-in: adds paging and the `Footer` pager. Off by default |
|
|
49
56
|
|
|
50
57
|
A column whose menu has no remaining items renders no menu button. Dividers are
|
|
51
58
|
never left at the end of a menu.
|
|
@@ -62,8 +69,76 @@ const grid = useTMDataGrid({
|
|
|
62
69
|
});
|
|
63
70
|
```
|
|
64
71
|
|
|
65
|
-
|
|
66
|
-
|
|
72
|
+
## Row selection
|
|
73
|
+
|
|
74
|
+
On by default, in two modes. Both write to the same `rowSelection` state, so
|
|
75
|
+
everything downstream — the toolbar count, `getSelectedRowModel()`, persistence
|
|
76
|
+
— is unaffected by the choice.
|
|
77
|
+
|
|
78
|
+
**Checkbox** — the default. A checkbox column is added as the first column, with
|
|
79
|
+
a select-all box in its header. Clicking a row elsewhere does not select it, and
|
|
80
|
+
a selected row is not highlighted: the checkbox already says so.
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
const grid = useTMDataGrid({ data, columns });
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Row** — no checkbox column. Clicking a row toggles it, and the row takes the
|
|
87
|
+
highlight background — the only feedback a click gives. Other rows keep their
|
|
88
|
+
state, so a click never clears the rest of the selection. Rows are focusable in
|
|
89
|
+
this mode and Space or Enter toggles the focused row.
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
const grid = useTMDataGrid({ data, columns, rowSelectionMode: "row" });
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`enableRowSelection: false` removes both, and `rowSelectionMode` is then
|
|
96
|
+
ignored. `TMDataGrid.Table`'s `onRowClick` still fires in either mode — under
|
|
97
|
+
`"row"` it runs in addition to the selection, not instead of it.
|
|
98
|
+
|
|
99
|
+
`highlightSelectedRows` follows the mode — on for `"row"`, off for
|
|
100
|
+
`"checkbox"` — and can be set to override either way. The colour is the
|
|
101
|
+
`--dg-row-selected-bg` CSS variable (default `--mantine-primary-color-light`);
|
|
102
|
+
change it on the grid element without touching the flag:
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
// Checkbox column, and selected rows are highlighted too.
|
|
106
|
+
const grid = useTMDataGrid({ data, columns, highlightSelectedRows: true });
|
|
107
|
+
|
|
108
|
+
<TMDataGrid
|
|
109
|
+
{...grid}
|
|
110
|
+
style={{ "--dg-row-selected-bg": "var(--mantine-color-blue-0)" }}
|
|
111
|
+
/>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Rows carry `data-selected` whenever selected and `data-highlighted` only when
|
|
115
|
+
also highlighted, so custom styling can key off either.
|
|
116
|
+
|
|
117
|
+
## Pagination
|
|
118
|
+
|
|
119
|
+
Off by default: the grid renders every filtered and sorted row and relies on
|
|
120
|
+
virtualization. Three modes:
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
// No pagination (default) — TMDataGrid.Footer renders nothing.
|
|
124
|
+
const grid = useTMDataGrid({ data, columns });
|
|
125
|
+
|
|
126
|
+
// Client pagination — pages locally, Footer renders its pager.
|
|
127
|
+
const grid = useTMDataGrid({ data, columns, enablePagination: true });
|
|
128
|
+
|
|
129
|
+
// Manual pagination — manualPagination implies enablePagination.
|
|
130
|
+
const grid = useTMDataGrid({
|
|
131
|
+
data: page.rows,
|
|
132
|
+
columns,
|
|
133
|
+
manualPagination: true,
|
|
134
|
+
rowCount: page.total,
|
|
135
|
+
state: { pagination },
|
|
136
|
+
onPaginationChange: setPagination,
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The built-in pager can be replaced with the Footer's `pagination` render prop
|
|
141
|
+
(see the `getting-started` skill) or built from scratch on the table API.
|
|
67
142
|
|
|
68
143
|
## Capability helpers
|
|
69
144
|
|
|
@@ -90,7 +165,8 @@ function ExportButton() {
|
|
|
90
165
|
| `canHideAny` | At least one leaf column can be hidden. |
|
|
91
166
|
| `canPinAny` | At least one leaf column can be pinned. |
|
|
92
167
|
| `canReorderAny` | At least one leaf column can be moved. |
|
|
93
|
-
| `canSelectRows` | `enableRowSelection` is not `false`. |
|
|
168
|
+
| `canSelectRows` | `enableRowSelection` is not `false`. The mode is in `features.rowSelectionMode`. |
|
|
169
|
+
| `canPaginate` | `enablePagination` or `manualPagination` is `true`. |
|
|
94
170
|
|
|
95
171
|
`getColumnCapabilities(column, features)` returns the same information for a
|
|
96
172
|
single column as `canSort`, `canFilter`, `canHide`, `canPin`, `canResize` and
|
|
@@ -207,6 +283,18 @@ table.setColumnOrder(["__select__", "department", "id", …]);
|
|
|
207
283
|
moveColumn({ table, columnId: "department", targetId: "id", side: "before" });
|
|
208
284
|
```
|
|
209
285
|
|
|
286
|
+
### Rendering the Footer without enabling pagination
|
|
287
|
+
|
|
288
|
+
```tsx
|
|
289
|
+
// Wrong — pagination defaults to off, so the Footer renders nothing.
|
|
290
|
+
const grid = useTMDataGrid({ data, columns });
|
|
291
|
+
<TMDataGrid.Footer />
|
|
292
|
+
|
|
293
|
+
// Right — opt in (manualPagination: true also counts).
|
|
294
|
+
const grid = useTMDataGrid({ data, columns, enablePagination: true });
|
|
295
|
+
<TMDataGrid.Footer />
|
|
296
|
+
```
|
|
297
|
+
|
|
210
298
|
### Expecting a table-level flag to override a column
|
|
211
299
|
|
|
212
300
|
Table and column options compose — the table flag gates the feature, and the
|
|
@@ -4,25 +4,26 @@ description: >
|
|
|
4
4
|
Set up TMDataGrid, a compound React data grid built on TanStack Table v9 and
|
|
5
5
|
Mantine. Covers useTMDataGrid, the TMDataGrid root, context, the component
|
|
6
6
|
catalog (Table, Footer, Toolbar, Spacer, SummaryCount, FilterButton,
|
|
7
|
-
ColumnsButton, FilterPanel, ColumnsPanel), the size scale and the
|
|
7
|
+
ColumnsButton, FilterPanel, FilterPills, ColumnsPanel), the size scale and the
|
|
8
8
|
bounded-height layout requirement. Load when adding a grid, choosing which
|
|
9
9
|
parts to render, or when rows do not appear.
|
|
10
10
|
metadata:
|
|
11
11
|
type: core
|
|
12
12
|
library: '@jielga/tmdatagrid'
|
|
13
|
-
library_version: '0.
|
|
13
|
+
library_version: '0.3.0'
|
|
14
14
|
sources:
|
|
15
15
|
- 'Jielga/TMDataGrid:src/docs/getting-started.md'
|
|
16
16
|
- 'Jielga/TMDataGrid:src/docs/components.md'
|
|
17
|
-
- 'Jielga/TMDataGrid:src/tmdatagrid/TMDataGrid.tsx'
|
|
18
|
-
- 'Jielga/TMDataGrid:src/tmdatagrid/sizes.ts'
|
|
17
|
+
- 'Jielga/TMDataGrid:src/tmdatagrid/components/TMDataGrid.tsx'
|
|
18
|
+
- 'Jielga/TMDataGrid:src/tmdatagrid/core/sizes.ts'
|
|
19
19
|
---
|
|
20
20
|
|
|
21
21
|
# TMDataGrid — Getting started
|
|
22
22
|
|
|
23
23
|
`useTMDataGrid` creates the table, `TMDataGrid` provides it through context, and
|
|
24
24
|
the parts rendered inside read what they need from that context. Only the parts
|
|
25
|
-
you render exist
|
|
25
|
+
you render exist, and only the features you enable have state: pagination is
|
|
26
|
+
opt-in via `enablePagination` — by default every row renders, virtualized.
|
|
26
27
|
|
|
27
28
|
## Install
|
|
28
29
|
|
|
@@ -69,6 +70,7 @@ export function Employees({ data }: { data: Employee[] }) {
|
|
|
69
70
|
data,
|
|
70
71
|
columns,
|
|
71
72
|
getRowId: (row) => String(row.id),
|
|
73
|
+
enablePagination: true,
|
|
72
74
|
});
|
|
73
75
|
|
|
74
76
|
return (
|
|
@@ -101,13 +103,14 @@ Spread the hook result (`{...grid}`) rather than assigning `table`, `ui` and
|
|
|
101
103
|
| Column menu | On hover: sort, filter, pin, move, hide, manage columns. |
|
|
102
104
|
| Filter panel | Column, operator and value rows. |
|
|
103
105
|
| Column manager | Search, toggle, show/hide all, reset. |
|
|
104
|
-
| Row selection | Checkbox column pinned to the left
|
|
105
|
-
| Pagination |
|
|
106
|
+
| Row selection | Checkbox column pinned to the left, or click-to-select rows with `rowSelectionMode: "row"`. |
|
|
107
|
+
| Pagination | Off by default: all rows render, virtualized. Opt in with `enablePagination: true`. |
|
|
106
108
|
| Sizing | `size="xs"` to `size="xl"` scales rows, type and controls. |
|
|
107
109
|
|
|
108
110
|
Each is bound to a capability check — disabling the standard table or column
|
|
109
|
-
option also removes its interface. Column ordering
|
|
110
|
-
|
|
111
|
+
option also removes its interface. Column ordering (`enableColumnOrdering`) and
|
|
112
|
+
pagination (`enablePagination`) are the two switches the grid defines itself.
|
|
113
|
+
See the `features` skill.
|
|
111
114
|
|
|
112
115
|
## Layout
|
|
113
116
|
|
|
@@ -120,21 +123,24 @@ takes a fixed pixel width once resized or pinned.
|
|
|
120
123
|
|
|
121
124
|
## Components
|
|
122
125
|
|
|
123
|
-
All read the grid from context and must be rendered inside `TMDataGrid
|
|
124
|
-
|
|
126
|
+
All read the grid from context and must be rendered inside `TMDataGrid`, except
|
|
127
|
+
`TMDataGrid.FilterPills`, which takes the grid as an `api` prop and can live
|
|
128
|
+
anywhere on the page. Order and presence are up to you — the root is a plain
|
|
129
|
+
flex column.
|
|
125
130
|
|
|
126
131
|
| Component | Props | Notes |
|
|
127
132
|
| --- | --- | --- |
|
|
128
|
-
| `TMDataGrid` | `table`, `ui`, `features`, `size`, `className`, `style` | Root. Provides context. |
|
|
129
|
-
| `TMDataGrid.Table` | `onRowClick(row)` | Header, virtualized body, filter panel. |
|
|
130
|
-
| `TMDataGrid.Footer` | `pageSizeOptions` (default `[10, 25, 50, 100]`) | Pagination controls. |
|
|
133
|
+
| `TMDataGrid` | `table`, `ui`, `features`, `size`, `className`, `style` | Root. Provides context. `style` also takes CSS variables: `--dg-row-selected-bg`, `--dg-row-height`, `--dg-header-height`, `--dg-font-size`, `--dg-padding`. |
|
|
134
|
+
| `TMDataGrid.Table` | `onRowClick(row)`, `rowContextMenu` render prop, `rowContextMenuProps` | Header, virtualized body, filter panel. `onRowClick` runs in addition to selection under `rowSelectionMode: "row"`. |
|
|
135
|
+
| `TMDataGrid.Footer` | `pageSizeOptions` (default `[10, 25, 50, 100]`), `pagination` render prop | Pagination controls. Renders nothing unless pagination is enabled. |
|
|
131
136
|
| `TMDataGrid.Toolbar` | `children` | Flex row above the grid. |
|
|
132
137
|
| `TMDataGrid.Spacer` | — | Pushes later toolbar items right. |
|
|
133
138
|
| `TMDataGrid.SummaryCount` | `children` | Visible rows out of total. |
|
|
134
139
|
| `TMDataGrid.FilterButton` | — | Toggles filter panel. Renders nothing if no column is filterable. |
|
|
135
140
|
| `TMDataGrid.ColumnsButton` | — | Opens column manager. Renders nothing if no column is hideable. |
|
|
136
|
-
| `TMDataGrid.FilterPanel` | — | Rendered by `.Table`; exported for custom layouts. |
|
|
141
|
+
| `TMDataGrid.FilterPanel` | — | Rendered by `.Table`; exported for custom layouts. Header close button, Escape, click-away, "Add filter" and "Clear all". |
|
|
137
142
|
| `TMDataGrid.ColumnsPanel` | — | Rendered by `.ColumnsButton`; exported for custom layouts. |
|
|
143
|
+
| `TMDataGrid.FilterPills` | `api`, `size` (default `"sm"`), `showClearAll` (default `true`), `onPillClick(columnId)`, `className` | One pill per active filter, ✕ to clear it. Takes the api as a prop, so it can be rendered outside the grid. Also exported as `TMDataGridFilterPills`. |
|
|
138
144
|
|
|
139
145
|
Pass the row type so `onRowClick` stays typed:
|
|
140
146
|
|
|
@@ -142,10 +148,61 @@ Pass the row type so `onRowClick` stays typed:
|
|
|
142
148
|
<TMDataGrid.Table<Employee> onRowClick={(row) => open(row.original.id)} />
|
|
143
149
|
```
|
|
144
150
|
|
|
151
|
+
`rowContextMenu` fills the dropdown of a Mantine `Menu` the grid opens at the
|
|
152
|
+
pointer on a right-click (or a long press). The grid owns the `Menu` — opening,
|
|
153
|
+
positioning, and closing on Escape, outside click, body scroll or an item pick —
|
|
154
|
+
so the render prop only says what goes in it:
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
<TMDataGrid.Table<Employee>
|
|
158
|
+
rowContextMenu={({ table, row, cell, close }) => (
|
|
159
|
+
<>
|
|
160
|
+
<Menu.Label>{row.original.firstName}</Menu.Label>
|
|
161
|
+
<Menu.Item onClick={() => open(row.original.id)}>Open</Menu.Item>
|
|
162
|
+
<Menu.Item
|
|
163
|
+
onClick={() =>
|
|
164
|
+
navigator.clipboard.writeText(String(cell?.getValue() ?? ""))
|
|
165
|
+
}
|
|
166
|
+
>
|
|
167
|
+
Copy cell value
|
|
168
|
+
</Menu.Item>
|
|
169
|
+
</>
|
|
170
|
+
)}
|
|
171
|
+
/>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
`cell` is the one that was right-clicked, `table` is there for actions that read
|
|
175
|
+
the selection, and `close` is for dropdown content that is not a `Menu.Item`
|
|
176
|
+
(those close themselves). Return `null` to leave a row without a menu. It is
|
|
177
|
+
called during render, and only for the open row, so it must stay pure — put the
|
|
178
|
+
work in the item handlers. Right-clicking does not change the selection or the
|
|
179
|
+
highlight; the row carries `data-context-menu` while its menu is open. Pass
|
|
180
|
+
`rowContextMenuProps` for `width`, `shadow`, `position` and the rest.
|
|
181
|
+
|
|
145
182
|
`TMDataGrid.Footer` reads totals from `table.getRowCount()`, which prefers
|
|
146
183
|
`options.rowCount`. `TMDataGrid.SummaryCount` uses `meta.totalRowCount` when
|
|
147
184
|
provided, otherwise the pre-filtered row count.
|
|
148
185
|
|
|
186
|
+
The Footer's `pagination` render prop replaces the built-in pager with your own
|
|
187
|
+
UI, fed by the distilled pagination API:
|
|
188
|
+
|
|
189
|
+
```tsx
|
|
190
|
+
<TMDataGrid.Footer
|
|
191
|
+
pagination={(api) => (
|
|
192
|
+
<Pagination
|
|
193
|
+
total={api.pageCount}
|
|
194
|
+
value={api.pageIndex + 1}
|
|
195
|
+
onChange={(page) => api.setPageIndex(page - 1)}
|
|
196
|
+
/>
|
|
197
|
+
)}
|
|
198
|
+
/>
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
`TMDataGridPaginationApi` carries `pageIndex`, `pageSize`, `pageCount`,
|
|
202
|
+
`rowCount`, `canPreviousPage`, `canNextPage` and the actions `setPageIndex`,
|
|
203
|
+
`setPageSize`, `previousPage`, `nextPage`, `firstPage`, `lastPage`. Outside the
|
|
204
|
+
Footer, `getTMDataGridPaginationApi(grid.table)` returns the same object.
|
|
205
|
+
|
|
149
206
|
## size
|
|
150
207
|
|
|
151
208
|
Standard Mantine scale. Controls row height, header height, font size and cell
|
|
@@ -171,6 +228,7 @@ mirrors them. Set `meta.rowHeight` for a height outside the scale.
|
|
|
171
228
|
| `openColumnFilter(api, columnId)` | Adds an empty filter for a column and opens the panel. |
|
|
172
229
|
| `getColumnLabel(column)` | `meta.label`, a string header, or the column id. |
|
|
173
230
|
| `getColumnType(column)` | `meta.type`, defaulting to `"string"`. |
|
|
231
|
+
| `formatFilterLabel({ label, type, filter })` | The one-line filter description used on the pills. |
|
|
174
232
|
| `moveColumn({ table, columnId, targetId, side })` | Moves a column next to another. See the `features` skill. |
|
|
175
233
|
| `moveColumnByStep({ table, columnId, direction })` | Moves a column one position within its region. |
|
|
176
234
|
| `SELECT_COLUMN_ID` | Id of the generated checkbox column. |
|
|
@@ -201,9 +259,9 @@ is no error.
|
|
|
201
259
|
`<TMDataGrid table={grid.table}>` omits `ui` and `features`. Panels stop opening
|
|
202
260
|
and feature toggles stop being reactive. Spread instead: `<TMDataGrid {...grid}>`.
|
|
203
261
|
|
|
204
|
-
### Expecting Footer to
|
|
262
|
+
### Expecting Footer to enable pagination
|
|
205
263
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
264
|
+
Rendering `TMDataGrid.Footer` does not switch pagination on — the option does.
|
|
265
|
+
With pagination off (the default) the Footer renders nothing and every row is
|
|
266
|
+
rendered, virtualized. Set `enablePagination: true` (or `manualPagination:
|
|
267
|
+
true` for server paging) to page the data and show the pager.
|
package/skills/options/SKILL.md
CHANGED
|
@@ -4,7 +4,8 @@ description: >
|
|
|
4
4
|
useTMDataGrid options, return value and state persistence. Covers passthrough
|
|
5
5
|
of TanStack TableOptions, the default initialState (pagination, columnPinning,
|
|
6
6
|
globalFilterFn), the meta object (loading, noResultsLabel, rowHeight,
|
|
7
|
-
totalRowCount), the grid's own persist
|
|
7
|
+
totalRowCount), the grid's own persist, enableColumnOrdering,
|
|
8
|
+
enablePagination, rowSelectionMode and highlightSelectedRows options, the
|
|
8
9
|
persist option with dataKey/settingsKey slice selection and storageMode, the
|
|
9
10
|
returned table/ui/features triple, ui panel and column drag actions, and
|
|
10
11
|
reading grid state with useSelector. Load when configuring the hook,
|
|
@@ -12,11 +13,11 @@ description: >
|
|
|
12
13
|
metadata:
|
|
13
14
|
type: core
|
|
14
15
|
library: '@jielga/tmdatagrid'
|
|
15
|
-
library_version: '0.
|
|
16
|
+
library_version: '0.3.0'
|
|
16
17
|
sources:
|
|
17
18
|
- 'Jielga/TMDataGrid:src/docs/use-tm-data-grid.md'
|
|
18
19
|
- 'Jielga/TMDataGrid:src/tmdatagrid/useTMDataGrid.tsx'
|
|
19
|
-
- 'Jielga/TMDataGrid:src/tmdatagrid/persistence.ts'
|
|
20
|
+
- 'Jielga/TMDataGrid:src/tmdatagrid/core/persistence.ts'
|
|
20
21
|
---
|
|
21
22
|
|
|
22
23
|
# TMDataGrid — useTMDataGrid
|
|
@@ -37,21 +38,25 @@ All TanStack `TableOptions` are supported and passed through unchanged, includin
|
|
|
37
38
|
flags and `rowCount`. The `features` option is supplied internally and cannot be
|
|
38
39
|
overridden.
|
|
39
40
|
|
|
40
|
-
`persist`
|
|
41
|
-
|
|
41
|
+
`persist`, `enableColumnOrdering`, `enablePagination`, `rowSelectionMode` and
|
|
42
|
+
`highlightSelectedRows` are the grid's own options and are consumed by the hook
|
|
43
|
+
rather than forwarded to TanStack.
|
|
42
44
|
|
|
43
45
|
| Option | Type | Default | Description |
|
|
44
46
|
| --- | --- | --- | --- |
|
|
45
47
|
| `data` | `TData[]` | – | Row data. Keep the reference stable with `useMemo`. |
|
|
46
48
|
| `columns` | `ColumnDef[]` | – | Created with `createTMDataGridColumnHelper`. |
|
|
47
49
|
| `getRowId` | `(row, index) => string` | Row index | Used by row selection and virtualization. |
|
|
48
|
-
| `enableRowSelection` | `boolean \| (row) => boolean` | `true` | `false` removes
|
|
50
|
+
| `enableRowSelection` | `boolean \| (row) => boolean` | `true` | `false` removes row selection and its checkbox column. |
|
|
51
|
+
| `rowSelectionMode` | `"checkbox" \| "row"` | `"checkbox"` | `"row"` drops the checkbox column and selects on row click. Defined by the grid. |
|
|
52
|
+
| `highlightSelectedRows` | `boolean` | Follows the mode | Highlight background on selected rows: off for `"checkbox"`, on for `"row"`. Colour is the `--dg-row-selected-bg` CSS variable. Defined by the grid. |
|
|
49
53
|
| `enableSorting` | `boolean` | `true` | Enables sorting for the table. |
|
|
50
54
|
| `enableColumnFilters` | `boolean` | `true` | Enables filtering for the table. |
|
|
51
55
|
| `enableHiding` | `boolean` | `true` | Enables column visibility for the table. |
|
|
52
56
|
| `enableColumnPinning` | `boolean` | `true` | Enables pinning for the table. |
|
|
53
57
|
| `enableColumnResizing` | `boolean` | `true` | Enables resizing for the table. |
|
|
54
58
|
| `enableColumnOrdering` | `boolean` | `true` | Enables header dragging and the move menu items. Defined by the grid. |
|
|
59
|
+
| `enablePagination` | `boolean` | `false` | Enables client-side paging and the `Footer` pager. Implied by `manualPagination`. Defined by the grid. |
|
|
55
60
|
| `columnResizeMode` | `"onChange" \| "onEnd"` | `"onChange"` | Resize update strategy. |
|
|
56
61
|
| `initialState` | `Partial<TableState>` | See below | Merged over the grid defaults. |
|
|
57
62
|
| `meta` | `TMDataGridTableMeta` | `{}` | Grid configuration, see below. |
|
|
@@ -61,7 +66,7 @@ by the hook rather than forwarded to TanStack.
|
|
|
61
66
|
|
|
62
67
|
| Slice | Default |
|
|
63
68
|
| --- | --- |
|
|
64
|
-
| `pagination` | `{ pageIndex: 0, pageSize: 25 }` |
|
|
69
|
+
| `pagination` | `{ pageIndex: 0, pageSize: 25 }` — inert until pagination is enabled |
|
|
65
70
|
| `columnPinning.left` | The checkbox column, followed by any columns you provide |
|
|
66
71
|
| `globalFilterFn` | `"includesString"` |
|
|
67
72
|
|
|
@@ -10,7 +10,7 @@ description: >
|
|
|
10
10
|
metadata:
|
|
11
11
|
type: core
|
|
12
12
|
library: '@jielga/tmdatagrid'
|
|
13
|
-
library_version: '0.
|
|
13
|
+
library_version: '0.3.0'
|
|
14
14
|
sources:
|
|
15
15
|
- 'Jielga/TMDataGrid:src/docs/server-side.md'
|
|
16
16
|
- 'Jielga/TMDataGrid:src/tmdatagrid/useTMDataGrid.tsx'
|
|
@@ -21,7 +21,10 @@ sources:
|
|
|
21
21
|
The grid reads rows through `getPaginatedRowModel()` and totals through
|
|
22
22
|
`getRowCount()` and `getPageCount()`, all of which respect TanStack's manual
|
|
23
23
|
modes. A server-driven grid therefore needs only the standard `manual*`
|
|
24
|
-
configuration — no grid-specific options.
|
|
24
|
+
configuration — no grid-specific options. `manualPagination: true` also
|
|
25
|
+
switches the grid's pagination flag on, so `TMDataGrid.Footer` renders its
|
|
26
|
+
pager without `enablePagination`. Declare `pageCount: -1` when the total is
|
|
27
|
+
unknown; the next button then stays enabled.
|
|
25
28
|
|
|
26
29
|
## Setup
|
|
27
30
|
|