Community edition React data grid component with sorting, filtering, pagination, and Material-UI integration
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Row management handles data structure, state management, and selection for grid rows. The system provides efficient handling of large datasets with built-in selection state and row identification.
Core data structures for representing rows and their associated metadata.
/**
* Base interface for row data objects
* All row data must include a unique identifier
*/
interface RowData extends ObjectWithId {
/** Unique identifier for the row */
id: RowId;
/** Additional data fields as key-value pairs */
[key: string]: any;
}
interface ObjectWithId {
id: RowId;
}
/**
* Internal row model containing data and state
* Used internally by the grid for state management
*/
interface RowModel {
/** Unique row identifier */
id: RowId;
/** Original row data */
data: RowData;
/** Selection state */
selected: boolean;
}
type RowId = string | number;
type RowsProp = RowData[];
type Rows = RowModel[];
type CellValue = string | number | boolean | Date | null | undefined | object;Usage Examples:
import { RowData, RowId } from "@material-ui/data-grid";
// Basic row data
const basicRows: RowData[] = [
{ id: 1, name: "Alice", age: 25, email: "alice@example.com" },
{ id: 2, name: "Bob", age: 30, email: "bob@example.com" },
{ id: "user-3", name: "Charlie", age: 35, email: "charlie@example.com" },
];
// Complex row data with nested objects
const complexRows: RowData[] = [
{
id: "order-1",
orderNumber: "ORD-001",
customer: {
name: "John Doe",
email: "john@example.com",
},
items: [
{ product: "Laptop", quantity: 1, price: 999.99 },
{ product: "Mouse", quantity: 2, price: 29.99 },
],
total: 1059.97,
status: "shipped",
createdAt: new Date("2023-01-15"),
},
{
id: "order-2",
orderNumber: "ORD-002",
customer: {
name: "Jane Smith",
email: "jane@example.com",
},
items: [
{ product: "Keyboard", quantity: 1, price: 149.99 },
],
total: 149.99,
status: "pending",
createdAt: new Date("2023-01-16"),
},
];Utility functions for creating and managing row models.
/**
* Creates a RowModel from RowData
* Initializes selection state and wraps data
* @param rowData - Raw row data with id field
* @returns RowModel with initialized state
*/
function createRow(rowData: RowData): RowModel;Usage Examples:
import { createRow, RowData, RowModel } from "@material-ui/data-grid";
// Create row models from data
const rowData: RowData = { id: 1, name: "Alice", age: 25 };
const rowModel: RowModel = createRow(rowData);
console.log(rowModel);
// Output: { id: 1, data: { id: 1, name: "Alice", age: 25 }, selected: false }
// Batch create rows
const rawData: RowData[] = [
{ id: 1, name: "Alice", age: 25 },
{ id: 2, name: "Bob", age: 30 },
];
const rowModels: RowModel[] = rawData.map(createRow);Row selection management in the community edition (single selection only).
interface RowSelectedParams {
/** ID of the selected/deselected row */
id: RowId;
/** Complete row data */
row: RowData;
/** Current selection state */
isSelected: boolean;
/** Grid API reference */
api: GridApi;
}
interface SelectionChangeParams {
/** Array of currently selected row IDs (max 1 in community edition) */
selectionModel: RowId[];
/** Grid API reference */
api: GridApi;
}Usage Examples:
import React from "react";
import { DataGrid, RowSelectedParams, SelectionChangeParams } from "@material-ui/data-grid";
function SelectionExample() {
const [selectedRows, setSelectedRows] = React.useState<RowId[]>([]);
const handleRowSelected = (params: RowSelectedParams) => {
console.log(`Row ${params.id} ${params.isSelected ? "selected" : "deselected"}`);
console.log("Row data:", params.row);
};
const handleSelectionChange = (params: SelectionChangeParams) => {
setSelectedRows(params.selectionModel);
console.log("Current selection:", params.selectionModel);
// In community edition, maximum 1 row can be selected
if (params.selectionModel.length > 0) {
console.log("Selected row ID:", params.selectionModel[0]);
}
};
return (
<div style={{ height: 400, width: "100%" }}>
<DataGrid
rows={rows}
columns={columns}
checkboxSelection
onRowSelected={handleRowSelected}
onSelectionChange={handleSelectionChange}
/>
<div>
Selected rows: {selectedRows.join(", ")}
</div>
</div>
);
}Event handlers for row-level user interactions.
interface RowParams {
/** Row identifier */
id: RowId;
/** Array of all columns */
columns: Columns;
/** Complete row data */
row: RowData;
/** Grid API reference */
api: GridApi;
}Usage Examples:
import React from "react";
import { DataGrid, RowParams } from "@material-ui/data-grid";
function RowInteractionExample() {
const handleRowClick = (params: RowParams) => {
console.log("Row clicked:", params.id);
console.log("Row data:", params.row);
// Access specific field values
console.log("Name:", params.row.name);
console.log("Age:", params.row.age);
};
const handleRowHover = (params: RowParams) => {
console.log("Row hovered:", params.id);
};
return (
<div style={{ height: 400, width: "100%" }}>
<DataGrid
rows={rows}
columns={columns}
onRowClick={handleRowClick}
onRowHover={handleRowHover}
/>
</div>
);
}System for identifying and navigating between cells within rows.
/**
* Coordinates of a cell in the grid
* Used for navigation and focus management
*/
interface CellIndexCoordinates {
/** Column index (0-based) */
colIndex: number;
/** Row index (0-based) */
rowIndex: number;
}Usage Examples:
import { CellIndexCoordinates } from "@material-ui/data-grid";
// Cell coordinate examples
const topLeftCell: CellIndexCoordinates = { colIndex: 0, rowIndex: 0 };
const specificCell: CellIndexCoordinates = { colIndex: 2, rowIndex: 5 };
// Using coordinates for programmatic navigation
function navigateToCell(coordinates: CellIndexCoordinates) {
console.log(`Navigating to row ${coordinates.rowIndex}, column ${coordinates.colIndex}`);
}Internal state management for rows including selection and data synchronization.
interface InternalColumns {
/** All column definitions */
all: Columns;
/** Visible column definitions */
visible: Columns;
/** Column metadata including positions and total width */
meta: ColumnsMeta;
/** Whether any columns are defined */
hasColumns: boolean;
/** Whether any visible columns exist */
hasVisibleColumns: boolean;
/** Fast lookup for columns by field name */
lookup: ColumnLookup;
}
interface ColumnsMeta {
/** Total width of all visible columns */
totalWidth: number;
/** Array of column positions for positioning calculations */
positions: number[];
}
type ColumnLookup = { [field: string]: ColDef };Usage Notes:
// Row data best practices for performance
// ✅ Good: Stable row IDs
const goodRows: RowData[] = [
{ id: "user-123", name: "Alice", lastModified: Date.now() },
{ id: "user-456", name: "Bob", lastModified: Date.now() },
];
// ❌ Bad: Changing row IDs will cause unnecessary re-renders
const badRows: RowData[] = [
{ id: Math.random(), name: "Alice" }, // Don't use random IDs
{ id: Date.now(), name: "Bob" }, // Don't use timestamps as IDs
];
// ✅ Good: Memoize row data to prevent unnecessary re-renders
const MemoizedGrid = React.memo(() => {
const rows = React.useMemo(() => [
{ id: 1, name: "Alice", age: 25 },
{ id: 2, name: "Bob", age: 30 },
], []); // Dependencies array controls when rows are recreated
return <DataGrid rows={rows} columns={columns} />;
});