How can I automatically style in each cell in React Table based on the cell value generated?

VixGraves picture VixGraves · May 30, 2020 · Viewed 7k times · Source

I'm trying to style a table using react table based on the value of the cell, to start with I'm trying to change the background colour of each cell but what I've got based on the react table api documentation and adding getProps() to the column array doesn't seem to work.

To start with, I wanted to just update the style of the cell based on the value, however adding a custom className based on the cell value would also work.

This is the array which creates the columns:

const columns = [
  {
    Header: 'Things to Do',
    accessor: 'item',
    getProps: (rowInfo) => {
      return {
        style: {
            backgroundColor: rowInfo && rowInfo.row.item === 'Do a thing' ? 'red' : null,
        },
      }
    }
  },
  {
    Header: '2020-04-01',
    accessor: 'date.2020-04-01',
    getProps: (rowInfo) => {
      return {
        style: {
          backgroundColor: rowInfo && rowInfo.row['date.2020-04-01'] === 'Y' ? 'red' : null,
        },
      }
    }
  },

This is one piece of sample data (you can see that the headers will be nested when accessing them to generate the cells, e.g. date.2020-04-01.

const data = [
  {
    item: 'Do a thing',
    date: {
      '2020-04-01': 'Y',
      '2020-04-02': 'Y',
      '2020-04-03': 'N',
      '2020-04-04': 'Y',
    }
  },
]

To be clear, my table is generated using some pretty standard stuff:

const Table = ({ columns,  data }) => {
        const {
            getTableProps,
            getTableBodyProps,
            headerGroups,
            rows,
            prepareRow,
        } = useTable({
            columns,
            data,
        });


    return (
        <table {...getTableProps()} className="table">
            <thead>
                {headerGroups.map(headerGroup => (
                    <tr {...headerGroup.getHeaderGroupProps()}>
                        {headerGroup.headers.map(column => (
                            <th {...column.getHeaderProps()}>{column.render('Header')}</th>
                        ))}
                    </tr>
                ))}
            </thead>
            <tbody {...getTableBodyProps()}>
                {rows.map((row, i) => {
                    prepareRow(row)
                    return (
                    <tr {...row.getRowProps()}>
                        {row.cells.map(cell => {
                        return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
                        })}
                    </tr>
                    )
                })}
            </tbody>
        </table>
        );
  }

Answer

Harish Kulkarni picture Harish Kulkarni · Jun 8, 2020

Yes, You can style rows and cells:

Since it is headless UI library, We can style table however we want:

In your React table markup code, You basically have a Table row (tr) and Table data (td) html elements. You can style rows or cells there OR you can extend functionality of row.getRowProps or cell.getCellProps -> This is also called prop getter pattern (Read more: https://kentcdodds.com/blog/how-to-give-rendering-control-to-users-with-prop-getters)

For example, Here I style the rows or cells: (console log: cell.getCellProps() and see what you get, Now you can extend its functionality like this)

                 cell.getCellProps({
                     style: {color : 'red'}
                  })

Pass style object to cell.getCellProps()

Or

                <div
                  className="tr"
                  {...row.getRowProps()}
                  style={{ ...row.getRowProps().style, ...getRowStyle(row) }}
                  >

In the above code, getRowStyle(row) is custom function that returns style for that particular row/ cell.

I had answered same question in github discussions too! Happy Coding :)