Source:  Twitter logo

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>
        );
  }

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 :)

2 users liked answer #0dislike answer #02
Harish Kulkarni profile pic
Harish Kulkarni

1. To apply inline style in Table's Header Section:

   <tr {...headerGroup.getHeaderGroupProps()}>
          {headerGroup.headers.map((column) => (
            <th  {...column.getHeaderProps(column.getSortByToggleProps())}
                 style={{
                   borderBottom: "solid 3px red",
                   background: "aliceblue",
                   color: "black",
                   fontWeight: "bold",
                 }}
            >
            </th>
          ))}
        </tr>

2. To apply inline style in Table's Data Section:

        <tr {...row.getRowProps()}>
            {row.cells.map((cell) => {
              return (
                <td
                  {...cell.getCellProps()}
                  style={{
                    paddingLeft: "20px",
                    textAlign: "center",
                    border: "solid 1px gray",
                    background: "papayawhip",
                  }}
                >
                  {cell.render("Cell")}
                </td>
              );
            })}
          </tr>

3. Alternatively: Use span Tags to assign a class to any column:

Here I used conditional rendering to assign dynamic class which can be easily styled using external CSS file.

Header: "Status",
accessor: "status",
Cell: s => (
          <span className={s.value === Completed ? "GreenColor" : "RedColor"}>
            {s.value} 
          </span>
        ),

I used this trick to display the completed task in green.

2 users liked answer #1dislike answer #12
Dipak Kumar Yadav profile pic
Dipak Kumar Yadav

You can define custom props in the column definition, then use them when rendering cells.

column definition:

const columns = [
  {
    id: 'item',
    Header: 'Things to Do',
    accessor: 'item',
    className: 'bg-red',
  },
  ...
}

render:

{row.cells.map((cell) => {
  return (
    <td
      {...cell.getCellProps()}
      className={`text-white ${cell.column.className ?? ""}`}
    >
      {cell.render("Cell")}
    </td>
  );
})}

In this example, text-white class will be applied to cells in each row, whereas bg-red will only be applied to cells in the column "Things to Do".

I used tailwind classes in this example but you can also manually add the desired styling in your css file.

1 users liked answer #2dislike answer #21
szaman profile pic
szaman

Copyright © 2022 QueryThreads

All content on Query Threads is licensed under the Creative Commons Attribution-ShareAlike 3.0 license (CC BY-SA 3.0).