@mui/x-data-grid 9.8.0 → 9.10.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 (266) hide show
  1. package/CHANGELOG.md +230 -0
  2. package/DataGrid/DataGrid.js +7 -0
  3. package/DataGrid/DataGrid.mjs +7 -0
  4. package/colDef/gridNumericOperators.d.mts +1 -1
  5. package/colDef/gridNumericOperators.d.ts +1 -1
  6. package/components/GridColumnSortButton.d.mts +1 -1
  7. package/components/GridColumnSortButton.d.ts +1 -1
  8. package/components/GridColumnUnsortedIcon.d.mts +2 -1
  9. package/components/GridColumnUnsortedIcon.d.ts +2 -1
  10. package/components/GridHeader.d.mts +2 -1
  11. package/components/GridHeader.d.ts +2 -1
  12. package/components/GridHeaders.d.mts +1 -1
  13. package/components/GridHeaders.d.ts +1 -1
  14. package/components/GridPagination.d.mts +2 -1
  15. package/components/GridPagination.d.ts +2 -1
  16. package/components/GridRowDragAndDropOverlay.d.mts +1 -1
  17. package/components/GridRowDragAndDropOverlay.d.ts +1 -1
  18. package/components/GridScrollArea.d.mts +2 -1
  19. package/components/GridScrollArea.d.ts +2 -1
  20. package/components/GridScrollShadows.d.mts +2 -1
  21. package/components/GridScrollShadows.d.ts +2 -1
  22. package/components/GridScrollbarFillerCell.d.mts +1 -1
  23. package/components/GridScrollbarFillerCell.d.ts +1 -1
  24. package/components/GridSkeletonLoadingOverlay.d.mts +1 -1
  25. package/components/GridSkeletonLoadingOverlay.d.ts +1 -1
  26. package/components/base/GridFooterPlaceholder.d.mts +1 -1
  27. package/components/base/GridFooterPlaceholder.d.ts +1 -1
  28. package/components/base/GridFooterPlaceholder.js +1 -1
  29. package/components/base/GridFooterPlaceholder.mjs +1 -1
  30. package/components/base/GridOverlays.d.mts +1 -1
  31. package/components/base/GridOverlays.d.ts +1 -1
  32. package/components/cell/GridActionsCell.d.mts +2 -2
  33. package/components/cell/GridActionsCell.d.ts +2 -2
  34. package/components/cell/GridActionsCellItem.d.mts +10 -10
  35. package/components/cell/GridActionsCellItem.d.ts +10 -10
  36. package/components/cell/GridActionsCellItem.js +1 -58
  37. package/components/cell/GridActionsCellItem.mjs +1 -58
  38. package/components/cell/GridBooleanCell.d.mts +1 -4
  39. package/components/cell/GridBooleanCell.d.ts +1 -4
  40. package/components/cell/GridEditBooleanCell.d.mts +2 -2
  41. package/components/cell/GridEditBooleanCell.d.ts +2 -2
  42. package/components/cell/GridEditDateCell.d.mts +2 -2
  43. package/components/cell/GridEditDateCell.d.ts +2 -2
  44. package/components/cell/GridEditInputCell.d.mts +1 -1
  45. package/components/cell/GridEditInputCell.d.ts +1 -1
  46. package/components/cell/GridEditLongTextCell.d.mts +2 -2
  47. package/components/cell/GridEditLongTextCell.d.ts +2 -2
  48. package/components/cell/GridEditSingleSelectCell.d.mts +3 -2
  49. package/components/cell/GridEditSingleSelectCell.d.ts +3 -2
  50. package/components/cell/GridFooterCell.d.mts +1 -1
  51. package/components/cell/GridFooterCell.d.ts +1 -1
  52. package/components/cell/GridLongTextCell.d.mts +2 -2
  53. package/components/cell/GridLongTextCell.d.ts +2 -2
  54. package/components/cell/GridSkeletonCell.d.mts +1 -4
  55. package/components/cell/GridSkeletonCell.d.ts +1 -4
  56. package/components/columnHeaders/ColumnHeaderMenuIcon.d.mts +1 -1
  57. package/components/columnHeaders/ColumnHeaderMenuIcon.d.ts +1 -1
  58. package/components/columnHeaders/GridColumnGroupHeader.d.mts +1 -1
  59. package/components/columnHeaders/GridColumnGroupHeader.d.ts +1 -1
  60. package/components/columnHeaders/GridColumnHeaderFilterIconButton.d.mts +1 -1
  61. package/components/columnHeaders/GridColumnHeaderFilterIconButton.d.ts +1 -1
  62. package/components/columnHeaders/GridColumnHeaderItem.d.mts +1 -4
  63. package/components/columnHeaders/GridColumnHeaderItem.d.ts +1 -4
  64. package/components/columnHeaders/GridColumnHeaderSeparator.d.mts +1 -4
  65. package/components/columnHeaders/GridColumnHeaderSeparator.d.ts +1 -4
  66. package/components/columnHeaders/GridColumnHeaderSortIcon.d.mts +1 -4
  67. package/components/columnHeaders/GridColumnHeaderSortIcon.d.ts +1 -4
  68. package/components/columnHeaders/GridColumnHeaderTitle.d.mts +1 -1
  69. package/components/columnHeaders/GridColumnHeaderTitle.d.ts +1 -1
  70. package/components/columnsManagement/GridColumnsManagement.d.mts +2 -1
  71. package/components/columnsManagement/GridColumnsManagement.d.ts +2 -1
  72. package/components/menu/GridMenu.d.mts +1 -1
  73. package/components/menu/GridMenu.d.ts +1 -1
  74. package/components/menu/columnMenu/GridColumnHeaderMenu.d.mts +1 -1
  75. package/components/menu/columnMenu/GridColumnHeaderMenu.d.ts +1 -1
  76. package/components/menu/columnMenu/menuItems/GridColumnMenuColumnsItem.d.mts +2 -1
  77. package/components/menu/columnMenu/menuItems/GridColumnMenuColumnsItem.d.ts +2 -1
  78. package/components/menu/columnMenu/menuItems/GridColumnMenuFilterItem.d.mts +2 -1
  79. package/components/menu/columnMenu/menuItems/GridColumnMenuFilterItem.d.ts +2 -1
  80. package/components/menu/columnMenu/menuItems/GridColumnMenuHideItem.d.mts +2 -1
  81. package/components/menu/columnMenu/menuItems/GridColumnMenuHideItem.d.ts +2 -1
  82. package/components/menu/columnMenu/menuItems/GridColumnMenuManageItem.d.mts +2 -1
  83. package/components/menu/columnMenu/menuItems/GridColumnMenuManageItem.d.ts +2 -1
  84. package/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.d.mts +2 -1
  85. package/components/menu/columnMenu/menuItems/GridColumnMenuSortItem.d.ts +2 -1
  86. package/components/panel/GridColumnsPanel.d.mts +1 -1
  87. package/components/panel/GridColumnsPanel.d.ts +1 -1
  88. package/components/panel/GridPanelContent.d.mts +1 -1
  89. package/components/panel/GridPanelContent.d.ts +1 -1
  90. package/components/panel/GridPanelContext.d.mts +1 -1
  91. package/components/panel/GridPanelContext.d.ts +1 -1
  92. package/components/panel/GridPanelFooter.d.mts +1 -1
  93. package/components/panel/GridPanelFooter.d.ts +1 -1
  94. package/components/panel/GridPanelHeader.d.mts +1 -1
  95. package/components/panel/GridPanelHeader.d.ts +1 -1
  96. package/components/panel/GridPreferencesPanel.d.mts +1 -1
  97. package/components/panel/GridPreferencesPanel.d.ts +1 -1
  98. package/components/panel/filterPanel/GridFilterForm.d.mts +1 -98
  99. package/components/panel/filterPanel/GridFilterForm.d.ts +1 -98
  100. package/components/panel/filterPanel/GridFilterForm.js +9 -355
  101. package/components/panel/filterPanel/GridFilterForm.mjs +8 -354
  102. package/components/panel/filterPanel/GridFilterFormBase.d.mts +119 -0
  103. package/components/panel/filterPanel/GridFilterFormBase.d.ts +119 -0
  104. package/components/panel/filterPanel/GridFilterFormBase.js +497 -0
  105. package/components/panel/filterPanel/GridFilterFormBase.mjs +491 -0
  106. package/components/panel/filterPanel/GridFilterInputBoolean.d.mts +2 -1
  107. package/components/panel/filterPanel/GridFilterInputBoolean.d.ts +2 -1
  108. package/components/panel/filterPanel/GridFilterInputBoolean.js +6 -1
  109. package/components/panel/filterPanel/GridFilterInputBoolean.mjs +6 -1
  110. package/components/panel/filterPanel/GridFilterInputDate.d.mts +2 -1
  111. package/components/panel/filterPanel/GridFilterInputDate.d.ts +2 -1
  112. package/components/panel/filterPanel/GridFilterInputDate.js +21 -9
  113. package/components/panel/filterPanel/GridFilterInputDate.mjs +21 -9
  114. package/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.d.mts +2 -1
  115. package/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.d.ts +2 -1
  116. package/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +6 -1
  117. package/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.mjs +6 -1
  118. package/components/panel/filterPanel/GridFilterInputMultipleValue.d.mts +2 -1
  119. package/components/panel/filterPanel/GridFilterInputMultipleValue.d.ts +2 -1
  120. package/components/panel/filterPanel/GridFilterInputMultipleValue.js +6 -1
  121. package/components/panel/filterPanel/GridFilterInputMultipleValue.mjs +6 -1
  122. package/components/panel/filterPanel/GridFilterInputSingleSelect.d.mts +2 -1
  123. package/components/panel/filterPanel/GridFilterInputSingleSelect.d.ts +2 -1
  124. package/components/panel/filterPanel/GridFilterInputSingleSelect.js +6 -1
  125. package/components/panel/filterPanel/GridFilterInputSingleSelect.mjs +6 -1
  126. package/components/panel/filterPanel/GridFilterInputValue.d.mts +2 -1
  127. package/components/panel/filterPanel/GridFilterInputValue.d.ts +2 -1
  128. package/components/panel/filterPanel/GridFilterInputValue.js +19 -8
  129. package/components/panel/filterPanel/GridFilterInputValue.mjs +19 -8
  130. package/components/panel/filterPanel/GridFilterPanel.d.mts +3 -40
  131. package/components/panel/filterPanel/GridFilterPanel.d.ts +3 -40
  132. package/components/panel/filterPanel/GridFilterPanel.js +19 -174
  133. package/components/panel/filterPanel/GridFilterPanel.mjs +14 -173
  134. package/components/panel/filterPanel/GridFilterPanelBase.d.mts +79 -0
  135. package/components/panel/filterPanel/GridFilterPanelBase.d.ts +79 -0
  136. package/components/panel/filterPanel/GridFilterPanelBase.js +304 -0
  137. package/components/panel/filterPanel/GridFilterPanelBase.mjs +297 -0
  138. package/components/panel/filterPanel/index.d.mts +3 -1
  139. package/components/panel/filterPanel/index.d.ts +3 -1
  140. package/components/panel/filterPanel/index.js +9 -1
  141. package/components/panel/filterPanel/index.mjs +3 -0
  142. package/components/quickFilter/QuickFilter.d.mts +1 -1
  143. package/components/quickFilter/QuickFilter.d.ts +1 -1
  144. package/components/toolbar/GridToolbarExport.d.mts +2 -2
  145. package/components/toolbar/GridToolbarExport.d.ts +2 -2
  146. package/components/toolbar/GridToolbarQuickFilter.d.mts +1 -1
  147. package/components/toolbar/GridToolbarQuickFilter.d.ts +1 -1
  148. package/components/toolbarV8/GridToolbar.d.mts +3 -3
  149. package/components/toolbarV8/GridToolbar.d.ts +3 -3
  150. package/components/toolbarV8/utils.d.mts +1 -1
  151. package/components/toolbarV8/utils.d.ts +1 -1
  152. package/components/virtualization/GridBottomContainer.d.mts +1 -1
  153. package/components/virtualization/GridBottomContainer.d.ts +1 -1
  154. package/components/virtualization/GridTopContainer.d.mts +1 -1
  155. package/components/virtualization/GridTopContainer.d.ts +1 -1
  156. package/components/virtualization/GridVirtualScroller.d.mts +1 -1
  157. package/components/virtualization/GridVirtualScroller.d.ts +1 -1
  158. package/components/virtualization/GridVirtualScrollerFiller.d.mts +2 -1
  159. package/components/virtualization/GridVirtualScrollerFiller.d.ts +2 -1
  160. package/constants/cssVariables.d.mts +120 -120
  161. package/constants/cssVariables.d.ts +120 -120
  162. package/constants/dataGridPropsDefaultValues.js +1 -0
  163. package/constants/dataGridPropsDefaultValues.mjs +1 -0
  164. package/context/GridContextProvider.d.mts +1 -1
  165. package/context/GridContextProvider.d.ts +1 -1
  166. package/hooks/core/useGridLocaleText.d.mts +1 -1
  167. package/hooks/core/useGridLocaleText.d.ts +1 -1
  168. package/hooks/core/useGridLoggerFactory.d.mts +1 -1
  169. package/hooks/core/useGridLoggerFactory.d.ts +1 -1
  170. package/hooks/features/clipboard/useGridClipboard.d.mts +1 -1
  171. package/hooks/features/clipboard/useGridClipboard.d.ts +1 -1
  172. package/hooks/features/columnGrouping/useGridColumnGrouping.d.mts +1 -1
  173. package/hooks/features/columnGrouping/useGridColumnGrouping.d.ts +1 -1
  174. package/hooks/features/columnHeaders/useGridColumnHeaders.d.mts +4 -4
  175. package/hooks/features/columnHeaders/useGridColumnHeaders.d.ts +4 -4
  176. package/hooks/features/columnResize/useGridColumnResize.d.mts +1 -1
  177. package/hooks/features/columnResize/useGridColumnResize.d.ts +1 -1
  178. package/hooks/features/columns/gridColumnsUtils.d.mts +1 -1
  179. package/hooks/features/columns/gridColumnsUtils.d.ts +1 -1
  180. package/hooks/features/dataSource/useGridDataSourceBase.d.mts +2 -2
  181. package/hooks/features/dataSource/useGridDataSourceBase.d.ts +2 -2
  182. package/hooks/features/dataSource/useGridDataSourceBase.js +39 -10
  183. package/hooks/features/dataSource/useGridDataSourceBase.mjs +39 -10
  184. package/hooks/features/density/useGridDensity.d.mts +1 -1
  185. package/hooks/features/density/useGridDensity.d.ts +1 -1
  186. package/hooks/features/editing/useGridCellEditing.d.mts +1 -1
  187. package/hooks/features/editing/useGridCellEditing.d.ts +1 -1
  188. package/hooks/features/editing/useGridEditing.d.mts +1 -1
  189. package/hooks/features/editing/useGridEditing.d.ts +1 -1
  190. package/hooks/features/editing/useGridRowEditing.d.mts +1 -1
  191. package/hooks/features/editing/useGridRowEditing.d.ts +1 -1
  192. package/hooks/features/editing/utils.d.mts +1 -1
  193. package/hooks/features/editing/utils.d.ts +1 -1
  194. package/hooks/features/export/useGridCsvExport.d.mts +1 -1
  195. package/hooks/features/export/useGridCsvExport.d.ts +1 -1
  196. package/hooks/features/export/useGridPrintExport.d.mts +1 -1
  197. package/hooks/features/export/useGridPrintExport.d.ts +1 -1
  198. package/hooks/features/filter/gridFilterUtils.d.mts +13 -1
  199. package/hooks/features/filter/gridFilterUtils.d.ts +13 -1
  200. package/hooks/features/filter/gridFilterUtils.js +56 -1
  201. package/hooks/features/filter/gridFilterUtils.mjs +52 -0
  202. package/hooks/features/filter/useGridFilter.d.mts +1 -1
  203. package/hooks/features/filter/useGridFilter.d.ts +1 -1
  204. package/hooks/features/filter/useGridFilter.js +4 -35
  205. package/hooks/features/filter/useGridFilter.mjs +5 -36
  206. package/hooks/features/focus/useGridFocus.d.mts +1 -1
  207. package/hooks/features/focus/useGridFocus.d.ts +1 -1
  208. package/hooks/features/headerFiltering/useGridHeaderFiltering.d.mts +1 -1
  209. package/hooks/features/headerFiltering/useGridHeaderFiltering.d.ts +1 -1
  210. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.d.mts +1 -1
  211. package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.d.ts +1 -1
  212. package/hooks/features/overlays/useGridOverlays.d.mts +1 -1
  213. package/hooks/features/overlays/useGridOverlays.d.ts +1 -1
  214. package/hooks/features/pagination/gridPaginationUtils.d.mts +1 -1
  215. package/hooks/features/pagination/gridPaginationUtils.d.ts +1 -1
  216. package/hooks/features/pagination/useGridPaginationMeta.d.mts +1 -1
  217. package/hooks/features/pagination/useGridPaginationMeta.d.ts +1 -1
  218. package/hooks/features/pagination/useGridPaginationModel.d.mts +2 -2
  219. package/hooks/features/pagination/useGridPaginationModel.d.ts +2 -2
  220. package/hooks/features/pagination/useGridRowCount.d.mts +1 -1
  221. package/hooks/features/pagination/useGridRowCount.d.ts +1 -1
  222. package/hooks/features/preferencesPanel/useGridPreferencesPanel.d.mts +1 -1
  223. package/hooks/features/preferencesPanel/useGridPreferencesPanel.d.ts +1 -1
  224. package/hooks/features/rowSelection/useGridRowSelection.d.mts +1 -1
  225. package/hooks/features/rowSelection/useGridRowSelection.d.ts +1 -1
  226. package/hooks/features/rows/gridRowsUtils.d.mts +4 -4
  227. package/hooks/features/rows/gridRowsUtils.d.ts +4 -4
  228. package/hooks/features/rows/useGridRowSpanning.d.mts +1 -1
  229. package/hooks/features/rows/useGridRowSpanning.d.ts +1 -1
  230. package/hooks/features/rows/useGridRows.d.mts +1 -1
  231. package/hooks/features/rows/useGridRows.d.ts +1 -1
  232. package/hooks/features/rows/useGridRowsMeta.d.mts +1 -1
  233. package/hooks/features/rows/useGridRowsMeta.d.ts +1 -1
  234. package/hooks/features/scroll/useGridScroll.d.mts +1 -1
  235. package/hooks/features/scroll/useGridScroll.d.ts +1 -1
  236. package/hooks/features/sorting/useGridSorting.d.mts +1 -1
  237. package/hooks/features/sorting/useGridSorting.d.ts +1 -1
  238. package/hooks/features/virtualization/gridFocusedVirtualCellSelector.d.mts +2 -2
  239. package/hooks/features/virtualization/gridFocusedVirtualCellSelector.d.ts +2 -2
  240. package/hooks/utils/useGridEvent.d.mts +1 -1
  241. package/hooks/utils/useGridEvent.d.ts +1 -1
  242. package/hooks/utils/useGridVisibleRows.d.mts +2 -2
  243. package/hooks/utils/useGridVisibleRows.d.ts +2 -2
  244. package/index.js +1 -1
  245. package/index.mjs +1 -1
  246. package/internals/demo/TailwindDemoContainer.d.mts +1 -1
  247. package/internals/demo/TailwindDemoContainer.d.ts +1 -1
  248. package/models/api/gridApiCommon.d.mts +1 -1
  249. package/models/api/gridApiCommon.d.ts +1 -1
  250. package/models/gridFilterInputComponent.d.mts +5 -0
  251. package/models/gridFilterInputComponent.d.ts +5 -0
  252. package/models/gridSlotsComponentsProps.d.mts +1 -1
  253. package/models/gridSlotsComponentsProps.d.ts +1 -1
  254. package/models/props/DataGridProps.d.mts +7 -0
  255. package/models/props/DataGridProps.d.ts +7 -0
  256. package/package.json +5 -5
  257. package/utils/cellBorderUtils.d.mts +2 -2
  258. package/utils/cellBorderUtils.d.ts +2 -2
  259. package/utils/css/context.d.mts +3 -3
  260. package/utils/css/context.d.ts +3 -3
  261. package/utils/getPublicApiRef.d.mts +1 -1
  262. package/utils/getPublicApiRef.d.ts +1 -1
  263. package/utils/keyboardUtils.d.mts +1 -1
  264. package/utils/keyboardUtils.d.ts +1 -1
  265. package/utils/rtlFlipSide.d.mts +1 -1
  266. package/utils/rtlFlipSide.d.ts +1 -1
@@ -209,6 +209,11 @@ const useGridDataSourceBase = (apiRef, props, options = {}) => {
209
209
  });
210
210
  const handleDataUpdate = React.useCallback(params => {
211
211
  if ('error' in params) {
212
+ // Reset the rows on error, even with `dataSourceKeepPreviousData`. The previous
213
+ // rows belong to the previous query while the pagination/sorting/filtering controls
214
+ // already reflect the failed request, so keeping them would present stale data as if
215
+ // it satisfied the new query. This matches TanStack Query, where `keepPreviousData`
216
+ // clears the placeholder once the query settles with an error.
212
217
  apiRef.current.setRows([]);
213
218
  return;
214
219
  }
@@ -265,17 +270,26 @@ const useGridDataSourceBase = (apiRef, props, options = {}) => {
265
270
  };
266
271
  const debouncedFetchRows = React.useMemo(() => (0, _debounce.default)(fetchRows, 0), [fetchRows]);
267
272
  const handleFetchRowsOnParamsChange = React.useCallback(() => {
268
- // Clear the rows first and immediately mark the grid as loading so the overlay
269
- // selector never observes the intermediate `rows=[] && loading=false` state that
270
- // would otherwise pick `noRowsOverlay`. Order matters: `setRows([])` rebuilds
271
- // `state.rows` from `props.loading`, so the `setLoading(true)` call must come after
272
- // it to survive the rebuild. This handler is only wired up when a standard strategy
273
- // is active via the `runIf` guards on the returned `events` object.
274
- apiRef.current.setRows([]);
273
+ // `dataSourceKeepPreviousData` only applies to the flat `Default` strategy. For
274
+ // `GroupedData` (tree data / row grouping), skipping the synchronous `setRows([])`
275
+ // would leave the existing tree merged on top of the new response and render rows
276
+ // in stale sort order (https://github.com/mui/mui-x/pull/21619).
277
+ // This handler is only wired up when a standard strategy is active via the `runIf`
278
+ // guards on the returned `events` object.
279
+ const activeStrategy = apiRef.current.getActiveStrategy(_strategyProcessing.GridStrategyGroup.DataSource);
280
+ const keepPreviousData = props.dataSourceKeepPreviousData && activeStrategy === _utils2.DataSourceRowsUpdateStrategy.Default;
281
+ if (!keepPreviousData) {
282
+ // Clear the rows first and immediately mark the grid as loading so the overlay
283
+ // selector never observes the intermediate `rows=[] && loading=false` state that
284
+ // would otherwise pick `noRowsOverlay`. Order matters: `setRows([])` rebuilds
285
+ // `state.rows` from `props.loading`, so the `setLoading(true)` call must come after
286
+ // it to survive the rebuild.
287
+ apiRef.current.setRows([]);
288
+ }
275
289
  apiRef.current.setLoading(true);
276
290
  stopPolling();
277
291
  debouncedFetchRows();
278
- }, [apiRef, stopPolling, debouncedFetchRows]);
292
+ }, [apiRef, props.dataSourceKeepPreviousData, stopPolling, debouncedFetchRows]);
279
293
  const isFirstRender = React.useRef(true);
280
294
  React.useEffect(() => {
281
295
  if (isFirstRender.current) {
@@ -307,7 +321,14 @@ const useGridDataSourceBase = (apiRef, props, options = {}) => {
307
321
  }
308
322
  if (props.dataSource) {
309
323
  stopPolling();
310
- apiRef.current.setRows([]);
324
+ // `dataSourceKeepPreviousData` only applies to the flat `Default` strategy (mirroring
325
+ // `handleFetchRowsOnParamsChange`). Keep the previous rows visible when the `dataSource`
326
+ // reference changes so the feature isn't silently defeated for a non-memoized
327
+ // `dataSource`. Other strategies must still reset the rows to keep their order consistent
328
+ // with the new response (https://github.com/mui/mui-x/pull/21619).
329
+ if (!props.dataSourceKeepPreviousData || currentStrategy !== _utils2.DataSourceRowsUpdateStrategy.Default) {
330
+ apiRef.current.setRows([]);
331
+ }
311
332
  apiRef.current.dataSource.cache.clear();
312
333
  apiRef.current.dataSource.fetchRows();
313
334
  }
@@ -315,7 +336,15 @@ const useGridDataSourceBase = (apiRef, props, options = {}) => {
315
336
  // ignore the current request on unmount
316
337
  lastRequestId.current += 1;
317
338
  };
318
- }, [apiRef, props.dataSource, currentStrategy, stopPolling]);
339
+ }, [apiRef, props.dataSource, props.dataSourceKeepPreviousData, currentStrategy, stopPolling]);
340
+ React.useEffect(() => {
341
+ // `dataSourceKeepPreviousData` is a no-op for tree data and row grouping: those
342
+ // strategies always reset the rows on refetch to keep their order consistent with the
343
+ // response. Warn so the limitation is discoverable at runtime, not only in the docs.
344
+ if (process.env.NODE_ENV !== 'production' && props.dataSourceKeepPreviousData && (currentStrategy === _utils2.DataSourceRowsUpdateStrategy.GroupedData || currentStrategy === _utils2.DataSourceRowsUpdateStrategy.LazyLoadedGroupedData)) {
345
+ (0, _warning.warnOnce)(['MUI X: The `dataSourceKeepPreviousData` prop only applies to flat data.', 'It is ignored when tree data or row grouping is enabled, because the rows are always reset on refetch to keep their order consistent with the response.', 'For more details, see https://mui.com/x/react-data-grid/server-side-data/#keep-previous-data-while-fetching.']);
346
+ }
347
+ }, [props.dataSourceKeepPreviousData, currentStrategy]);
319
348
  return {
320
349
  api: {
321
350
  public: dataSourceApi
@@ -202,6 +202,11 @@ export const useGridDataSourceBase = (apiRef, props, options = {}) => {
202
202
  });
203
203
  const handleDataUpdate = React.useCallback(params => {
204
204
  if ('error' in params) {
205
+ // Reset the rows on error, even with `dataSourceKeepPreviousData`. The previous
206
+ // rows belong to the previous query while the pagination/sorting/filtering controls
207
+ // already reflect the failed request, so keeping them would present stale data as if
208
+ // it satisfied the new query. This matches TanStack Query, where `keepPreviousData`
209
+ // clears the placeholder once the query settles with an error.
205
210
  apiRef.current.setRows([]);
206
211
  return;
207
212
  }
@@ -258,17 +263,26 @@ export const useGridDataSourceBase = (apiRef, props, options = {}) => {
258
263
  };
259
264
  const debouncedFetchRows = React.useMemo(() => debounce(fetchRows, 0), [fetchRows]);
260
265
  const handleFetchRowsOnParamsChange = React.useCallback(() => {
261
- // Clear the rows first and immediately mark the grid as loading so the overlay
262
- // selector never observes the intermediate `rows=[] && loading=false` state that
263
- // would otherwise pick `noRowsOverlay`. Order matters: `setRows([])` rebuilds
264
- // `state.rows` from `props.loading`, so the `setLoading(true)` call must come after
265
- // it to survive the rebuild. This handler is only wired up when a standard strategy
266
- // is active via the `runIf` guards on the returned `events` object.
267
- apiRef.current.setRows([]);
266
+ // `dataSourceKeepPreviousData` only applies to the flat `Default` strategy. For
267
+ // `GroupedData` (tree data / row grouping), skipping the synchronous `setRows([])`
268
+ // would leave the existing tree merged on top of the new response and render rows
269
+ // in stale sort order (https://github.com/mui/mui-x/pull/21619).
270
+ // This handler is only wired up when a standard strategy is active via the `runIf`
271
+ // guards on the returned `events` object.
272
+ const activeStrategy = apiRef.current.getActiveStrategy(GridStrategyGroup.DataSource);
273
+ const keepPreviousData = props.dataSourceKeepPreviousData && activeStrategy === DataSourceRowsUpdateStrategy.Default;
274
+ if (!keepPreviousData) {
275
+ // Clear the rows first and immediately mark the grid as loading so the overlay
276
+ // selector never observes the intermediate `rows=[] && loading=false` state that
277
+ // would otherwise pick `noRowsOverlay`. Order matters: `setRows([])` rebuilds
278
+ // `state.rows` from `props.loading`, so the `setLoading(true)` call must come after
279
+ // it to survive the rebuild.
280
+ apiRef.current.setRows([]);
281
+ }
268
282
  apiRef.current.setLoading(true);
269
283
  stopPolling();
270
284
  debouncedFetchRows();
271
- }, [apiRef, stopPolling, debouncedFetchRows]);
285
+ }, [apiRef, props.dataSourceKeepPreviousData, stopPolling, debouncedFetchRows]);
272
286
  const isFirstRender = React.useRef(true);
273
287
  React.useEffect(() => {
274
288
  if (isFirstRender.current) {
@@ -300,7 +314,14 @@ export const useGridDataSourceBase = (apiRef, props, options = {}) => {
300
314
  }
301
315
  if (props.dataSource) {
302
316
  stopPolling();
303
- apiRef.current.setRows([]);
317
+ // `dataSourceKeepPreviousData` only applies to the flat `Default` strategy (mirroring
318
+ // `handleFetchRowsOnParamsChange`). Keep the previous rows visible when the `dataSource`
319
+ // reference changes so the feature isn't silently defeated for a non-memoized
320
+ // `dataSource`. Other strategies must still reset the rows to keep their order consistent
321
+ // with the new response (https://github.com/mui/mui-x/pull/21619).
322
+ if (!props.dataSourceKeepPreviousData || currentStrategy !== DataSourceRowsUpdateStrategy.Default) {
323
+ apiRef.current.setRows([]);
324
+ }
304
325
  apiRef.current.dataSource.cache.clear();
305
326
  apiRef.current.dataSource.fetchRows();
306
327
  }
@@ -308,7 +329,15 @@ export const useGridDataSourceBase = (apiRef, props, options = {}) => {
308
329
  // ignore the current request on unmount
309
330
  lastRequestId.current += 1;
310
331
  };
311
- }, [apiRef, props.dataSource, currentStrategy, stopPolling]);
332
+ }, [apiRef, props.dataSource, props.dataSourceKeepPreviousData, currentStrategy, stopPolling]);
333
+ React.useEffect(() => {
334
+ // `dataSourceKeepPreviousData` is a no-op for tree data and row grouping: those
335
+ // strategies always reset the rows on refetch to keep their order consistent with the
336
+ // response. Warn so the limitation is discoverable at runtime, not only in the docs.
337
+ if (process.env.NODE_ENV !== 'production' && props.dataSourceKeepPreviousData && (currentStrategy === DataSourceRowsUpdateStrategy.GroupedData || currentStrategy === DataSourceRowsUpdateStrategy.LazyLoadedGroupedData)) {
338
+ warnOnce(['MUI X: The `dataSourceKeepPreviousData` prop only applies to flat data.', 'It is ignored when tree data or row grouping is enabled, because the rows are always reset on refetch to keep their order consistent with the response.', 'For more details, see https://mui.com/x/react-data-grid/server-side-data/#keep-previous-data-while-fetching.']);
339
+ }
340
+ }, [props.dataSourceKeepPreviousData, currentStrategy]);
312
341
  return {
313
342
  api: {
314
343
  public: dataSourceApi
@@ -3,4 +3,4 @@ import type { GridPrivateApiCommunity } from "../../../models/api/gridApiCommuni
3
3
  import type { DataGridProcessedProps } from "../../../models/props/DataGridProps.mjs";
4
4
  import type { GridStateInitializer } from "../../utils/useGridInitializeState.mjs";
5
5
  export declare const densityStateInitializer: GridStateInitializer<Pick<DataGridProcessedProps, 'initialState' | 'density'>>;
6
- export declare const useGridDensity: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, "density" | "onDensityChange" | "initialState">) => void;
6
+ export declare const useGridDensity: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, 'density' | 'onDensityChange' | 'initialState'>) => void;
@@ -3,4 +3,4 @@ import type { GridPrivateApiCommunity } from "../../../models/api/gridApiCommuni
3
3
  import type { DataGridProcessedProps } from "../../../models/props/DataGridProps.js";
4
4
  import type { GridStateInitializer } from "../../utils/useGridInitializeState.js";
5
5
  export declare const densityStateInitializer: GridStateInitializer<Pick<DataGridProcessedProps, 'initialState' | 'density'>>;
6
- export declare const useGridDensity: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, "density" | "onDensityChange" | "initialState">) => void;
6
+ export declare const useGridDensity: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, 'density' | 'onDensityChange' | 'initialState'>) => void;
@@ -1,4 +1,4 @@
1
1
  import type { RefObject } from '@mui/x-internals/types';
2
2
  import type { GridPrivateApiCommunity } from "../../../models/api/gridApiCommunity.mjs";
3
3
  import type { DataGridProcessedProps } from "../../../models/props/DataGridProps.mjs";
4
- export declare const useGridCellEditing: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, "editMode" | "processRowUpdate" | "onCellEditStart" | "onCellEditStop" | "cellModesModel" | "onCellModesModelChange" | "onProcessRowUpdateError" | "signature" | "dataSource">) => void;
4
+ export declare const useGridCellEditing: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, 'editMode' | 'processRowUpdate' | 'onCellEditStart' | 'onCellEditStop' | 'cellModesModel' | 'onCellModesModelChange' | 'onProcessRowUpdateError' | 'signature' | 'dataSource'>) => void;
@@ -1,4 +1,4 @@
1
1
  import type { RefObject } from '@mui/x-internals/types';
2
2
  import type { GridPrivateApiCommunity } from "../../../models/api/gridApiCommunity.js";
3
3
  import type { DataGridProcessedProps } from "../../../models/props/DataGridProps.js";
4
- export declare const useGridCellEditing: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, "editMode" | "processRowUpdate" | "onCellEditStart" | "onCellEditStop" | "cellModesModel" | "onCellModesModelChange" | "onProcessRowUpdateError" | "signature" | "dataSource">) => void;
4
+ export declare const useGridCellEditing: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, 'editMode' | 'processRowUpdate' | 'onCellEditStart' | 'onCellEditStop' | 'cellModesModel' | 'onCellModesModelChange' | 'onProcessRowUpdateError' | 'signature' | 'dataSource'>) => void;
@@ -4,4 +4,4 @@ import type { DataGridProcessedProps } from "../../../models/props/DataGridProps
4
4
  import type { GridConfiguration } from "../../../models/configuration/gridConfiguration.mjs";
5
5
  import type { GridStateInitializer } from "../../utils/useGridInitializeState.mjs";
6
6
  export declare const editingStateInitializer: GridStateInitializer;
7
- export declare const useGridEditing: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, "isCellEditable" | "editMode" | "processRowUpdate" | "dataSource" | "onDataSourceError">, configuration: GridConfiguration) => void;
7
+ export declare const useGridEditing: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, 'isCellEditable' | 'editMode' | 'processRowUpdate' | 'dataSource' | 'onDataSourceError'>, configuration: GridConfiguration) => void;
@@ -4,4 +4,4 @@ import type { DataGridProcessedProps } from "../../../models/props/DataGridProps
4
4
  import type { GridConfiguration } from "../../../models/configuration/gridConfiguration.js";
5
5
  import type { GridStateInitializer } from "../../utils/useGridInitializeState.js";
6
6
  export declare const editingStateInitializer: GridStateInitializer;
7
- export declare const useGridEditing: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, "isCellEditable" | "editMode" | "processRowUpdate" | "dataSource" | "onDataSourceError">, configuration: GridConfiguration) => void;
7
+ export declare const useGridEditing: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, 'isCellEditable' | 'editMode' | 'processRowUpdate' | 'dataSource' | 'onDataSourceError'>, configuration: GridConfiguration) => void;
@@ -1,4 +1,4 @@
1
1
  import type { RefObject } from '@mui/x-internals/types';
2
2
  import type { GridPrivateApiCommunity } from "../../../models/api/gridApiCommunity.mjs";
3
3
  import type { DataGridProcessedProps } from "../../../models/props/DataGridProps.mjs";
4
- export declare const useGridRowEditing: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, "editMode" | "processRowUpdate" | "onRowEditStart" | "onRowEditStop" | "onProcessRowUpdateError" | "rowModesModel" | "onRowModesModelChange" | "signature" | "dataSource">) => void;
4
+ export declare const useGridRowEditing: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, 'editMode' | 'processRowUpdate' | 'onRowEditStart' | 'onRowEditStop' | 'onProcessRowUpdateError' | 'rowModesModel' | 'onRowModesModelChange' | 'signature' | 'dataSource'>) => void;
@@ -1,4 +1,4 @@
1
1
  import type { RefObject } from '@mui/x-internals/types';
2
2
  import type { GridPrivateApiCommunity } from "../../../models/api/gridApiCommunity.js";
3
3
  import type { DataGridProcessedProps } from "../../../models/props/DataGridProps.js";
4
- export declare const useGridRowEditing: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, "editMode" | "processRowUpdate" | "onRowEditStart" | "onRowEditStop" | "onProcessRowUpdateError" | "rowModesModel" | "onRowModesModelChange" | "signature" | "dataSource">) => void;
4
+ export declare const useGridRowEditing: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, 'editMode' | 'processRowUpdate' | 'onRowEditStart' | 'onRowEditStop' | 'onProcessRowUpdateError' | 'rowModesModel' | 'onRowModesModelChange' | 'signature' | 'dataSource'>) => void;
@@ -1,2 +1,2 @@
1
1
  import type { GridColDef } from "../../../models/colDef/gridColDef.mjs";
2
- export declare const getDefaultCellValue: (colDef: GridColDef) => false | "" | undefined;
2
+ export declare const getDefaultCellValue: (colDef: GridColDef) => "" | false | undefined;
@@ -1,2 +1,2 @@
1
1
  import type { GridColDef } from "../../../models/colDef/gridColDef.js";
2
- export declare const getDefaultCellValue: (colDef: GridColDef) => false | "" | undefined;
2
+ export declare const getDefaultCellValue: (colDef: GridColDef) => "" | false | undefined;
@@ -8,4 +8,4 @@ import type { DataGridProcessedProps } from "../../../models/props/DataGridProps
8
8
  * @requires useGridSelection (state)
9
9
  * @requires useGridParamsApi (method)
10
10
  */
11
- export declare const useGridCsvExport: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, "ignoreValueFormatterDuringExport">) => void;
11
+ export declare const useGridCsvExport: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, 'ignoreValueFormatterDuringExport'>) => void;
@@ -8,4 +8,4 @@ import type { DataGridProcessedProps } from "../../../models/props/DataGridProps
8
8
  * @requires useGridSelection (state)
9
9
  * @requires useGridParamsApi (method)
10
10
  */
11
- export declare const useGridCsvExport: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, "ignoreValueFormatterDuringExport">) => void;
11
+ export declare const useGridCsvExport: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, 'ignoreValueFormatterDuringExport'>) => void;
@@ -7,4 +7,4 @@ import type { DataGridProcessedProps } from "../../../models/props/DataGridProps
7
7
  * @requires useGridSorting (state)
8
8
  * @requires useGridParamsApi (method)
9
9
  */
10
- export declare const useGridPrintExport: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, "pagination" | "columnHeaderHeight" | "headerFilterHeight">) => void;
10
+ export declare const useGridPrintExport: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, 'pagination' | 'columnHeaderHeight' | 'headerFilterHeight'>) => void;
@@ -7,4 +7,4 @@ import type { DataGridProcessedProps } from "../../../models/props/DataGridProps
7
7
  * @requires useGridSorting (state)
8
8
  * @requires useGridParamsApi (method)
9
9
  */
10
- export declare const useGridPrintExport: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, "pagination" | "columnHeaderHeight" | "headerFilterHeight">) => void;
10
+ export declare const useGridPrintExport: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, 'pagination' | 'columnHeaderHeight' | 'headerFilterHeight'>) => void;
@@ -1,8 +1,20 @@
1
1
  import type { RefObject } from '@mui/x-internals/types';
2
+ import { GridLogicOperator } from "../../../models/index.mjs";
2
3
  import type { GridColDef, GridFilterItem, GridFilterModel, GridRowModel } from "../../../models/index.mjs";
3
4
  import type { GridPrivateApiCommunity } from "../../../models/api/gridApiCommunity.mjs";
4
5
  import type { GridStateCommunity } from "../../../models/gridStateCommunity.mjs";
5
6
  import type { GridAggregatedFilterItemApplier, GridFilterItemResult, GridQuickFilterValueResult } from "./gridFilterState.mjs";
7
+ /**
8
+ * Pure helpers computing a new filter model from an existing one.
9
+ * Shared by the imperative `apiRef` methods (`useGridFilter`) and the controlled
10
+ * filter panel (`GridFilterPanelBase`) so both paths produce identical models.
11
+ * Each helper returns the same model reference when nothing changes, so callers
12
+ * relying on referential equality can skip no-op updates.
13
+ */
14
+ export declare const upsertFilterItemInModel: (model: GridFilterModel, item: GridFilterItem) => GridFilterModel;
15
+ export declare const upsertFilterItemsInModel: (model: GridFilterModel, itemsToUpsert: GridFilterItem[]) => GridFilterModel;
16
+ export declare const deleteFilterItemFromModel: (model: GridFilterModel, itemToDelete: GridFilterItem) => GridFilterModel;
17
+ export declare const setFilterLogicOperatorInModel: (model: GridFilterModel, logicOperator: GridLogicOperator) => GridFilterModel;
6
18
  /**
7
19
  * Adds default values to the optional fields of a filter items.
8
20
  * @param {GridFilterItem} item The raw filter item.
@@ -12,7 +24,7 @@ import type { GridAggregatedFilterItemApplier, GridFilterItemResult, GridQuickFi
12
24
  */
13
25
  export declare const cleanFilterItem: (item: GridFilterItem, apiRef: RefObject<GridPrivateApiCommunity>) => GridFilterItem;
14
26
  export declare const sanitizeFilterModel: (model: GridFilterModel, disableMultipleColumnsFiltering: boolean, apiRef: RefObject<GridPrivateApiCommunity>) => GridFilterModel;
15
- export declare const mergeStateWithFilterModel: (filterModel: GridFilterModel, disableMultipleColumnsFiltering: boolean, apiRef: RefObject<GridPrivateApiCommunity>) => (filteringState: GridStateCommunity["filter"]) => GridStateCommunity["filter"];
27
+ export declare const mergeStateWithFilterModel: (filterModel: GridFilterModel, disableMultipleColumnsFiltering: boolean, apiRef: RefObject<GridPrivateApiCommunity>) => (filteringState: GridStateCommunity['filter']) => GridStateCommunity['filter'];
16
28
  export declare const removeDiacritics: (value: unknown) => unknown;
17
29
  export declare const shouldQuickFilterExcludeHiddenColumns: (filterModel: GridFilterModel) => boolean;
18
30
  export declare const buildAggregatedFilterApplier: (filterModel: GridFilterModel, filterValueGetter: (row: GridRowModel, column: GridColDef) => any, apiRef: RefObject<GridPrivateApiCommunity>, disableEval: boolean) => GridAggregatedFilterItemApplier;
@@ -1,8 +1,20 @@
1
1
  import type { RefObject } from '@mui/x-internals/types';
2
+ import { GridLogicOperator } from "../../../models/index.js";
2
3
  import type { GridColDef, GridFilterItem, GridFilterModel, GridRowModel } from "../../../models/index.js";
3
4
  import type { GridPrivateApiCommunity } from "../../../models/api/gridApiCommunity.js";
4
5
  import type { GridStateCommunity } from "../../../models/gridStateCommunity.js";
5
6
  import type { GridAggregatedFilterItemApplier, GridFilterItemResult, GridQuickFilterValueResult } from "./gridFilterState.js";
7
+ /**
8
+ * Pure helpers computing a new filter model from an existing one.
9
+ * Shared by the imperative `apiRef` methods (`useGridFilter`) and the controlled
10
+ * filter panel (`GridFilterPanelBase`) so both paths produce identical models.
11
+ * Each helper returns the same model reference when nothing changes, so callers
12
+ * relying on referential equality can skip no-op updates.
13
+ */
14
+ export declare const upsertFilterItemInModel: (model: GridFilterModel, item: GridFilterItem) => GridFilterModel;
15
+ export declare const upsertFilterItemsInModel: (model: GridFilterModel, itemsToUpsert: GridFilterItem[]) => GridFilterModel;
16
+ export declare const deleteFilterItemFromModel: (model: GridFilterModel, itemToDelete: GridFilterItem) => GridFilterModel;
17
+ export declare const setFilterLogicOperatorInModel: (model: GridFilterModel, logicOperator: GridLogicOperator) => GridFilterModel;
6
18
  /**
7
19
  * Adds default values to the optional fields of a filter items.
8
20
  * @param {GridFilterItem} item The raw filter item.
@@ -12,7 +24,7 @@ import type { GridAggregatedFilterItemApplier, GridFilterItemResult, GridQuickFi
12
24
  */
13
25
  export declare const cleanFilterItem: (item: GridFilterItem, apiRef: RefObject<GridPrivateApiCommunity>) => GridFilterItem;
14
26
  export declare const sanitizeFilterModel: (model: GridFilterModel, disableMultipleColumnsFiltering: boolean, apiRef: RefObject<GridPrivateApiCommunity>) => GridFilterModel;
15
- export declare const mergeStateWithFilterModel: (filterModel: GridFilterModel, disableMultipleColumnsFiltering: boolean, apiRef: RefObject<GridPrivateApiCommunity>) => (filteringState: GridStateCommunity["filter"]) => GridStateCommunity["filter"];
27
+ export declare const mergeStateWithFilterModel: (filterModel: GridFilterModel, disableMultipleColumnsFiltering: boolean, apiRef: RefObject<GridPrivateApiCommunity>) => (filteringState: GridStateCommunity['filter']) => GridStateCommunity['filter'];
16
28
  export declare const removeDiacritics: (value: unknown) => unknown;
17
29
  export declare const shouldQuickFilterExcludeHiddenColumns: (filterModel: GridFilterModel) => boolean;
18
30
  export declare const buildAggregatedFilterApplier: (filterModel: GridFilterModel, filterValueGetter: (row: GridRowModel, column: GridColDef) => any, apiRef: RefObject<GridPrivateApiCommunity>, disableEval: boolean) => GridAggregatedFilterItemApplier;
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.shouldQuickFilterExcludeHiddenColumns = exports.sanitizeFilterModel = exports.removeDiacritics = exports.passFilterLogic = exports.mergeStateWithFilterModel = exports.cleanFilterItem = exports.buildAggregatedFilterApplier = void 0;
7
+ exports.upsertFilterItemsInModel = exports.upsertFilterItemInModel = exports.shouldQuickFilterExcludeHiddenColumns = exports.setFilterLogicOperatorInModel = exports.sanitizeFilterModel = exports.removeDiacritics = exports.passFilterLogic = exports.mergeStateWithFilterModel = exports.deleteFilterItemFromModel = exports.cleanFilterItem = exports.buildAggregatedFilterApplier = void 0;
8
8
  var _formatErrorMessage2 = _interopRequireDefault(require("@mui/x-internals/formatErrorMessage"));
9
9
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
10
  var _warning = require("@mui/x-internals/warning");
@@ -12,6 +12,61 @@ var _models = require("../../../models");
12
12
  var _gridFilterState = require("./gridFilterState");
13
13
  var _getPublicApiRef = require("../../../utils/getPublicApiRef");
14
14
  var _columns = require("../columns");
15
+ /**
16
+ * Pure helpers computing a new filter model from an existing one.
17
+ * Shared by the imperative `apiRef` methods (`useGridFilter`) and the controlled
18
+ * filter panel (`GridFilterPanelBase`) so both paths produce identical models.
19
+ * Each helper returns the same model reference when nothing changes, so callers
20
+ * relying on referential equality can skip no-op updates.
21
+ */
22
+
23
+ const upsertFilterItemInModel = (model, item) => {
24
+ const items = [...model.items];
25
+ const itemIndex = items.findIndex(filterItem => filterItem.id === item.id);
26
+ if (itemIndex === -1) {
27
+ items.push(item);
28
+ } else {
29
+ items[itemIndex] = item;
30
+ }
31
+ return (0, _extends2.default)({}, model, {
32
+ items
33
+ });
34
+ };
35
+ exports.upsertFilterItemInModel = upsertFilterItemInModel;
36
+ const upsertFilterItemsInModel = (model, itemsToUpsert) => {
37
+ const items = [...model.items];
38
+ itemsToUpsert.forEach(item => {
39
+ const itemIndex = items.findIndex(filterItem => filterItem.id === item.id);
40
+ if (itemIndex === -1) {
41
+ items.push(item);
42
+ } else {
43
+ items[itemIndex] = item;
44
+ }
45
+ });
46
+ return (0, _extends2.default)({}, model, {
47
+ items
48
+ });
49
+ };
50
+ exports.upsertFilterItemsInModel = upsertFilterItemsInModel;
51
+ const deleteFilterItemFromModel = (model, itemToDelete) => {
52
+ const items = model.items.filter(item => item.id !== itemToDelete.id);
53
+ if (items.length === model.items.length) {
54
+ return model;
55
+ }
56
+ return (0, _extends2.default)({}, model, {
57
+ items
58
+ });
59
+ };
60
+ exports.deleteFilterItemFromModel = deleteFilterItemFromModel;
61
+ const setFilterLogicOperatorInModel = (model, logicOperator) => {
62
+ if (model.logicOperator === logicOperator) {
63
+ return model;
64
+ }
65
+ return (0, _extends2.default)({}, model, {
66
+ logicOperator
67
+ });
68
+ };
69
+ exports.setFilterLogicOperatorInModel = setFilterLogicOperatorInModel;
15
70
  let hasEval;
16
71
  function getHasEval() {
17
72
  if (hasEval !== undefined) {
@@ -5,6 +5,58 @@ import { GridLogicOperator } from "../../../models/index.mjs";
5
5
  import { getDefaultGridFilterModel } from "./gridFilterState.mjs";
6
6
  import { getPublicApiRef } from "../../../utils/getPublicApiRef.mjs";
7
7
  import { gridColumnFieldsSelector, gridColumnLookupSelector, gridColumnVisibilityModelSelector } from "../columns/index.mjs";
8
+
9
+ /**
10
+ * Pure helpers computing a new filter model from an existing one.
11
+ * Shared by the imperative `apiRef` methods (`useGridFilter`) and the controlled
12
+ * filter panel (`GridFilterPanelBase`) so both paths produce identical models.
13
+ * Each helper returns the same model reference when nothing changes, so callers
14
+ * relying on referential equality can skip no-op updates.
15
+ */
16
+
17
+ export const upsertFilterItemInModel = (model, item) => {
18
+ const items = [...model.items];
19
+ const itemIndex = items.findIndex(filterItem => filterItem.id === item.id);
20
+ if (itemIndex === -1) {
21
+ items.push(item);
22
+ } else {
23
+ items[itemIndex] = item;
24
+ }
25
+ return _extends({}, model, {
26
+ items
27
+ });
28
+ };
29
+ export const upsertFilterItemsInModel = (model, itemsToUpsert) => {
30
+ const items = [...model.items];
31
+ itemsToUpsert.forEach(item => {
32
+ const itemIndex = items.findIndex(filterItem => filterItem.id === item.id);
33
+ if (itemIndex === -1) {
34
+ items.push(item);
35
+ } else {
36
+ items[itemIndex] = item;
37
+ }
38
+ });
39
+ return _extends({}, model, {
40
+ items
41
+ });
42
+ };
43
+ export const deleteFilterItemFromModel = (model, itemToDelete) => {
44
+ const items = model.items.filter(item => item.id !== itemToDelete.id);
45
+ if (items.length === model.items.length) {
46
+ return model;
47
+ }
48
+ return _extends({}, model, {
49
+ items
50
+ });
51
+ };
52
+ export const setFilterLogicOperatorInModel = (model, logicOperator) => {
53
+ if (model.logicOperator === logicOperator) {
54
+ return model;
55
+ }
56
+ return _extends({}, model, {
57
+ logicOperator
58
+ });
59
+ };
8
60
  let hasEval;
9
61
  function getHasEval() {
10
62
  if (hasEval !== undefined) {
@@ -9,4 +9,4 @@ export declare const filterStateInitializer: GridStateInitializer<Pick<DataGridP
9
9
  * @requires useGridParamsApi (method)
10
10
  * @requires useGridRows (event)
11
11
  */
12
- export declare const useGridFilter: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, "rows" | "initialState" | "filterModel" | "getRowId" | "onFilterModelChange" | "filterMode" | "disableMultipleColumnsFiltering" | "slots" | "slotProps" | "disableColumnFilter" | "disableEval" | "ignoreDiacritics" | "signature">, configuration: GridConfiguration) => void;
12
+ export declare const useGridFilter: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, 'rows' | 'initialState' | 'filterModel' | 'getRowId' | 'onFilterModelChange' | 'filterMode' | 'disableMultipleColumnsFiltering' | 'slots' | 'slotProps' | 'disableColumnFilter' | 'disableEval' | 'ignoreDiacritics' | 'signature'>, configuration: GridConfiguration) => void;
@@ -9,4 +9,4 @@ export declare const filterStateInitializer: GridStateInitializer<Pick<DataGridP
9
9
  * @requires useGridParamsApi (method)
10
10
  * @requires useGridRows (event)
11
11
  */
12
- export declare const useGridFilter: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, "rows" | "initialState" | "filterModel" | "getRowId" | "onFilterModelChange" | "filterMode" | "disableMultipleColumnsFiltering" | "slots" | "slotProps" | "disableColumnFilter" | "disableEval" | "ignoreDiacritics" | "signature">, configuration: GridConfiguration) => void;
12
+ export declare const useGridFilter: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, 'rows' | 'initialState' | 'filterModel' | 'getRowId' | 'onFilterModelChange' | 'filterMode' | 'disableMultipleColumnsFiltering' | 'slots' | 'slotProps' | 'disableColumnFilter' | 'disableEval' | 'ignoreDiacritics' | 'signature'>, configuration: GridConfiguration) => void;
@@ -89,41 +89,15 @@ const useGridFilter = (apiRef, props, configuration) => {
89
89
  */
90
90
  const upsertFilterItem = React.useCallback(item => {
91
91
  const filterModel = (0, _gridFilterSelector.gridFilterModelSelector)(apiRef);
92
- const items = [...filterModel.items];
93
- const itemIndex = items.findIndex(filterItem => filterItem.id === item.id);
94
- if (itemIndex === -1) {
95
- items.push(item);
96
- } else {
97
- items[itemIndex] = item;
98
- }
99
- apiRef.current.setFilterModel((0, _extends2.default)({}, filterModel, {
100
- items
101
- }), 'upsertFilterItem');
92
+ apiRef.current.setFilterModel((0, _gridFilterUtils.upsertFilterItemInModel)(filterModel, item), 'upsertFilterItem');
102
93
  }, [apiRef]);
103
94
  const upsertFilterItems = React.useCallback(items => {
104
95
  const filterModel = (0, _gridFilterSelector.gridFilterModelSelector)(apiRef);
105
- const existingItems = [...filterModel.items];
106
- items.forEach(item => {
107
- const itemIndex = existingItems.findIndex(filterItem => filterItem.id === item.id);
108
- if (itemIndex === -1) {
109
- existingItems.push(item);
110
- } else {
111
- existingItems[itemIndex] = item;
112
- }
113
- });
114
- apiRef.current.setFilterModel((0, _extends2.default)({}, filterModel, {
115
- items: existingItems
116
- }), 'upsertFilterItems');
96
+ apiRef.current.setFilterModel((0, _gridFilterUtils.upsertFilterItemsInModel)(filterModel, items), 'upsertFilterItems');
117
97
  }, [apiRef]);
118
98
  const deleteFilterItem = React.useCallback(itemToDelete => {
119
99
  const filterModel = (0, _gridFilterSelector.gridFilterModelSelector)(apiRef);
120
- const items = filterModel.items.filter(item => item.id !== itemToDelete.id);
121
- if (items.length === filterModel.items.length) {
122
- return;
123
- }
124
- apiRef.current.setFilterModel((0, _extends2.default)({}, filterModel, {
125
- items
126
- }), 'deleteFilterItem');
100
+ apiRef.current.setFilterModel((0, _gridFilterUtils.deleteFilterItemFromModel)(filterModel, itemToDelete), 'deleteFilterItem');
127
101
  }, [apiRef]);
128
102
  const showFilterPanel = React.useCallback((targetColumnField, panelId, labelId) => {
129
103
  logger.debug('Displaying filter panel');
@@ -178,12 +152,7 @@ const useGridFilter = (apiRef, props, configuration) => {
178
152
  }, [apiRef, logger]);
179
153
  const setFilterLogicOperator = React.useCallback(logicOperator => {
180
154
  const filterModel = (0, _gridFilterSelector.gridFilterModelSelector)(apiRef);
181
- if (filterModel.logicOperator === logicOperator) {
182
- return;
183
- }
184
- apiRef.current.setFilterModel((0, _extends2.default)({}, filterModel, {
185
- logicOperator
186
- }), 'changeLogicOperator');
155
+ apiRef.current.setFilterModel((0, _gridFilterUtils.setFilterLogicOperatorInModel)(filterModel, logicOperator), 'changeLogicOperator');
187
156
  }, [apiRef]);
188
157
  const setQuickFilterValues = React.useCallback(values => {
189
158
  const filterModel = (0, _gridFilterSelector.gridFilterModelSelector)(apiRef);
@@ -15,7 +15,7 @@ import { useFirstRender } from "../../utils/useFirstRender.mjs";
15
15
  import { gridRowsLookupSelector } from "../rows/index.mjs";
16
16
  import { useGridRegisterPipeProcessor } from "../../core/pipeProcessing/index.mjs";
17
17
  import { GRID_DEFAULT_STRATEGY, useGridRegisterStrategyProcessor } from "../../core/strategyProcessing/index.mjs";
18
- import { buildAggregatedFilterApplier, sanitizeFilterModel, mergeStateWithFilterModel, cleanFilterItem, passFilterLogic, shouldQuickFilterExcludeHiddenColumns } from "./gridFilterUtils.mjs";
18
+ import { buildAggregatedFilterApplier, sanitizeFilterModel, mergeStateWithFilterModel, cleanFilterItem, passFilterLogic, shouldQuickFilterExcludeHiddenColumns, upsertFilterItemInModel, upsertFilterItemsInModel, deleteFilterItemFromModel, setFilterLogicOperatorInModel } from "./gridFilterUtils.mjs";
19
19
  import { jsx as _jsx } from "react/jsx-runtime";
20
20
  export const filterStateInitializer = (state, props, apiRef) => {
21
21
  const filterModel = props.filterModel ?? props.initialState?.filter?.filterModel ?? getDefaultGridFilterModel();
@@ -80,41 +80,15 @@ export const useGridFilter = (apiRef, props, configuration) => {
80
80
  */
81
81
  const upsertFilterItem = React.useCallback(item => {
82
82
  const filterModel = gridFilterModelSelector(apiRef);
83
- const items = [...filterModel.items];
84
- const itemIndex = items.findIndex(filterItem => filterItem.id === item.id);
85
- if (itemIndex === -1) {
86
- items.push(item);
87
- } else {
88
- items[itemIndex] = item;
89
- }
90
- apiRef.current.setFilterModel(_extends({}, filterModel, {
91
- items
92
- }), 'upsertFilterItem');
83
+ apiRef.current.setFilterModel(upsertFilterItemInModel(filterModel, item), 'upsertFilterItem');
93
84
  }, [apiRef]);
94
85
  const upsertFilterItems = React.useCallback(items => {
95
86
  const filterModel = gridFilterModelSelector(apiRef);
96
- const existingItems = [...filterModel.items];
97
- items.forEach(item => {
98
- const itemIndex = existingItems.findIndex(filterItem => filterItem.id === item.id);
99
- if (itemIndex === -1) {
100
- existingItems.push(item);
101
- } else {
102
- existingItems[itemIndex] = item;
103
- }
104
- });
105
- apiRef.current.setFilterModel(_extends({}, filterModel, {
106
- items: existingItems
107
- }), 'upsertFilterItems');
87
+ apiRef.current.setFilterModel(upsertFilterItemsInModel(filterModel, items), 'upsertFilterItems');
108
88
  }, [apiRef]);
109
89
  const deleteFilterItem = React.useCallback(itemToDelete => {
110
90
  const filterModel = gridFilterModelSelector(apiRef);
111
- const items = filterModel.items.filter(item => item.id !== itemToDelete.id);
112
- if (items.length === filterModel.items.length) {
113
- return;
114
- }
115
- apiRef.current.setFilterModel(_extends({}, filterModel, {
116
- items
117
- }), 'deleteFilterItem');
91
+ apiRef.current.setFilterModel(deleteFilterItemFromModel(filterModel, itemToDelete), 'deleteFilterItem');
118
92
  }, [apiRef]);
119
93
  const showFilterPanel = React.useCallback((targetColumnField, panelId, labelId) => {
120
94
  logger.debug('Displaying filter panel');
@@ -169,12 +143,7 @@ export const useGridFilter = (apiRef, props, configuration) => {
169
143
  }, [apiRef, logger]);
170
144
  const setFilterLogicOperator = React.useCallback(logicOperator => {
171
145
  const filterModel = gridFilterModelSelector(apiRef);
172
- if (filterModel.logicOperator === logicOperator) {
173
- return;
174
- }
175
- apiRef.current.setFilterModel(_extends({}, filterModel, {
176
- logicOperator
177
- }), 'changeLogicOperator');
146
+ apiRef.current.setFilterModel(setFilterLogicOperatorInModel(filterModel, logicOperator), 'changeLogicOperator');
178
147
  }, [apiRef]);
179
148
  const setQuickFilterValues = React.useCallback(values => {
180
149
  const filterModel = gridFilterModelSelector(apiRef);
@@ -8,4 +8,4 @@ export declare const focusStateInitializer: GridStateInitializer;
8
8
  * @requires useGridRows (method)
9
9
  * @requires useGridEditing (event)
10
10
  */
11
- export declare const useGridFocus: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, "pagination" | "paginationMode">) => void;
11
+ export declare const useGridFocus: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, 'pagination' | 'paginationMode'>) => void;