@opencorestack/opengridx 2.0.4 → 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.
- package/CHANGELOG.md +408 -3
- package/README.md +93 -72
- package/dist/index.d.ts +611 -121
- package/dist/opengridx.css +1 -1
- package/dist/opengridx.es.js +7992 -5650
- package/dist/opengridx.es.js.map +1 -1
- package/dist/opengridx.umd.js +17 -23
- package/dist/opengridx.umd.js.map +1 -1
- package/docs/API_REFERENCE.md +348 -161
- package/docs/README.md +6 -1
- package/docs/architecture/datagrid-orchestration.md +81 -0
- package/docs/architecture/grid-row-meta.md +102 -0
- package/docs/architecture/use-grid-columns.md +128 -0
- package/docs/architecture/use-grid-controlled-state.md +157 -0
- package/docs/architecture/use-grid-row-pipeline.md +120 -0
- package/docs/architecture/use-grid-scroll-sync.md +111 -0
- package/docs/architecture/use-grid-state-snapshot.md +90 -0
- package/docs/architecture/use-grid-virtualization.md +115 -0
- package/docs/architecture/use-grid-visible-rows.md +85 -0
- package/docs/assets/banner-alt.png +0 -0
- package/docs/assets/banner.png +0 -0
- package/docs/assets/hero.png +0 -0
- package/docs/assets/logo.png +0 -0
- package/docs/components/aggregation-footer.md +15 -10
- package/docs/components/cell.md +16 -6
- package/docs/components/column-group-header.md +55 -28
- package/docs/components/column-resize.md +17 -13
- package/docs/components/column-visibility.md +45 -22
- package/docs/components/datagrid.md +14 -12
- package/docs/components/empty-state.md +2 -1
- package/docs/components/error-overlay.md +12 -7
- package/docs/components/filter-panel.md +28 -8
- package/docs/components/header.md +28 -9
- package/docs/components/pagination.md +14 -8
- package/docs/components/row.md +21 -5
- package/docs/components/toolbar.md +27 -9
- package/docs/components/tooltip.md +16 -7
- package/docs/customization/slots-api.md +100 -36
- package/docs/customization/theming.md +66 -18
- package/docs/features/aggregation-pivot.md +75 -9
- package/docs/features/cell-spanning.md +80 -125
- package/docs/features/clipboard.md +41 -16
- package/docs/features/custom-pagination.md +38 -18
- package/docs/features/data-source.md +36 -13
- package/docs/features/editing-reordering.md +125 -16
- package/docs/features/export-guide.md +147 -41
- package/docs/features/filtering.md +44 -6
- package/docs/features/infinite-scroll.md +54 -46
- package/docs/features/keyboard-navigation.md +83 -0
- package/docs/features/list-view.md +58 -5
- package/docs/features/loading-states.md +18 -20
- package/docs/features/master-detail.md +18 -5
- package/docs/features/pdf-export.md +56 -19
- package/docs/features/pinning.md +23 -5
- package/docs/features/selection.md +50 -10
- package/docs/features/sorting-pagination.md +66 -14
- package/docs/features/state-persistence.md +78 -10
- package/docs/features/toolbar-customization.md +26 -17
- package/docs/features/tree-data-grouping.md +44 -9
- package/docs/features/virtualization.md +64 -15
- package/docs/migration/v1-to-v2.md +115 -0
- package/docs/migration/v2-to-v3.md +1222 -0
- package/docs/performance.md +124 -0
- package/docs/roadmap.md +16 -10
- package/lib/components/Cell/Cell.css +13 -1
- package/lib/components/Cell/Cell.tsx +130 -57
- package/lib/components/Cell/CellErrorBoundary.tsx +12 -6
- package/lib/components/Cell/GridEditInputCell.tsx +114 -41
- package/lib/components/ColumnGroupHeader/ColumnGroupHeader.css +7 -1
- package/lib/components/ColumnResizeHandle/ColumnResizeHandle.css +11 -0
- package/lib/components/ColumnResizeHandle/ColumnResizeHandle.tsx +104 -38
- package/lib/components/ColumnResizeHandle/clampResizeWidth.ts +13 -0
- package/lib/components/ColumnVisibilityPanel/ColumnVisibilityPanel.css +6 -0
- package/lib/components/ColumnVisibilityPanel/ColumnVisibilityPanel.tsx +21 -13
- package/lib/components/DataGrid/DataGrid.css +84 -12
- package/lib/components/DataGrid/DataGrid.tsx +606 -872
- package/lib/components/DataGrid/GridAggregationFooter.tsx +53 -17
- package/lib/components/DataGrid/GridEmptyState.tsx +7 -1
- package/lib/components/DataGrid/GridErrorOverlay.tsx +15 -12
- package/lib/components/DataGrid/GridListView.tsx +166 -23
- package/lib/components/DataGrid/GridLiveRegion.tsx +31 -0
- package/lib/components/DataGrid/GridLoadingOverlay.tsx +27 -0
- package/lib/components/DataGrid/GridPaginationArea.tsx +44 -0
- package/lib/components/DataGrid/GridPinnedRows.tsx +65 -11
- package/lib/components/DataGrid/GridStandaloneColumnPanel.tsx +40 -38
- package/lib/components/DataGrid/GridToolbarSlot.tsx +51 -0
- package/lib/components/DataGrid/GridVirtualRows.tsx +48 -25
- package/lib/components/DetailPanel/DetailPanel.css +0 -6
- package/lib/components/DetailPanel/DetailPanel.tsx +34 -5
- package/lib/components/DetailPanel/DetailPanelContent.tsx +17 -0
- package/lib/components/FilterPanel/FilterPanel.css +13 -2
- package/lib/components/FilterPanel/FilterPanel.tsx +272 -99
- package/lib/components/Header/ColumnMenu.tsx +91 -39
- package/lib/components/Header/Header.css +3 -3
- package/lib/components/Header/Header.tsx +179 -160
- package/lib/components/ListView/ListView.css +25 -0
- package/lib/components/ListView/ListViewRow.tsx +79 -10
- package/lib/components/Pagination/Pagination.tsx +15 -7
- package/lib/components/Row/Row.tsx +185 -75
- package/lib/components/Toolbar/GlobalSearch.css +6 -3
- package/lib/components/Toolbar/GlobalSearch.tsx +26 -27
- package/lib/components/Toolbar/GridToolbar.css +12 -11
- package/lib/components/Toolbar/GridToolbar.tsx +133 -89
- package/lib/components/Toolbar/PivotPanel.tsx +89 -49
- package/lib/components/Tooltip/Tooltip.css +20 -0
- package/lib/components/Tooltip/Tooltip.tsx +68 -35
- package/lib/components/ui/Button.tsx +3 -0
- package/lib/components/ui/Checkbox.tsx +2 -1
- package/lib/components/ui/ExpandIcon.css +0 -9
- package/lib/components/ui/ExpandIcon.tsx +4 -1
- package/lib/hooks/core/gridApiPlaceholder.ts +34 -0
- package/lib/hooks/core/gridToolbarHostContext.ts +14 -0
- package/lib/hooks/core/useDataGrid.ts +115 -173
- package/lib/hooks/core/useGridAggregationApi.ts +72 -0
- package/lib/hooks/core/useGridApiMethods.ts +115 -0
- package/lib/hooks/core/useGridApiRef.ts +15 -3
- package/lib/hooks/core/useGridApiRefBinding.ts +18 -0
- package/lib/hooks/core/useGridAriaRows.ts +38 -0
- package/lib/hooks/core/useGridClipboardApi.ts +38 -0
- package/lib/hooks/core/useGridColumnLookup.ts +30 -0
- package/lib/hooks/core/useGridColumns.tsx +284 -76
- package/lib/hooks/core/useGridColumnsPanel.ts +77 -0
- package/lib/hooks/core/useGridControlledState.ts +99 -6
- package/lib/hooks/core/useGridDetailPanel.ts +51 -0
- package/lib/hooks/core/useGridDevWarnings.ts +123 -0
- package/lib/hooks/core/useGridFocusHandlers.ts +50 -0
- package/lib/hooks/core/useGridGroupingColumn.ts +62 -0
- package/lib/hooks/core/useGridHeaderHandlers.ts +92 -0
- package/lib/hooks/core/useGridHierarchy.ts +81 -0
- package/lib/hooks/core/useGridKeyboardNavigation.ts +452 -250
- package/lib/hooks/core/useGridLiveRowSelection.ts +67 -0
- package/lib/hooks/core/useGridPageCorrection.ts +55 -0
- package/lib/hooks/core/useGridRowIdOf.ts +32 -0
- package/lib/hooks/core/useGridRowInteractions.ts +81 -0
- package/lib/hooks/core/useGridRowPipeline.ts +69 -39
- package/lib/hooks/core/useGridRowSelection.ts +91 -0
- package/lib/hooks/core/useGridScrollSync.ts +80 -32
- package/lib/hooks/core/useGridScrollToIndexesApi.ts +45 -0
- package/lib/hooks/core/useGridStateSnapshot.ts +40 -5
- package/lib/hooks/core/useGridThemeDimensions.ts +49 -0
- package/lib/hooks/core/useGridToolbarProps.ts +97 -0
- package/lib/hooks/core/useGridViewport.ts +38 -0
- package/lib/hooks/core/useGridViewportSize.ts +26 -0
- package/lib/hooks/core/useGridVisibleRows.ts +20 -7
- package/lib/hooks/core/useLayout.ts +215 -195
- package/lib/hooks/core/useRowsScrollEndLatch.ts +41 -0
- package/lib/hooks/core/useStableColumns.ts +34 -0
- package/lib/hooks/features/useAggregation.ts +86 -90
- package/lib/hooks/features/useColumnGroupReorderGuard.ts +34 -0
- package/lib/hooks/features/useDetailPanelHeights.ts +29 -0
- package/lib/hooks/features/useGridClipboard.ts +133 -73
- package/lib/hooks/features/useGridDataSource.ts +354 -128
- package/lib/hooks/features/useGridEditing.ts +211 -51
- package/lib/hooks/features/useGridPivot.ts +92 -0
- package/lib/hooks/features/useGridSpanRenderWindow.ts +104 -0
- package/lib/hooks/features/useGridSpanning.ts +410 -306
- package/lib/hooks/features/usePivot.ts +0 -0
- package/lib/hooks/features/useServerTreeChildren.ts +50 -0
- package/lib/hooks/useColumnReorder.ts +38 -44
- package/lib/hooks/useRowGrouping.ts +335 -214
- package/lib/hooks/useRowReorder.ts +62 -31
- package/lib/hooks/useTreeData.ts +330 -262
- package/lib/index.ts +30 -2
- package/lib/state/index.ts +1 -0
- package/lib/state/types.ts +7 -1
- package/lib/state/useGridStateStorage.ts +88 -29
- package/lib/theme/DataGridThemeProvider.tsx +143 -38
- package/lib/theme/gridThemeContext.ts +5 -0
- package/lib/theme/index.ts +5 -0
- package/lib/theme/presets.ts +5 -4
- package/lib/theme/types.ts +40 -2
- package/lib/types/index.ts +311 -108
- package/lib/utils/aggregation/index.ts +157 -0
- package/lib/utils/aria/index.ts +40 -0
- package/lib/utils/columnGroups.ts +110 -0
- package/lib/utils/columnLookup.ts +33 -0
- package/lib/utils/columnWidth.ts +22 -0
- package/lib/utils/dataSource/index.ts +46 -0
- package/lib/utils/detailPanel.ts +66 -0
- package/lib/utils/dragData.ts +44 -0
- package/lib/utils/editing/index.ts +30 -0
- package/lib/utils/export/exportShared.ts +197 -0
- package/lib/utils/export/exportToExcelAdvanced.ts +344 -121
- package/lib/utils/export/exportToPdf.ts +143 -92
- package/lib/utils/export/groupLabel.ts +14 -0
- package/lib/utils/export/index.ts +278 -272
- package/lib/utils/export/pdfText.ts +50 -0
- package/lib/utils/filtering/index.ts +277 -148
- package/lib/utils/focus/index.ts +115 -0
- package/lib/utils/gridApiRows.ts +35 -0
- package/lib/utils/gridModes.ts +77 -0
- package/lib/utils/grouping/groupedExportRows.ts +91 -0
- package/lib/utils/pagination/index.ts +56 -0
- package/lib/utils/pinning/index.ts +77 -33
- package/lib/utils/pivot/index.ts +368 -0
- package/lib/utils/scroll/index.ts +78 -0
- package/lib/utils/scroll/scrollEnd.ts +18 -0
- package/lib/utils/sorting/index.ts +154 -30
- package/lib/utils/syntheticRows.ts +12 -0
- package/lib/utils/values.ts +206 -0
- package/lib/utils/viewport.ts +14 -0
- package/llms.txt +272 -166
- package/package.json +18 -6
- package/lib/components/ColumnGroupHeader/ColumnGroupHeader.tsx +0 -220
- package/lib/components/ColumnVisibilityPanel/ColumnVisibilityPanel.test.tsx +0 -85
- package/lib/components/DataGrid/DataGrid.regression.test.tsx +0 -132
- package/lib/components/DataGrid/DataGrid.smoke.test.tsx +0 -58
- package/lib/components/DataGrid/DataGrid.v2.test.tsx +0 -127
- package/lib/components/Header/Header.test.tsx +0 -135
- package/lib/components/Pagination/Pagination.test.tsx +0 -64
- package/lib/hooks/core/useDataGrid.regression.test.ts +0 -66
- package/lib/hooks/core/useGridControlledState.test.ts +0 -86
- package/lib/hooks/core/useGridKeyboardNavigation.test.ts +0 -176
- package/lib/hooks/core/useGridRowPipeline.test.ts +0 -117
- package/lib/hooks/features/useAggregation.test.ts +0 -175
- package/lib/hooks/features/usePivot.test.ts +0 -202
- package/lib/hooks/useRowGrouping.test.ts +0 -137
- package/lib/utils/export/exportToPdf.test.ts +0 -120
- package/lib/utils/export/groupedExport.test.ts +0 -144
- package/lib/utils/filtering/filtering.test.ts +0 -178
- package/lib/utils/sorting/sorting.test.ts +0 -88
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,409 @@
|
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
+
## [3.0.0] — 2026-09-24
|
|
9
|
+
|
|
10
|
+
A correctness release: every feature area was audited against its documentation and the grid's own behaviour. Most changes are bug fixes, but many of them change observable output (formatted text, exported files, callback indices, request ranges), which is why this is a major version.
|
|
11
|
+
|
|
12
|
+
**Upgrading from 2.x: read [docs/migration/v2-to-v3.md](docs/migration/v2-to-v3.md).** It starts with a table that maps what your app uses to the sections you need.
|
|
13
|
+
|
|
14
|
+
**React 18 users:** 2.1.0 crashed on React 18 (the build bundled React 19's JSX runtime). 3.0.0 works on React 18 and 19 again; see *Fixed → Build & SSR*.
|
|
15
|
+
|
|
16
|
+
### Breaking
|
|
17
|
+
|
|
18
|
+
- **The underscore hierarchy fields are no longer added to rows.** `_hasChildren`, `_treeDepth`, `_isExpanded`, `_groupingField`, `_groupingValue`, `_descendantCount` and `_isGroupRow` (deprecated since 1.1) are gone at runtime; use `params.rowMeta`. TypeScript does not flag reads of them, because `GridRowModel` has an index signature.
|
|
19
|
+
- **`params.row` under row grouping and tree data is now the consumer's own row object**, not a per-render copy. Code that mutated `params.row` in a render callback now mutates the source data. As a side effect, rows are no longer re-created on every render.
|
|
20
|
+
- **`getRowId` no longer writes an `id` onto your rows.** Rows are stored untouched everywhere (grid, callbacks, `processRowUpdate`, `apiRef`), so `row.id === getRowId(row)` no longer holds. Pass `getRowId` to export functions when exporting `selectedRows`.
|
|
21
|
+
- **Grouped-export default labels in `exportToExcelAdvanced` now match the grid.** Without a `groupingValueFormatter`, group headers read `"field: value"` (the grid's documented default) instead of `"Header: value"`. Set `groupingValueFormatter` on the grouping column to control the label in the grid and in every export format.
|
|
22
|
+
- **Cells are formatted by column `type` when there is no `valueFormatter`:** `date` shows `toLocaleDateString()`, `boolean` shows Yes/No, `singleSelect` shows the option label and `image` renders an `<img>`. This applies to cells, `params.formattedValue`, list view and text exports.
|
|
23
|
+
- **Empty filter values no longer filter**, the quick filter searches only visible filterable columns, and the toolbar search box splits its text into words that must all match.
|
|
24
|
+
- **Aggregation ignores blank strings, booleans and arrays** in `sum` / `avg` / `min` / `max`, and `min` / `max` over dates return a `Date` (was epoch milliseconds).
|
|
25
|
+
- **CSV files start with a UTF-8 BOM and text that looks like a formula gets a leading `'`** (CSV and basic Excel). Opt out with `bom: false` / `escapeFormulas: false`.
|
|
26
|
+
- **A non-empty `selectedRows` now wins over `groupedRows`** in every export: the selection is exported flat and totals are recomputed over it.
|
|
27
|
+
- **`exportToExcel` always writes `.xls`**; a `.xlsx` file name is renamed with a warning (the file was always HTML, which Excel rejects under `.xlsx`).
|
|
28
|
+
- **Tab leaves the grid in one press** outside edit mode (it used to step through cells). While editing, Tab still moves to the next editable cell.
|
|
29
|
+
- **Index values changed meaning:** `colIndex` is absolute among visible data columns (was window-relative), bottom-pinned rows get `rowIndex` after the page rows (were 0..n), `onRowOrderChange` indices are positions in the `rows` prop (were page-local and sorted), and `onColumnOrderChange` indices are positions in the full column order.
|
|
30
|
+
- **`isCellEditable` now governs every way of starting an edit** (double-click, Enter, Tab) and `aria-readonly`, not only Tab stops.
|
|
31
|
+
- **`processRowUpdate` is called when an edit is lost** (the cell scrolls out, is filtered or paged away, or another cell starts editing). Those edits used to be dropped.
|
|
32
|
+
- **Built-in editors commit the column's value type:** `singleSelect` commits the option value (not its string form), `date` commits a `Date` for `Date` cells and `null` when cleared.
|
|
33
|
+
- **Pinned columns render in `pinnedColumns.left` / `.right` order**, not column order.
|
|
34
|
+
- **Header and top-pinned rows are wrapped in `div.ogx__sticky-top`, bottom-pinned rows and the aggregation footer in `div.ogx__sticky-bottom`.** `.ogx__pinned-rows--top` / `--bottom` are no longer sticky themselves; custom CSS that targets them must move to the wrappers.
|
|
35
|
+
- **Group and pivot row ids changed format.** Row-grouping ids for non-string values, tree-data auto-parent ids and pivot row ids use new, collision-free formats; do not parse them.
|
|
36
|
+
- **`DataGridThemeProvider` pins a complete light or dark palette** chosen by the new `GridTheme.mode`, whatever the operating-system colour scheme. A provider-wrapped grid no longer switches with the OS.
|
|
37
|
+
- **Grid buttons have `type="button"`** (including the exported `Button`), so they never submit an enclosing `<form>`. Pass `type="submit"` explicitly where you want a submit button.
|
|
38
|
+
- **`apiRef.current.copySelectedRows()` rejects when the clipboard write fails** (it resolved and logged).
|
|
39
|
+
- **`dataSource` requests changed:** `getRows` is now called with all-client modes, infinite scroll requests the gap after the loaded rows, and tree children are requested with `endRow: Number.MAX_SAFE_INTEGER` (was `-1`).
|
|
40
|
+
- **Column resizing uses pointer events** (tests that simulate `mousedown` / `mousemove` must use pointer events) and no longer caps widths at 1000px.
|
|
41
|
+
- **Removed `GridThemeSkeleton.darkBaseColor` and `darkHighlightColor`**, which had no effect.
|
|
42
|
+
|
|
43
|
+
### Security
|
|
44
|
+
|
|
45
|
+
- `printGrid` escapes the title, cell values, image URLs and alt text, and error messages in the same-origin print window, and only renders images from `http(s)`, `data:image`, `blob:` and relative URLs.
|
|
46
|
+
- `exportToCsv` and `exportToExcel` neutralise spreadsheet formula injection: text starting with `=`, `+`, `-`, `@`, tab or carriage return gets a leading `'`. New option `escapeFormulas` (default `true`).
|
|
47
|
+
- `exportToExcelAdvanced` writes object values as text, so `{ formula }`, `{ hyperlink }`, `{ richText }` or `{ error }` objects in row data can no longer become live cells or links.
|
|
48
|
+
- Grouped `exportToJson` no longer leaks `exportable: false` columns through subtotals and the grand total.
|
|
49
|
+
|
|
50
|
+
### Fixed
|
|
51
|
+
|
|
52
|
+
#### Export
|
|
53
|
+
|
|
54
|
+
- Grouped CSV, basic Excel, JSON, print and PDF exports ignored `groupingValueFormatter` for group-header labels; all exporters now share one label rule, and `getGroupedExportRows()` entries carry the grid's label as `groupLabel`.
|
|
55
|
+
- `exportToExcelAdvanced` dates were shifted by the UTC offset (a day early east of UTC).
|
|
56
|
+
- NaN, Infinity and Invalid Date values produced a corrupt xlsx file.
|
|
57
|
+
- `selectedRows` was ignored when `groupedRows` was also passed; totals are now recomputed over the selection.
|
|
58
|
+
- Exporting a large selection froze the tab.
|
|
59
|
+
- CSV did not quote values containing the configured delimiter or a bare carriage return.
|
|
60
|
+
- `count` / `unique` totals were formatted as currency or dates.
|
|
61
|
+
- A `valueFormatter` that reads other row fields or expects a `Date` aborted exports with totals.
|
|
62
|
+
- The first column's aggregate was replaced by the Subtotal / Grand Total / TOTAL label; the label is now prefixed to the value.
|
|
63
|
+
- Spacer columns (`isSpacer`) and grid system columns (`__checkbox_col__`, `__expand_col__`, `__reorder_col__`, `__group__`) passed in `columns` were exported; they are always left out.
|
|
64
|
+
- A `valueFormatter` placeholder for missing values is exported, as the grid shows it.
|
|
65
|
+
- Basic Excel dropped leading zeros and mangled long numeric ids, and wrote invalid sheet names.
|
|
66
|
+
- `exportToExcelAdvanced`: `rows: 'selected'` sheets contain only the selection; invalid or duplicate sheet names no longer throw; `embedImage` follows `valueGetter` and falls back to the URL for SVG, WebP and AVIF; ISO date strings and numeric strings become native cells; integers have no trailing "."; totals and the summary sheet are numeric; striped rows have no gaps.
|
|
67
|
+
- PDF: non-Latin-1 text was garbled wholesale; `#fff` shorthand colours work; the row count is correct when `groupedRows` is `[]`; the filter summary reflects nested groups, OR and quick search, and wraps.
|
|
68
|
+
- JSON aggregation values are numbers, as documented.
|
|
69
|
+
- Print keeps group-row highlights on even rows.
|
|
70
|
+
|
|
71
|
+
#### Filtering & sorting
|
|
72
|
+
|
|
73
|
+
- Date operators `after`, `onOrAfter`, `before` and `onOrBefore` did not filter (every row passed, with a warning per row).
|
|
74
|
+
- Date `is` / `not` compared raw strings; they now match the local calendar day for `Date` values, ISO datetimes and epoch numbers.
|
|
75
|
+
- A filter item with no value filtered anyway (`>` meant `> 0`, `=` hid every row).
|
|
76
|
+
- Numeric filters treated blank cells as 0; `!=` treats empty cells consistently.
|
|
77
|
+
- A `singleSelect` filter set from the panel emptied the grid; the panel now offers the column's `valueOptions`.
|
|
78
|
+
- Opening the filter panel rewrote values (an `isAnyOf` array became `"a,b"`) and fired `onFilterModelChange`.
|
|
79
|
+
- Editing a panel row deleted filter groups and other conditions on the same column.
|
|
80
|
+
- Changing the operator right after typing lost the typed value, and a pending keystroke undid Clear all.
|
|
81
|
+
- `valueGetter` columns could not be sorted, filtered or quick-searched (including under tree data and row grouping).
|
|
82
|
+
- The quick filter matched the row id, hidden columns, non-column fields, `[object Object]` and `Date.toString()` text; it now matches what cells show.
|
|
83
|
+
- A multi-word toolbar search now matches words across columns.
|
|
84
|
+
- The row-grouping "Group" column appeared in the filter panel.
|
|
85
|
+
- Number columns holding numeric strings sort numerically; NaN and Invalid Date no longer break sorting; accented strings sort next to their base letter.
|
|
86
|
+
- Shift-click on a sorted column kept moving it to the end of the sort; column-menu Unsort / Asc / Desc cleared the other sort keys.
|
|
87
|
+
- The toolbar search box stole focus back on re-render.
|
|
88
|
+
- The boolean filter could not select "true" directly; the panel shows the real operator of programmatic items.
|
|
89
|
+
- `initialState.filter` was ignored; the toolbar search and Filters button did nothing without a `filterModel` prop.
|
|
90
|
+
- A `valueGetter` or `valueFormatter` that throws no longer crashes the grid once the column is sorted, filtered, quick-filtered, aggregated, grouped or pivoted, or shown in list view: the value reads as `undefined` and a dev warning is logged once per column.
|
|
91
|
+
- Text typed into the FilterPanel or the toolbar search box just before the panel closes is no longer lost.
|
|
92
|
+
|
|
93
|
+
#### Editing
|
|
94
|
+
|
|
95
|
+
- `isCellEditable` did not block double-click and Enter editing; rejected cells now carry `aria-readonly="true"`.
|
|
96
|
+
- `processRowUpdate` ran twice for one commit (Tab, or Enter then blur).
|
|
97
|
+
- A slow `processRowUpdate` closed an edit on another cell or discarded text typed meanwhile.
|
|
98
|
+
- Clicking inside an open editor committed and closed it; the dropdown editor was unusable with the mouse; clicks inside editors fired `onCellClick` / `onRowClick` and toggled selection.
|
|
99
|
+
- An edit was lost when its row scrolled out, was filtered or paged away, or another cell started editing; it is now committed.
|
|
100
|
+
- Committing one edit reverted other changes to the row and reset the server row count.
|
|
101
|
+
- Tree-data parent rows could not be edited by double-click; Enter opened a useless editor on row-grouping group rows.
|
|
102
|
+
- Committing by clicking a control outside the grid stole focus back.
|
|
103
|
+
- The `singleSelect` editor committed typed option values as strings and showed no empty choice for an empty or unknown value.
|
|
104
|
+
- The date editor was blank for `Date` and ISO datetime values and committed a different kind of value; clearing it commits `null`.
|
|
105
|
+
- With a custom `getRowId`, a `processRowUpdate` result without the grid's id was not applied.
|
|
106
|
+
- An inline `getRowId` function reverted committed edits on every parent re-render.
|
|
107
|
+
- `onRowDoubleClick` did not fire on editable cells.
|
|
108
|
+
- The boolean editor did not close on blur; IME composition Enter committed the edit; built-in editors had no accessible name.
|
|
109
|
+
- Double-clicking inside an editor discarded the typed value.
|
|
110
|
+
- A `processRowUpdate` that returns nothing is now reported clearly and the editor stays open.
|
|
111
|
+
- Enter-to-edit starts from the `valueGetter` value.
|
|
112
|
+
- Every cell re-rendered on every grid render.
|
|
113
|
+
|
|
114
|
+
#### Selection & apiRef
|
|
115
|
+
|
|
116
|
+
- `apiRef` methods `sortColumn`, `setFilterModel`, `setPage`, `setPageSize`, `selectRow` and `selectRows` did not change the grid or fire callbacks; `getSortModel`, `getFilterModel` and `getSelectedRows` returned stale values.
|
|
117
|
+
- `apiRef.current.getSelectedRows()` returned the previous selection inside `onRowSelectionModelChange`.
|
|
118
|
+
- `getVisibleColumns` included hidden columns and ignored display order; `getVisibleRows` and `getAllFilteredRows` omitted pinned rows; `getAllFilteredRows` missed rows under tree data and row grouping.
|
|
119
|
+
- `getGroupedExportRows()` dropped the rows of collapsed groups and ignored sort and filter.
|
|
120
|
+
- Select-all selected filtered-out rows, could not be undone with a `dataSource`, and the header checkbox showed the wrong state.
|
|
121
|
+
- `disableMultipleRowSelection` was ignored by checkboxes, Space and select-all.
|
|
122
|
+
- Selection kept the ids of rows that were removed from `rows`.
|
|
123
|
+
- `getRowId` overwrote the row's own `id` field (grid, `dataSource` rows and tree children).
|
|
124
|
+
- Duplicate row ids rendered one row twice.
|
|
125
|
+
- `onStateChange` looped with inline models; its payload now carries `density` and never contains `__group__`; `initialState.density` is honoured.
|
|
126
|
+
- `useGridStateStorage` crashed when storage is blocked, `clearState` was undone, and storage was written on every re-render.
|
|
127
|
+
- `useGridApiRef()` did not type-check against the `apiRef` prop under `@types/react` 18.
|
|
128
|
+
- Changing `rows` and `columns` together (or leaving pivot mode) ran the new columns against the old rows, crashing `valueGetter`s.
|
|
129
|
+
- A controlled `rowSelectionModel` holding an id that is no longer in `rows` fired `onRowSelectionModelChange` on every render and could loop; the pruned selection (and a corrected page) is now reported once, also under StrictMode.
|
|
130
|
+
- `getAggregationResult`, `getAggregationModel`, `getGroupedExportRows` and `scrollToIndexes` are available in a parent's `useLayoutEffect`.
|
|
131
|
+
- `getVisibleColumns` returns columns in render order (left-pinned, unpinned, right-pinned).
|
|
132
|
+
- `apiRef.selectRow` / `selectRows` ignore synthetic ids (group, subtotal, auto-parent and pivot Grand Total rows), and a call that does not change the selection fires nothing. The pivot Grand Total row cannot be selected.
|
|
133
|
+
|
|
134
|
+
#### Pagination & data source
|
|
135
|
+
|
|
136
|
+
- The pager total ignored the filter and counted pinned rows.
|
|
137
|
+
- Server pagination, sorting or filtering without a `dataSource` re-sliced, re-sorted or re-filtered the rows.
|
|
138
|
+
- The `rowCount` prop was read only at mount.
|
|
139
|
+
- The default page size could be missing from `pageSizeOptions`.
|
|
140
|
+
- `slots.footer` received the page length instead of the server total.
|
|
141
|
+
- Shrinking data left the grid on an empty page past the end; it now shows the last page and reports it through `onPaginationModelChange`.
|
|
142
|
+
- The rows-per-page select did not show a page size missing from `pageSizeOptions`, had a hard-coded accessible name, and showed "Infinity" for page size 0.
|
|
143
|
+
- Infinite scroll skipped rows when the page advanced quickly or while loading; it now requests the missing range without duplicates.
|
|
144
|
+
- Infinite scroll: changing sort, filter, `pageSize` or `dataSource` restarts from the first row and reports page 0.
|
|
145
|
+
- Server sort or filter with client pagination showed only the first page.
|
|
146
|
+
- A `dataSource` with the default (client) modes never loaded its rows.
|
|
147
|
+
- The error overlay's Retry reloaded the whole page; it now re-requests rows, and shows the message of any rejected object with a `message`.
|
|
148
|
+
- Stale responses overwrote newer ones.
|
|
149
|
+
- Inline `filterModel`, `sortModel`, `aggregationModel` or `dataSource` objects refetched on every render and wiped loaded infinite pages.
|
|
150
|
+
- An inline `rows={[]}` next to a `dataSource` wiped the fetched rows.
|
|
151
|
+
- "No Data" flashed before the first response, and the live region announced "Loading data... No Data".
|
|
152
|
+
- Server tree data: children now load with every row, keep the pager total, are not re-filtered or re-sorted under server modes, reload for expanded nodes after a refetch, and a failed children request collapses its node instead of covering the grid.
|
|
153
|
+
- `paginationMode="infinite"` combined with `pagination` sliced the rows.
|
|
154
|
+
- `loading` with rows present showed nothing; it now shows a progress bar (or `slots.loadingOverlay`) over the rows.
|
|
155
|
+
- A `dataSource` response that cannot be processed shows the error overlay instead of loading forever.
|
|
156
|
+
- Row grouping with a `paginationMode="server"` `dataSource` loads every row in one request (with a dev warning) instead of grouping only the first page.
|
|
157
|
+
|
|
158
|
+
#### Row grouping & tree data
|
|
159
|
+
|
|
160
|
+
- The aggregation footer double-counted expanded groups. Under row grouping it aggregated the *visible* rows: group rows, which already carry their subtotals in the same fields, plus the expanded leaves. Expanding a group inflated `sum`, and `count` / `avg` / `unique` were wrong even when every group was collapsed. The footer, `getAggregationResult()`, the `aggregationResult` / `rowCount` passed to `slots.footer`, and grouped-export grand totals now use the filtered data rows, independent of expansion.
|
|
161
|
+
- Group rows lost their label and expand toggle when the first column was hidden, and showed them mid-row when that column was reordered or another column was pinned left; the hierarchy UI now goes on the leftmost column on screen.
|
|
162
|
+
- Subtotals, the "(n)" count and `descendantCount` counted filtered-out rows; groups left empty by the filter are hidden.
|
|
163
|
+
- `getAggregationPosition` was ignored; it is now called for every group and once with `null` for the grand total.
|
|
164
|
+
- `groupingColDef` had no effect under tree data.
|
|
165
|
+
- `pinnedRows` disappeared under tree data and row grouping.
|
|
166
|
+
- Tree paths containing `/` collided with deeper paths.
|
|
167
|
+
- Grouping values `null` and `'null'`, `1` and `'1'` fell into the same group.
|
|
168
|
+
- Detail-panel callbacks ran for every rendered row, including group rows; they now run only for expanded data rows, and a throwing `getDetailPanelContent` is contained to its panel.
|
|
169
|
+
- A throwing `getDetailPanelHeight`, `groupingValueFormatter` or `getAggregationPosition` falls back to the default instead of crashing.
|
|
170
|
+
- `getGroupedExportRows` and `getAllFilteredRows` follow screen order when sorting by the hierarchy column.
|
|
171
|
+
- `defaultGroupingExpansionDepth` expands and loads lazy server tree nodes.
|
|
172
|
+
|
|
173
|
+
#### Aggregation & pivot
|
|
174
|
+
|
|
175
|
+
- Footer totals now use the column's `valueFormatter` for `sum` / `avg` / `min` / `max`; `count` / `unique` stay plain numbers, and date `min` / `max` show as dates.
|
|
176
|
+
- Group rows formatted counts with the column's currency or unit formatter.
|
|
177
|
+
- Blank cells, booleans and arrays counted as 0 in `sum` / `avg` / `min` / `max`; `count` / `unique` counted blank strings.
|
|
178
|
+
- Aggregates of `valueGetter` columns summed `row[field]` instead of the computed values.
|
|
179
|
+
- `aggregable: false` columns were aggregated when `aggregationModel` or `pivotModel` named them.
|
|
180
|
+
- Footer totals now come from the server whenever a `dataSource` drives the rows, including infinite scroll and server-only filtering.
|
|
181
|
+
- An inline `aggregationModel` refetched `getRows` and cleared server totals on every render; stale server totals no longer show under a new function, filter or sort, while pending, or after a failure.
|
|
182
|
+
- Pivot mode crashed with `RangeError` on datasets over ~110k rows with a `min` or `max` value field, and `count` counted numeric values only.
|
|
183
|
+
- Pivot: filters and the quick filter apply to source rows, filters on generated value columns apply to pivot rows, and the Grand Total matches the rows shown, stays last when sorting and is not selected by select-all.
|
|
184
|
+
- Pivot: `getRowId` collapsed the pivot into one row; `treeData` and `rowGroupingModel` crashed or regrouped it; a `dataSource` produced broken output (pivot is now ignored with a warning).
|
|
185
|
+
- Pivot: the same field twice (for example `sum` and `count`) doubled values; a source `valueFormatter` that reads row data crashed the grid.
|
|
186
|
+
- Pivot: row-label columns keep the source column's formatter, renderer, type and alignment; column-field headers are formatted; numeric column keys sort numerically.
|
|
187
|
+
- Pivot: an empty pivot keeps its value columns and shows the no-rows overlay; a row field named `id` no longer overwrites row ids; pivot rows no longer share ids with source rows.
|
|
188
|
+
- Pivot: leaving pivot mode restores the column order; a controlled `columnOrder` no longer puts value columns before the label column, and the Columns panel can reorder generated columns.
|
|
189
|
+
- Pivot: `getAggregationResult()` and `slots.footer` no longer report totals over pivot rows, and the Summaries panel no longer lists generated columns.
|
|
190
|
+
- PivotPanel: editing or removing one of two chips on the same field affected both; it now follows `aggregable: false`, `availableAggregationFunctions` and `groupable: false`, and its controls have descriptive names.
|
|
191
|
+
|
|
192
|
+
#### Layout & pinning
|
|
193
|
+
|
|
194
|
+
- Columns pinned out of column order overlapped or left gaps; header, body, footer and keyboard navigation now agree on `pinnedColumns` order.
|
|
195
|
+
- Column widths ignored `minWidth` / `maxWidth` for fixed, resized and pinned columns; percentage widths cascaded; pinned `%`, `flex` and `auto` columns were 100px wide.
|
|
196
|
+
- Top-pinned rows covered the header when column groups were used; the aggregation footer was hidden behind bottom-pinned rows.
|
|
197
|
+
- Keyboard navigation and `scrollToIndexes` left the target row under the footer or bottom-pinned rows; `scrollToIndexes({ colIndex })` left the column under system or right-pinned columns.
|
|
198
|
+
- `'auto'` detail panels are laid out at their real height; `getDetailPanelHeight` returning 0 renders 0px (was 200px).
|
|
199
|
+
- `onRowsScrollEnd` fired on every scroll event near the bottom (including horizontal scrolling) and never for a list shorter than the viewport; it now fires once per arrival, in grid and list view.
|
|
200
|
+
- The grid re-measures its viewport and restores the scroll position after list view is switched off.
|
|
201
|
+
- Infinite-scroll placeholder rows appeared before the last loaded row.
|
|
202
|
+
- Row-spanned cells painted over the sticky drag and expand columns.
|
|
203
|
+
- A new `overscanRowCount` applied only after scrolling.
|
|
204
|
+
- Pinned-section edge classes and shadows were not applied.
|
|
205
|
+
- `autoHeight` filtered visible rows in quadratic time.
|
|
206
|
+
|
|
207
|
+
#### Spanning & column groups
|
|
208
|
+
|
|
209
|
+
- Body cells lost `flex`, percentage and `auto` widths (misaligned with headers) as soon as any column used `colSpan`.
|
|
210
|
+
- `colSpan` / `rowSpan` recomputed on every resize tick (a ~2 s freeze per rows change at 100k rows) and cost time even when unused.
|
|
211
|
+
- Spans counted hidden columns, crossed into another pinned section, and crossed between pinned and scrolling rows.
|
|
212
|
+
- A span broke when its origin row or column scrolled out of the render window.
|
|
213
|
+
- Huge, Infinity, NaN or fractional span values hung or corrupted the grid; `aria-colspan` / `aria-rowspan` report the clamped value.
|
|
214
|
+
- A throwing `colSpan` / `rowSpan` callback unmounted the grid; it now falls back to no span with a dev warning. Infinite-scroll placeholder rows are never passed to span callbacks.
|
|
215
|
+
- `colSpan` received the raw field value instead of the `valueGetter` result, and a `colIndex` different from `renderCell`'s.
|
|
216
|
+
- `colSpan` plus `rowSpan` covered only the origin column in following rows.
|
|
217
|
+
- `rowSpan` painted over an expanded detail panel; a merged cell was capped by its origin column's `maxWidth`.
|
|
218
|
+
- Keyboard navigation lost focus on covered cells; arrows now cross a merged cell in one step.
|
|
219
|
+
- Column group header rows did not follow member columns under `flex` / `%` / `auto` widths, hiding, reordering and pinning; pinned groups scrolled away; non-contiguous groups caused duplicate-key errors.
|
|
220
|
+
- `GridColumnGroup.headerClassName` was ignored.
|
|
221
|
+
- Group header cells expose `aria-colspan` / `aria-colindex`, filler cells are hidden from assistive technology, and `aria-rowcount` counts group header rows.
|
|
222
|
+
- `rowSpan` never starts on or crosses group, subtotal, tree auto-parent or pivot Grand Total rows.
|
|
223
|
+
|
|
224
|
+
#### Column reorder & resize
|
|
225
|
+
|
|
226
|
+
- `onRowOrderChange` indices depended on page, sort, filter and pinned rows; rows with id `0` and columns with field `''` could not be reordered.
|
|
227
|
+
- With `rowReordering`, pinned rows had no handle cell and misaligned; pinned and group rows could be dragged and dropped onto.
|
|
228
|
+
- Row and column drags did not start in Firefox; drags from outside the grid were treated as reorders; a drag broke after its source row scrolled away.
|
|
229
|
+
- Header drag-reorder moved the wrong column after columns were added, when `__group__` appeared, or with a partial controlled `columnOrder`; dropping on a pinned column sent the dragged column to the far end.
|
|
230
|
+
- `pinnable: false` also blocked drag-reorder.
|
|
231
|
+
- Controlled or `initialState` `columnOrder` was ignored when `disableColumnReorder` was set.
|
|
232
|
+
- The Manage-columns panel listed columns in definition order, and its Reset did nothing under a controlled `columnOrder`.
|
|
233
|
+
- Resize clamped to a hidden 1000px maximum and snapped narrow columns to 50px; a click on the handle resized, sorted or turned a flex column fixed; ending a resize over the header sorted the column; right-pinned columns resized from the wrong edge; a resize kept running after unmount.
|
|
234
|
+
- `rowReordering` had no effect but showed handles in pivot mode.
|
|
235
|
+
|
|
236
|
+
#### Keyboard & accessibility
|
|
237
|
+
|
|
238
|
+
- Keys typed into inputs inside cells and detail panels were taken by the grid; clicking an input rendered by `renderCell` lost focus.
|
|
239
|
+
- Focus was lost when the focused cell scrolled out, on window switch, when tabbing out and back (the last cell is now restored), and when rows or columns were removed, filtered or hidden.
|
|
240
|
+
- Tab could not reach detail-panel content.
|
|
241
|
+
- Arrow keys stopped on hidden columns and ignored the pinned visual order; Space and arrows at the edges scrolled the viewport.
|
|
242
|
+
- ArrowDown onto a row with a tall detail panel scrolled the row out of view; Home onto an unpinned checkbox column did not scroll it into view.
|
|
243
|
+
- Enter / Space on the select-all header sorted by `__checkbox_col__` instead of selecting all.
|
|
244
|
+
- Keyboard sorting from a header ignored `multiSort` and Shift.
|
|
245
|
+
- Reorder, expand and checkbox columns were not real focus stops; pinned rows could not be edited.
|
|
246
|
+
- DOM focus did not return to the cell after a re-click or an edit.
|
|
247
|
+
- A row with id `"HEADER"` was treated as the header row.
|
|
248
|
+
- `aria-rowindex`, `aria-rowcount`, `aria-colindex`, `aria-colcount` and `aria-sort` were wrong; `colIndex` in `onCellClick`, `renderCell`, `cellClassName` and `renderHeader` was relative to the render window.
|
|
249
|
+
- The detail panel had an invalid row/gridcell structure.
|
|
250
|
+
- A cell whose `renderCell` threw stayed broken; it now recovers when the renderer or value changes.
|
|
251
|
+
- `GridTooltip` placement `left` / `right` did not work; it now opens on focus, uses `role="tooltip"` with `aria-describedby`, closes on Escape, uses theme colours and cleans up its timers.
|
|
252
|
+
- Columns-panel checkboxes are announced with their column name.
|
|
253
|
+
|
|
254
|
+
#### Clipboard
|
|
255
|
+
|
|
256
|
+
- Copy (Ctrl/Cmd+C and `apiRef.copySelectedRows()`) included hidden and `exportable: false` columns in definition order; it now copies the visible columns in screen order.
|
|
257
|
+
- Copy read `row[field]` instead of the `valueGetter` value before formatting.
|
|
258
|
+
- Values containing tabs, line breaks or quotes broke the pasted table; they are now quoted.
|
|
259
|
+
- Only selected rows on the current page and in expanded groups were copied; now every selected row that passes the filter is copied, including pinned rows and collapsed groups.
|
|
260
|
+
- Copying right after `selectRows` or from `onRowSelectionModelChange` copied the old selection.
|
|
261
|
+
- Focus moved to `<body>` after copying.
|
|
262
|
+
- Ctrl+C did not copy with Caps Lock on or with non-Latin keyboard layouts, and it copied while focus was outside the grid or a text selection was active.
|
|
263
|
+
- Fields starting with `__` (for example `__typename`) were not copied.
|
|
264
|
+
- The Ctrl+C listener was registered more than once.
|
|
265
|
+
|
|
266
|
+
#### Toolbar, header & list view
|
|
267
|
+
|
|
268
|
+
- `slots.toolbar` rejected `memo`, `forwardRef`, class and `lazy` components; switching the toolbar did not remount cleanly; an inline toolbar lost its state.
|
|
269
|
+
- `slotProps.toolbar` render props had implicitly-`any` parameters under `strict`; `slots.pagination` typed with `PaginationProps` did not type-check; `groupingColDef` required a `field`.
|
|
270
|
+
- The column menu offered Hide for `hideable: false` and pin actions for `pinnable: false` columns (including the grouping column).
|
|
271
|
+
- Manage columns worked only once (after the toolbar button or Escape closed the panel) and did nothing with a custom toolbar; it now opens a standalone panel. The Columns panel closes on Escape and `onColumnsPanelClose` fires on every close.
|
|
272
|
+
- The Summaries panel offered functions outside `availableAggregationFunctions` and omitted `unique`.
|
|
273
|
+
- Toolbar panels misaligned with a classic (non-overlay) scrollbar.
|
|
274
|
+
- List view passed loading placeholders to `renderCell`, paged incorrectly under tree data, ignored server totals, never fired `onRowsScrollEnd`, and gave `renderCell` no `value`, `formattedValue`, `colDef` or `rowMeta`; `aria-rowindex` restarted every page.
|
|
275
|
+
- List view ignored `loading`, `slots.loadingOverlay`, `slots.noRowsOverlay` and `slots.footer`, and showed "No Data" while loading; `listView` without `listViewColumn` rendered nothing (it now falls back to the grid with a dev warning).
|
|
276
|
+
- List view had no expand chevron or depth indent for tree-data and group parents.
|
|
277
|
+
- List view: `renderCell` errors are contained, group rows get no checkbox and fall back to their label, and "N items" counts data rows.
|
|
278
|
+
- Two column-menu hides or pins in the same tick both apply.
|
|
279
|
+
|
|
280
|
+
#### Theming
|
|
281
|
+
|
|
282
|
+
- `DataGridThemeProvider` left part of the palette to the OS colour scheme, so `darkTheme` in a light browser (or light presets in a dark browser) was unreadable.
|
|
283
|
+
- Brand presets and `colors.primary` did not recolour the toolbar, filter panel, column menu, selection and focus ring.
|
|
284
|
+
- `grid.rowHeight*` and `grid.headerHeight` did not size rows and the header (`compactTheme` now gives 36px rows and a 40px header).
|
|
285
|
+
- `toolbar.*`, `scrollbar.*`, `overlays.itemDanger*` and `grid.cellFocusBorder` had no effect.
|
|
286
|
+
|
|
287
|
+
#### Build & SSR
|
|
288
|
+
|
|
289
|
+
- **The package works on React 18 again.** The 2.1.0 build bundled React 19's JSX runtime, which React 18 cannot render (`recentlyCreatedOwnerStacks` error on first render). A build check now fails if the JSX runtime is bundled.
|
|
290
|
+
- `DataGrid` crashed under server rendering (`renderToString`, Next.js, Remix) because a panel read `document` during render.
|
|
291
|
+
- `docs/migration/` now ships in the npm package; the v2 → v3 guide was missing from `node_modules`.
|
|
292
|
+
|
|
293
|
+
#### Documentation
|
|
294
|
+
|
|
295
|
+
- The README, `llms.txt` and the AI context file no longer claim the stylesheet loads automatically: `import '@opencorestack/opengridx/styles'` is required.
|
|
296
|
+
- The README props tables list only real props, with correct defaults; `llms.txt` examples compile and use real APIs.
|
|
297
|
+
- Server-side guides describe the real requests; "millions of rows" is replaced by the browser's height limit (about 645k rows at 52px in Chromium).
|
|
298
|
+
- The theming docs no longer reference a non-existent `themes` export; the API reference and component pages were corrected against the code.
|
|
299
|
+
|
|
300
|
+
### Performance
|
|
301
|
+
|
|
302
|
+
- Inline `columns` (a new array each render with the same definitions) no longer re-runs client filtering and sorting.
|
|
303
|
+
- The quick filter no longer re-reads every cell on each keystroke.
|
|
304
|
+
- Faster date formatting.
|
|
305
|
+
|
|
306
|
+
### Added
|
|
307
|
+
|
|
308
|
+
- `GridColDef.valueSetter` (`GridValueSetterParams`) maps an edited value back onto the row for editable `valueGetter` columns.
|
|
309
|
+
- `renderEditCell` receives `onValueChange`, `onCommit` and `onCancel` (`GridRenderEditCellParams`); errors in custom editors are contained to their cell.
|
|
310
|
+
- `formattedValue` and `rowMeta` are passed to `renderEditCell` and to the function form of `cellClassName`, as they already were to `renderCell`.
|
|
311
|
+
- Default cell formatting by `GridColDef.type` when there is no `valueFormatter` (see *Breaking*).
|
|
312
|
+
- `GridFilterOperator` values `'='`, `'after'`, `'onOrAfter'`, `'before'` and `'onOrBefore'`; a date input and `singleSelect` / multi-select value controls in the filter panel; the panel notes conditions it cannot show.
|
|
313
|
+
- `onColumnOrderModelChange(columnOrder)` fires with the whole new order after every change, including the Columns panel's Reset.
|
|
314
|
+
- `disableClipboardCopy` prop; Ctrl+C events already handled (`defaultPrevented`) are left alone.
|
|
315
|
+
- Export options: `CsvExportOptions.escapeFormulas`, `CsvExportOptions.bom`, `ExcelExportOptions.escapeFormulas`, `PdfExportOptions.font` (a Unicode TrueType font), and `getRowId` on every export function.
|
|
316
|
+
- `GridGroupedExportRow.groupLabel`; `GridRowMeta.isGroupFooter` and the `ogx__row--group-footer` class for subtotal rows shown in `'footer'` position.
|
|
317
|
+
- Keyboard: Shift+Space selects the focused row, Ctrl/Cmd+A selects all, Alt+ArrowRight / Alt+ArrowLeft expand and collapse, Alt+ArrowDown or Ctrl+Enter opens the column menu, Alt+ArrowLeft / Alt+ArrowRight on a focused header resizes it (Shift for 50px steps).
|
|
318
|
+
- Enter on a non-editable cell: on a row with children (group rows, tree-data parents) it only toggles expansion, without firing `onRowClick` or selecting; on any other row it acts like a click (`onRowClick`, click-to-select).
|
|
319
|
+
- Keyboard navigation between rows in list view.
|
|
320
|
+
- Column resizing by touch and pen; resize separators expose `aria-valuenow` / `aria-valuemin` / `aria-valuemax`.
|
|
321
|
+
- `aria-level` / `aria-expanded` on hierarchy rows and `aria-multiselectable` on the grid.
|
|
322
|
+
- `GridTheme.mode` (`'light' | 'dark'`), `colors.white`, `colors.black`, `colors.gray` (50–900), `grid.cellFontSize` and `grid.headerFontSize`.
|
|
323
|
+
- Type exports: `GridRenderEditCellParams`, `GridValueSetterParams`, `GridThemeToolbar`, `GridThemeOverlays`, `GridThemeScrollbar`, `GridThemeSkeleton`, `GridThemeGrayScale`, `GridGroupedExportRow`, `GridRowScrollEndParams`, `GridColumnOrder`, `GridDataSourceState`, `GridDetailPanelHeight`, `GridAggregationPosition`, `GridSlots`, `GridSlotProps`, and the props types `CellProps`, `RowProps`, `HeaderProps`, `SkeletonProps`, `FilterPanelProps`, `PaginationProps`, `GridTooltipProps`, `ButtonProps`, `InputProps`, `CheckboxProps`.
|
|
324
|
+
- `Pagination` component export.
|
|
325
|
+
- Optional `rowId` prop on `Row`, and optional `ariaRowIndex` / `ariaColIndex` / `columnIndexMap` props on the exported `Row`, `Cell` and `Header` components.
|
|
326
|
+
- Optional props on the exported components: `Cell.isPinnedEdge` (adds the pinned-section edge class), `Cell.valueError` (shows a `valueGetter` error as a cell error), `Row.onDetailPanelHeightChange(rowId, height)` (measured height of an `'auto'` detail panel) and `Row.isCellEditable`.
|
|
327
|
+
- Dev warnings: the grid stylesheet is not loaded, `pinnedRows` ignored under hierarchy, content taller than browsers can scroll, duplicate row ids, empty or duplicate tree paths, `valueGetter` + `editable` without `valueSetter`, pivot combined with `dataSource` / tree data / row grouping, `listView` without `listViewColumn`.
|
|
328
|
+
- CSS hooks: `ogx__sticky-top`, `ogx__sticky-bottom`, `ogx__header-cell--pinned-left-last`, `ogx__header-cell--pinned-right-first`, `ogx__cell--pinned-left-last`, `ogx__cell--pinned-right-first`, `ogx__aggregation-spacer`, `ogx__aggregation-spacer--pinned`, `ogx__aggregation-footer--loading`, `ogx__loading-bar`, `ogx__loading-overlay--over-rows`, `ogx__loading-overlay--custom`, `ogx__cell-image`, `ogx-list-view__expand`, `ogx-list-view__loading`, `ogx-filter__hidden-note`, `ogx-filter__value-multiselect`, `ogx-col-group-cell--pinned`, `ogx-col-group-cell--pinned-left` / `--pinned-right`, `ogx-column-resize-handle--start`, `ogx-tooltip--left` / `--right`.
|
|
329
|
+
|
|
330
|
+
### Changed
|
|
331
|
+
|
|
332
|
+
- Sorting is type- and language-aware (`Intl.Collator` with numeric collation, dates parsed, mixed kinds ordered by kind).
|
|
333
|
+
- The quick filter searches only visible, filterable columns, using `valueGetter` and `valueFormatter` text.
|
|
334
|
+
- Pinned columns render in `pinnedColumns.left` / `.right` order; the column menu appends, so the most recently pinned column sits next to the scrolling area.
|
|
335
|
+
- `onColumnOrderChange` indices are positions in the full current column order (including hidden columns and `__group__`).
|
|
336
|
+
- Header drag-reorder works inside a column group when `columnGroupingModel` is set (it was disabled for every column); the toolbar and Columns panel can no longer move a column out of its group.
|
|
337
|
+
- A synchronous `processRowUpdate` result is applied in the same event.
|
|
338
|
+
- `apiRef.current.copySelectedRows()` rejects when the clipboard write fails.
|
|
339
|
+
- `min` / `max` of dates return a `Date`; the default `avg` format in pivot cells is locale-grouped (`56,666.67`); the footer exposes `aria-busy` while server totals load.
|
|
340
|
+
- `GridToolbar` shows the Summaries button only when `onAggregationModelChange` is passed; toolbar triggers have `aria-haspopup="dialog"` and `aria-expanded`.
|
|
341
|
+
- `GridTooltip` renders into the theme provider (`.ogx-theme-provider`) with `position: fixed` instead of `document.body`.
|
|
342
|
+
- `useGridApiRef()` returns a `MutableRefObject<GridApi>` that is never `null` before mount; `GridInitialState` accepts partial `columns`.
|
|
343
|
+
- The exported `Header` reports a focused header cell as `focusedCell.id === null` (was `'HEADER'`).
|
|
344
|
+
- The exported `Cell` no longer stops propagation of the double-click that starts an edit, so it reaches the row (`onRowDoubleClick`).
|
|
345
|
+
- `onStateChange` fires on value changes only (it fired for every new prop identity). With `useGridStateStorage`, remount the grid with `<DataGrid key={storageKey}>` when the key changes; storage is read during the first render, so SSR apps with saved state should render the grid on the client only (see the migration guide, §26).
|
|
346
|
+
- `GridAggregationPosition` is `'inline' | 'footer' | null` (it was an unused `'footer' | 'inline' | 'both'`).
|
|
347
|
+
- Accent colours use CSS `color-mix()` (Chrome 111+, Safari 16.2+, Firefox 113+); `darkTheme` gives the toolbar a solid `#1e293b` background.
|
|
348
|
+
|
|
349
|
+
### Typing changes
|
|
350
|
+
|
|
351
|
+
- Rows can be typed with your own interfaces and type aliases: every public generic is constrained by the new `GridValidRowModel` (`object`) instead of `GridRowModel`, and an untyped `GridColDef[]` can be passed next to typed rows. The README example now compiles under `strict`.
|
|
352
|
+
- `DataGrid` and the export functions, `usePivot` and `useAggregation` have a typed and an untyped-columns overload. Use `DataGridProps<R>` rather than `React.ComponentProps<typeof DataGrid>`.
|
|
353
|
+
- `GridColDef` row callbacks are declared as methods, so `GridColDef<Row>` is assignable to `GridColDef` when `Row` is a type alias or extends `GridRowModel`. For an interface without an index signature it is not: type the array as `GridColDef<Row>[]`, or leave the columns untyped and use the untyped-columns overload.
|
|
354
|
+
- Calling `col.renderEditCell(params)` yourself with a `GridRenderCellParams` is now a type error: its parameter is `GridRenderEditCellParams` (the old params plus `onValueChange`, `onCommit`, `onCancel`).
|
|
355
|
+
- `usePivot` is declared to return `PivotResult`; `UsePivotReturn` is now a type alias of it (same fields, no declaration merging).
|
|
356
|
+
- Exported `Header`: `focusedCell.id` is `GridRowId | null`. Exported `Cell`: `onEditStop(cancel?, field?)`. Exported `Row`: `onEditStop` params gain optional `id` / `field`; `rowSpanningCaches.hiddenCellOriginMap` is `Record<GridRowId, Record<string, GridRowId>>` (was `Record<number, Record<string, number>>`).
|
|
357
|
+
- Slots are typed with the props the grid passes: new `GridToolbarSlotProps`, `GridPaginationSlotProps`, `GridOverlaySlotProps`, `GridFooterSlotProps`. Known `slotProps` keys are type-checked.
|
|
358
|
+
- Export option types are generic (`CsvExportOptions<R>`, …), so `getRowId` receives your row type.
|
|
359
|
+
- New root exports: `GridValidRowModel`, `DataGridUntypedColumnsProps` and the slot props types.
|
|
360
|
+
- Removed unused, never-exported internal types (`GridEditCellProps`, `GridRowModes`, `GridRowModesModel`, `GridDetailPanelContent`, `GridDetailPanelState`, `GridVirtualizationState`, `GridRenderContext`, `GridAggregationFunction`).
|
|
361
|
+
- The repository is type-checked in CI (`npm run typecheck`: library, tests and demo).
|
|
362
|
+
|
|
363
|
+
### Removed
|
|
364
|
+
|
|
365
|
+
- `GridThemeSkeleton.darkBaseColor` and `GridThemeSkeleton.darkHighlightColor` (they had no effect).
|
|
366
|
+
- The runtime underscore hierarchy fields on rows (see *Breaking*).
|
|
367
|
+
- The OS dark-mode (`prefers-color-scheme`) rules for the expand icon and detail panel; the theme palette colours them.
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## [2.1.0] — 2026-09-23
|
|
372
|
+
|
|
373
|
+
Fixes from a consumer defect report (migration of an ERP report writer from ag-grid) plus issues found while verifying it.
|
|
374
|
+
|
|
375
|
+
### Fixed
|
|
376
|
+
|
|
377
|
+
- **Row-grouping subtotals were wrong when data contained nulls** — `useRowGrouping` had its own copy of the aggregation functions that coerced `null` to `0` (`Number(v) || 0`). For `[10, null, 20]` a group showed `min` 0, `avg` 10 and `count` 3. It also ignored `unique` and `availableAggregationFunctions`. Group rows now use the same shared functions as the footer (`lib/utils/aggregation`), giving 10 / 15 / 2. Grouped exports (`getGroupedExportRows`) inherit the fix.
|
|
378
|
+
- **`min` / `max` could throw `RangeError` on very large datasets** — `Math.min(...values)` exceeds the engine's argument limit at roughly 120k values. Replaced with loops.
|
|
379
|
+
- **Expanded groups collapsed on every data change** — any new `rows` array (an inline edit, a live refresh) or a new-but-equal `rowGroupingModel` array reset expansion to the default. User choices are now overrides keyed by the grouping config, and are discarded only when `rowGroupingModel` or `defaultGroupingExpansionDepth` changes value.
|
|
380
|
+
- **`getVisibleRows` sorted the memoized tree's child arrays in place** under row grouping; it now sorts a copy.
|
|
381
|
+
- **Tree data reset user expansion whenever rows changed** (when `defaultGroupingExpansionDepth` was non-zero). With server-side tree data, a lazily expanded node could collapse as soon as its children arrived. Tree data now uses the same override model as row grouping, and the default expansion applies on the first render instead of after an effect.
|
|
382
|
+
- **`onRowExpansionChange` (server-side child fetch) was called inside a React state updater**, which React may run twice (always in StrictMode). It is now called exactly once per expand.
|
|
383
|
+
- **`useTreeData().getVisibleRows()` crashed when `filterModel` was omitted**, although the param is optional.
|
|
384
|
+
- **Rows were drawn in the wrong place when rows were pinned to the top.** `useGridVisibleRows` subtracted the pinned count from render-window indices that already exclude pinned rows. With N top-pinned rows, every row past the first screen was drawn N rows too low, and the bottom N rows of the viewport were left blank.
|
|
385
|
+
- **Keyboard navigation and `apiRef.scrollToIndexes` left the target row hidden below the fold.** The scroll math ignored the sticky header, so the row ended up about one header height below the visible area. Keyboard navigation also mapped pinned rows onto the wrong layout index. Both now share `scrollRowIntoView` and never scroll to pinned rows, which are always visible.
|
|
386
|
+
- **`valueFormatter` was dropped for every column once row grouping was on** — the injected hierarchy renderers fell back to the raw value. They now render the formatted value. *(Report D3)*
|
|
387
|
+
- **`slots.footer`, `slots.noRowsOverlay` and `slots.loadingOverlay` were typed and documented but never rendered.** All three are now wired. `footer` replaces the pagination area, as documented, and also receives `aggregationResult`, `rowCount`, `paginationModel`, `onPaginationModelChange` and `apiRef`. *(Report D2)*
|
|
388
|
+
|
|
389
|
+
### Added
|
|
390
|
+
|
|
391
|
+
- **`onRowDoubleClick`** on `DataGridProps`, in grid and list view. *(Report D6)*
|
|
392
|
+
- **`GridRenderCellParams.formattedValue`** — the `valueFormatter` output, now passed to `renderCell`.
|
|
393
|
+
- **`ColumnVisibilityPanel` and `ColumnVisibilityPanelProps` exported**, as the docs already claimed. *(Report D5)*
|
|
394
|
+
- **`ExcelAdvancedExportOptions.groupedRows`** — grouped reports in `exportToExcelAdvanced`, with Excel row outlining, numeric subtotals that keep `numFmt`, and `groupHeaderFillColor` / `groupSubtotalFillColor`. *(Report D7)*
|
|
395
|
+
- **Development-mode warnings** (skipped when `NODE_ENV === 'production'`):
|
|
396
|
+
- when the grid renders every row of a dataset larger than 200 rows because its container has no bounded height *(root cause of report D1)*;
|
|
397
|
+
- when `pagination` is passed with an active `rowGroupingModel` *(report D4)*.
|
|
398
|
+
- **Real-browser test project** — Vitest browser mode with Playwright/Chromium (`npm run test:browser`; `npm test` stays on jsdom). `@vitest/browser-playwright` and `playwright` are now declared devDependencies.
|
|
399
|
+
- **CI:** `.github/workflows/npm-publish.yml` runs unit and browser tests before publishing. It previously ran only lint and build, so a failing test could not block a release.
|
|
400
|
+
|
|
401
|
+
### Documentation
|
|
402
|
+
|
|
403
|
+
- `features/virtualization.md` — new "The grid needs a bounded height" section. It explains the flex `min-height: 0` trap and replaces the claim that grouping "works seamlessly" with virtualization. Report D1 turned out to be this: grouped rows *are* virtualized (a 25,000-row group renders ~20 DOM rows in a bounded container, verified in Chromium), but an unbounded container renders everything, and pagination had been hiding it. Also corrects the claims that columns are not virtualized and that the default overscan is 5.
|
|
404
|
+
- `features/tree-data-grouping.md`, `features/sorting-pagination.md` — pagination is ignored under row grouping (report D4); expansion and aggregation semantics.
|
|
405
|
+
- `features/export-guide.md` — CSV and basic Excel append **two** aggregation rows, labels then values (report D8); grouped advanced-Excel export.
|
|
406
|
+
- `customization/slots-api.md` — `footer` props. `components/column-visibility.md` — the examples showed `<ColumnVisibilityPanel />` with no props, which cannot work; replaced with real usage.
|
|
407
|
+
- `roadmap.md` — removed "upcoming" items that had already shipped (npm publishing, native PDF export, GitHub Pages deployment).
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
8
411
|
## [2.0.4] — 2026-09-10
|
|
9
412
|
|
|
10
413
|
### Added
|
|
@@ -23,7 +426,7 @@ Comprehensive accuracy audit — 32 issues corrected across 19 files:
|
|
|
23
426
|
- **Wrong defaults corrected**: `pageSizeOptions` (`[10,25,50]` → `[10,25,50,100]`), `pinCheckboxColumn`/`pinExpandColumn` (`false` → `true`), `noRowsLabel` (`'No rows'` → `'No Data'`) — in `API_REFERENCE.md`, `components/datagrid.md`, `features/sorting-pagination.md`, `features/selection.md`, `components/empty-state.md`
|
|
24
427
|
- **Missing API surface added**: `getAllFilteredRows()` and `getGroupedExportRows()` added to `GridApi` table; `groupLabel` field added to `GridRowMeta`; `groupedRows` option added to `PdfExportOptions`; `'unique'` added to aggregation function type in `components/aggregation-footer.md`
|
|
25
428
|
- **Non-existent API removed or corrected**: `'both'` is not a valid `getAggregationPosition` return (valid: `'inline' | 'footer' | null`); `disableColumnResize` DataGrid prop, `columnResizeHandle`/`columnVisibilityPanel`/`columnGroupHeader`/`tooltip` slots, `onColumnWidthChange` callback, `disableReorder` on `GridColDef`, `showQuickFilter` in `GridToolbarProps`, `toolbar`/`toolbarProps` DataGrid props — all documented as real but never existed; corrected throughout
|
|
26
|
-
- **Stale content updated**: `use-grid-scroll-sync.md` and `use-grid-virtualization.md` params/returns updated from old `scrollPosRef`/`scrollTick` pattern to current `scrollTop`/`scrollLeft`; `grid-row-meta.md` updated from "will be removed in v2" to "was removed in v2"; `roadmap.md` column virtualization claim corrected; `virtualization.md` "Aui DataGrid" placeholder fixed and `density` prop section added; `upgrade-guide` version and slots API corrected
|
|
429
|
+
- **Stale content updated**: `use-grid-scroll-sync.md` and `use-grid-virtualization.md` params/returns updated from old `scrollPosRef`/`scrollTick` pattern to current `scrollTop`/`scrollLeft`; `grid-row-meta.md` updated from "will be removed in v2" to "was removed in v2" *(correction, 2026-09-16: this specific change was itself inaccurate — the shim was never actually removed in v2.0; reverted to reflect that it is still present and deprecated)*; `roadmap.md` column virtualization claim corrected; `virtualization.md` "Aui DataGrid" placeholder fixed and `density` prop section added; `upgrade-guide` version and slots API corrected
|
|
27
430
|
|
|
28
431
|
---
|
|
29
432
|
|
|
@@ -190,10 +593,12 @@ Comprehensive accuracy audit — 32 issues corrected across 19 files:
|
|
|
190
593
|
- `docs/architecture/grid-row-meta.md` — architecture doc for `GridRowMeta` and `rowMetaMap` data flow.
|
|
191
594
|
|
|
192
595
|
### Changed
|
|
193
|
-
- `GridRowModel` no longer declares `_hasChildren`, `_treeDepth`, `_isExpanded`, `_groupingField`, `_groupingValue`, `_descendantCount` as typed properties. These fields remain on the row object at runtime (backward-compat shim
|
|
596
|
+
- `GridRowModel` no longer declares `_hasChildren`, `_treeDepth`, `_isExpanded`, `_groupingField`, `_groupingValue`, `_descendantCount` as typed properties. These fields remain on the row object at runtime (backward-compat shim; scheduled for removal in v2.0 at the time of this release — see correction below). Access hierarchy metadata via `params.rowMeta` instead.
|
|
194
597
|
|
|
195
598
|
### Deprecated
|
|
196
|
-
- `params.row._hasChildren` etc. — use `params.rowMeta?.hasChildren`. Runtime shim
|
|
599
|
+
- `params.row._hasChildren` etc. — use `params.rowMeta?.hasChildren`. Runtime shim scheduled for removal in v2.0 at the time of this release.
|
|
600
|
+
|
|
601
|
+
> **Correction (added retroactively):** the runtime shim removal described above did not ship in v2.0.0–v2.0.4. The underscore fields are still injected at runtime as of v2.0.4. Removal is deferred to a future major version. See `docs/architecture/grid-row-meta.md`.
|
|
197
602
|
|
|
198
603
|
---
|
|
199
604
|
|