Migration from v6 to v7
This guide describes the changes needed to migrate the Data Grid from v6 to v7.
Start using the new release
In package.json, change the version of the data grid package to next.
-"@mui/x-data-grid": "6.x.x",
+"@mui/x-data-grid": "next",
-"@mui/x-data-grid-pro": "6.x.x",
+"@mui/x-data-grid-pro": "next",
-"@mui/x-data-grid-premium": "6.x.x",
+"@mui/x-data-grid-premium": "next",
Since v7 is a major release, it contains changes that affect the public API. These changes were done for consistency, improved stability and to make room for new features. Described below are the steps needed to migrate from v6 to v7.
Update @mui/material package
To have the option of using the latest API from @mui/material, the package peer dependency version has been updated to ^5.15.0.
It is a change in minor version only, so it should not cause any breaking changes.
Please update your @mui/material package to this or a newer version.
Update the license package
If you're using the commercial version of the Data Grid (Pro and Premium plans), you need to update the import path:
-import { LicenseInfo } from '@mui/x-license-pro';
+import { LicenseInfo } from '@mui/x-license';
If you have @mui/x-license-pro in the dependencies section of your package.json, rename and update the license package to the latest version:
-"@mui/x-license-pro": "6.x.x",
+"@mui/x-license": "next",
Run codemods
The preset-safe codemod will automatically adjust the bulk of your code to account for breaking changes in v7.
You can run v7.0.0/data-grid/preset-safe targeting only Data Grid or v7.0.0/preset-safe to target other MUI X components like Date and Time pickers as well.
You can either run it on a specific file, folder, or your entire codebase when choosing the <path> argument.
// Data Grid specific
npx @mui/x-codemod@next v7.0.0/data-grid/preset-safe <path>
// Target other MUI X components as well
npx @mui/x-codemod@next v7.0.0/preset-safe <path>
Breaking changes that are handled by preset-safe codemod are denoted by a ✅ emoji in the table of contents on the right side of the screen or next to the specific point that is handled by it.
If you have already applied the v7.0.0/data-grid/preset-safe (or v7.0.0/preset-safe) codemod, then you should not need to take any further action on these items. If there's a specific part of the breaking change that is not part of the codemod or needs some manual work, it will be listed in the end of each section.
All other changes must be handled manually.
Breaking changes
Since v7 is a major release, it contains some changes that affect the public API. These changes were done for consistency, improve stability and make room for new features. Below are described the steps you need to make to migrate from v6 to v7.
DOM changes
The Data Grid's layout has been substantially altered to use CSS sticky positioned elements. As a result, the following changes have been made:
- The main element now corresponds to the virtal scroller element.
- Headers are now contained in the virtual scroller.
- Pinned row and column sections are now contained in the virtual scroller.
Removed props
- The deprecated props - componentsand- componentsPropshave been removed. Use- slotsand- slotPropsinstead. See components section for more details.
- The - slots.preferencesPanelslot and the- slotProps.preferencesPanelprop were removed. Use- slots.paneland- slotProps.panelinstead.
- The - getOptionValueand- getOptionLabelprops were removed from the following components:- GridEditSingleSelectCell
- GridFilterInputSingleSelect
- GridFilterInputMultipleSingleSelect
 - Use the - getOptionValueand- getOptionLabelproperties on the- singleSelectcolumn definition instead:- const column: GridColDef = { type: 'singleSelect', field: 'country', valueOptions: [ { code: 'BR', name: 'Brazil' }, { code: 'FR', name: 'France' }, ], getOptionValue: (value: any) => value.code, getOptionLabel: (value: any) => value.name, };
Behavioral changes
The disabled column specific features like hiding, sorting, filtering, pinning, row grouping, etc., can now be controlled programmatically using initialState, respective controlled models, or the API object.
Here's the list of affected features, column definition flags and props to disable them, and the related props and API methods to control them programmatically.
State access
Some selectors now require passing instanceId as a second argument:
- gridColumnFieldsSelector(apiRef.current.state);
+ gridColumnFieldsSelector(apiRef.current.state, apiRef.current.instanceId);
However, it's preferable to pass the apiRef as the first argument instead:
gridColumnFieldsSelector(apiRef);
See the Direct state access page for more info.
Columns
- The - GridColDef['type']has been narrowed down to only accept the built-in column types. TypeScript users need to use the- GridColDefinterface when defining columns:- // 🛑 `type` is inferred as `string` and is too wide const columns = [{ type: 'number', field: 'id' }]; <DataGrid columns={columns} />; // ✅ `type` is `'number'` const columns: GridColDef[] = [{ type: 'number', field: 'id' }]; <DataGrid columns={columns} />; // ✅ Alternalively, `as const` can be used to narrow down the type const columns = [{ type: 'number' as const, field: 'id' }]; <DataGrid columns={columns} />;
- The type - GridPinnedColumnshas been renamed to- GridPinnedColumnFields.
- The type - GridPinnedPositionhas been renamed to- GridPinnedColumnPosition.
- Column grouping is now enabled by default. The flag - columnGroupingis no longer needed to be passed to the- experimentalFeaturesprop to enable it.
- The column grouping API methods - getColumnGroupPathand- getAllGroupDetailsare not anymore prefixed with- unstable_.
- The column grouping selectors - gridFocusColumnGroupHeaderSelectorand- gridTabIndexColumnGroupHeaderSelectorare not anymore prefixed with- unstable_.
- The columns management component has been redesigned and the component is extracted from the - ColumnsPanelwhich now only serves as a wrapper to display the component over the headers as a panel. As a result, a new slot- columnsManagement, and corresponding prop- slotProps.columnsManagementhave been introduced. The props corresponding to the columns management component which were previously passed to the prop- slotProps.columnsPanelshould now be passed to- slotProps.columnsManagement.- slotProps.columnsPanelcould still be used to override props corresponding to the- Panelcomponent used in- ColumnsPanelwhich uses- Poppercomponent under the hood.
 <DataGrid
  slotProps={{
-   columnsPanel: {
+   columnsManagement: {
      sort: 'asc',
      autoFocusSearchField: false,
    },
  }}
 />
- Show alland- Hide allbuttons in the- ColumnsPanelhave been combined into one- Show/Hide Allcheckbox in the new columns management component. The related props- disableShowAllButtonand- disableHideAllButtonhave been replaced with a new prop- disableShowHideToggle.
- The signature of - GridColDef['valueGetter']has been changed for performance reasons:- - valueGetter: ({ value, row }) => value, + valueGetter: (value, row, column, apiRef) => value,- The - GridValueGetterParamsinterface has been removed:- - const customValueGetter = (params: GridValueGetterParams) => params.row.budget; + const customValueGetter: GridValueGetterFn = (value, row) => row.budget;
- The signature of - GridColDef['valueFormatter']has been changed for performance reasons:- - valueFormatter: ({ value }) => value, + valueFormatter: (value, row, column, apiRef) => value,- The - GridValueFormatterParamsinterface has been removed:- - const gridDateFormatter = ({ value, field, id }: GridValueFormatterParams<Date>) => value.toLocaleDateString(); + const gridDateFormatter: GridValueFormatter = (value: Date) => value.toLocaleDateString();
- The signature of - GridColDef['valueSetter']has been changed for performance reasons:- - valueSetter: (params) => { - const [firstName, lastName] = params.value!.toString().split(' '); - return { ...params.row, firstName, lastName }; - } + valueSetter: (value, row) => { + const [firstName, lastName] = value!.toString().split(' '); + return { ...row, firstName, lastName }; +}- The - GridValueSetterParamsinterface has been removed:- - const setFullName = (params: GridValueSetterParams) => { - const [firstName, lastName] = params.value!.toString().split(' '); - return { ...params.row, firstName, lastName }; - }; + const setFullName: GridValueSetter<Row> = (value, row) => { + const [firstName, lastName] = value!.toString().split(' '); + return { ...row, firstName, lastName }; + }
- The signature of - GridColDef['valueParser']has been changed for performance reasons:- - valueParser: (value, params: GridCellParams) => value.toLowerCase(), + valueParser: (value, row, column, apiRef) => value.toLowerCase(),
- The signature of - GridColDef['colSpan']has been changed for performance reasons:- - colSpan: ({ row, field, value }: GridCellParams) => (row.id === 'total' ? 2 : 1), + colSpan: (value, row, column, apiRef) => (row.id === 'total' ? 2 : 1),
- The signature of - GridColDef['pastedValueParser']has been changed for performance reasons:- - pastedValueParser: (value, params) => new Date(value), + pastedValueParser: (value, row, column, apiRef) => new Date(value),
- The signature of - GridColDef['groupingValueGetter']has been changed for performance reasons:- - groupingValueGetter: (params) => params.value.name, + groupingValueGetter: (value: { name: string }) => value.name,
Clipboard
- Clipboard paste is now enabled by default. The flag clipboardPasteis no longer needed to be passed to theexperimentalFeaturesprop to enable it.
- The clipboard related exports ignoreValueFormatterDuringExportandsplitClipboardPastedTextare not anymore prefixed withunstable_.
Print export
- The print export will now only print the selected rows if there are any.
If there are no selected rows, it will print all rows. This makes the print export consistent with the other exports.
You can customize the rows to export by using the getRowsToExportfunction.
Selection
- ✅ The - unstable_prefix has been removed from the cell selection props listed below.- Old name - New name - unstable_cellSelection- cellSelection- unstable_cellSelectionModel- cellSelectionModel- unstable_onCellSelectionModelChange- onCellSelectionModelChange
- The - unstable_prefix has been removed from the cell selection API methods listed below.- Old name - New name - unstable_getCellSelectionModel- getCellSelectionModel- unstable_getSelectedCellsAsArray- getSelectedCellsAsArray- unstable_isCellSelected- isCellSelected- unstable_selectCellRange- selectCellRange- unstable_setCellSelectionModel- setCellSelectionModel
Filtering
- The - getApplyFilterFnV7in- GridFilterOperatorwas renamed to- getApplyFilterFn. If you use- getApplyFilterFnV7directly - rename it to- getApplyFilterFn.
- The signature of the function returned by - getApplyFilterFnhas changed for performance reasons:
 const getApplyFilterFn: GetApplyFilterFn<any, unknown> = (filterItem) => {
   if (!filterItem.value) {
     return null;
   }
   const filterRegex = new RegExp(escapeRegExp(filterItem.value), 'i');
-  return (cellParams) => {
-    const { value } = cellParams;
+  return (value, row, colDef, apiRef) => {
     return value != null ? filterRegex.test(String(value)) : false;
   };
 }
- The - getApplyQuickFilterFnV7in- GridColDefwas renamed to- getApplyQuickFilterFn. If you use- getApplyQuickFilterFnV7directly - rename it to- getApplyQuickFilterFn.
- The signature of the function returned by - getApplyQuickFilterFnhas changed for performance reasons:
 const getGridStringQuickFilterFn: GetApplyQuickFilterFn<any, unknown> = (value) => {
   if (!value) {
     return null;
   }
   const filterRegex = new RegExp(escapeRegExp(value), 'i');
-  return (cellParams) => {
-    const { formattedValue } = cellParams;
+  return (value, row, column, apiRef) => {
+    let formattedValue = apiRef.current.getRowFormattedValue(row, column);
     return formattedValue != null ? filterRegex.test(formattedValue.toString()) : false;
   };
 };
- The Quick Filter now ignores hidden columns by default. See Including hidden columns section for more details. 
- The header filters feature is now stable. - unstable_prefix is removed from prop- headerFiltersand the following exports.- Old name - New name - unstable_gridFocusColumnHeaderFilterSelector- gridFocusColumnHeaderFilterSelector- unstable_gridHeaderFilteringEditFieldSelector- gridHeaderFilteringEditFieldSelector- unstable_gridHeaderFilteringMenuSelector- gridHeaderFilteringMenuSelector- unstable_gridHeaderFilteringStateSelector- gridHeaderFilteringStateSelector- unstable_gridTabIndexColumnHeaderFilterSelector- gridTabIndexColumnHeaderFilterSelector
- The filter panel no longer uses the native version of the - Selectcomponent for all components.
- The - filterModelnow supports- Dateobjects as values for- dateand- dateTimecolumn types. The- filterModelstill accepts strings as values for- dateand- dateTimecolumn types, but all updates to the- filterModelcoming from the UI (e.g. filter panel) will set the value as a- Dateobject.
Accessibility
- The - ariaV7experimental flag has been removed and the Data Grid now uses the improved accessibility implementation by default. If you were using the- ariaV7flag, you can remove it from the- experimentalFeaturesprop:- -<DataGrid experimentalFeatures={{ ariaV7: true }} /> +<DataGrid />- The most notable changes that might affect your application or tests are: - The - role="grid"attribute along with related ARIA attributes are now applied to the inner- divelement instead of the root- divelement:- -<div class="MuiDataGrid-root" role="grid" aria-colcount="5" aria-rowcount="101" aria-multiselectable="false"> +<div class="MuiDataGrid-root"> <div class="MuiDataGrid-toolbarContainer"></div> - <div class="MuiDataGrid-main"></div> + <div class="MuiDataGrid-main" role="grid" aria-colcount="5" aria-rowcount="101" aria-multiselectable="false"></div> <div class="MuiDataGrid-footerContainer"></div> </div>
- When Tree data feature is used, the grid role is now - role="treegrid"instead of- role="grid".
- The Data Grid cells now have - role="gridcell"instead of- role="cell".
 
Editing
- The rowEditCommitevent and the related proponRowEditCommitwas removed. TheprocessRowUpdateprop can be used in its place.
Other exports
- The import path for locales has been changed: - -import { enUS } from '@mui/x-data-grid'; +import { enUS } from '@mui/x-data-grid/locales'; -import { enUS } from '@mui/x-data-grid-pro'; +import { enUS } from '@mui/x-data-grid-pro/locales'; -import { enUS } from '@mui/x-data-grid-premium'; +import { enUS } from '@mui/x-data-grid-premium/locales';
- The deprecated constants - SUBMIT_FILTER_STROKE_TIMEand- SUBMIT_FILTER_DATE_STROKE_TIMEare no longer exported. Use the- filterDebounceMsprop to customize filter debounce time.
- The - GridPreferencesPanelcomponent is not exported anymore as it wasn't meant to be used outside of the Data Grid.
- The buttons in toolbar composable components - GridToolbarColumnsButton,- GridToolbarFilterButton,- GridToolbarDensity, and- GridToolbarExportare now wrapped with a tooltip component and have a consistent interface. In order to override some props corresponding to the toolbar buttons or their corresponding tooltips, you can use the- slotPropsprop. Following is an example diff. See Toolbar section for more details.
 function CustomToolbar() {
  return (
    <GridToolbarContainer>
      <GridToolbarColumnsButton />
      <GridToolbarFilterButton
-       title="Custom filter" // 🛑 This was previously forwarded to the tooltip component
+       slotProps={{ tooltip: { title: 'Custom filter' } }} // ✅ This is the correct way now
      />
      <GridToolbarDensitySelector
-       variant="outlined"    // 🛑 This was previously forwarded to the button component
+       slotProps={{ button: { variant: 'outlined' } }} // ✅ This is the correct way now
      />
    </GridToolbarContainer>
  );
 }
CSS classes
- You can now style a row's hover state using just :hoverinstead of.Mui-hovered.
- The .MuiDataGrid--pinnedColumns-(left\|right)class for pinned columns has been removed.
Changes to the public API
- The method getRootDimensions()now returns a non-null value.
- The field mainElementRefis now always non-null.
- The field rootElementRefis now always non-null.
- The field virtualScrollerRefis now always non-null.
- The event renderedRowsIntervalChangeparams changed fromGridRenderedRowsIntervalChangeParamstoGridRenderContext, and the former has been removed.
Changes to slots
- The slot columnHeadershas had these props removed:columnPositions,densityFactor,minColumnIndex.
- The slot rowhas had these props removed:containerWidth,position.
- The slot rowhas typed props now.
- The slot headerFilterCellhas had these props removed:filterOperators.
- All slots are now strongly typed, previously were React.JSXElementConstructor<any>.