@mui/x-data-grid 8.27.1 → 9.0.0-alpha.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 (60) hide show
  1. package/CHANGELOG.md +204 -5
  2. package/components/GridPagination.js +5 -4
  3. package/components/virtualization/GridVirtualScrollbar.js +1 -52
  4. package/constants/localeTextConstants.js +3 -2
  5. package/esm/components/GridPagination.js +5 -4
  6. package/esm/components/virtualization/GridVirtualScrollbar.js +1 -52
  7. package/esm/constants/localeTextConstants.js +3 -2
  8. package/esm/hooks/features/dataSource/useGridDataSourceBase.js +1 -0
  9. package/esm/hooks/features/pagination/gridPaginationUtils.js +1 -1
  10. package/esm/hooks/features/pagination/useGridRowCount.js +19 -3
  11. package/esm/index.js +1 -1
  12. package/esm/internals/utils/propValidation.js +1 -1
  13. package/esm/locales/beBY.js +3 -2
  14. package/esm/locales/bgBG.js +3 -2
  15. package/esm/locales/bnBD.js +3 -2
  16. package/esm/locales/daDK.js +3 -2
  17. package/esm/locales/elGR.js +3 -2
  18. package/esm/locales/faIR.js +3 -2
  19. package/esm/locales/fiFI.js +3 -2
  20. package/esm/locales/huHU.js +3 -2
  21. package/esm/locales/hyAM.js +3 -2
  22. package/esm/locales/isIS.js +3 -2
  23. package/esm/locales/nlNL.js +3 -2
  24. package/esm/locales/roRO.js +3 -2
  25. package/esm/locales/ruRU.js +3 -2
  26. package/esm/locales/svSE.js +3 -2
  27. package/esm/locales/thTH.d.ts +2 -0
  28. package/esm/locales/thTH.js +297 -0
  29. package/esm/locales/trTR.js +3 -2
  30. package/esm/locales/ukUA.js +3 -2
  31. package/esm/locales/urPK.js +3 -2
  32. package/esm/locales/viVN.js +3 -2
  33. package/esm/material/index.js +1 -1
  34. package/hooks/features/dataSource/useGridDataSourceBase.js +1 -0
  35. package/hooks/features/pagination/gridPaginationUtils.js +1 -1
  36. package/hooks/features/pagination/useGridRowCount.js +19 -3
  37. package/index.js +1 -1
  38. package/internals/utils/propValidation.js +1 -1
  39. package/locales/beBY.js +3 -2
  40. package/locales/bgBG.js +3 -2
  41. package/locales/bnBD.js +3 -2
  42. package/locales/daDK.js +3 -2
  43. package/locales/elGR.js +3 -2
  44. package/locales/faIR.js +3 -2
  45. package/locales/fiFI.js +3 -2
  46. package/locales/huHU.js +3 -2
  47. package/locales/hyAM.js +3 -2
  48. package/locales/isIS.js +3 -2
  49. package/locales/nlNL.js +3 -2
  50. package/locales/roRO.js +3 -2
  51. package/locales/ruRU.js +3 -2
  52. package/locales/svSE.js +3 -2
  53. package/locales/thTH.d.ts +2 -0
  54. package/locales/thTH.js +303 -0
  55. package/locales/trTR.js +3 -2
  56. package/locales/ukUA.js +3 -2
  57. package/locales/urPK.js +3 -2
  58. package/locales/viVN.js +3 -2
  59. package/material/index.js +1 -1
  60. package/package.json +5 -5
package/CHANGELOG.md CHANGED
@@ -1,13 +1,212 @@
1
1
  # Changelog
2
2
 
3
- > For full v8 changelog, please refer to the [v.8x branch](https://github.com/mui/mui-x/blob/v8.x/CHANGELOG.md).
3
+ ## 9.0.0-alpha.0
4
4
 
5
- All notable changes to this project will be documented in this file.
6
- See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+ _Feb 16, 2026_
7
6
 
8
- ## v8.27.1
7
+ We'd like to extend a big thank you to the 21 contributors who made this release possible. Here are some highlights ✨:
8
+
9
+ - Add support for virtualized items on `<RichTreeViewPro />`:
10
+
11
+ ```tsx
12
+ <RichTreeViewPro items={ITEMS} virtualization itemHeight={48} />
13
+ ```
14
+
15
+ - Add Thai (`thTH`) locale on the Data Grid and the Date and Time Pickers (#21116) @siriwatknp
16
+ - Add a new `AdapterDayjsBuddhist` adapter for Date and Time Pickers (#20984) @siriwatknp
17
+ - Add support for virtualization in the rich tree view (#20780) @flaviendelangle
18
+ - Add WebGL renderer to Heatmap (#20756) @bernardobelchior
19
+
20
+ Special thanks go out to these community members for their valuable contributions:
21
+ @jhe-iqbis
22
+
23
+ The following team members contributed to this release:
24
+ @alexfauquette, @arminmeh, @bernardobelchior, @brijeshb42, @cherniavskii, @dav-is, @flaviendelangle, @Janpot, @JCQuintas, @mapache-salvaje, @MBilalShafi, @michelengelen, @mj12albert, @noraleonte, @oliviertassinari, @rita-codes, @romgrk, @sai6855, @siriwatknp
25
+
26
+ ### Data Grid
27
+
28
+ #### `@mui/x-data-grid@9.0.0-alpha.0`
29
+
30
+ - [DataGrid] Update default `logicOperator` behavior in filtering docs (#21098) @michelengelen
31
+ - [DataGrid] Add `thTH` locale (#21116) @siriwatknp
32
+ - [DataGrid] Fix initial filter value state in CustomMultiValueOperator demo (#21217) @sai6855
33
+
34
+ #### `@mui/x-data-grid-pro@9.0.0-alpha.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
35
+
36
+ Same changes as in `@mui/x-data-grid@9.0.0-alpha.0`, plus:
37
+
38
+ - [DataGridPro] Cleanup outdated rows on `dataSource` reference update (#21138) @MBilalShafi
39
+
40
+ #### `@mui/x-data-grid-premium@9.0.0-alpha.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
41
+
42
+ Same changes as in `@mui/x-data-grid-pro@9.0.0-alpha.0`.
43
+
44
+ ### Date and Time Pickers
45
+
46
+ #### `@mui/x-date-pickers@9.0.0-alpha.0`
47
+
48
+ - [pickers] Add `AdapterDayjsBuddhist` adapter (#20984) @siriwatknp
49
+ - [pickers] Add `thTH` locale (#21116) @siriwatknp
50
+
51
+ #### `@mui/x-date-pickers-pro@9.0.0-alpha.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
52
+
53
+ Same changes as in `@mui/x-date-pickers@9.0.0-alpha.0`.
54
+
55
+ ### Charts
56
+
57
+ #### `@mui/x-charts@9.0.0-alpha.0`
58
+
59
+ - [charts] Add Legend actions (#20404) @JCQuintas
60
+ - [charts] Add `Chart` suffix to MUI Classes (#21042) @JCQuintas
61
+ - [charts] Add `axesGap` props to put space between axes (#20904) @alexfauquette
62
+ - [charts] Add `cleanIdentifier` function to charts series instance (#20832) @JCQuintas
63
+ - [charts] Add `initialHiddenItems` prop to set initial state (#20894) @JCQuintas
64
+ - [charts] Add `useXAxisCoordinates` and `useYAxisCoordinates` hooks (#20972) @bernardobelchior
65
+ - [charts] Add axis slots and expose axis ticks hooks (#20935) @bernardobelchior
66
+ - [charts] Change `line` legend marker to be a line (#21059) @JCQuintas
67
+ - [charts] Codemod test pattern with function (#21111) @JCQuintas
68
+ - [charts] Control the item tooltip (#20617) @alexfauquette
69
+ - [charts] Enable keyboard navigation in radar chart (#20765) @alexfauquette
70
+ - [charts] Export `CartesianChartSeriesType` and `StackableChartSeriesType` (#21012) @bernardobelchior
71
+ - [charts] Export plugins from premium (#20866) @JCQuintas
72
+ - [charts] Filter hidden series from axis tooltip (#21273) @Copilot
73
+ - [charts] Filter hidden series from axis tooltip (#21273) @Copilot
74
+ - [charts] Fix rename `getSVGPoint` to `getChartPoint` (#21335) @bernardobelchior
75
+ - [charts] Fix cleanup function in useChartInteractionListener to correctly remove event listeners with options (#21218) @sai6855
76
+ - [charts] Fix import rename in codemod (#21112) @JCQuintas
77
+ - [charts] Fix multiple exports of `HighlightScope` (#21270) @bernardobelchior
78
+ - [charts] Fix test inconsistency in charts (#20907) @JCQuintas
79
+ - [charts] Fix tooltip position for stacked line series (#20901) @alexfauquette
80
+ - [charts] Make Highlight scope a generic (#21189) @alexfauquette
81
+ - [charts] Make `LegendItemParams.type` required (#21003) @alexfauquette
82
+ - [charts] Make `seriesId` a string only (#20997) @alexfauquette
83
+ - [charts] Make the `useChartRootRef` support typing parameter (#21023) @alexfauquette
84
+ - [charts] Memoize HeatmapItem to avoid re-render when fading/highlighting (#20865) @bernardobelchior
85
+ - [charts] Move axis id to `data-axis-id` attribute instead of class (#21037) @JCQuintas
86
+ - [charts] Move `cleanIdentifier` and `serializeIdentifier` instance methods to `useChartSeriesConfig` plugin (#21025) @JCQuintas
87
+ - [charts] Move `seriesConfig` to `useChartSeriesConfig` plugin (#21004) @JCQuintas
88
+ - [charts] Move element refs to `useChartElementRef` plugin (#21099) @JCQuintas
89
+ - [charts] Move types related to `seriesConfig` into the `useChartSeriesConfig` plugin folder (#21026) @JCQuintas
90
+ - [charts] Remove `data-has-focused-item` from `ChartsSurface` (#21255) @bernardobelchior
91
+ - [charts] Remove default generic of item identifiers (#21182) @alexfauquette
92
+ - [charts] Remove deprecated `id` from `LegendItemParams` (#21055) @alexfauquette
93
+ - [charts] Remove deprecated `ChartApi` export from `ChartContainer` (#20975) @JCQuintas
94
+ - [charts] Remove deprecated `useAxisTooltip` in favor of `useAxesTooltip` (#20962) @Copilot
95
+ - [charts] Remove deprecated series type helpers and functions (#20998) @alexfauquette
96
+ - [charts] Rename `ChartContainer` to `ChartsContainer` (#21173) @JCQuintas
97
+ - [charts] Rename `getSVGPoint` to `getChartPoint` (#21322) @bernardobelchior
98
+ - [charts] Rename `TickItemType` to `TickItem` (#21008) @bernardobelchior
99
+ - [charts] Replace props `id` by `seriesId` when necessary (#21057) @alexfauquette
100
+ - [charts] Revert `touch-action: pan-y` removal when zoom is disabled (#20852) @bernardobelchior
101
+ - [charts] The `useXxxSeries([])` return empty array (#21001) @alexfauquette
102
+ - [charts] Use `NumberValue` in domain limit function (#21054) @JCQuintas
103
+
104
+ #### `@mui/x-charts-pro@9.0.0-alpha.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
9
105
 
10
- <!-- generated comparing v8.27.0..v8.x -->
106
+ Same changes as in `@mui/x-charts@9.0.0-alpha.0`, plus:
107
+
108
+ - [charts-pro] Add border radius to heatmap (#20931) @bernardobelchior
109
+ - [charts-pro] Add keyboard navigation to funnel (#20766) @alexfauquette
110
+ - [charts-pro] Add keyboard navigation to heatmap (#20786) @alexfauquette
111
+ - [charts-pro] Add keyboard navigation to sankey (#20777) @alexfauquette
112
+ - [charts-pro] Fix Heatmap's `onItemClick` not triggering (#21016) @bernardobelchior
113
+ - [charts-pro] Fix crash when two same-direction axes have a zoom preview (#20916) @bernardobelchior
114
+ - [charts-pro] Handle edge case in export image (#21190) @bernardobelchior
115
+ - [charts-pro] Prefer global pointer interaction tracker in Heatmap (#20697) @bernardobelchior
116
+ - [charts-pro] Support composition for Sankey (#20604) @alexfauquette
117
+ - [charts-pro] Update Heatmap identifier (#21124) @alexfauquette
118
+ - [charts-pro] Update default value of `hideLegend` prop in `Heatmap` (#20961) @Copilot
119
+
120
+ #### `@mui/x-charts-premium@9.0.0-alpha.0` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
121
+
122
+ Same changes as in `@mui/x-charts-pro@9.0.0-alpha.0`, plus:
123
+
124
+ - [charts-premium] Add WebGL renderer to Heatmap (#20756) @bernardobelchior
125
+ - [charts-premium] Add `ChartContainerPremium` (#20910) @bernardobelchior
126
+ - [charts-premium] Add `HeatmapPremium` (#20930) @bernardobelchior
127
+ - [charts-premium] Add keyboard navigation to range-bar (#21272) @alexfauquette
128
+ - [charts-premium] Extract `HeatmapSVGPlot` from `HeatmapPlot` component (#21015) @bernardobelchior
129
+ - [charts-premium] Fix `ChartDataProviderPremium` tests (#20868) @bernardobelchior
130
+ - [charts-premium] Fix links in comments for chart containers and data providers (#21105) @bernardobelchior
131
+
132
+ ### Tree View
133
+
134
+ #### `@mui/x-tree-view@9.0.0-alpha.0`
135
+
136
+ _No changes._
137
+
138
+ #### `@mui/x-tree-view-pro@9.0.0-alpha.0` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
139
+
140
+ Same changes as in `@mui/x-tree-view@9.0.0-alpha.0`, plus:
141
+
142
+ - [RichTreeViewPro] Add support for virtualization (#20780) @flaviendelangle
143
+
144
+ ### Codemod
145
+
146
+ #### `@mui/x-codemod@9.0.0-alpha.0`
147
+
148
+ - [codemod] Document and Clean the codemod utils (#21014) @alexfauquette
149
+
150
+ ### Docs
151
+
152
+ - [docs] Add focus highlight in composition snipets (#20614) @alexfauquette
153
+ - [docs] Add simple candlestick chart demo (#20912) @bernardobelchior
154
+ - [docs] Fix Waterfall Chart documentation badge from Pro to Premium (#20888) @Copilot
155
+ - [docs] Fix broken links on Data Grid Editing sub-pages (#20911) @arminmeh
156
+ - [docs] Fix docs API for HeatmapPremium (#21137) @alexfauquette
157
+ - [docs] Fix horizontal overflow in heatmap docs (#20968) @bernardobelchior
158
+ - [docs] Move Range Bar Chart to existing charts (#21120) @bernardobelchior
159
+ - [docs] Prepare the scheduler doc for the alpha (#21268) @flaviendelangle
160
+ - [docs] Rewording of the heatmap item click (#20987) @alexfauquette
161
+ - [scheduler][docs] Create the Quickstart page (#20913) @flaviendelangle
162
+ - [charts][docs] Revise the Charts CSP doc (#20906) @mapache-salvaje
163
+ - [charts][docs] Revise the Charts Composition doc (#20032) @mapache-salvaje
164
+ - [charts][docs] Revise the Charts Hooks Overview doc (#20921) @mapache-salvaje
165
+ - [charts][docs] Revise the Charts Legend doc (#20821) @mapache-salvaje
166
+ - [charts][docs] Revise the Charts Localization doc (#20800) @mapache-salvaje
167
+ - [charts][docs] Revise the Charts Plugins doc (#20933) @mapache-salvaje
168
+ - [charts][docs] Revise the Charts Stacking doc (#20830) @mapache-salvaje
169
+ - [charts][docs] Revise the Charts Styling doc (#20835) @mapache-salvaje
170
+ - [charts][docs] Revise the Charts Toolbar doc (#20867) @mapache-salvaje
171
+ - [charts][docs] Revise the Charts Tooltip doc (#20869) @mapache-salvaje
172
+ - [charts][docs] Revise the Charts Zoom and Pan doc (#20893) @mapache-salvaje
173
+ - [DataGrid][docs] Add a recipe for handling long text cell (#20754) @siriwatknp
174
+ - [DataGrid][docs] Add high-level competitor comparison to Overview doc (DX-117) (#20870) @mapache-salvaje
175
+ - [DataGrid][docs] Remove Bundling section from quickstart (#21177) @MBilalShafi
176
+
177
+ ### Core
178
+
179
+ - [code-infra] Add `MUI_TEST_ENV` global (#21187) @Janpot
180
+ - [code-infra] Fix `material-ui/disallow-react-api-in-server-components` (#20909) @JCQuintas
181
+ - [code-infra] Fix `renameImports` codemod not preserving comments (#20977) @JCQuintas
182
+ - [code-infra] Fix the label comparison to use lower case (#20934) @brijeshb42
183
+ - [code-infra] Github action to sync title and label (#20922) @brijeshb42
184
+ - [code-infra] Ignore scheduler demo with random data (#20982) @JCQuintas
185
+ - [code-infra] Improve `codemod` testing setup (#20981) @JCQuintas
186
+ - [code-infra] Only ignore renovate[bot] in changelog generation script (#21185) @bernardobelchior
187
+ - [code-infra] Prepare for v9 (#20860) @JCQuintas
188
+ - [code-infra] Set `rasterizehtml` version in pnpm catalog (#21175) @bernardobelchior
189
+ - [code-infra] Update codeowners (#20886) @JCQuintas
190
+ - [code-infra] V9 preparation (#20928) @JCQuintas
191
+ - [code-infra] eslint rule rename (#21172) @Janpot
192
+ - [code-infra][docs] V9 charts migration doc kickoff (#20973) @JCQuintas
193
+ - [docs-infra] Add Cookie Banner and Analytics Provider (#21228) @dav-is
194
+ - [docs-infra] Fix missing slots section on API page (#20915) @Janpot
195
+ - [docs-infra] Fix two broken links (#20914) @Janpot
196
+ - [docs-infra] Port demo changes (#20971) @Janpot
197
+ - [internal] Add information about codemods to AGENTS.md (#21011) @bernardobelchior
198
+ - [internal] Fix codemod versioning instructions in `AGENTS.md` (#21024) @bernardobelchior
199
+ - [internal] Fix missing generated props in master (#21142) @bernardobelchior
200
+ - [internal] Headless sorting plugin (#21089) @arminmeh
201
+ - [internal] Remove duplicate code (#20896) @oliviertassinari
202
+
203
+ ### Miscellaneous
204
+
205
+ - Bump next to ^15.5.11 (#21171) @Copilot
206
+ - [core] Fix CI (#21223) @flaviendelangle
207
+ - [PoC] Headless data grid (#20645) @cherniavskii
208
+
209
+ ## v8.27.1
11
210
 
12
211
  _Feb 13, 2026_
13
212
 
@@ -34,14 +34,15 @@ function GridPagination() {
34
34
  paginationMode,
35
35
  loading
36
36
  } = rootProps;
37
- const disabled = rowCount === -1 && paginationMode === 'server' && loading;
37
+ const unknownRowCount = rowCount == null || rowCount === -1;
38
+ const disabled = unknownRowCount && paginationMode === 'server' && loading;
38
39
  const lastPage = React.useMemo(() => Math.max(0, pageCount - 1), [pageCount]);
39
40
  const computedPage = React.useMemo(() => {
40
- if (rowCount === -1) {
41
+ if (unknownRowCount) {
41
42
  return paginationModel.page;
42
43
  }
43
44
  return paginationModel.page <= lastPage ? paginationModel.page : lastPage;
44
- }, [lastPage, paginationModel.page, rowCount]);
45
+ }, [lastPage, paginationModel.page, unknownRowCount]);
45
46
  const handlePageSizeChange = React.useCallback(pageSize => {
46
47
  apiRef.current.setPageSize(pageSize);
47
48
  }, [apiRef]);
@@ -73,7 +74,7 @@ function GridPagination() {
73
74
  const pageSizeOptions = isPageSizeIncludedInPageSizeOptions(paginationModel.pageSize) ? rootProps.pageSizeOptions : [];
74
75
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(GridPaginationRoot, (0, _extends2.default)({
75
76
  as: rootProps.slots.basePagination,
76
- count: rowCount,
77
+ count: rowCount ?? -1,
77
78
  page: computedPage,
78
79
  rowsPerPageOptions: pageSizeOptions,
79
80
  rowsPerPage: paginationModel.pageSize,
@@ -9,11 +9,8 @@ Object.defineProperty(exports, "__esModule", {
9
9
  exports.scrollbarSizeCssExpression = exports.ScrollbarCorner = exports.GridVirtualScrollbar = void 0;
10
10
  var React = _interopRequireWildcard(require("react"));
11
11
  var _styles = require("@mui/material/styles");
12
- var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
13
- var _useForkRef = _interopRequireDefault(require("@mui/utils/useForkRef"));
14
12
  var _composeClasses = _interopRequireDefault(require("@mui/utils/composeClasses"));
15
13
  var _forwardRef = require("@mui/x-internals/forwardRef");
16
- var _useOnMount = require("../../hooks/utils/useOnMount");
17
14
  var _useGridPrivateApiContext = require("../../hooks/utils/useGridPrivateApiContext");
18
15
  var _hooks = require("../../hooks");
19
16
  var _useGridRootProps = require("../../hooks/utils/useGridRootProps");
@@ -91,64 +88,16 @@ const ScrollbarCorner = exports.ScrollbarCorner = (0, _styles.styled)(Scrollbar,
91
88
  const GridVirtualScrollbar = exports.GridVirtualScrollbar = (0, _forwardRef.forwardRef)(function GridVirtualScrollbar(props, ref) {
92
89
  const apiRef = (0, _useGridPrivateApiContext.useGridPrivateApiContext)();
93
90
  const rootProps = (0, _useGridRootProps.useGridRootProps)();
94
- const isLocked = React.useRef(false);
95
- const lastPosition = React.useRef(0);
96
- const scrollbarRef = React.useRef(null);
97
91
  const classes = useUtilityClasses(rootProps, props.position);
98
92
  const dimensions = (0, _hooks.useGridSelector)(apiRef, _hooks.gridDimensionsSelector);
99
93
  const propertyDimension = props.position === 'vertical' ? 'height' : 'width';
100
- const propertyScroll = props.position === 'vertical' ? 'scrollTop' : 'scrollLeft';
101
- const propertyScrollPosition = props.position === 'vertical' ? 'top' : 'left';
102
94
  const scrollbarInnerSize = props.position === 'horizontal' ? dimensions.minimumSize.width : dimensions.minimumSize.height - dimensions.headersTotalHeight;
103
- const onScrollerScroll = (0, _useEventCallback.default)(() => {
104
- const scrollbar = scrollbarRef.current;
105
- const scrollPosition = props.scrollPosition.current;
106
- if (!scrollbar) {
107
- return;
108
- }
109
- if (scrollPosition[propertyScrollPosition] === lastPosition.current) {
110
- return;
111
- }
112
- lastPosition.current = scrollPosition[propertyScrollPosition];
113
- if (isLocked.current) {
114
- isLocked.current = false;
115
- return;
116
- }
117
- isLocked.current = true;
118
- scrollbar[propertyScroll] = props.scrollPosition.current[propertyScrollPosition];
119
- });
120
- const onScrollbarScroll = (0, _useEventCallback.default)(() => {
121
- const scroller = apiRef.current.virtualScrollerRef.current;
122
- const scrollbar = scrollbarRef.current;
123
- if (!scrollbar) {
124
- return;
125
- }
126
- if (isLocked.current) {
127
- isLocked.current = false;
128
- return;
129
- }
130
- isLocked.current = true;
131
- scroller[propertyScroll] = scrollbar[propertyScroll];
132
- });
133
- (0, _useOnMount.useOnMount)(() => {
134
- const scroller = apiRef.current.virtualScrollerRef.current;
135
- const scrollbar = scrollbarRef.current;
136
- const options = {
137
- passive: true
138
- };
139
- scroller.addEventListener('scroll', onScrollerScroll, options);
140
- scrollbar.addEventListener('scroll', onScrollbarScroll, options);
141
- return () => {
142
- scroller.removeEventListener('scroll', onScrollerScroll, options);
143
- scrollbar.removeEventListener('scroll', onScrollbarScroll, options);
144
- };
145
- });
146
95
  const Container = props.position === 'vertical' ? ScrollbarVertical : ScrollbarHorizontal;
147
96
  const scrollbarInnerStyle = React.useMemo(() => ({
148
97
  [propertyDimension]: `${scrollbarInnerSize}px`
149
98
  }), [propertyDimension, scrollbarInnerSize]);
150
99
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(Container, {
151
- ref: (0, _useForkRef.default)(ref, scrollbarRef),
100
+ ref: ref,
152
101
  className: classes.root,
153
102
  tabIndex: -1,
154
103
  "aria-hidden": "true"
@@ -171,11 +171,12 @@ const GRID_DEFAULT_LOCALE_TEXT = exports.GRID_DEFAULT_LOCALE_TEXT = {
171
171
  count,
172
172
  estimated
173
173
  }) => {
174
+ const unknownRowCount = count == null || count === -1;
174
175
  if (!estimated) {
175
- return `${from}–${to} of ${count !== -1 ? count : `more than ${to}`}`;
176
+ return `${from}–${to} of ${!unknownRowCount ? count : `more than ${to}`}`;
176
177
  }
177
178
  const estimatedLabel = estimated && estimated > to ? `around ${estimated}` : `more than ${to}`;
178
- return `${from}–${to} of ${count !== -1 ? count : estimatedLabel}`;
179
+ return `${from}–${to} of ${!unknownRowCount ? count : estimatedLabel}`;
179
180
  },
180
181
  paginationItemAriaLabel: type => {
181
182
  if (type === 'first') {
@@ -27,14 +27,15 @@ function GridPagination() {
27
27
  paginationMode,
28
28
  loading
29
29
  } = rootProps;
30
- const disabled = rowCount === -1 && paginationMode === 'server' && loading;
30
+ const unknownRowCount = rowCount == null || rowCount === -1;
31
+ const disabled = unknownRowCount && paginationMode === 'server' && loading;
31
32
  const lastPage = React.useMemo(() => Math.max(0, pageCount - 1), [pageCount]);
32
33
  const computedPage = React.useMemo(() => {
33
- if (rowCount === -1) {
34
+ if (unknownRowCount) {
34
35
  return paginationModel.page;
35
36
  }
36
37
  return paginationModel.page <= lastPage ? paginationModel.page : lastPage;
37
- }, [lastPage, paginationModel.page, rowCount]);
38
+ }, [lastPage, paginationModel.page, unknownRowCount]);
38
39
  const handlePageSizeChange = React.useCallback(pageSize => {
39
40
  apiRef.current.setPageSize(pageSize);
40
41
  }, [apiRef]);
@@ -66,7 +67,7 @@ function GridPagination() {
66
67
  const pageSizeOptions = isPageSizeIncludedInPageSizeOptions(paginationModel.pageSize) ? rootProps.pageSizeOptions : [];
67
68
  return /*#__PURE__*/_jsx(GridPaginationRoot, _extends({
68
69
  as: rootProps.slots.basePagination,
69
- count: rowCount,
70
+ count: rowCount ?? -1,
70
71
  page: computedPage,
71
72
  rowsPerPageOptions: pageSizeOptions,
72
73
  rowsPerPage: paginationModel.pageSize,
@@ -2,11 +2,8 @@
2
2
 
3
3
  import * as React from 'react';
4
4
  import { styled } from '@mui/material/styles';
5
- import useEventCallback from '@mui/utils/useEventCallback';
6
- import useForkRef from '@mui/utils/useForkRef';
7
5
  import composeClasses from '@mui/utils/composeClasses';
8
6
  import { forwardRef } from '@mui/x-internals/forwardRef';
9
- import { useOnMount } from "../../hooks/utils/useOnMount.js";
10
7
  import { useGridPrivateApiContext } from "../../hooks/utils/useGridPrivateApiContext.js";
11
8
  import { gridDimensionsSelector, useGridSelector } from "../../hooks/index.js";
12
9
  import { useGridRootProps } from "../../hooks/utils/useGridRootProps.js";
@@ -84,64 +81,16 @@ export const ScrollbarCorner = styled(Scrollbar, {
84
81
  const GridVirtualScrollbar = forwardRef(function GridVirtualScrollbar(props, ref) {
85
82
  const apiRef = useGridPrivateApiContext();
86
83
  const rootProps = useGridRootProps();
87
- const isLocked = React.useRef(false);
88
- const lastPosition = React.useRef(0);
89
- const scrollbarRef = React.useRef(null);
90
84
  const classes = useUtilityClasses(rootProps, props.position);
91
85
  const dimensions = useGridSelector(apiRef, gridDimensionsSelector);
92
86
  const propertyDimension = props.position === 'vertical' ? 'height' : 'width';
93
- const propertyScroll = props.position === 'vertical' ? 'scrollTop' : 'scrollLeft';
94
- const propertyScrollPosition = props.position === 'vertical' ? 'top' : 'left';
95
87
  const scrollbarInnerSize = props.position === 'horizontal' ? dimensions.minimumSize.width : dimensions.minimumSize.height - dimensions.headersTotalHeight;
96
- const onScrollerScroll = useEventCallback(() => {
97
- const scrollbar = scrollbarRef.current;
98
- const scrollPosition = props.scrollPosition.current;
99
- if (!scrollbar) {
100
- return;
101
- }
102
- if (scrollPosition[propertyScrollPosition] === lastPosition.current) {
103
- return;
104
- }
105
- lastPosition.current = scrollPosition[propertyScrollPosition];
106
- if (isLocked.current) {
107
- isLocked.current = false;
108
- return;
109
- }
110
- isLocked.current = true;
111
- scrollbar[propertyScroll] = props.scrollPosition.current[propertyScrollPosition];
112
- });
113
- const onScrollbarScroll = useEventCallback(() => {
114
- const scroller = apiRef.current.virtualScrollerRef.current;
115
- const scrollbar = scrollbarRef.current;
116
- if (!scrollbar) {
117
- return;
118
- }
119
- if (isLocked.current) {
120
- isLocked.current = false;
121
- return;
122
- }
123
- isLocked.current = true;
124
- scroller[propertyScroll] = scrollbar[propertyScroll];
125
- });
126
- useOnMount(() => {
127
- const scroller = apiRef.current.virtualScrollerRef.current;
128
- const scrollbar = scrollbarRef.current;
129
- const options = {
130
- passive: true
131
- };
132
- scroller.addEventListener('scroll', onScrollerScroll, options);
133
- scrollbar.addEventListener('scroll', onScrollbarScroll, options);
134
- return () => {
135
- scroller.removeEventListener('scroll', onScrollerScroll, options);
136
- scrollbar.removeEventListener('scroll', onScrollbarScroll, options);
137
- };
138
- });
139
88
  const Container = props.position === 'vertical' ? ScrollbarVertical : ScrollbarHorizontal;
140
89
  const scrollbarInnerStyle = React.useMemo(() => ({
141
90
  [propertyDimension]: `${scrollbarInnerSize}px`
142
91
  }), [propertyDimension, scrollbarInnerSize]);
143
92
  return /*#__PURE__*/_jsx(Container, {
144
- ref: useForkRef(ref, scrollbarRef),
93
+ ref: ref,
145
94
  className: classes.root,
146
95
  tabIndex: -1,
147
96
  "aria-hidden": "true"
@@ -165,11 +165,12 @@ export const GRID_DEFAULT_LOCALE_TEXT = {
165
165
  count,
166
166
  estimated
167
167
  }) => {
168
+ const unknownRowCount = count == null || count === -1;
168
169
  if (!estimated) {
169
- return `${from}–${to} of ${count !== -1 ? count : `more than ${to}`}`;
170
+ return `${from}–${to} of ${!unknownRowCount ? count : `more than ${to}`}`;
170
171
  }
171
172
  const estimatedLabel = estimated && estimated > to ? `around ${estimated}` : `more than ${to}`;
172
- return `${from}–${to} of ${count !== -1 ? count : estimatedLabel}`;
173
+ return `${from}–${to} of ${!unknownRowCount ? count : estimatedLabel}`;
173
174
  },
174
175
  paginationItemAriaLabel: type => {
175
176
  if (type === 'first') {
@@ -203,6 +203,7 @@ export const useGridDataSourceBase = (apiRef, props, options = {}) => {
203
203
  return undefined;
204
204
  }
205
205
  if (props.dataSource) {
206
+ apiRef.current.setRows([]);
206
207
  apiRef.current.dataSource.cache.clear();
207
208
  apiRef.current.dataSource.fetchRows();
208
209
  }
@@ -5,7 +5,7 @@ export const getPageCount = (rowCount, pageSize, page) => {
5
5
  if (pageSize > 0 && rowCount > 0) {
6
6
  return Math.ceil(rowCount / pageSize);
7
7
  }
8
- if (rowCount === -1) {
8
+ if (rowCount === -1 || rowCount == null) {
9
9
  // With unknown row-count, we can assume a page after the current one
10
10
  return page + 2;
11
11
  }
@@ -11,10 +11,11 @@ import { gridPaginationRowCountSelector, gridPaginationMetaSelector, gridPaginat
11
11
  export const useGridRowCount = (apiRef, props) => {
12
12
  const logger = useGridLogger(apiRef, 'useGridRowCount');
13
13
  const previousPageSize = useLazyRef(() => gridPaginationModelSelector(apiRef).pageSize);
14
+ const onRowCountChangeProp = props.onRowCountChange;
14
15
  apiRef.current.registerControlState({
15
16
  stateId: 'paginationRowCount',
16
17
  propModel: props.rowCount,
17
- propOnChange: props.onRowCountChange,
18
+ propOnChange: onRowCountChangeProp,
18
19
  stateSelector: gridPaginationRowCountSelector,
19
20
  changeEvent: 'rowCountChange'
20
21
  });
@@ -28,12 +29,26 @@ export const useGridRowCount = (apiRef, props) => {
28
29
  return;
29
30
  }
30
31
  logger.debug("Setting 'rowCount' to", newRowCount);
32
+ if (rowCountState == null || rowCountState === -1) {
33
+ const newState = _extends({}, apiRef.current.state, {
34
+ pagination: _extends({}, apiRef.current.state.pagination, {
35
+ rowCount: newRowCount
36
+ })
37
+ });
38
+ apiRef.current.state = newState;
39
+ apiRef.current.store.update(newState);
40
+ apiRef.current.publishEvent('rowCountChange', newRowCount);
41
+ if (onRowCountChangeProp) {
42
+ onRowCountChangeProp(newRowCount);
43
+ }
44
+ return;
45
+ }
31
46
  apiRef.current.setState(state => _extends({}, state, {
32
47
  pagination: _extends({}, state.pagination, {
33
48
  rowCount: newRowCount
34
49
  })
35
50
  }));
36
- }, [apiRef, logger]);
51
+ }, [apiRef, logger, onRowCountChangeProp]);
37
52
  const paginationRowCountApi = {
38
53
  setRowCount
39
54
  };
@@ -110,7 +125,8 @@ export const useGridRowCount = (apiRef, props) => {
110
125
  }
111
126
  return undefined;
112
127
  }, (_, isLastPageOrRowCount) => {
113
- if (isLastPageOrRowCount === true && gridPaginationRowCountSelector(apiRef) !== -1) {
128
+ const rowCount = gridPaginationRowCountSelector(apiRef);
129
+ if (isLastPageOrRowCount === true && (rowCount == null || rowCount === -1)) {
114
130
  const visibleTopLevelRowCount = gridFilteredTopLevelRowCountSelector(apiRef);
115
131
  const paginationModel = gridPaginationModelSelector(apiRef);
116
132
  apiRef.current.setRowCount(paginationModel.pageSize * paginationModel.page + visibleTopLevelRowCount);
package/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v8.27.1
2
+ * @mui/x-data-grid v9.0.0-alpha.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -1,7 +1,7 @@
1
1
  import { warnOnce } from '@mui/x-internals/warning';
2
2
  import { isNumber } from "../../utils/utils.js";
3
3
  import { GridSignature } from "../../constants/signature.js";
4
- export const propValidatorsDataGrid = [props => props.autoPageSize && props.autoHeight && ['MUI X: `<DataGrid autoPageSize={true} autoHeight={true} />` are not valid props.', 'You cannot use both the `autoPageSize` and `autoHeight` props at the same time because `autoHeight` scales the height of the Data Grid according to the `pageSize`.', '', 'Please remove one of these two props.'].join('\n') || undefined, props => props.paginationMode === 'client' && props.paginationMeta != null && ['MUI X: Usage of the `paginationMeta` prop with client-side pagination (`paginationMode="client"`) has no effect.', '`paginationMeta` is only meant to be used with `paginationMode="server"`.'].join('\n') || undefined, props => props.signature === GridSignature.DataGrid && props.paginationMode === 'client' && isNumber(props.rowCount) && ['MUI X: Usage of the `rowCount` prop with client side pagination (`paginationMode="client"`) has no effect.', '`rowCount` is only meant to be used with `paginationMode="server"`.'].join('\n') || undefined, props => props.paginationMode === 'server' && props.rowCount == null && !props.dataSource && ["MUI X: The `rowCount` prop must be passed using `paginationMode='server'`", 'For more detail, see http://mui.com/components/data-grid/pagination/#index-based-pagination'].join('\n') || undefined];
4
+ export const propValidatorsDataGrid = [props => props.autoPageSize && props.autoHeight && ['MUI X: `<DataGrid autoPageSize={true} autoHeight={true} />` are not valid props.', 'You cannot use both the `autoPageSize` and `autoHeight` props at the same time because `autoHeight` scales the height of the Data Grid according to the `pageSize`.', '', 'Please remove one of these two props.'].join('\n') || undefined, props => props.paginationMode === 'client' && props.paginationMeta != null && ['MUI X: Usage of the `paginationMeta` prop with client-side pagination (`paginationMode="client"`) has no effect.', '`paginationMeta` is only meant to be used with `paginationMode="server"`.'].join('\n') || undefined, props => props.signature === GridSignature.DataGrid && props.paginationMode === 'client' && isNumber(props.rowCount) && ['MUI X: Usage of the `rowCount` prop with client side pagination (`paginationMode="client"`) has no effect.', '`rowCount` is only meant to be used with `paginationMode="server"`.'].join('\n') || undefined, props => props.paginationMode === 'server' && props.rowCount == null && !props.dataSource && !props.paginationMeta && ["MUI X: The `rowCount` prop must be passed using `paginationMode='server'`", 'For more detail, see http://mui.com/components/data-grid/pagination/#index-based-pagination'].join('\n') || undefined];
5
5
  export function validateProps(props, validators) {
6
6
  validators.forEach(validator => {
7
7
  const message = validator(props);
@@ -196,11 +196,12 @@ const beBYGrid = {
196
196
  // count,
197
197
  // estimated
198
198
  // }) => {
199
+ // const unknownRowCount = count == null || count === -1;
199
200
  // if (!estimated) {
200
- // return `${from}–${to} of ${count !== -1 ? count : `more than ${to}`}`;
201
+ // return `${from}–${to} of ${!unknownRowCount ? count : `more than ${to}`}`;
201
202
  // }
202
203
  // const estimatedLabel = estimated && estimated > to ? `around ${estimated}` : `more than ${to}`;
203
- // return `${from}–${to} of ${count !== -1 ? count : estimatedLabel}`;
204
+ // return `${from}–${to} of ${!unknownRowCount ? count : estimatedLabel}`;
204
205
  // },
205
206
  paginationItemAriaLabel: type => {
206
207
  if (type === 'first') {
@@ -173,11 +173,12 @@ const bgBGGrid = {
173
173
  // count,
174
174
  // estimated
175
175
  // }) => {
176
+ // const unknownRowCount = count == null || count === -1;
176
177
  // if (!estimated) {
177
- // return `${from}–${to} of ${count !== -1 ? count : `more than ${to}`}`;
178
+ // return `${from}–${to} of ${!unknownRowCount ? count : `more than ${to}`}`;
178
179
  // }
179
180
  // const estimatedLabel = estimated && estimated > to ? `around ${estimated}` : `more than ${to}`;
180
- // return `${from}–${to} of ${count !== -1 ? count : estimatedLabel}`;
181
+ // return `${from}–${to} of ${!unknownRowCount ? count : estimatedLabel}`;
181
182
  // },
182
183
  paginationItemAriaLabel: type => {
183
184
  if (type === 'first') {
@@ -172,11 +172,12 @@ const bnBDGrid = {
172
172
  // count,
173
173
  // estimated
174
174
  // }) => {
175
+ // const unknownRowCount = count == null || count === -1;
175
176
  // if (!estimated) {
176
- // return `${from}–${to} of ${count !== -1 ? count : `more than ${to}`}`;
177
+ // return `${from}–${to} of ${!unknownRowCount ? count : `more than ${to}`}`;
177
178
  // }
178
179
  // const estimatedLabel = estimated && estimated > to ? `around ${estimated}` : `more than ${to}`;
179
- // return `${from}–${to} of ${count !== -1 ? count : estimatedLabel}`;
180
+ // return `${from}–${to} of ${!unknownRowCount ? count : estimatedLabel}`;
180
181
  // },
181
182
  paginationItemAriaLabel: type => {
182
183
  if (type === 'first') {
@@ -172,11 +172,12 @@ const daDKGrid = {
172
172
  // count,
173
173
  // estimated
174
174
  // }) => {
175
+ // const unknownRowCount = count == null || count === -1;
175
176
  // if (!estimated) {
176
- // return `${from}–${to} of ${count !== -1 ? count : `more than ${to}`}`;
177
+ // return `${from}–${to} of ${!unknownRowCount ? count : `more than ${to}`}`;
177
178
  // }
178
179
  // const estimatedLabel = estimated && estimated > to ? `around ${estimated}` : `more than ${to}`;
179
- // return `${from}–${to} of ${count !== -1 ? count : estimatedLabel}`;
180
+ // return `${from}–${to} of ${!unknownRowCount ? count : estimatedLabel}`;
180
181
  // },
181
182
  paginationItemAriaLabel: type => {
182
183
  if (type === 'first') {
@@ -173,11 +173,12 @@ const elGRGrid = {
173
173
  // count,
174
174
  // estimated
175
175
  // }) => {
176
+ // const unknownRowCount = count == null || count === -1;
176
177
  // if (!estimated) {
177
- // return `${from}–${to} of ${count !== -1 ? count : `more than ${to}`}`;
178
+ // return `${from}–${to} of ${!unknownRowCount ? count : `more than ${to}`}`;
178
179
  // }
179
180
  // const estimatedLabel = estimated && estimated > to ? `around ${estimated}` : `more than ${to}`;
180
- // return `${from}–${to} of ${count !== -1 ? count : estimatedLabel}`;
181
+ // return `${from}–${to} of ${!unknownRowCount ? count : estimatedLabel}`;
181
182
  // },
182
183
  paginationItemAriaLabel: type => {
183
184
  if (type === 'first') {