Skip to content
+

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;}
Press Enter to start editing

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:

  1. Transform the value

    const columns: GridColDef[] = [
      {
        field: 'taxRate',
        valueGetter: (value) => {
          if (!value) {
            return value;
          }
          // Convert the decimal value to a percentage
          return value * 100;
        },
      },
    ];
    
  2. Render a combination of different fields

    const columns: GridColDef[] = [
      {
        field: 'fullName',
        valueGetter: (value, row) => {
          return `${row.firstName || ''} ${row.lastName || ''}`;
        },
      },
    ];
    
  3. 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:

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:

  1. renderCell() => ReactElement
  2. valueFormatter() => string
  3. valueGetter() => string
  4. 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.

Press Enter to start editing

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
Press Enter to start editing

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:

Press Enter to start editing

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}`;
  },
}

Selectors

Visible columns

Those selectors do not take into account hidden columns.

Signature:
gridColumnPositionsSelector: (apiRef: GridApiRef) => number[]
// or
gridColumnPositionsSelector: (state: GridState, instanceId?: number) => number[]
Example
gridColumnPositionsSelector(apiRef)
// or
gridColumnPositionsSelector(state, apiRef.current.instanceId)
Signature:
gridColumnVisibilityModelSelector: (apiRef: GridApiRef) => GridColumnVisibilityModel
// or
gridColumnVisibilityModelSelector: (state: GridState, instanceId?: number) => GridColumnVisibilityModel
Example
gridColumnVisibilityModelSelector(apiRef)
// or
gridColumnVisibilityModelSelector(state, apiRef.current.instanceId)
Signature:
gridColumnsTotalWidthSelector: (apiRef: GridApiRef) => number
// or
gridColumnsTotalWidthSelector: (state: GridState, instanceId?: number) => number
Example
gridColumnsTotalWidthSelector(apiRef)
// or
gridColumnsTotalWidthSelector(state, apiRef.current.instanceId)
Signature:
gridPinnedColumnsSelector: (state: GridState) => GridPinnedColumnFields
Example
const pinnedColumns = gridPinnedColumnsSelector(apiRef.current.state);
Signature:
gridVisibleColumnDefinitionsSelector: (apiRef: GridApiRef) => GridStateColDef[]
// or
gridVisibleColumnDefinitionsSelector: (state: GridState, instanceId?: number) => GridStateColDef[]
Example
gridVisibleColumnDefinitionsSelector(apiRef)
// or
gridVisibleColumnDefinitionsSelector(state, apiRef.current.instanceId)
Signature:
gridVisibleColumnFieldsSelector: (apiRef: GridApiRef) => string[]
// or
gridVisibleColumnFieldsSelector: (state: GridState, instanceId?: number) => string[]
Example
gridVisibleColumnFieldsSelector(apiRef)
// or
gridVisibleColumnFieldsSelector(state, apiRef.current.instanceId)
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.

Signature:
gridColumnDefinitionsSelector: (apiRef: GridApiRef) => GridStateColDef[]
// or
gridColumnDefinitionsSelector: (state: GridState, instanceId?: number) => GridStateColDef[]
Example
gridColumnDefinitionsSelector(apiRef)
// or
gridColumnDefinitionsSelector(state, apiRef.current.instanceId)
Signature:
gridColumnFieldsSelector: (apiRef: GridApiRef) => string[]
// or
gridColumnFieldsSelector: (state: GridState, instanceId?: number) => string[]
Example
gridColumnFieldsSelector(apiRef)
// or
gridColumnFieldsSelector(state, apiRef.current.instanceId)
Signature:
gridColumnLookupSelector: (apiRef: GridApiRef) => GridColumnLookup
// or
gridColumnLookupSelector: (state: GridState, instanceId?: number) => GridColumnLookup
Example
gridColumnLookupSelector(apiRef)
// or
gridColumnLookupSelector(state, apiRef.current.instanceId)
Signature:
gridColumnsStateSelector: (state: GridState) => GridColumnsState
Example
const columnsState = gridColumnsStateSelector(apiRef.current.state);
Signature:
gridFilterableColumnDefinitionsSelector: (apiRef: GridApiRef) => GridStateColDef[]
// or
gridFilterableColumnDefinitionsSelector: (state: GridState, instanceId?: number) => GridStateColDef[]
Example
gridFilterableColumnDefinitionsSelector(apiRef)
// or
gridFilterableColumnDefinitionsSelector(state, apiRef.current.instanceId)
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.

API