Key information for working with rows.
Rows represent individual records in your grid. Each row corresponds to an item in your data array and provides methods for selection, expansion, editing, and more.
// Row object available in cell renderers
cell: ({ row }) => {
const data = row.original;
const isSelected = row.getIsSelected();
const isPinned = row.getIsPinned();
return <div>{data.name}</div>;
}The row object provides access to:
Get the raw data object:
cell: ({ row }) => {
const user = row.original;
return <div>{user.name}</div>;
}Get a specific cell value:
cell: ({ row }) => {
const email = row.getValue('email');
return <a href={`mailto:${email}`}>{email}</a>;
}Get the unique row identifier:
cell: ({ row }) => {
return <div>Row ID: {row.id}</div>;
}Check if row is selected:
cell: ({ row }) => {
const isSelected = row.getIsSelected();
return (
<div className={isSelected ? 'bg-blue-50' : ''}>
{row.original.name}
</div>
);
}Toggle row selection:
<Checkbox
checked={row.getIsSelected()}
onCheckedChange={(value) => row.toggleSelected(!!value)}
/>Check if row can be selected:
const canSelect = row.getCanSelect();Check pin status:
const isPinned = row.getIsPinned(); // 'top' | 'bottom' | falsePin or unpin row:
// Pin to top
row.pin('top');
// Pin to bottom
row.pin('bottom');
// Unpin
row.pin(false);Check if row is expanded:
const isExpanded = row.getIsExpanded();Toggle expansion:
Check if row can expand:
Get nesting depth:
Get parent row (for nested data):
Get child rows:
Get row index in current page:
Rows automatically receive CSS classes based on state:
Use rowClassRules for conditional styling:
Handle row clicks:
Handle double-clicks:
Access full row context in custom cells:
By default, row ID is the array index:
Provide a custom ID function:
This is important for:
For hierarchical data:
Access different row models:
<Button onClick={() => row.toggleExpanded()}>
{row.getIsExpanded() ? 'Collapse' : 'Expand'}
</Button>const canExpand = row.getCanExpand();const depth = row.depth; // 0 for top-level rowsconst parent = row.getParentRow();const children = row.subRows;const rowNumber = row.index + 1;.grid-row[data-state="selected"] {
/* Selected row */
}
.grid-row--pinned-top {
/* Pinned to top */
}
.grid-row--pinned-bottom {
/* Pinned to bottom */
}
.grid-row--expanded {
/* Expanded row */
}<ActiveGrid
settings={{
rowClassRules: {
'bg-red-50': (row) => row.status === 'error',
'bg-green-50': (row) => row.status === 'success',
'opacity-50': (row) => !row.isActive,
'font-bold': (row) => row.priority === 'high',
},
}}
{...}
/><ActiveGrid
onRowClick={(row) => {
console.log('Clicked row:', row.original);
router.push(`/users/${row.original.id}`);
}}
{...}
/><ActiveGrid
onRowDoubleClick={(row) => {
handleEdit(row.original);
}}
{...}
/>import { useState } from 'react';
import { RowSelectionState } from '@tanstack/react-table';
function UsersTable() {
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
return (
<ActiveGrid
columns={columns}
data={users}
state={{ rowSelection }}
onRowSelectionChange={setRowSelection}
getRowId={(row) => row.id}
/>
);
}function UsersTable() {
const table = useActiveGrid();
const handleAction = () => {
const selectedRows = table.getSelectedRowModel().rows;
const selectedData = selectedRows.map(row => row.original);
console.log('Selected users:', selectedData);
};
return (
<>
<Button onClick={handleAction}>
Process {table.getSelectedRowModel().rows.length} Selected
</Button>
<ActiveGrid {...} />
</>
);
}{
id: 'select',
header: ({ table }) => (
<Checkbox
checked={table.getIsAllRowsSelected()}
onCheckedChange={(value) => table.toggleAllRowsSelected(!!value)}
/>
),
cell: ({ row }) => (
<Checkbox
checked={row.getIsSelected()}
disabled={!row.getCanSelect()} // Disable for some rows
onCheckedChange={(value) => row.toggleSelected(!!value)}
/>
),
}
// Disable selection for specific rows
<ActiveGrid
enableRowSelection={(row) => row.status === 'active'}
{...}
/>{
id: 'actions',
header: 'Actions',
cell: ({ row }) => {
const user = row.original;
const isSelected = row.getIsSelected();
const isPinned = row.getIsPinned();
return (
<div className="flex gap-2">
<Button
size="sm"
variant={isSelected ? 'default' : 'outline'}
onClick={() => handleEdit(user)}
>
Edit
</Button>
{isPinned ? (
<Button
size="sm"
variant="ghost"
onClick={() => row.pin(false)}
>
Unpin
</Button>
) : (
<Button
size="sm"
variant="ghost"
onClick={() => row.pin('top')}
>
Pin
</Button>
)}
</div>
);
},
}// row.id = '0', '1', '2', etc.<ActiveGrid
getRowId={(row) => row.id}
// Now row.id uses the data's id property
{...}
/>type Department = {
id: string;
name: string;
employees: Employee[];
};
<ActiveGrid
columns={columns}
data={departments}
getSubRows={(row) => row.employees}
enableExpanding={true}
{...}
/>const table = useActiveGrid();
// All rows
const allRows = table.getRowModel().rows;
// Filtered rows
const filteredRows = table.getFilteredRowModel().rows;
// Sorted rows
const sortedRows = table.getSortedRowModel().rows;
// Paginated rows
const paginatedRows = table.getPaginatedRowModel().rows;
// Selected rows
const selectedRows = table.getSelectedRowModel().rows;
// Expanded rows
const expandedRows = table.getExpandedRowModel().rows;import { GridColumnDef } from '@workspace/active-grid';
type User = {
id: string;
name: string;
email: string;
status: 'active' | 'inactive';
isVIP: boolean;
};
const columns: GridColumnDef<User>[] = [
{
id: 'select',
cell: ({ row }) => (
<Checkbox
checked={row.getIsSelected()}
disabled={row.original.status === 'inactive'}
onCheckedChange={(value) => row.toggleSelected(!!value)}
/>
),
},
{
accessorKey: 'name',
header: 'Name',
cell: ({ row }) => {
const isPinned = row.getIsPinned();
return (
<div className="flex items-center gap-2">
{isPinned && <Pin className="h-3 w-3" />}
{row.original.name}
{row.original.isVIP && <Badge>VIP</Badge>}
</div>
);
},
},
{
accessorKey: 'email',
header: 'Email',
},
{
accessorKey: 'status',
header: 'Status',
cell: ({ row }) => (
<BadgeCell
value={row.getValue('status')}
variant={row.getValue('status') === 'active' ? 'default' : 'secondary'}
/>
),
},
{
id: 'actions',
header: 'Actions',
cell: ({ row }) => (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="sm">⋮</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem onClick={() => edit(row.original)}>
Edit
</DropdownMenuItem>
<DropdownMenuItem onClick={() => row.toggleSelected()}>
{row.getIsSelected() ? 'Deselect' : 'Select'}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => row.pin('top')}>
Pin to Top
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
),
},
];import { Row } from '@tanstack/react-table';
type User = {
id: string;
name: string;
};
const handleRowClick = (row: Row<User>) => {
const user = row.original;
console.log(user.name);
};
// In cell renderer
cell: ({ row }: { row: Row<User> }) => {
return <div>{row.original.name}</div>;
}