DataGrid - Customizing cells/rows/headers

Customizing rows

<ReactDataGrid /> rows can be customized & styled using multiple props. Styling can be done by using rowStyle or rowClassName.
rowStyle can be an object, or it can be a function. In case it's specified as a function, it's called like rowStyle({ data, props, style }). The returned object is merged on the already existing row style object.
rowClassName can be a string, or it can be a function. In case it's specified as a function, it's called like rowClassName({ data, props, className }). The returned value is appended to the already existing classNamevalue of the row.
In the default theme, the background is specified for <ReactDataGrid /> cells, so setting the background in the rowStyle will not have the intended effect.
Setting a height for rows should be done by using the rowHeight prop, and not rowStyle.height!
When the <ReactDataGrid /> is configured to have dynamic row height (rowHeight=null), the minimum height for a row should be configured via minRowHeight.
By default, the <ReactDataGrid /> displays zebra rows. Use showZebraRows=false to disable odd/even zebra row styling.
Another neat feature for <ReactDataGrid /> rows is the ability to fill the remaining vertical space with empty rows - in the case where the dataset is small and does not fill all the <ReactDataGrid /> viewport. Use showEmptyRows=true to accomplish that.

Custom rendering

The <ReactDataGrid /> can also be configured to use a custom row rendering function, using the renderRow(rowProps) function prop.
If this function returns undefined, the default rendering is used. Although returning undefined, it can still be useful since it can control & change values in the rowProps, object it receives as first parameter. For example, it can add styles to rowProps.style or can manipulate classNames by modifying rowProps.className. Or it can add other events or DOM properties to the rowProps object.
In case it returns a React.Node, that node is rendered instead of the default implementation.
When returning a custom React.Node from renderRow be aware that you are probably breaking virtualization or other useful <ReactDataGrid /> features. So make sure you know what you're doing!
Instead of using renderRow we recommend you use onRenderRow(rowProps), which has the same benefit of being called with the rowProps object and be able to modify it, but it discards the returned value, so the default row rendering happens. This ensures all <ReactDataGrid /> features will probably work the same unless you change the layout-related styling props.
The example below shows how you can use custom row and cell class names to have different backgrounds for different rows/cells, based on custom application logic.
The css file (quite verbose, but you can achieve a lot less code with preprocessors) is shown below:
We use !important below for brevity, to override the default grid theme. Instead, you could write your own theme for the <ReactDataGrid /> and get rid of unwanted !important.
.global-custom-row:hover,
.global-custom-row:hover .InovuaReactDataGrid__cell {
  background: #4e3207 !important;
}

.global-custom-row-green {
  background: #153115 !important;
}
.global-custom-row-green:hover,
.global-custom-row-green:hover .InovuaReactDataGrid__cell {
  background: #2e6538 !important;
}

.global-custom-row-dark-magenta {
  background: #382a38 !important;
}
.global-custom-row-dark-magenta:hover,
.global-custom-row-dark-magenta:hover .InovuaReactDataGrid__cell {
  background: #382a38 !important;
}

.global-custom-row.InovuaReactDataGrid__row--selected,
.global-custom-row.InovuaReactDataGrid__row--selected
  .InovuaReactDataGrid__cell {
  background: #0a265a !important;
  color: white;
}

.global-custom-row.InovuaReactDataGrid__row--selected:hover,
.global-custom-row.InovuaReactDataGrid__row--selected:hover
  .InovuaReactDataGrid__cell {
  background: #13326d !important;
  color: white;
}

Customizing cells and headers

<ReactDataGrid /> cells and headers are fully customizable in both styling and content - by using styling props or custom render functions. In the sections below you can see a complete walk-through in how to achieve full customization.

Aligning cell & header contents

The alignment of text can be controlled for each <ReactDataGrid /> column separately by using the column.textAlign prop.
In the example above, the Name and City columns have their textAlign property controlled by the first select-box. All other columns have a fixed textAlign property.
Additionally, the City column renders another select-box in the column header for controlling the headerAlign prop. If no headerAlign is specified, the textAlign value is also used for headerAlign.
When no column.headerAlign prop is specified for a column, its textAlign prop will be used.
Similarly, when no column.headerVerticalAlign prop is specified for a column, its textVerticalAlign prop will be used.
When a column header is aligned to the end (the column has headerAlign="end" or there is no headerAlign but it has textAlign="end"), the sort arrow (when the column is sortable) is positioned before the column header.
In the example above, you can also see custom column header rendering via the column.header function used for the City column. Using this render function, the <ReactDataGrid /> can render any valid React.Node (so basically any valid jsx contents). This gives you complete flexibility over what gets rendered in the <ReactDataGrid /> headers.

Custom header rendering

Valid values for column.header are the following:
  • any valid React.Node - for static headers, that don't need to change based on some dynamic condition or logic.
  • a function returning a valid React.Node - very useful for dynamic content that can change based on the column state (eg: sort order).
When no column.header is specified, the column.name will be rendered (after being humanized: capitalized, split into several words where appropriate).
When column.header is a function, it is called with a cellProps object that holds the column state. Basically, in this way you gain access to any column props, including the following:
  • cellProps.computedSortInfo - info about the current sort state
  • cellProps.computedSortable - if the column is sortable or not.
  • cellProps.resizable - if the column is resizable or not.
  • cellProps.computedWidth - info about the current column width
  • cellProps.computedVisibleIndex - the index of the column in the list of visible columns
  • ... and many others. All column state is kept in this object. All properties in cellProps are read-only.
When using custom rendering via column.header (or column.render for cell contents), the ellipsis for headers - as configured by column.headerEllipsis (or for cells, as configured by column.textEllipsis) is no longer displayed.
Because you have specified a custom rendering logic, you are in charge of showing the ellipsis and adding the correct styles to the correct elements to make it work as expected.

Custom header styling

Use column.headerProps.style to add a custom style to the column header.
For adding a custom CSS className, use column.headerProps.className.
If you use column.style, the style value will be applied to both cells and headers. If you only want to style headers, use column.headerProps.style. If you only want to style cells, use column.cellProps.style.
The same applies to className: if you use column.className, the className value will be applied to both cells and headers. If you only want to specify className for headers, use column.headerProps.className. If you only want to specify className for cells, use column.cellProps.className.

Cell borders

The <ReactDataGrid /> supports four strategies for displaying cell borders:
In the example below, you can see a combination of showCellBorders, showZebraRows and showHoverRows, all used together.

Custom cell rendering

Columns configured with a name prop by default render the value in the corresponding property in the dataSource items.
Custom rendering (for all columns, either with a name or an id) is supported via the column.render function prop. The column.render is passed an object with the following properties:
  • value - if the column has a name, the value would be the value rendered if no column.render property were configured.
  • data - the data object in the dataSource corresponding to the current row being rendered.
  • cellProps: Object - the props being passed to the cell corresponding to the current row and column.
  • rowIndex: Number - the index of the current row being rendered
  • rowSelected: Boolean - a boolean value indicating if the current row is selected or not
  • empty: Boolean - a boolean value indicating if the current row is an empty row or not
  • totalDataCount: Number - the total count of rows that will be rendered
The object passed to the column.render function is reused - so you should not keep a reference to it. Instead, use ES6 destructuring to take the values you are interested in from this object.
const columns = [
  { name: 'firstName', defaultFlex: 1 },
  { name: 'lastName', defaultFlex: 1 },
  {
    name: 'country',
    width: 60,
    resizable: false,
    textAlign: 'center',
    render: ({ value }) => flags[value] ? flags[value] : 'unknown'
  },
  {
    id: 'fullName',
    minWidth: 100,
    defaultFlex: 1,
    render: ({ data }) => data.firstName + ' ' + data.lastName
  },
  {
    name: 'age',
    render: ({ value }) => <span style={{ color: value < 30 ? 'green' : 'inherit'}}>{value}</span>
  }
]

Custom cell styling

Use column.cellProps.style to add a custom style to the column cells.
For adding a custom CSS className, use column.cellProps.className.
If you use column.style, the style value will be applied to both cells and headers. If you only want to style cells, use column.cellProps.style. If you only want to style headers, use column.headerProps.style.
The same applies to className: if you use column.className, the className value will be applied to both cells and headers. If you only want to specify className for cells, use column.cellProps.className. If you only want to specify className for headers, use column.headerProps.className.
However, column.style can also be a function. In this case, the returned style object is ONLY applied to <ReactDataGrid /> cells.

Hooking cell & header events

You often need to hook to events related to <ReactDataGrid /> cells. Read the examples below to see how this can be done.
For attaching any valid DOM properties to cells (which also includes events), use column.cellDOMProps.
column.cellDOMProps can be an object or a function. In case it's a function, it is called with the cellProps used for rendering the corresponding cell. (eg: cellDOMProps: (cellProps) => { ... }).
For attaching any valid DOM properties to column headers (which also includes events), use column.headerDOMProps.
column.headerDOMProps can be an object or a function. In case it's a function, it is called with the headerProps used for rendering the corresponding column header. (eg: headerDOMProps: (headerProps) => { ... }).
Additionally, the following event props are available on the grid:
When native DOM events are supported directly on the grid, they are called with the event object as the first argument.
Note the difference between onRowContextMenu(rowProps, event) (which is a custom <ReactDataGrid /> event) and onContextMenu(event), which is a native DOM event.
Besides attaching to DOM events as mentioned above, at any time you can render jsx content in cells & headers and attach your events to the custom-rendered content if it better serves your needs.
Top