2

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>
        );
  }
VixGraves
  • 21
  • 1
  • 1
  • 4
  • create a new simple component cell.js -> CellComponent ... inside that componen you use the next variable to get your value cell. -> this.props.cell.props.value...... finally create simple condition className= {(this.props.cell.props.value==true)?"your-class-in-true":"your-class-in-false")} – Cristian Agudelo Jan 21 '22 at 06:18
  • https://codesandbox.io/embed/exciting-murdock-tciyw?fontsize=14&hidenavigation=1&theme=dark – Cristian Agudelo Jan 21 '22 at 06:53

3 Answers3

3

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

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.

szaman
  • 2,159
  • 1
  • 14
  • 30
1

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

Harish Kulkarni
  • 1,481
  • 11
  • 18