reactjs - TanStack react tabel v8 style hver celle baseret på celleværdien


Vi migrerer vores tabeller fra v7 til v8. Og jeg har lidt et problem med cellers betingede styling. Så grundlæggende, hvad jeg vil gøre, er, baseret på en status (som kommer til tabeldataene), at jeg skal tilføje et specifikt className til hver celle i en række.

I v7 brugte vi dette: https://react-table-v7.tanstack.com/docs/examples/data-driven-classes-and-styles

Men i v8 kan jeg ikke finde noget som helst lignende....

Indtil videre har jeg forsøgt at bruge meta i kolonnedefinitioner https://tanstack.com/table/v8/docs/api/core/column-def#meta, hvor jeg kan sætte nogle værdier til className-egenskaben og bruge det i min JSX sådan her:

className={cell.column.columnDef.meta?.className}

Men problemet er, at alt jeg kan sætte til meta er statiske værdier. I mit tilfælde har jeg brug for at sætte en specifik className baseret på min statusværdi. Og det ser ud til, at vi i meta ikke kan få adgang til nogen celleprops...

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",
     },
    },
    ...

Så er der nogen måde at opnå det på ved at bruge v8???

Tak!

Svar #1

Første metode - Gennem kolonnedefinition meta-nøgle: :

Vi kan få den detaljerede kontekst af hver celle i V8 gennem meta, som

{
    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',
                }
            }
        },
    },
},

For at få dynamisk kontekst som denne, skal vi inkludere yderligere props til ColumnMeta.

declare module '@tanstack/react-table' {
    interface ColumnMeta<TData, TValue> {
        // Your additional properties here
        getCellContext: (context: CellContext<TData, TValue>) => TableCellProps | void
    }
}

Så kan vi bruge denne funktion inde i løkken

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

Da dette kan du tilføje styles, className,, osv. til hver *** TABLE CELL*** baseret på værdien.

Men du kan ikke style TABELLINJEN med ovenstående metode. Til det

Anden metode - Gennem callback-funktion: :

Definer to funktioner for rækker og celler

// 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',
        }
    }
}

Og bare destrukturer funktionerne

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

Svar #2

Jeg stødte også på det samme problem, og som du nævnte, er der et separat eksempel i V7.

og for v8 er der ikke nok dokumentation eller korrekt eksempel

Her er link til min implementering, hvor jeg var i stand til at tilføje forskellige kolonnefarver i v8. Håber dette hjælper. Hvis du har yderligere spørgsmål, så lad mig vide det.

Relaterede artikler