DEV Community

Cover image for Expand Tanstack Table Row to display non-uniform data
Yanger Rai
Yanger Rai

Posted on

Expand Tanstack Table Row to display non-uniform data

You can expand row in Tanstack Table using getCanExpand api as long as the row and sub rows data are uniform in structure.

"But what if you want to show non-uniform data in the sub row?"
That is exactly what we will achieve today. 😃 🌀

Still, if your use case is the later, you can follow tanstack example here to achieve it.

Lets begin!🚀

The complete code implementation can be found here, you can follow along.

We will make use of getIsExpanded api which is suitable for our use case.

For this tutorial, the table row object look like this; amount, status and email are the table column, the rest will be displayed in the expanded row:

 {
      id: "728ed52f",
      amount: 100,
      status: "pending",
      email: "m@example.com",
      date: "2023-07-01",
      method: "credit_card",
      description: "Payment for subscription",
      transactionId: "TXN728ED52F",
 },
Enter fullscreen mode Exit fullscreen mode

Step 1:

Begin by defining the column, add a click handler and use getIsExpanded to get the expanded state of the row.

export const columns: ColumnDef<Payment>[] = [
  // this handle the row expands
  {
    id: "select",
    cell: ({ row }) => (
      <button onClick={() => row.toggleExpanded()}>
        {row.getIsExpanded() ? <CircleChevronDown /> : <CircleChevronUp />}
      </button>
    ),
  },
  //rest of the table columns
  {
    accessorKey: "status",
    header: "Status",
  },
  {
    accessorKey: "email",
    header: "Email",
  },
  {
    accessorKey: "amount",
    header: "Amount",
  },
];
Enter fullscreen mode Exit fullscreen mode

Step 2:

Defined your data table component. We will use getIsExanded api to get the state of row that is expanded and render rest of the data inside the table cell.


export function DataTable<TData, TValue>({
  columns,
  data,
}: DataTableProps<TData, TValue>) {
  //define the expanded state
  const [expanded, setExpanded] = useState<ExpandedState>({});

  const table = useReactTable({
   //.. rest of the code
    onExpandedChange: setExpanded,
    getExpandedRowModel: getExpandedRowModel(),
    state: {
      expanded,
    },
  });

  return (
    <div className="rounded-md border">
      <Table>
        <TableHeader>
          //.. rest of the code
        </TableHeader>

        <TableBody>
          {table.getRowModel().rows?.length ? (
            table.getRowModel().rows.map((row) => (
              <>
              {/* this render the main columns */}
                <TableRow
                  key={row.id}
                  data-state={row.getIsSelected() && "selected"}
                >
                  //.. rest of the code
                </TableRow>
                {/* this render the expanded row */}
                {row.getIsExpanded() && (
                  <TableRow>
                    <TableCell colSpan={columns.length} className="h-24">
                      {/* You can create a seperate component to display the expanded data */}
                      <div className="grid px-10">
                        <h2 className=" font-bold">More Details</h2>
                        <p>
                          Transaction Id:{" "}
                          <span className=" text-slate-500">
                            {row.original.transactionId}
                          </span>
                        </p>
                        <p>
                          Transaction Date:{" "}
                          <span className=" text-slate-500">
                            {row.original.date}
                          </span>
                        </p>
                        <p>
                          Transaction Method:{" "}
                          <span className=" text-slate-500">
                            {row.original.method}
                          </span>
                        </p>
                        <p>
                          Description:{" "}
                          <span className=" text-slate-500">
                            {row.original.description}
                          </span>
                        </p>
                      </div>
                    </TableCell>
                  </TableRow>
                )}
              </>
            ))
          ) : (
            <TableRow>
              <TableCell colSpan={columns.length} className="h-24 text-center">
                No results.
              </TableCell>
            </TableRow>
          )}
        </TableBody>
      </Table>
    </div>
  );
}


Enter fullscreen mode Exit fullscreen mode

and you should be able to take it from here, incase you missed it, you will find the complete code here. Do give a star 😊

Thanks for dropping by 🌟
Add a ❤️ if you liked it.

Top comments (0)