react-kd-grid
v5.0.2
Published
A feature-rich, performant React data grid component with virtualization, grouping, filtering, and export capabilities
Maintainers
Readme
React KD Grid
A feature-rich, performant React data grid component with virtualization, grouping, filtering, sorting, and export capabilities.
Note: This package requires a license key for production use.
Features
- Virtualization: Efficiently render large datasets with both vertical and horizontal virtualization
- Grouping: Multi-level grouping with expandable/collapsible groups
- Filtering: Global and column-specific filtering with multiple filter types
- Sorting: Multi-column sorting with customizable sort functions
- Pagination: Client and server-side pagination support
- Export: Export data to CSV, JSON, and Excel formats
- Selection: Row and cell selection with keyboard navigation
- Responsive: Flexible column sizing with flex support
- Accessibility: Full keyboard navigation and screen reader support
- TypeScript: Built with TypeScript for excellent type safety
Installation
npm install react-kd-gridBasic Usage
import React from "react";
import { KDGrid } from "react-kd-grid";
const columns = [
{ key: "id", header: "ID", width: 80 },
{ key: "name", header: "Name", width: 200, sortable: true },
{ key: "email", header: "Email", width: 300, sortable: true },
{ key: "department", header: "Department", width: 150, sortable: true },
{
key: "salary",
header: "Salary",
width: 120,
sortable: true,
aggregate: "avg",
},
];
const data = [
{
id: 1,
name: "John Doe",
email: "[email protected]",
department: "Engineering",
salary: 75000,
},
{
id: 2,
name: "Jane Smith",
email: "[email protected]",
department: "Marketing",
salary: 65000,
},
// ... more data
];
function App() {
return (
<div style={{ height: 600 }}>
<KDGrid
licenseKey="YOUR_LICENSE_KEY"
data={data}
columns={columns}
getRowId={(row) => row.id}
height={600}
filterable={true}
sortable={true}
groupable={true}
virtualized={true}
pagination={{
enabled: true,
mode: "client",
pageSize: 20,
}}
/>
</div>
);
}Advanced Features
Column Configuration
const columns = [
{
key: "status",
header: "Status",
width: 120,
filterable: {
type: "multiselect",
options: [
{ label: "Active", value: "active" },
{ label: "Inactive", value: "inactive" },
{ label: "Pending", value: "pending" },
],
},
formatter: (value) => value.toUpperCase(),
aggregate: "count",
},
{
key: "createdAt",
header: "Created",
width: 150,
filterable: {
type: "date",
placeholder: "Filter by date...",
},
formatter: (value) => new Date(value).toLocaleDateString(),
},
{
key: "actions",
header: "Actions",
width: 100,
cellRenderer: (value, row) => (
<button onClick={() => handleEdit(row)}>Edit</button>
),
},
];Server-Side Operations
function ServerGrid() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
const [pagination, setPagination] = useState({
page: 1,
pageSize: 20,
total: 0,
});
const handleServerPagination = async (page: number, pageSize: number) => {
setLoading(true);
const result = await fetchServerData(page, pageSize);
setData(result.data);
setPagination((prev) => ({ ...prev, page, pageSize, total: result.total }));
setLoading(false);
};
const handleServerFilter = async (filters: any) => {
setLoading(true);
const result = await fetchFilteredData(filters);
setData(result.data);
setLoading(false);
};
return (
<KDGrid
licenseKey="YOUR_LICENSE_KEY"
data={data}
columns={columns}
pagination={{
enabled: true,
mode: "server",
pageSize: pagination.pageSize,
serverConfig: {
onPageChange: handleServerPagination,
loading: loading,
totalRows: pagination.total,
},
}}
onFilterChange={handleServerFilter}
isLoading={loading}
/>
);
}Custom Styling
const customRowStyle = (row) => ({
backgroundColor: row.status === "active" ? "#f0fff4" : "#fff5f5",
});
const customCellStyle = (value, row) => ({
color: row.priority === "high" ? "#dc2626" : "#1f2937",
});
<KDGrid
licenseKey="YOUR_LICENSE_KEY"
// ... other props
rowStyle={customRowStyle}
columns={columns.map((col) => ({
...col,
cellStyle: customCellStyle,
}))}
/>;Event Handling
const handleRowClick = (row, event) => {
console.log("Row clicked:", row);
};
const handleCellClick = ({ row, column, value, event }) => {
console.log("Cell clicked:", { row, column, value });
};
const handleSelectionChange = (selectedRows) => {
console.log("Selected rows:", Array.from(selectedRows));
};
const handleSort = (columnKey, direction) => {
console.log("Sort changed:", { columnKey, direction });
};
<KDGrid
licenseKey="YOUR_LICENSE_KEY"
// ... other props
onRowClick={handleRowClick}
onCellClick={handleCellClick}
onSelectedRowsChange={handleSelectionChange}
onSort={handleSort}
selectable={true}
/>;API Reference
KDGrid Props
| Prop | Type | Default | Description |
| ---------------------- | --------------------------------------------------------- | -------------------- | ----------------------------------------------------- |
| licenseKey | string | Required | License key for the grid (will not render without it) |
| data | GridRow[] | Required | Array of data rows to display |
| columns | GridColumn[] | Required | Array of column definitions |
| getRowId | (row: GridRow) => string \| number | Optional | Function to extract unique ID from row |
| height | number | 400 | Grid height in pixels |
| density | 'sm' \| 'md' \| 'lg' | 'md' | Row density (affects row height) |
| selectable | boolean | false | Enable row selection |
| filterable | boolean | true | Enable filtering |
| sortable | boolean | true | Enable sorting |
| groupable | boolean | false | Enable grouping |
| virtualized | boolean | true | Enable virtualization |
| pagination | PaginationOptions | { enabled: false } | Pagination configuration |
| loading | boolean | false | Show loading state or skeleton |
| editable | boolean | false | Enable grid-level inline editing |
| onRowSelect | (row: GridRow) => void | Optional | Row selection callback |
| onSelectedRowsChange | (selectedRows: Set<string \| number>) => void | Optional | Selection change callback |
| onFilterChange | (filters: ServerFilterChangePayload) => void | Optional | Filter change callback |
| onSort | (columnKey: string, direction: 'asc' \| 'desc') => void | Optional | Sort change callback |
| onCellEdit | (params: CellEditParams) => void | Optional | Called when a cell edit is committed |
Imperative API (via React Ref)
The KDGrid component exposes several methods through its ref:
| Method | Params | Description |
| ------------------- | --------------------------- | ----------------------------------------- |
| scrollToRow | (rowId: string \| number) | Scrolls to a specific row by its ID |
| scrollToColumn | (columnKey: string) | Scrolls to a specific column by its key |
| expandAllGroups | () | Expands all collapsed groups |
| collapseAllGroups | () | Collapses all expanded groups |
| clearAllFilters | () | Clears global and column-specific filters |
Column Definition
| Property | Type | Default | Description |
| ------------------ | --------------------------------------------------------- | -------- | ------------------------- |
| key | string | Required | Unique column identifier |
| header | string | Required | Column header text |
| width | number | 100 | Column width in pixels |
| flex | boolean \| number | false | Flexible column sizing |
| sortable | boolean | true | Enable column sorting |
| filterable | boolean \| ColumnFilter | false | Enable column filtering |
| formatter | (value: any) => string | Optional | Custom value formatter |
| cellRenderer | (value: any, row: GridRow) => ReactNode | Optional | Custom cell renderer |
| aggregate | 'sum' \| 'avg' \| 'min' \| 'max' \| function | Optional | Group aggregate function |
| footer_aggregate | 'count' \| 'sum' \| 'avg' \| 'min' \| 'max' \| function | Optional | Footer aggregate function |
Performance Tips
- Enable Virtualization: For datasets with > 1000 rows, always enable virtualization
- Use Server-Side Operations: For very large datasets, use server-side pagination and filtering
- Optimize Renderers: Avoid creating new objects/functions in cell renderers
- Limit Column Count: Horizontal virtualization kicks in at 50+ columns
- Use Memoization: Memoize expensive calculations in formatters and renderers
Browser Support
- Chrome 80+
- Firefox 75+
- Safari 13+
- Edge 80+
License
MIT License - see LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Support
If you encounter any issues or have questions, please open an issue on GitHub.
