Published on

Collapsible Rows in Shadcn Data Table with Full-Width Content

Authors
  • Name
    Ripal & Zalak
    Twitter

Collapsible Rows in Shadcn Data Table with Full-Width Content

When building interactive tables using Shadcn's UI components, you might want to include collapsible rows where the expanded content spans the entire width of the table. This guide demonstrates how to achieve that using React, Shadcn UI, and Tailwind CSS.

Overview

Collapsible rows are useful for displaying additional details about a row without cluttering the main table view. By default, expanded content in Shadcn's Data Table aligns with the first column. We'll use colspan in <td> to make the content span across all columns.

Prerequisites

Ensure your project includes:

  • React
  • Shadcn UI
  • Tailwind CSS
  • TanStack Table for table data management

Step-by-Step Implementation

Step 1: Setup the Collapsible Content

Update your CollapsibleContent to render as a <tr> element using the asChild prop. Then, ensure the expanded content is wrapped in a <td> with the colSpan attribute.

import React from 'react'
import { ColumnDef, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from 'shadcn/ui/table'
import { Collapsible, CollapsibleContent } from 'shadcn/ui/collapsible'
import { Button } from 'shadcn/ui/button'
import { ChevronDown } from 'lucide-react'

export function DataTable({ data, columns }) {
  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
  })

  return (
    <Table>
      <TableHeader>
        {table.getHeaderGroups().map((headerGroup) => (
          <TableRow key={headerGroup.id}>
            {headerGroup.headers.map((header) => (
              <TableHead key={header.id}>
                {header.isPlaceholder
                  ? null
                  : flexRender(header.column.columnDef.header, header.getContext())}
              </TableHead>
            ))}
          </TableRow>
        ))}
      </TableHeader>
      <TableBody>
        {table.getRowModel().rows.map((row) => (
          <Collapsible key={row.id} asChild>
            <>
              <TableRow>
                {row.getVisibleCells().map((cell) => (
                  <TableCell key={cell.id}>
                    {flexRender(cell.column.columnDef.cell, cell.getContext())}
                  </TableCell>
                ))}
              </TableRow>
              <CollapsibleContent className="bg-gray-100" asChild>
                <tr>
                  <td colSpan={columns.length} className="p-4">
                    {row.original.collapsibleContent}
                  </td>
                </tr>
              </CollapsibleContent>
            </>
          </Collapsible>
        ))}
      </TableBody>
    </Table>
  )
}

Step 2: Ensure Column Definitions are Configured

In your columns definition, include a collapsible trigger button in the first column.

export const columns = [
  {
    accessorKey: 'column1',
    header: 'Column 1',
    cell: ({ row }) => (
      <div className="flex items-center">
        <Button variant="ghost">
          <ChevronDown className="mr-2 h-4 w-4" />
        </Button>
        {row.getValue('column1')}
      </div>
    ),
  },
  {
    accessorKey: 'column2',
    header: 'Column 2',
  },
]

Step 3: Styling the Expanded Content

Use Tailwind CSS to style the collapsible content, ensuring it spans the table width.

.bg-gray-100 {
  background-color: #f7f7f7;
}
.p-4 {
  padding: 1rem;
}

FAQs

Why is the expanded content not spanning the table width?

Ensure the colSpan property of the <td> matches the total number of table columns.

How can I improve the toggle button’s appearance?

Customize the Button component or use Tailwind CSS classes to add hover effects, icons, or animations.

Can this implementation handle dynamic column counts?

Yes, by setting colSpan={columns.length}, the expanded content dynamically spans all visible columns.

Conclusion

With the steps outlined above, you can create a collapsible row in Shadcn Data Table where the expanded content spans the full width of the table. This approach is clean, customizable, and ensures a better user experience for displaying detailed data.