TanStack Table: Expand only one cell on click without expanding the entire row
Iβm using TanStack Table and have multiple expandable cells within the same row.
When I click one expand button, all expandable cells in that row are triggered.
How can I make only the clicked cell expand independently, without affecting other cells in the row?
Whatever I've tried so far is in this codesandbox.
App.tsx
import {
ColumnDef,
ColumnFiltersState,
SortingState,
VisibilityState,
flexRender,
getCoreRowModel,
getExpandedRowModel,
getFacetedRowModel,
getFacetedUniqueValues,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table";
import { useState } from "react";
import { expandableColumn, expandableData } from "./column-data";
interface DataTableProps {
columns: ColumnDef[];
data: TData[];
renderSubComponent: (props: { row: Row }) => React.ReactElement;
getRowCanExpand: (row: Row) => boolean;
}
const renderSubComponent = ({ row }: { row: Row }) => {
return (
{JSON.stringify(row.original, null, 2)}
);
};
export function ExpandableTable({
columns,
data,
renderSubComponent,
getRowCanExpand,
}: DataTableProps) {
const [columnVisibility, setColumnVisibility] = useState({});
const table = useReactTable({
data,
columns,
getRowCanExpand,
state: {
columnVisibility,
},
autoResetPageIndex: false,
enableRowSelection: true,
onColumnVisibilityChange: setColumnVisibility,
getCoreRowModel: getCoreRowModel(),
getExpandedRowModel: getExpandedRowModel(),
});
return (
{/* */}
{table.getHeaderGroups().map((headerGroup) => (
{headerGroup.headers.map((header) => {
return (
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
);
})}
))}
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<>
{row.getVisibleCells().map((cell) => (
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
))}
{row.getIsExpanded() && (
{/* 2nd row is a custom 1 cell row */}
{renderSubComponent({ row })}
)}
>
))
) : (
No results.
)}
);
}
export default function App() {
return (
Expand Table Example
Start editing to see some magic happen!
true}
/>
);
}
column.tsx
export const expandableColumn = [
{
accessorKey: "firstName",
header: "First Name",
cell: ({ row, getValue }) => (
{row.getCanExpand() ? (
) : (
"π΅"
)}
{getValue()}
),
footer: (props) => props.column.id,
},
{
accessorFn: (row) => row.lastName,
id: "lastName",
cell: ({ row, getValue }) => (
{row.getCanExpand() ? (
) : (
"π΅"
)}
{getValue()}
),
header: () => Last Name,
footer: (props) => props.column.id,
},
{
accessorKey: "age",
header: () => "Age",
footer: (props) => props.column.id,
},
{
accessorKey: "visits",
header: () => Visits,
footer: (props) => props.column.id,
},
{
accessorKey: "status",
header: "Status",
footer: (props) => props.column.id,
},
{
accessorKey: "progress",
header: "Profile Progress",
footer: (props) => props.column.id,
},
];
export const expandableData = [
{
firstName: "Marquis",
lastName: "Runolfsdottir",
age: 36,
visits: 322,
progress: 46,
status: "single",
},
{
firstName: "Hayden",
lastName: "Ritchie",
age: 35,
visits: 208,
progress: 79,
status: "relationship",
},
{
firstName: "Destany",
lastName: "Boehm",
age: 37,
visits: 752,
progress: 97,
status: "relationship",
},
{
firstName: "Kale",
lastName: "Johnston",
age: 36,
visits: 378,
progress: 13,
status: "complicated",
},
{
firstName: "Maybell",
lastName: "Brown",
age: 16,
visits: 783,
progress: 76,
status: "complicated",
},
{
firstName: "Emelia",
lastName: "Cronin",
age: 30,
visits: 655,
progress: 96,
status: "complicated",
},
{
firstName: "Kali",
lastName: "Marvin",
age: 18,
visits: 926,
progress: 57,
status: "complicated",
},
{
firstName: "Khalid",
lastName: "Robel",
age: 34,
visits: 671,
progress: 100,
status: "complicated",
},
{
firstName: "Zena",
lastName: "Hilll",
age: 34,
visits: 934,
progress: 18,
status: "single",
},
{
firstName: "Hiram",
lastName: "Koss",
age: 12,
visits: 757,
progress: 44,
status: "relationship",
},
];