@opencorestack/opengridx 2.1.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/CHANGELOG.md +363 -0
  2. package/README.md +93 -72
  3. package/dist/index.d.ts +573 -124
  4. package/dist/opengridx.css +1 -1
  5. package/dist/opengridx.es.js +7890 -5636
  6. package/dist/opengridx.es.js.map +1 -1
  7. package/dist/opengridx.umd.js +17 -23
  8. package/dist/opengridx.umd.js.map +1 -1
  9. package/docs/API_REFERENCE.md +341 -163
  10. package/docs/README.md +6 -1
  11. package/docs/architecture/datagrid-orchestration.md +81 -0
  12. package/docs/architecture/grid-row-meta.md +102 -0
  13. package/docs/architecture/use-grid-columns.md +128 -0
  14. package/docs/architecture/use-grid-controlled-state.md +157 -0
  15. package/docs/architecture/use-grid-row-pipeline.md +120 -0
  16. package/docs/architecture/use-grid-scroll-sync.md +111 -0
  17. package/docs/architecture/use-grid-state-snapshot.md +90 -0
  18. package/docs/architecture/use-grid-virtualization.md +115 -0
  19. package/docs/architecture/use-grid-visible-rows.md +85 -0
  20. package/docs/assets/banner-alt.png +0 -0
  21. package/docs/assets/banner.png +0 -0
  22. package/docs/assets/hero.png +0 -0
  23. package/docs/assets/logo.png +0 -0
  24. package/docs/components/aggregation-footer.md +15 -10
  25. package/docs/components/cell.md +16 -6
  26. package/docs/components/column-group-header.md +55 -28
  27. package/docs/components/column-resize.md +17 -13
  28. package/docs/components/column-visibility.md +6 -7
  29. package/docs/components/datagrid.md +14 -12
  30. package/docs/components/empty-state.md +2 -1
  31. package/docs/components/error-overlay.md +12 -7
  32. package/docs/components/filter-panel.md +28 -8
  33. package/docs/components/header.md +28 -9
  34. package/docs/components/pagination.md +14 -8
  35. package/docs/components/row.md +21 -5
  36. package/docs/components/toolbar.md +27 -9
  37. package/docs/components/tooltip.md +16 -7
  38. package/docs/customization/slots-api.md +90 -38
  39. package/docs/customization/theming.md +66 -18
  40. package/docs/features/aggregation-pivot.md +75 -9
  41. package/docs/features/cell-spanning.md +80 -125
  42. package/docs/features/clipboard.md +41 -16
  43. package/docs/features/custom-pagination.md +38 -18
  44. package/docs/features/data-source.md +36 -13
  45. package/docs/features/editing-reordering.md +125 -16
  46. package/docs/features/export-guide.md +126 -39
  47. package/docs/features/filtering.md +44 -6
  48. package/docs/features/infinite-scroll.md +54 -46
  49. package/docs/features/keyboard-navigation.md +83 -0
  50. package/docs/features/list-view.md +58 -5
  51. package/docs/features/loading-states.md +18 -20
  52. package/docs/features/master-detail.md +18 -5
  53. package/docs/features/pdf-export.md +56 -19
  54. package/docs/features/pinning.md +23 -5
  55. package/docs/features/selection.md +50 -10
  56. package/docs/features/sorting-pagination.md +64 -14
  57. package/docs/features/state-persistence.md +78 -10
  58. package/docs/features/toolbar-customization.md +26 -17
  59. package/docs/features/tree-data-grouping.md +36 -8
  60. package/docs/features/virtualization.md +28 -7
  61. package/docs/migration/v1-to-v2.md +115 -0
  62. package/docs/migration/v2-to-v3.md +1222 -0
  63. package/docs/performance.md +124 -0
  64. package/docs/roadmap.md +4 -4
  65. package/lib/components/Cell/Cell.css +13 -1
  66. package/lib/components/Cell/Cell.tsx +129 -57
  67. package/lib/components/Cell/CellErrorBoundary.tsx +12 -6
  68. package/lib/components/Cell/GridEditInputCell.tsx +114 -41
  69. package/lib/components/ColumnGroupHeader/ColumnGroupHeader.css +7 -1
  70. package/lib/components/ColumnResizeHandle/ColumnResizeHandle.css +11 -0
  71. package/lib/components/ColumnResizeHandle/ColumnResizeHandle.tsx +104 -38
  72. package/lib/components/ColumnResizeHandle/clampResizeWidth.ts +13 -0
  73. package/lib/components/ColumnVisibilityPanel/ColumnVisibilityPanel.css +6 -0
  74. package/lib/components/ColumnVisibilityPanel/ColumnVisibilityPanel.tsx +21 -13
  75. package/lib/components/DataGrid/DataGrid.css +77 -12
  76. package/lib/components/DataGrid/DataGrid.tsx +576 -874
  77. package/lib/components/DataGrid/GridAggregationFooter.tsx +53 -17
  78. package/lib/components/DataGrid/GridErrorOverlay.tsx +15 -12
  79. package/lib/components/DataGrid/GridListView.tsx +164 -24
  80. package/lib/components/DataGrid/GridLiveRegion.tsx +31 -0
  81. package/lib/components/DataGrid/GridLoadingOverlay.tsx +27 -0
  82. package/lib/components/DataGrid/GridPaginationArea.tsx +44 -0
  83. package/lib/components/DataGrid/GridPinnedRows.tsx +62 -11
  84. package/lib/components/DataGrid/GridStandaloneColumnPanel.tsx +40 -38
  85. package/lib/components/DataGrid/GridToolbarSlot.tsx +51 -0
  86. package/lib/components/DataGrid/GridVirtualRows.tsx +40 -24
  87. package/lib/components/DetailPanel/DetailPanel.css +0 -6
  88. package/lib/components/DetailPanel/DetailPanel.tsx +34 -5
  89. package/lib/components/DetailPanel/DetailPanelContent.tsx +17 -0
  90. package/lib/components/FilterPanel/FilterPanel.css +13 -2
  91. package/lib/components/FilterPanel/FilterPanel.tsx +272 -99
  92. package/lib/components/Header/ColumnMenu.tsx +91 -39
  93. package/lib/components/Header/Header.css +3 -3
  94. package/lib/components/Header/Header.tsx +179 -160
  95. package/lib/components/ListView/ListView.css +25 -0
  96. package/lib/components/ListView/ListViewRow.tsx +76 -10
  97. package/lib/components/Pagination/Pagination.tsx +15 -7
  98. package/lib/components/Row/Row.tsx +177 -77
  99. package/lib/components/Toolbar/GlobalSearch.css +6 -3
  100. package/lib/components/Toolbar/GlobalSearch.tsx +26 -27
  101. package/lib/components/Toolbar/GridToolbar.css +12 -11
  102. package/lib/components/Toolbar/GridToolbar.tsx +133 -89
  103. package/lib/components/Toolbar/PivotPanel.tsx +89 -49
  104. package/lib/components/Tooltip/Tooltip.css +20 -0
  105. package/lib/components/Tooltip/Tooltip.tsx +68 -35
  106. package/lib/components/ui/Button.tsx +3 -0
  107. package/lib/components/ui/Checkbox.tsx +2 -1
  108. package/lib/components/ui/ExpandIcon.css +0 -9
  109. package/lib/components/ui/ExpandIcon.tsx +4 -1
  110. package/lib/hooks/core/gridApiPlaceholder.ts +34 -0
  111. package/lib/hooks/core/gridToolbarHostContext.ts +14 -0
  112. package/lib/hooks/core/useDataGrid.ts +115 -173
  113. package/lib/hooks/core/useGridAggregationApi.ts +72 -0
  114. package/lib/hooks/core/useGridApiMethods.ts +115 -0
  115. package/lib/hooks/core/useGridApiRef.ts +15 -3
  116. package/lib/hooks/core/useGridApiRefBinding.ts +18 -0
  117. package/lib/hooks/core/useGridAriaRows.ts +38 -0
  118. package/lib/hooks/core/useGridClipboardApi.ts +38 -0
  119. package/lib/hooks/core/useGridColumnLookup.ts +30 -0
  120. package/lib/hooks/core/useGridColumns.tsx +279 -76
  121. package/lib/hooks/core/useGridColumnsPanel.ts +77 -0
  122. package/lib/hooks/core/useGridControlledState.ts +99 -6
  123. package/lib/hooks/core/useGridDetailPanel.ts +51 -0
  124. package/lib/hooks/core/useGridDevWarnings.ts +82 -1
  125. package/lib/hooks/core/useGridFocusHandlers.ts +50 -0
  126. package/lib/hooks/core/useGridGroupingColumn.ts +62 -0
  127. package/lib/hooks/core/useGridHeaderHandlers.ts +92 -0
  128. package/lib/hooks/core/useGridHierarchy.ts +81 -0
  129. package/lib/hooks/core/useGridKeyboardNavigation.ts +447 -243
  130. package/lib/hooks/core/useGridLiveRowSelection.ts +67 -0
  131. package/lib/hooks/core/useGridPageCorrection.ts +55 -0
  132. package/lib/hooks/core/useGridRowIdOf.ts +32 -0
  133. package/lib/hooks/core/useGridRowInteractions.ts +81 -0
  134. package/lib/hooks/core/useGridRowPipeline.ts +69 -39
  135. package/lib/hooks/core/useGridRowSelection.ts +91 -0
  136. package/lib/hooks/core/useGridScrollSync.ts +80 -32
  137. package/lib/hooks/core/useGridScrollToIndexesApi.ts +45 -0
  138. package/lib/hooks/core/useGridStateSnapshot.ts +40 -5
  139. package/lib/hooks/core/useGridThemeDimensions.ts +49 -0
  140. package/lib/hooks/core/useGridToolbarProps.ts +97 -0
  141. package/lib/hooks/core/useGridViewport.ts +38 -0
  142. package/lib/hooks/core/useGridViewportSize.ts +26 -0
  143. package/lib/hooks/core/useGridVisibleRows.ts +17 -5
  144. package/lib/hooks/core/useLayout.ts +215 -195
  145. package/lib/hooks/core/useRowsScrollEndLatch.ts +41 -0
  146. package/lib/hooks/core/useStableColumns.ts +34 -0
  147. package/lib/hooks/features/useAggregation.ts +82 -51
  148. package/lib/hooks/features/useColumnGroupReorderGuard.ts +34 -0
  149. package/lib/hooks/features/useDetailPanelHeights.ts +29 -0
  150. package/lib/hooks/features/useGridClipboard.ts +133 -73
  151. package/lib/hooks/features/useGridDataSource.ts +354 -128
  152. package/lib/hooks/features/useGridEditing.ts +211 -51
  153. package/lib/hooks/features/useGridPivot.ts +92 -0
  154. package/lib/hooks/features/useGridSpanRenderWindow.ts +104 -0
  155. package/lib/hooks/features/useGridSpanning.ts +410 -306
  156. package/lib/hooks/features/usePivot.ts +0 -0
  157. package/lib/hooks/features/useServerTreeChildren.ts +50 -0
  158. package/lib/hooks/useColumnReorder.ts +38 -44
  159. package/lib/hooks/useRowGrouping.ts +298 -160
  160. package/lib/hooks/useRowReorder.ts +62 -31
  161. package/lib/hooks/useTreeData.ts +287 -220
  162. package/lib/index.ts +28 -2
  163. package/lib/state/index.ts +1 -0
  164. package/lib/state/types.ts +7 -1
  165. package/lib/state/useGridStateStorage.ts +88 -29
  166. package/lib/theme/DataGridThemeProvider.tsx +143 -38
  167. package/lib/theme/gridThemeContext.ts +5 -0
  168. package/lib/theme/index.ts +5 -0
  169. package/lib/theme/presets.ts +5 -4
  170. package/lib/theme/types.ts +40 -2
  171. package/lib/types/index.ts +299 -109
  172. package/lib/utils/aggregation/index.ts +119 -24
  173. package/lib/utils/aria/index.ts +40 -0
  174. package/lib/utils/columnGroups.ts +110 -0
  175. package/lib/utils/columnLookup.ts +33 -0
  176. package/lib/utils/columnWidth.ts +22 -0
  177. package/lib/utils/dataSource/index.ts +46 -0
  178. package/lib/utils/detailPanel.ts +66 -0
  179. package/lib/utils/dragData.ts +44 -0
  180. package/lib/utils/editing/index.ts +30 -0
  181. package/lib/utils/export/exportShared.ts +197 -0
  182. package/lib/utils/export/exportToExcelAdvanced.ts +278 -139
  183. package/lib/utils/export/exportToPdf.ts +143 -92
  184. package/lib/utils/export/groupLabel.ts +14 -0
  185. package/lib/utils/export/index.ts +278 -272
  186. package/lib/utils/export/pdfText.ts +50 -0
  187. package/lib/utils/filtering/index.ts +277 -148
  188. package/lib/utils/focus/index.ts +115 -0
  189. package/lib/utils/gridApiRows.ts +35 -0
  190. package/lib/utils/gridModes.ts +77 -0
  191. package/lib/utils/grouping/groupedExportRows.ts +91 -0
  192. package/lib/utils/pagination/index.ts +56 -0
  193. package/lib/utils/pinning/index.ts +77 -33
  194. package/lib/utils/pivot/index.ts +368 -0
  195. package/lib/utils/scroll/index.ts +55 -5
  196. package/lib/utils/scroll/scrollEnd.ts +18 -0
  197. package/lib/utils/sorting/index.ts +154 -30
  198. package/lib/utils/syntheticRows.ts +12 -0
  199. package/lib/utils/values.ts +206 -0
  200. package/lib/utils/viewport.ts +14 -0
  201. package/llms.txt +260 -163
  202. package/package.json +13 -5
  203. package/lib/components/ColumnGroupHeader/ColumnGroupHeader.tsx +0 -220
  204. package/lib/components/ColumnVisibilityPanel/ColumnVisibilityPanel.test.tsx +0 -85
  205. package/lib/components/DataGrid/DataGrid.defects.test.tsx +0 -103
  206. package/lib/components/DataGrid/DataGrid.regression.test.tsx +0 -132
  207. package/lib/components/DataGrid/DataGrid.smoke.test.tsx +0 -58
  208. package/lib/components/DataGrid/DataGrid.v2.test.tsx +0 -127
  209. package/lib/components/DataGrid/DataGrid.virtualization.browser.test.tsx +0 -183
  210. package/lib/components/Header/Header.test.tsx +0 -135
  211. package/lib/components/Pagination/Pagination.test.tsx +0 -64
  212. package/lib/hooks/core/useDataGrid.regression.test.ts +0 -66
  213. package/lib/hooks/core/useGridControlledState.test.ts +0 -86
  214. package/lib/hooks/core/useGridKeyboardNavigation.test.ts +0 -176
  215. package/lib/hooks/core/useGridRowPipeline.test.ts +0 -117
  216. package/lib/hooks/features/useAggregation.test.ts +0 -175
  217. package/lib/hooks/features/usePivot.test.ts +0 -202
  218. package/lib/hooks/useRowGrouping.test.ts +0 -298
  219. package/lib/hooks/useTreeData.test.ts +0 -83
  220. package/lib/utils/aggregation/aggregation.test.ts +0 -16
  221. package/lib/utils/export/exportToExcelAdvanced.test.ts +0 -109
  222. package/lib/utils/export/exportToPdf.test.ts +0 -120
  223. package/lib/utils/export/groupedExport.test.ts +0 -144
  224. package/lib/utils/filtering/filtering.test.ts +0 -178
  225. package/lib/utils/sorting/sorting.test.ts +0 -88
@@ -12,6 +12,7 @@ Row grouping allows you to categorize rows based on common column values.
12
12
  ```tsx
13
13
  <DataGrid
14
14
  rows={rows}
15
+ columns={columns}
15
16
  rowGroupingModel={['department', 'role']}
16
17
  />
17
18
  ```
@@ -19,14 +20,24 @@ Row grouping allows you to categorize rows based on common column values.
19
20
  ### Features
20
21
  - **Multi-Level Groups**: Nest data as deeply as needed — one level per field in `rowGroupingModel`, in order.
21
22
  - **Aggregation Integration**: Summarize values automatically for each group level.
22
- - **Expansion Control**: Control which groups are expanded by default.
23
+ - **Expansion Control**: `defaultGroupingExpansionDepth` sets how many levels start expanded (default `0`: all collapsed; `-1`: everything expanded).
24
+ - **Aggregate placement**: `getAggregationPosition(node)` returns `'inline'` (on the group row, the default), `'footer'` (a subtotal row after the group's children while it is expanded) or `null` (hidden). It is also called once with `null` for the grand-total footer row; returning `null` there hides the footer.
23
25
 
24
26
  ### Behaviour to know about
25
27
 
26
28
  - **Pagination is ignored** while `rowGroupingModel` is active. All groups render in one scrollable, virtualized view, so the grid needs a bounded height ([Virtualization](./virtualization.md#the-grid-needs-a-bounded-height)). A development-mode warning is logged if you pass `pagination` too.
27
29
  - **Expansion state survives data updates** (row grouping and tree data). Groups and nodes the user expanded or collapsed stay that way when `rows` changes: inline edits, live refreshes, new array identities, and lazily loaded server-side children. The state resets to `defaultGroupingExpansionDepth` only when `rowGroupingModel` or `defaultGroupingExpansionDepth` changes value.
28
30
  - **Group aggregation uses the same functions as the footer.** `sum`, `avg`, `count`, `min`, `max` and `unique` ignore `null`/`undefined`, so a group of `[10, null, 20]` gives `min` 10, `avg` 15 and `count` 2. `availableAggregationFunctions` on a column is honoured for group rows too.
31
+ - **The expand toggle, indentation and group label sit in the leftmost column on screen**, after column order, visibility and pinning are applied — not in whichever column is first in `columns`. Hiding or moving that column no longer leaves group rows without a label or toggle (fixed in v3.0).
32
+ - **Keyboard and screen readers** (v3.0): **Enter** on a non-editable cell of a group row or a tree-data parent expands or collapses it, and **Alt+ArrowRight** / **Alt+ArrowLeft** expand / collapse it. Rows expose `aria-level` (depth + 1), and rows with children expose `aria-expanded`. The expand buttons inside cells are not separate Tab stops. See [Keyboard & Accessibility](keyboard-navigation.md).
29
33
  - **`valueFormatter` applies to grouped rows** the same as flat rows (fixed in v2.1; earlier versions rendered raw values for every column once grouping was on).
34
+ - **Group subtotals and the `(n)` count follow the filter.** They cover only the leaf rows that pass the current filter, and groups with no matching row are left out (v3.0; before, they counted hidden rows too). Groups keep their order of first appearance while filtering.
35
+ - **Grouping values are compared by value, not by text**: `null` and `'null'`, `1` and `'1'`, `true` and `'true'` are separate groups; equal dates share one. A column with a `valueGetter` is grouped by the value it computes.
36
+ - **`groupable: false`** fields are dropped from the model before grouping, so the other levels keep their depth, indentation, `defaultGroupingExpansionDepth` and export depth.
37
+ - **Sorting the column that shows the group labels orders the groups by their grouping value**; sorting an aggregated column orders them by the aggregate.
38
+ - **Group rows are synthetic.** They have no selection checkbox and no detail panel, their ids never appear in the selection model, clicking them toggles them (without `onRowClick`), and a column's `valueGetter` is not called for them. `renderCell` *is* called for them: see [GridRowMeta](../architecture/grid-row-meta.md#accessing-metadata-in-rendercell).
39
+ - **Server modes**: with `filterMode="server"` / `sortingMode="server"` the grid does not filter or sort the rows again on the client, in row grouping and tree data as in a flat grid.
40
+ - **Pass stable callbacks.** `rowGroupingModel` and `aggregationModel` are compared by value, so inline arrays and objects are fine, but a new `getTreeDataPath` or `columns` identity on every render rebuilds the whole hierarchy. Define them at module scope or memoize them.
30
41
 
31
42
  ---
32
43
 
@@ -36,15 +47,29 @@ Tree data is used for data that has a natural parent-child relationship (e.g., a
36
47
 
37
48
  ### Implementation
38
49
  1. Enable `treeData={true}`.
39
- 2. Provide a `getTreeDataPath` function to define the hierarchy.
50
+ 2. Provide a `getTreeDataPath` function to define the hierarchy. It is required: without it the rows are shown flat. Define it at module scope or with `useCallback`.
40
51
 
41
52
  ```tsx
42
53
  <DataGrid
54
+ rows={rows}
55
+ columns={columns}
43
56
  treeData
44
- getTreeDataPath={(row) => row.hierarchyPath} // e.g. ['CEO', 'VP Engineering', 'Manager']
57
+ getTreeDataPath={getPath} // e.g. (row) => row.hierarchyPath: ['CEO', 'VP Engineering', 'Manager']
45
58
  />
46
59
  ```
47
60
 
61
+ ### Behaviour to know about
62
+
63
+ - **Path segments can contain any character**, including `/`: `['a/b']` and `['a', 'b']` are different paths.
64
+ - **Missing parents are created for you.** A path segment with no row of its own gets a synthetic parent row (`rowMeta.isGroupRow`, label in `rowMeta.groupLabel`, row object `{ id }`) shown in the toggle column as `label (n)`, whatever that column is called. It is shown only when a row under it passes the filter, and sorting the toggle column orders it by its label.
65
+ - **Parents that are your own rows behave like any row**: clicking one fires `onRowClick` and selects it; its chevron expands it. (Before v3.0 a click toggled it and never fired `onRowClick`.) From the keyboard it expands with Enter or Alt+ArrowRight (see below) and **Shift+Space** selects it.
66
+ - **`descendantCount`** (the `(n)`) counts the rows below a node at any depth that pass the filter. A parent whose children are all filtered out is shown without a toggle.
67
+ - **Invalid paths are reported in development**: a row whose path is empty is shown as a top-level row, rows sharing a path attach their children to the first of them, and `treeData` without `getTreeDataPath` shows the rows flat. Each logs a `console.warn`.
68
+ - **Pagination** pages the flattened visible tree; keyboard navigation stays on the current page.
69
+ - **Lazy (server) trees**: the children of an expanded node with `serverChildrenCount` are fetched when it is expanded, and fetched again after a server re-fetch (a sort or filter change) replaces the rows. `defaultGroupingExpansionDepth` counts such a node as expandable (v3.0+), so `-1` expands every lazy node and loads its children.
70
+ - **`apiRef.getAllFilteredRows()` with a filter** returns the rows that match the filter, the same set select-all and the aggregation footer use. Ancestors shown only to give a match its context are not in it (v3.0+; before, they were).
71
+ - **Row grouping with `paginationMode="server"`**: grouping turns pagination off, so a `dataSource` is asked for every row (see [Data Source](data-source.md#2-server-side-pagination)).
72
+
48
73
  ---
49
74
 
50
75
  ## ⚙️ API Reference
@@ -54,15 +79,18 @@ Tree data is used for data that has a natural parent-child relationship (e.g., a
54
79
  | :--- | :--- | :--- | :--- |
55
80
  | `rowGroupingModel` | `string[]` | `[]` | Fields to group by (in order). |
56
81
  | `treeData` | `boolean` | `false` | Enable tree data mode. |
57
- | `getTreeDataPath` | `(row) => string[]` | `undefined` | Function to get the path for a row. |
58
- | `defaultGroupingExpansionDepth` | `number` | `0` | How many levels to expand on load. |
59
- | `groupingColDef` | `GridColDef` | `undefined` | Custom configuration for the generated group column. |
82
+ | `getTreeDataPath` | `(row) => string[]` | `undefined` | Path of a row. Required with `treeData`. |
83
+ | `defaultGroupingExpansionDepth` | `number` | `0` | How many levels start expanded (`0` = collapsed, `-1` = all). |
84
+ | `groupingColDef` | `Partial<GridColDef<R>>` | `undefined` | Adds a dedicated group column (row grouping or tree data). |
85
+ | `getAggregationPosition` | `(node: GridTreeNode \| null) => 'inline' \| 'footer' \| null` | `undefined` | Where group aggregates appear; called with `null` for the grand total. |
86
+
87
+ Hierarchy information is never written onto your row objects: read it from `params.rowMeta` (`isGroupRow`, `hasChildren`, `treeDepth`, `groupLabel`, …) in `renderCell`. See [GridRowMeta](../architecture/grid-row-meta.md).
60
88
 
61
89
  ---
62
90
 
63
91
  ## 🎨 Customizing the Group Column
64
92
 
65
- When `rowGroupingModel` is active, pass `groupingColDef` to configure a dedicated `__group__` column that is prepended at position 0 and auto-pinned left, separate from your data columns. It accepts any `GridColDef` fields except `field` (always `'__group__'`).
93
+ When `rowGroupingModel` or `treeData` is active, pass `groupingColDef` to configure a dedicated `__group__` column that is prepended at position 0 and auto-pinned left, separate from your data columns. Its type is `Partial<GridColDef<R>>`: every key is optional, and a `field` you pass is ignored (it is always `'__group__'`). It also forces `hideable`, `sortable`, `filterable`, `pinnable` and `exportable` to `false`. Defaults: `headerName: 'Group'`, `width: 220`. With tree data (v3.0) the column shows the last segment of each row's path, and a `valueGetter` in `groupingColDef` can show something else (for example the whole path).
66
94
 
67
95
  ```tsx
68
96
  <DataGrid
@@ -76,7 +104,7 @@ When `rowGroupingModel` is active, pass `groupingColDef` to configure a dedicate
76
104
  />
77
105
  ```
78
106
 
79
- Without `groupingColDef`, the group toggle is overlaid on the first data column. With it, the group indicator always appears in its own fixed column regardless of your `columns` order.
107
+ Without `groupingColDef`, the group toggle is overlaid on the leftmost column on screen. With it, the group indicator always appears in its own fixed column regardless of your `columns` order. A `renderCell` in `groupingColDef` renders the group rows' label cell (return `undefined` to keep the default label).
80
108
 
81
109
  ---
82
110
 
@@ -17,7 +17,7 @@ Virtualization is a technique that dramatically improves performance when workin
17
17
  The grid calculates which rows are visible based on:
18
18
  - Current scroll position
19
19
  - Viewport height
20
- - Row height (fixed or variable)
20
+ - Row height (the fixed `rowHeight`, plus the height of any expanded detail panels)
21
21
  - Overscan buffer (adaptive, minimum `overscanRowCount`, default 3 rows)
22
22
 
23
23
  ```tsx
@@ -33,12 +33,22 @@ The grid calculates which rows are visible based on:
33
33
  - ✅ Renders ~15-25 rows regardless of total dataset size
34
34
  - ✅ Constant memory usage
35
35
  - ✅ Smooth 60fps scrolling
36
- - ✅ Supports millions of rows
36
+ - ⚠️ Not millions of rows. Browsers cap an element's height (33,554,432px in Chromium, about 17.9M px in Firefox) and the grid does no scroll scaling: it lays every row out at its real height, so rows past the cap cannot be scrolled to. The limit is roughly `33,554,432 / rowHeight` rows in Chromium (about 645,000 at the default 52px), and about half that in Firefox (about 340,000). Beyond that, use pagination, or server-side paging / infinite scroll. In development the grid warns when the content passes 17.8M px.
37
37
 
38
38
  ### Column Virtualization
39
39
 
40
40
  Unpinned columns are virtualized horizontally: only the columns in view plus 6 on each side are rendered, with spacer cells standing in for the rest. Pinned columns are always rendered.
41
41
 
42
+ ### Import the stylesheet
43
+
44
+ Virtualization depends on the grid's CSS. Import it once in your app:
45
+
46
+ ```tsx
47
+ import '@opencorestack/opengridx/styles';
48
+ ```
49
+
50
+ Without the stylesheet the viewport does not scroll, so the grid renders every row. In development the grid logs a one-time `[OpenGridX] The grid stylesheet is not loaded` warning.
51
+
42
52
  ### The grid needs a bounded height
43
53
 
44
54
  Virtualization renders as many rows as fit in the grid's viewport. If the grid's container has no bounded height, the viewport grows to fit **every** row, so every row is rendered. Nothing errors; the grid just stops virtualizing.
@@ -63,6 +73,16 @@ The most common cause is a flex child that is missing `min-height: 0`. A flex it
63
73
 
64
74
  `height="100%"` only helps if every ancestor up to a fixed-height element also has a definite height.
65
75
 
76
+ **`DataGridThemeProvider` counts as an ancestor.** It renders a plain `<div class="ogx-theme-provider">` around the grid, and that wrapper is auto-height like any other `div`. When you use `height="100%"` inside it, give the wrapper a height as well:
77
+
78
+ ```tsx
79
+ <div style={{ flex: 1, minHeight: 0 }}>
80
+ <DataGridThemeProvider theme={theme} style={{ height: '100%' }}>
81
+ <DataGrid rows={rows} columns={columns} height="100%" />
82
+ </DataGridThemeProvider>
83
+ </div>
84
+ ```
85
+
66
86
  In development builds the grid logs a `console.warn` when it detects that it is rendering every row of a dataset larger than 200 rows because its viewport is unbounded.
67
87
 
68
88
  Pagination can hide this problem, because a paginated grid only has one page of rows to render. Row grouping switches pagination off (see below), so an unbounded container that looked fine with pagination can freeze the tab once grouping is enabled.
@@ -71,7 +91,7 @@ Pagination can hide this problem, because a paginated grid only has one page of
71
91
 
72
92
  ### Row Height
73
93
 
74
- The grid supports both fixed and variable row heights:
94
+ Every data row has the same height. There is no per-row height callback; the only rows of a different height are expanded detail panels (see below).
75
95
 
76
96
  ```tsx
77
97
  // Fixed row height (default: 52px)
@@ -221,8 +241,9 @@ You should see console logs only for visible rows + overscan buffer.
221
241
  ## Known Limitations
222
242
 
223
243
  1. **Unbounded containers** - Virtualization needs a bounded viewport height (see above)
224
- 2. **Dynamic row heights** - Requires full dataset scan for accurate scroll calculations
225
- 3. **Horizontal scrolling** - May show brief flicker with very wide grids
244
+ 2. **Browser height cap** - Rows past roughly `33,554,432 / rowHeight` (Chromium; less in Firefox) cannot be scrolled to (see above)
245
+ 3. **Uniform row heights** - Only detail panels vary the height; cumulative heights are recomputed over all rows when panels change
246
+ 4. **Horizontal scrolling** - May show brief flicker with very wide grids
226
247
 
227
248
  ## Future Improvements
228
249
 
@@ -237,9 +258,9 @@ You should see console logs only for visible rows + overscan buffer.
237
258
  |---------|--------------|----------------|
238
259
  | Row virtualization | ✅ Yes | ✅ Yes |
239
260
  | Column virtualization | ✅ Yes (unpinned columns) | ✅ Yes (Pro) |
240
- | Variable row heights | ✅ Yes | ✅ Yes |
261
+ | Variable row heights | Detail panels only | ✅ Yes |
241
262
  | Overscan buffer | 3–30 rows (adaptive, velocity-based) | 3-8 rows (adaptive) |
242
- | Max recommended rows | 100,000+ | 100,000+ |
263
+ | Max scrollable rows | ~645,000 at 52px in Chromium (browser height cap) | — |
243
264
 
244
265
  ## Related Documentation
245
266
 
@@ -0,0 +1,115 @@
1
+ # Migrating from v1 to v2
2
+
3
+ This guide covers every change that requires action when upgrading `@opencorestack/opengridx` from any v1.x release to v2.0.0.
4
+
5
+ ---
6
+
7
+ ## 1. Remove two dead callback props
8
+
9
+ These props existed in v1 but their callbacks were **never called** — no UI existed to trigger them. They have been removed from `DataGridProps` in v2.
10
+
11
+ | Removed prop | Why | Fix |
12
+ | :--- | :--- | :--- |
13
+ | `onPinnedRowsChange` | No pin/unpin-row UI exists | Delete the prop from your JSX |
14
+ | `onRowGroupingModelChange` | No drag-to-group UI exists | Delete the prop from your JSX |
15
+
16
+ **TypeScript will give a compile error at every call site.** Runtime behavior is unchanged — these callbacks were never invoked, so removing them has no effect.
17
+
18
+ ```tsx
19
+ // v1 — remove these props:
20
+ <DataGrid
21
+ onPinnedRowsChange={handlePinnedRowsChange} // ❌ delete
22
+ onRowGroupingModelChange={handleGroupingChange} // ❌ delete
23
+ />
24
+
25
+ // v2:
26
+ <DataGrid />
27
+ ```
28
+
29
+ ---
30
+
31
+ ## 2. Audit columns with `groupable: false`
32
+
33
+ In v1 the `groupable: false` flag on a `GridColDef` was **silently ignored** — the column was still grouped if it appeared in `rowGroupingModel`. In v2 the flag is enforced: that field is skipped entirely when building the group tree.
34
+
35
+ **Action required only if** you have a column with `groupable: false` that also appears in `rowGroupingModel`.
36
+
37
+ ```tsx
38
+ // If you have this in v1 and the column was grouping:
39
+ { field: 'id', groupable: false }
40
+ // ...and rowGroupingModel includes 'id'
41
+
42
+ // v2: 'id' is now silently skipped from grouping.
43
+ // Either remove 'id' from rowGroupingModel, or remove groupable:false.
44
+ ```
45
+
46
+ ---
47
+
48
+ ## 3. Audit columns with `availableAggregationFunctions`
49
+
50
+ In v1 `availableAggregationFunctions` on a `GridColDef` was **silently ignored** — all configured aggregation functions ran regardless. In v2 this list is enforced: any function in `aggregationModel` that is not in `availableAggregationFunctions` for that field is skipped.
51
+
52
+ **Action required only if** you have `availableAggregationFunctions` set AND the active `aggregationModel` for that field uses a function not in that list.
53
+
54
+ ```tsx
55
+ // v1: both 'sum' and 'avg' aggregations ran, regardless of this list
56
+ { field: 'salary', availableAggregationFunctions: ['sum'] }
57
+ // ...with aggregationModel: { salary: 'avg' }
58
+
59
+ // v2: 'avg' is skipped for 'salary' because it is not in the allowed list.
60
+ // Fix: either add 'avg' to availableAggregationFunctions, or change aggregationModel.
61
+ ```
62
+
63
+ ---
64
+
65
+ ## 4. `groupingColDef` now creates a real column
66
+
67
+ In v1 passing `groupingColDef` had no runtime effect. In v2, when `rowGroupingModel` is active, `groupingColDef` creates a dedicated `__group__` column at position 0, auto-pinned left.
68
+
69
+ **Action required only if** you were passing `groupingColDef` expecting it to be a no-op.
70
+
71
+ ```tsx
72
+ // v1: this prop was accepted but did nothing
73
+ <DataGrid groupingColDef={{ headerName: 'Group', width: 200 }} rowGroupingModel={['dept']} />
74
+
75
+ // v2: this creates a pinned __group__ column at position 0.
76
+ // If you don't want the dedicated column, remove groupingColDef.
77
+ ```
78
+
79
+ ---
80
+
81
+ ## 5. No action needed: legacy underscore row fields are still present
82
+
83
+ > **v3.0 update:** the underscore fields are removed at runtime in 3.0.0. See [Migrating from v2 to v3](./v2-to-v3.md).
84
+
85
+ Earlier drafts of `docs/architecture/grid-row-meta.md` and `docs/roadmap.md` stated that the `_hasChildren` / `_treeDepth` / `_isExpanded` / `_groupingField` / `_groupingValue` / `_descendantCount` / `_isGroupRow` runtime shim was removed in v2.0. That was incorrect — it was never scheduled for v2.0 and nothing in this release touches it. `useTreeData` and `useRowGrouping` still inject these fields onto every row exactly as they did in v1.x.
86
+
87
+ **No migration action is required.** If you were already using `params.rowMeta` (recommended since v1.1), nothing changes. If you were still reading the underscore fields directly, they continue to work in v2.0 — but treat them as deprecated and migrate to `params.rowMeta` before they're removed in a future major version. See `docs/architecture/grid-row-meta.md` for the full field mapping.
88
+
89
+ ---
90
+
91
+ ## New features (no migration needed)
92
+
93
+ These are purely additive — existing v1 code continues to work unchanged.
94
+
95
+ | Feature | Prop | Notes |
96
+ | :--- | :--- | :--- |
97
+ | Multi-sort single-click | `multiSort` | `false` by default; Shift+click always worked |
98
+ | Multi-sort shift-click | (built-in) | Shift+click now appends; previously behaved like a plain click |
99
+ | Row density wired | `density` | Was accepted but ignored in v1 |
100
+ | Click-to-select control | `disableRowSelectionOnClick` | Was accepted but ignored in v1; `onRowSelectionModelChange` now fires correctly |
101
+ | Single-row selection cap | `disableMultipleRowSelection` | Was accepted but ignored in v1 |
102
+ | Group label formatter | `groupingValueFormatter` on `GridColDef` | New field, no v1 code has it |
103
+ | Header tooltip | `description` on `GridColDef` | Was in types but not rendered in v1; now renders as `title` attribute |
104
+ | Pagination fixed | (bug fix) | Uncontrolled pagination navigation now works; controlled usage unchanged |
105
+
106
+ ---
107
+
108
+ ## Quick checklist
109
+
110
+ - [ ] Search codebase for `onPinnedRowsChange` — delete every occurrence
111
+ - [ ] Search codebase for `onRowGroupingModelChange` — delete every occurrence
112
+ - [ ] Search codebase for `groupable: false` — verify those fields are not in `rowGroupingModel`
113
+ - [ ] Search codebase for `availableAggregationFunctions` — verify the list covers what `aggregationModel` actually uses
114
+ - [ ] Search codebase for `groupingColDef` — verify you want the `__group__` column it now creates
115
+ - [ ] Run TypeScript (`tsc --noEmit`) — compiler will flag any remaining type errors