Data Grid - Column definition
Define your columns.
The columns are defined with the columns
prop which has the type GridColDef[]
.
field
is the only required property since it's the column identifier. It's also used to match with GridRowModel
values.
interface GridColDef {
/**
* The column identifier. It's used to match with [[GridRowModel]] values.
*/
field: string;
…
}
Providing content
By default, the Data Grid uses the field of a column to get its value.
For instance, the column with field name
will render the value stored in row.name
.
But for some columns, it can be useful to manually get and format the value to render.
Value getter
Sometimes a column might not have a desired value.
You can use the valueGetter
attribute of GridColDef
to:
Transform the value
const columns: GridColDef[] = [ { field: 'taxRate', valueGetter: (value) => { if (!value) { return value; } // Convert the decimal value to a percentage return value * 100; }, }, ];
Render a combination of different fields
const columns: GridColDef[] = [ { field: 'fullName', valueGetter: (value, row) => { return `${row.firstName || ''} ${row.lastName || ''}`; }, }, ];
Derive a value from a complex value
const columns: GridColDef[] = [ { field: 'profit', valueGetter: (value, row) => { if (!row.gross || !row.costs) { return null; } return row.gross - row.costs; }, }, ];
The value returned by valueGetter
is used for:
- Filtering
- Sorting
- Rendering (unless enhanced further by
valueFormatter
orrenderCell
)
Value formatter
The value formatter allows you to convert the value before displaying it.
Common use cases include converting a JavaScript Date
object to a date string or a Number
into a formatted number (for example "1,000.50").
Note, that the value returned by valueFormatter
is only used for rendering purposes.
Filtering and sorting are based on the raw value (row[field]
) or the value returned by valueGetter
.
In the following demo, valueGetter
is used to convert the tax rate (for example 0.2
) to a decimal value (for example 20
),
and valueFormatter
is used to display it as a percentage (for example 20%
).
Rendering cells
By default, the Data Grid renders the value as a string in the cell. It resolves the rendered output in the following order:
renderCell() => ReactElement
valueFormatter() => string
valueGetter() => string
row[field]
The renderCell
method of the column definitions is similar to valueFormatter
.
However, it trades to be able to only render in a cell in exchange for allowing to return a React node (instead of a string).
const columns: GridColDef[] = [
{
field: 'date',
headerName: 'Year',
renderCell: (params: GridRenderCellParams<any, Date>) => (
<strong>
{params.value.getFullYear()}
<Button
variant="contained"
size="small"
style={{ marginLeft: 16 }}
tabIndex={params.hasFocus ? 0 : -1}
>
Open
</Button>
</strong>
),
},
];
Styling cells
You can check the styling cells section for more information.
Making accessible cells
Cell content should not be in the tab sequence except if cell is focused. You can check the tab sequence section for more information.
Using hooks inside a renderer
The renderCell
property is a function that returns a React node, not a React component.
If you want to use React hooks inside your renderer, you should wrap them inside a component.
// ❌ Not valid
const column = {
// ...other properties,
renderCell: () => {
const [count, setCount] = React.useState(0);
return (
<Button onClick={() => setCount((prev) => prev + 1)}>{count} click(s)</Button>
);
},
};
// ✅ Valid
const CountButton = () => {
const [count, setCount] = React.useState(0);
return (
<Button onClick={() => setCount((prev) => prev + 1)}>{count} click(s)</Button>
);
};
const column = {
// ...other properties,
renderCell: () => <CountButton />,
};
Expand cell renderer
By default, the Data Grid cuts the content of a cell and renders an ellipsis if the content of the cell does not fit in the cell. As a workaround, you can create a cell renderer that will allow seeing the full content of the cell in the Data Grid.
Column types
To facilitate the configuration of the columns, some column types are predefined. By default, columns are assumed to hold strings, so the default column string type will be applied. As a result, column sorting will use the string comparator, and the column content will be aligned to the left side of the cell. Some column types require that their value have a specific type.
The following are the native column types with their required value types:
Column type | Value type |
---|---|
'string' (default) |
string |
'number' |
number |
'date' |
Date() object |
'dateTime' |
Date() object |
'boolean' |
boolean |
'singleSelect' |
A value in .valueOptions |
'actions' |
Not applicable |
Converting types
Default methods, such as filtering and sorting, assume that the type of the values will match the type of the column specified in type
.
For example, values of column with type: 'dateTime'
are expecting to be stored as a Date()
objects.
If for any reason, your data type is not the correct one, you can use valueGetter
to parse the value to the correct type.
{
field: 'lastLogin',
type: 'dateTime',
valueGetter: (value) => value && new Date(value),
}
Special properties
To use most of the column types, you only need to define the type
property in your column definition.
However, some types require additional properties to be set to make them work correctly:
Single select
If the column type is 'singleSelect'
, you also need to set the valueOptions
property in the respective column definition. These values are options used for filtering and editing.
{
field: 'country',
type: 'singleSelect',
valueOptions: ['United Kingdom', 'Spain', 'Brazil']
}
Actions
If the column type is 'actions'
, you need to provide a getActions
function that returns an array of actions available for each row (React elements).
You can add the showInMenu
prop on the returned React elements to signal the Data Grid to group these actions inside a row menu.
{
field: 'actions',
type: 'actions',
getActions: (params: GridRowParams) => [
<GridActionsCellItem icon={...} onClick={...} label="Delete" />,
<GridActionsCellItem icon={...} onClick={...} label="Print" showInMenu />,
]
}
By default, actions shown in the menu will close the menu on click.
But in some cases, you might want to keep the menu open after clicking an action.
You can achieve this by setting the closeMenuOnClick
prop to false
.
In the following example, the "Delete" action opens a confirmation dialog and therefore needs to keep the menu mounted:
Custom column types
Please refer to the custom columns page for documentation and integration examples.
Autogenerated rows
Some features like row grouping or aggregation create autogenerated rows.
These rows also call functions like valueGetter
, valueFormatter
and renderCell
, and that can cause issues if you're not expecting it because the row
parameter will be an empty object and the value
parameter will be undefined
.
If we take for example the movie dataset, you can detect autogenerated rows using isAutogeneratedRow()
:
{
field: 'title',
valueGetter: (value, row) => {
if (isAutogeneratedRow(row)) {
return '[this is an autogenerated row]';
}
return `title: ${value}`;
},
}
gridColumnPositionsSelector
Signature:
gridColumnPositionsSelector: (apiRef: GridApiRef) => number[]
// or
gridColumnPositionsSelector: (state: GridState, instanceId?: number) => number[]
Example
gridColumnPositionsSelector(apiRef)
// or
gridColumnPositionsSelector(state, apiRef.current.instanceId)
gridColumnVisibilityModelSelector
Signature:
gridColumnVisibilityModelSelector: (apiRef: GridApiRef) => GridColumnVisibilityModel
// or
gridColumnVisibilityModelSelector: (state: GridState, instanceId?: number) => GridColumnVisibilityModel
Example
gridColumnVisibilityModelSelector(apiRef)
// or
gridColumnVisibilityModelSelector(state, apiRef.current.instanceId)
gridColumnsTotalWidthSelector
Signature:
gridColumnsTotalWidthSelector: (apiRef: GridApiRef) => number
// or
gridColumnsTotalWidthSelector: (state: GridState, instanceId?: number) => number
Example
gridColumnsTotalWidthSelector(apiRef)
// or
gridColumnsTotalWidthSelector(state, apiRef.current.instanceId)
gridPinnedColumnsSelector
Signature:
gridPinnedColumnsSelector: (state: GridState) => GridPinnedColumnFields
Example
const pinnedColumns = gridPinnedColumnsSelector(apiRef.current.state);
gridVisibleColumnDefinitionsSelector
Signature:
gridVisibleColumnDefinitionsSelector: (apiRef: GridApiRef) => GridStateColDef[]
// or
gridVisibleColumnDefinitionsSelector: (state: GridState, instanceId?: number) => GridStateColDef[]
Example
gridVisibleColumnDefinitionsSelector(apiRef)
// or
gridVisibleColumnDefinitionsSelector(state, apiRef.current.instanceId)
gridVisibleColumnFieldsSelector
Signature:
gridVisibleColumnFieldsSelector: (apiRef: GridApiRef) => string[]
// or
gridVisibleColumnFieldsSelector: (state: GridState, instanceId?: number) => string[]
Example
gridVisibleColumnFieldsSelector(apiRef)
// or
gridVisibleColumnFieldsSelector(state, apiRef.current.instanceId)
gridVisiblePinnedColumnDefinitionsSelector
Signature:
gridVisiblePinnedColumnDefinitionsSelector: (apiRef: GridApiRef) => { left: GridStateColDef[]; right: GridStateColDef[] }
// or
gridVisiblePinnedColumnDefinitionsSelector: (state: GridState, instanceId?: number) => { left: GridStateColDef[]; right: GridStateColDef[] }
Example
gridVisiblePinnedColumnDefinitionsSelector(apiRef)
// or
gridVisiblePinnedColumnDefinitionsSelector(state, apiRef.current.instanceId)
Defined columns
Those selectors consider all the defined columns, including hidden ones.
gridColumnDefinitionsSelector
Signature:
gridColumnDefinitionsSelector: (apiRef: GridApiRef) => GridStateColDef[]
// or
gridColumnDefinitionsSelector: (state: GridState, instanceId?: number) => GridStateColDef[]
Example
gridColumnDefinitionsSelector(apiRef)
// or
gridColumnDefinitionsSelector(state, apiRef.current.instanceId)
gridColumnFieldsSelector
Signature:
gridColumnFieldsSelector: (apiRef: GridApiRef) => string[]
// or
gridColumnFieldsSelector: (state: GridState, instanceId?: number) => string[]
Example
gridColumnFieldsSelector(apiRef)
// or
gridColumnFieldsSelector(state, apiRef.current.instanceId)
gridColumnLookupSelector
Signature:
gridColumnLookupSelector: (apiRef: GridApiRef) => GridColumnLookup
// or
gridColumnLookupSelector: (state: GridState, instanceId?: number) => GridColumnLookup
Example
gridColumnLookupSelector(apiRef)
// or
gridColumnLookupSelector(state, apiRef.current.instanceId)
gridColumnsStateSelector
Signature:
gridColumnsStateSelector: (state: GridState) => GridColumnsState
Example
const columnsState = gridColumnsStateSelector(apiRef.current.state);
gridFilterableColumnDefinitionsSelector
Signature:
gridFilterableColumnDefinitionsSelector: (apiRef: GridApiRef) => GridStateColDef[]
// or
gridFilterableColumnDefinitionsSelector: (state: GridState, instanceId?: number) => GridStateColDef[]
Example
gridFilterableColumnDefinitionsSelector(apiRef)
// or
gridFilterableColumnDefinitionsSelector(state, apiRef.current.instanceId)
gridFilterableColumnLookupSelector
Signature:
gridFilterableColumnLookupSelector: (apiRef: GridApiRef) => GridColumnLookup
// or
gridFilterableColumnLookupSelector: (state: GridState, instanceId?: number) => GridColumnLookup
Example
gridFilterableColumnLookupSelector(apiRef)
// or
gridFilterableColumnLookupSelector(state, apiRef.current.instanceId)
More information about the selectors and how to use them on the dedicated page.