- Published on
Collapsible Rows in Shadcn Data Table with Full-Width Content
- Authors
- Name
- Ripal & Zalak
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.