We are migrating our tables from v7 to v8. And I'm kinda got a problem with cells conditional styling. So basically what I want to do is, based on a status (which is coming to table data) I need to add a specific className to every cell in a row.
In v7 we used this: https://react-table-v7.tanstack.com/docs/examples/data-driven-classes-and-styles
But in v8 I can't find anything like that....
So far I tried to use meta in column definitions https://tanstack.com/table/v8/docs/api/core/column-def#meta where I can set some values to className property, and use it in my JSX like this:
className={cell.column.columnDef.meta?.className}
But problem is anything I can set to meta are static values. For my case I need to set specific className based on my status value. And seems like in meta we can't access any cell props...
const driverFormatter = ({ row }) => {
const { status } = row.original;
return <span>{status}</span>;
};
const columns: ColumnDef<any,any>[] = [
{
accessorKey: "customerName",
header: "Customer"
},
{
accessorKey: "driver",
header: "Driver",
enableSorting: false,
cell: driverFormatter,
meta: {
className: "disabled",
},
},
...
So is there are any way of achieving that using v8???
Thank you!
First Method - Through column definition meta key:
We can get the detailed context of each cell in V8 through meta, like
{
accessorKey: 'section',
cell: (info) => info.getValue(),
footer: (props) => props.column.id,
meta: {
getCellContext: (context: CellContext<Person, unknown>) => {
if (context.row.index === 0) {
// console.log(context)
return {
style: { fontWeight: 'bold', minWidth: '30%', textTransform: 'uppercase' },
className: 'bold',
}
}
},
},
},
To get dynamic context like this, we need to include additional props to ColumnMeta.
declare module '@tanstack/react-table' {
interface ColumnMeta<TData, TValue> {
// Your additional properties here
getCellContext: (context: CellContext<TData, TValue>) => TableCellProps | void
}
}
Then we can use this func inside the loop
<TableBody>
{table
.getRowModel()
.rows.slice(0, 20)
.map((row) => {
return (
<TableRow key={row.id} {...getRowProps(row)}>
{(isSplit ? row.getCenterVisibleCells() : row.getVisibleCells()).map((cell) => {
let hasMeta = cell.getContext().cell.column.columnDef.meta
return (
<TableCell
key={cell.id}
{...(hasMeta && { ...hasMeta.getCellContext(cell.getContext()) })}
>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
)
})}
</TableRow>
)
})}
</TableBody>
By this, you can add styles, className,, etc. To each *** TABLE CELL*** based on the value.
But you can't style the TABLE ROW with the above method. For that
Second Method - Through callback function:
Define two functions for rows and cells
// Func to provide props to table row
const getRowProps = (context: Row<Person>): TableRowProps | void => {
console.log(context)
if (context.original.section.includes('section')) {
return { className: 'sectionHeader', sx: (theme) => ({ background: theme.palette.primary.light }) }
}
}
// Func to provide props to table cell
const getCellProps = (context: CellContext<Person, unknown>): TableCellProps | void => {
if (context.row.index === 0) {
// console.log(context)
return {
style: { fontWeight: 'bold', minWidth: '30%', textTransform: 'uppercase' },
className: 'bold',
}
}
}
And just destructure the functions
<TableBody>
{table
.getRowModel()
.rows.slice(0, 20)
.map((row) => {
return (
<TableRow key={row.id} {...getRowProps(row)}> //<- here
{row.getLeftVisibleCells().map((cell) => {
return (
<TableCell
key={cell.id}
{...getCellProps(cell.getContext())} // <-here
>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
)
})}
</TableRow>
)
})}
</TableBody>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With