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;}
<DataGrid
  columns={[{ field: 'username' }, { field: 'age' }]}
  rows={[
    {
      id: 1,
      username: '@MUI',
      age: 20,
    },
  ]}
/>

Providing content

By default, the 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 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.

function getFullName(params) {
  return `${params.row.firstName || ''} ${params.row.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,
  },
];
<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 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 (e.g. "1,000.50").

In the following demo, a formatter is used to display the tax rate's decimal value (e.g. 0.2) as a percentage (e.g. 20%).

The value generated is only used for rendering purposes. Filtering and sorting do not rely on the formatted value. Use the valueParser to support filtering.

Rendering cells

By default, the 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<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 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} />

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.

The following are the native column types:

  • 'string' (default)
  • 'number'
  • 'date'
  • 'dateTime'
  • 'boolean'
  • 'singleSelect'
  • 'actions'

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:

  • 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']
    }
    
  • 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 />,
      ]
    }
    
<DataGrid columns={columns} 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}
/>

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:
gridVisibleColumnDefinitionsSelector: (apiRef: GridApiRef) => GridStateColDef<any, any, any>[]
// or
gridVisibleColumnDefinitionsSelector: (state: GridState, instanceId?: number) => GridStateColDef<any, any, any>[]
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)

Defined columns

Those selectors consider all the defined columns, including hidden ones.

Signature:
gridColumnDefinitionsSelector: (apiRef: GridApiRef) => GridStateColDef<any, any, any>[]
// or
gridColumnDefinitionsSelector: (state: GridState, instanceId?: number) => GridStateColDef<any, any, any>[]
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:
gridFilterableColumnDefinitionsSelector: (apiRef: GridApiRef) => GridStateColDef<any, any, any>[]
// or
gridFilterableColumnDefinitionsSelector: (state: GridState, instanceId?: number) => GridStateColDef<any, any, any>[]
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