Migration from v6 to v7
This guide describes the changes needed to migrate the Data Grid from v6 to v7.
Introduction
This is a reference guide for upgrading @mui/x-data-grid
from v6 to v7.
To read more about the changes from the new major, check out the blog post about the release of MUI X v7.
Start using the new release
In package.json
, change the version of the Data Grid package to ^7.0.0
.
-"@mui/x-data-grid": "^6.0.0",
+"@mui/x-data-grid": "^7.0.0",
-"@mui/x-data-grid-pro": "^6.0.0",
+"@mui/x-data-grid-pro": "^7.0.0",
-"@mui/x-data-grid-premium": "^6.0.0",
+"@mui/x-data-grid-premium": "^7.0.0",
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.14
.
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.0.0",
+"@mui/x-license": "^7.0.0",
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 the 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@latest v7.0.0/data-grid/preset-safe <path>
# Target other MUI X components as well
npx @mui/x-codemod@latest 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.
Drop the legacy bundle
The support for IE 11 has been removed from all MUI X packages.
The legacy
bundle that used to support old browsers like IE 11 is no longer included.
Drop webpack 4 support
Dropping old browsers support also means that we no longer transpile some features that are natively supported by modern browsers – like Nullish Coalescing and Optional Chaining.
These features are not supported by webpack 4, so if you are using webpack 4, you will need to transpile these features yourself or upgrade to webpack 5.
Here is an example of how you can transpile these features on webpack 4 using the @babel/preset-env
preset:
// webpack.config.js
module.exports = (env) => ({
// ...
module: {
rules: [
{
test: /\.[jt]sx?$/,
- exclude: /node_modules/,
+ exclude: [
+ {
+ test: path.resolve(__dirname, 'node_modules'),
+ exclude: [
+ // Covers @mui/x-data-grid, @mui/x-data-grid-pro, and @mui/x-data-grid-premium
+ path.resolve(__dirname, 'node_modules/@mui/x-data-grid'),
+ path.resolve(__dirname, 'node_modules/@mui/x-license'),
+ ],
+ },
+ ],
},
],
},
});
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 virtual scroller element.
- Headers are now contained in the virtual scroller.
- Pinned row and column sections are now contained in the virtual scroller.
- The cell inner wrapper
.MuiDataGrid-cellContent
has been removed.
Renamed props
- The props
rowBuffer
andcolumnBuffer
were renamed torowBufferPx
andcolumnBufferPx
. Their value is now a pixel value rather than a number of items. Their default value is now150
.
Removed props
✅ The deprecated props
components
andcomponentsProps
have been removed. Useslots
andslotProps
instead. See components section for more details.The
slots.preferencesPanel
slot and theslotProps.preferencesPanel
prop were removed. Useslots.panel
andslotProps.panel
instead.The
getOptionValue
andgetOptionLabel
props were removed from the following components:GridEditSingleSelectCell
GridFilterInputSingleSelect
GridFilterInputMultipleSingleSelect
Use the
getOptionValue
andgetOptionLabel
properties on thesingleSelect
column 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, };
The props
rowThreshold
andcolumnThreshold
have been removed. If you had therowThreshold
prop set to0
to force new rows to be rendered more often – this is no longer necessary.✅ Some feature flags were removed from the
experimentalFeatures
prop. These features are now stable and enabled by default:
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 theGridColDef
interface 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
GridPinnedColumns
has been renamed toGridPinnedColumnFields
.The type
GridPinnedPosition
has been renamed toGridPinnedColumnPosition
.The column grouping API methods
getColumnGroupPath
andgetAllGroupDetails
are no longer prefixed withunstable_
.The column grouping selectors
gridFocusColumnGroupHeaderSelector
andgridTabIndexColumnGroupHeaderSelector
are no longer prefixed withunstable_
.The columns management component has been redesigned and the component is extracted from the
ColumnsPanel
which now only serves as a wrapper to display the component over the headers as a panel. As a result, a new slotcolumnsManagement
, and corresponding propslotProps.columnsManagement
have been introduced. The props corresponding to the columns management component which were previously passed to the propslotProps.columnsPanel
should now be passed toslotProps.columnsManagement
.slotProps.columnsPanel
could still be used to override props corresponding to thePanel
component used inColumnsPanel
which usesPopper
component under the hood.
<DataGrid
slotProps={{
- columnsPanel: {
+ columnsManagement: {
sort: 'asc',
autoFocusSearchField: false,
},
}}
/>
Show all
andHide all
buttons in theColumnsPanel
have been combined into oneShow/Hide All
checkbox in the new columns management component. The related propsdisableShowAllButton
anddisableHideAllButton
have been replaced with a new propdisableShowHideToggle
.The signature of
GridColDef['valueGetter']
has been changed for performance reasons:-valueGetter: ({ value, row }) => value, +valueGetter: (value, row, column, apiRef) => value,
The
GridValueGetterParams
interface 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
GridValueFormatterParams
interface 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
GridValueSetterParams
interface 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 }, row, column, apiRef) => value.name,
Density
- The
density
is a controlled prop now, if you were previously passing thedensity
prop to the Data Grid, you will need to do one of the following:
- Move it to the
initialState.density
to initialize it.
<DataGrid
- density="compact"
+ initialState={{ density: "compact" }}
/>
- Move it to the state and use
onDensityChange
callback to update thedensity
prop accordingly for it to work as expected.
const [density, setDensity] = React.useState<GridDensity>('compact');
<DataGrid
- density="compact"
+ density={density}
+ onDensityChange={(newDensity) => setDensity(newDensity)}
/>
- The selector
gridDensityValueSelector
was removed, use thegridDensitySelector
instead.
Clipboard
- ✅ The clipboard related exports
ignoreValueFormatterDuringExport
andsplitClipboardPastedText
are 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
getRowsToExport
function.
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
getApplyFilterFnV7
inGridFilterOperator
has been renamed togetApplyFilterFn
. If you usegetApplyFilterFnV7
directly - rename it togetApplyFilterFn
.The signature of the function returned by
getApplyFilterFn
has 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
getApplyQuickFilterFnV7
inGridColDef
was renamed togetApplyQuickFilterFn
. If you usegetApplyQuickFilterFnV7
directly - rename it togetApplyQuickFilterFn
.The signature of the function returned by
getApplyQuickFilterFn
has 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 propheaderFilters
and 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
Select
component for all components.The
filterModel
now supportsDate
objects as values fordate
anddateTime
column types. ThefilterModel
still accepts strings as values fordate
anddateTime
column types, but all updates to thefilterModel
coming from the UI (for example filter panel) will set the value as aDate
object.
Accessibility
✅ The
ariaV7
experimental flag has been removed and the Data Grid now uses the improved accessibility implementation by default. If you were using theariaV7
flag, you can remove it from theexperimentalFeatures
prop:-<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 innerdiv
element instead of the rootdiv
element:-<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 ofrole="grid"
.The Data Grid cells now have
role="gridcell"
instead ofrole="cell"
.
Editing
- The
rowEditCommit
event and the related proponRowEditCommit
was removed. TheprocessRowUpdate
prop 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_TIME
andSUBMIT_FILTER_DATE_STROKE_TIME
are no longer exported. Use thefilterDebounceMs
prop to customize filter debounce time.The
GridPreferencesPanel
component 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
, andGridToolbarExport
are 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 theslotProps
prop. 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 and styling
You can now style a row's hover state using just
:hover
instead of.Mui-hovered
.The
.MuiDataGrid--pinnedColumns-(left\|right)
class for pinned columns has been removed.The
.MuiDataGrid-cell--withRenderer
class has been removed.The cell element isn't
display: flex
by default. You can adddisplay: 'flex'
on the column definition to restore the behavior.NOTE: If you're using dynamic row height, this also means cells aren't vertically centered by default anymore, you might want to set the
display: 'flex'
for all non-dynamic columns. This may also affect text-ellipsis, which you can restore by adding your own wrapper withtext-overflow: ellipsis
.{ display: 'flex', renderCell: ({ value }) => ( <div style={{ overflow: 'hidden', textOverflow: 'ellipsis' }}> {value} </div> ), },
The
columnHeader--showColumnBorder
class was replaced bycolumnHeader--withLeftBorder
andcolumnHeader--withRightBorder
.The
columnHeadersInner
,columnHeadersInner--scrollable
, andcolumnHeaderDropZone
classes were removed since the inner wrapper was removed in our effort to simplify the DOM structure and improve accessibility.The
pinnedColumnHeaders
,pinnedColumnHeaders--left
, andpinnedColumnHeaders--right
classes have been removed along with the element they were applied to. The pinned column headers now useposition: 'sticky'
and are rendered in the same row element as the regular column headers.The column headers and pinned section now require an explicit color. By default, the MUI
theme.palette.background.default
color will be used. To customize it, see https://mui.com/material-ui/customization/palette/#customization We will be adding a new color name to the palette for additional customization, read #12443 for more details.
Changes to the public API
- The method
getRootDimensions()
now returns a non-null value. - The field
mainElementRef
is now always non-null. - The field
rootElementRef
is now always non-null. - The field
virtualScrollerRef
is now always non-null. - The event
renderedRowsIntervalChange
params changed fromGridRenderedRowsIntervalChangeParams
toGridRenderContext
, and the former has been removed.
Changes to slots
- The slot
columnHeaders
has had these props removed:columnPositions
,densityFactor
,minColumnIndex
. - The slot
row
has had these props removed:containerWidth
,position
. - The slot
row
has typed props now. - The slot
headerFilterCell
has had these props removed:filterOperators
. - All slots are now strongly typed, previously were
React.JSXElementConstructor<any>
.