Data Grid - Columns
This section goes in details on the aspects of the columns you need to know.
Column definitions
Grid columns are defined with the columns
prop.
columns
expects an array of objects.
The columns should have this type: GridColDef[]
.
field
is the only required property since it's the column identifier. It's also used to match with GridRowData
values.
interface GridColDef {
/**
* The column identifier. It's used to match with [[GridRowData]] values.
*/
field: string;
…
}
<DataGrid
columns={[{ field: 'username' }, { field: 'age' }]}
rows={[
{
id: 1,
username: '@MaterialUI',
age: 20,
},
]}
/>
By default, columns are ordered according to the order they are included in the columns
array.
⚠️ The
columns
prop should keep the same reference between two renders. The columns are designed to be definitions, to never change once the component is mounted. Otherwise, you take the risk of losing the column width state (if resized). You can create the array outside of the render function or memoize it.
Headers
You can configure the headers with:
headerName
: The title of the column rendered in the column header cell.description
: The description of the column rendered as tooltip if the column header name is not fully displayed.
<DataGrid
columns={[
{
field: 'username',
headerName: 'Username',
description:
'The identification used by the person with access to the online service.',
},
{ field: 'age', headerName: 'Age' },
]}
rows={rows}
/>
Width
By default, the columns have a width of 100 pixels.
This is an arbitrary, easy to remember value.
To change the width of a column, use the width
property available in GridColDef
.
<DataGrid
columns={[{ field: 'username', width: 200 }, { field: 'age' }]}
rows={rows}
/>
Fluid width
Column fluidity or responsiveness can be by achieved by setting the flex
property in GridColDef
.
The flex
property accepts a value between 0 and ∞.
It works by dividing the remaining space in the grid among all flex columns in proportion to their flex
value.
For example, consider a grid with a total width of 500px that has three columns: the first with width: 200
; the second with flex: 1
; and third with flex: 0.5
.
The first column will be 200px wide, leaving 300px remaining. The column with flex: 1
is twice the size of flex: 0.5
, which means that final sizes will be: 200px, 200px, 100px.
Note
flex
doesn't work together withwidth
. If you set bothflex
andwidth
inGridColDef
,flex
will overridewidth
.flex
doesn't work if the combined width of the columns that havewidth
is more than the width of the grid itself. If that is the case a scroll bar will be visible, and the columns that haveflex
will default back to their base value of 100px.
Hiding
Set the column definition attribute hide
to true
to hide the column.
<DataGrid columns={[{ field: 'id', hide: true }]} />
Resizing
By default, XGrid
allows all columns to be resized by dragging the right portion of the column separator.
To prevent the resizing of a column, set resizable: false
in the GridColDef
.
Alternatively, to disable all columns resize, set the prop disableColumnResize={true}
.
<XGrid
columns={[
{ field: 'id' },
{ field: 'username' },
{ field: 'age', resizable: false },
]}
rows={rows}
/>
Value getter
Sometimes a column might not have a corresponding value, or you might want to render a combination of different fields.
To achieve that, set the valueGetter
attribute of GridColDef
as in the example below.
Note: You need to set a sortComparator
for the column sorting to work when setting the valueGetter
attribute.
function getFullName(params: ValueGetterParams) {
return `${params.getValue('firstName') || ''} ${
params.getValue('lastName') || ''
}`;
}
const columns: GridColDef[] = [
{ field: 'firstName', headerName: 'First name', width: 130 },
{ field: 'lastName', headerName: 'Last name', width: 130 },
{
field: 'fullName',
headerName: 'Full name',
width: 160,
valueGetter: getFullName,
sortComparator: (v1, v2, cellParams1, cellParams2) =>
getFullName(cellParams1).localeCompare(getFullName(cellParams2)),
},
];
<DataGrid rows={rows} columns={columns} />
The value generated is used for filtering, sorting, rendering, etc unless overridden by a more specific configuration.
Value formatter
The value formatters allow you to format values for display as a string.
For instance, you can use it to format a JavaScript Date
object.
const columns: GridColDef[] = [
{
field: 'date',
headerName: 'Year',
valueFormatter: (params: ValueFormatterParams) =>
(params.value as Date).getFullYear(),
},
];
<DataGrid rows={rows} columns={columns} />
The value generated is used for filtering, sorting, rendering in the cell and outside, etc unless overridden by a more specific configuration.
Render cell
By default, the grid render 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: GridCellParams) => (
<strong>
{(params.value as Date).getFullYear()}
<Button
variant="contained"
color="primary"
size="small"
style={{ marginLeft: 16 }}
>
Open
</Button>
</strong>
),
},
];
<DataGrid rows={rows} columns={columns} />
Render edit cell
The renderCell
render function allows customizing the rendered in "view mode" only.
For the "edit mode", set the renderEditCell
function to customize the edit component.
Check the editing page for more details about editing.
Expand cell renderer
By default, the 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 grid.
<DataGrid rows={rows} columns={columns} />
Render header
You can customize the look of each header with the renderHeader
method.
It takes precedence over the headerName
property.
const columns: GridColDef[] = [
{
field: 'date',
width: 150,
type: 'date',
renderHeader: (params: GridColumnHeaderParams) => (
<strong>
{'Birthday '}
<span role="img" aria-label="enjoy">
🎂
</span>
</strong>
),
},
];
<DataGrid rows={rows} columns={columns} />
Styling header
The GridColDef
type has properties to apply class names and custom CSS on the header.
headerClassName
: to apply class names into the column header.headerAlign
: to align the content of the header. It must be 'left' | 'right' | 'center'.
const columns: GridColumns = [
{
field: 'first',
headerClassName: 'super-app-theme--header',
headerAlign: 'center',
},
{
field: 'last',
headerClassName: 'super-app-theme--header',
headerAlign: 'center',
},
];
<DataGrid rows={rows} columns={columns} />
Styling cells
The GridColDef
type has properties to apply class names and custom CSS on the cells.
cellClassName
: to apply class names on every cell. It can also be a function.align
: to align the content of the cells. It must be 'left' | 'right' | 'center'. (Note you must useheaderAlign
to align the content of the header.)
const columns: GridColumns = [
{
field: 'name',
cellClassName: 'super-app-theme--cell',
},
{
field: 'score',
type: 'number',
cellClassName: (params: GridCellClassParams) =>
clsx('super-app', {
negative: (params.value as number) < 0,
positive: (params.value as number) > 0,
}),
},
];
<DataGrid rows={rows} columns={columns} />
Column types
To facilitate 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.
The following are the native column types:
'string'
(default)'number'
'date'
'dateTime'
'boolean'
To apply a column type, you need to define the type property in your column definition.
<DataGrid
columns={[
{ field: 'name', type: 'string' },
{ field: 'age', type: 'number' },
{ field: 'dateCreated', type: 'date', width: 130 },
{ field: 'lastLogin', type: 'dateTime', width: 180 },
{ field: 'isAdmin', type: 'boolean', width: 120 },
]}
rows={rows}
/>
Custom column types
You can extend the native column types with your own by simply spreading the necessary properties.
The demo below defines a new column type: usdPrice
that extends the native number
column type.
const usdPrice: GridColTypeDef = {
type: 'number',
width: 130,
valueFormatter: ({ value }) => valueFormatter.format(Number(value)),
cellClassName: 'font-tabular-nums',
};
<DataGrid
columns={[
{ field: 'status', width: 130 },
{ field: 'subTotal', ...usdPrice },
{ field: 'total', ...usdPrice },
]}
rows={rows}
/>
Column menu
By default, each column header displays a column menu. The column menu allows actions to be performed in the context of the target column, e.g. filtering. To disable the column menu, set the prop disableColumnMenu={true}
.
<DataGrid {...data} disableColumnMenu />
Column selector
To enable the the toolbar you need to add Toolbar: GridToolbar
to the grid components
prop.
In addition, the column selector can be shown by using the "Show columns" menu item in the column menu.
The user can choose which columns are visible using the column selector from the toolbar.
To disable the column selector, set the prop disableColumnSelector={true}
.
<DataGrid
{...data}
components={{
Toolbar: GridToolbar,
}}
/>
Column reorder
By default, XGrid
allows all column reordering by dragging the header cells and moving them left or right.
To disable column reordering, set the prop disableColumnReorder={true}
.
In addition, column reordering emits the following events that can be imported:
columnHeaderDragStart
: emitted when dragging of a header cell starts.columnHeaderDragEnter
: emitted when the cursor enters another header cell while dragging.columnHeaderDragOver
: emitted when dragging a header cell over another header cell.columnHeaderDragEnd
: emitted when dragging of a header cell stops.
<XGrid {...data} />
🚧 Column groups
⚠️ This feature isn't implemented yet. It's coming.
👍 Upvote issue #195 if you want to see it land faster.
Grouping columns allows you to have multiple levels of columns in your header and the ability, if needed, to 'open and close' column groups to show and hide additional columns.
🚧 Column pinning
⚠️ This feature isn't implemented yet. It's coming.
👍 Upvote issue #193 if you want to see it land faster.
Sticky (or frozen, locked, or pinned) columns are columns that are visible at all times while the user scrolls the grid horizontally.
🚧 Column spanning
⚠️ This feature isn't implemented yet. It's coming.
👍 Upvote issue #192 if you want to see it land faster.
Each cell takes up the width of one column.
Column spanning allows to change this default behavior.
It allows cells to span multiple columns.
This is very close to the "column spanning" in an HTML <table>
.