@insticc/react-datagrid-2
v1.1.13
Published
A powerful and flexible React data grid component built on top of Material React Table, providing advanced features for data visualization, filtering, sorting, pagination, and row selection.
Readme
DataGrid Component
A powerful and flexible React data grid component built on top of Material React Table, providing advanced features for data visualization, filtering, sorting, pagination, and row selection.
Table of Contents
Installation
npm install @insticc/react-datagrid-2Required Dependencies
npm install react prop-types material-react-table semantic-ui-react @mui/material bootstrapBasic Usage
import React, { useState } from 'react';
import DataGrid from '@insticc/react-datagrid-2';
function MyComponent() {
const [selectedRows, setSelectedRows] = useState([]);
const columns = [
{ accessorKey: 'id', header: 'ID', type: 'text' },
{ accessorKey: 'name', header: 'Name', type: 'text' },
{ accessorKey: 'email', header: 'Email', type: 'email' },
{ accessorKey: 'createdAt', header: 'Created', type: 'date', isDateColumn: true },
];
const data = [
{ id: '1', name: 'John Doe', email: '[email protected]', createdAt: '2025-01-15' },
{ id: '2', name: 'Jane Smith', email: '[email protected]', createdAt: '2025-02-20' },
];
return (
<DataGrid
columns={columns}
createRows={data}
rowKey="id"
selectData={setSelectedRows}
hasExcelExport={true}
hasPdfExport={true}
/>
);
}Props Reference
Core Props
columns (required)
- Type:
Array - Description: Array of column definitions that determine how data is displayed
- Example:
const columns = [
{
accessorKey: 'name', // Key to access data
header: 'Full Name', // Column header text
type: 'text', // Cell type - formatter applied automatically
enableSorting: true, // Enable/disable sorting
enableColumnFilter: true, // Enable/disable filtering
filterFn: 'contains', // Filter function type
isDateColumn: false, // Special handling for dates
cellClass: 'custom-class', // CSS class wrapping cell content
Cell: CustomComponent, // Optional: Custom cell renderer (receives typeValue)
}
];Column Rendering Modes:
typeonly: Formatter applied automaticallytype+cellClass: Formatted content wrapped in divtype+Cell: Custom component receivestypeValue(formatted content)Cellonly: Full custom rendering without type formatter
createRows (required)
- Type:
Array - Description: Array of data objects to display in the grid
- Example:
const data = [
{ id: 1, name: 'John', email: '[email protected]' },
{ id: 2, name: 'Jane', email: '[email protected]' }
];rowKey (required)
- Type:
string - Description: Property name used as unique identifier for each row
- Default:
'id' - Example:
rowKey="id"orrowKey="uuid"
selectData (required)
- Type:
function - Description: Callback function that receives selected rows whenever selection changes
- Signature:
(selectedRows: Array) => void - Example:
const handleSelection = (rows) => {
console.log('Selected rows:', rows);
};
<DataGrid selectData={handleSelection} />Column Configuration
columnVisibilityState
- Type:
object - Default:
{} - Description: Controls which columns are visible/hidden
- Example:
columnVisibilityState={{
email: false, // Hide email column
phone: true // Show phone column
}}columnOrder
- Type:
Array<string> - Default:
[] - Description: Defines the order of columns by their accessorKey
- Example:
columnOrder={['name', 'email', 'id']}Actions & Toolbar
actions
- Type:
Array<ActionObject> - Default:
null - Description: Array of custom action buttons displayed in the toolbar
- Action Object Properties:
name(string): Button labelfunction(function, required): Callback when button is clickedtooltip(string): Tooltip text on hovercolor(string): Button color - one of:'blue','red','green','yellow','orange','black','grey','teal','brown','violet','purple','olive','pink'icon(string|element): Icon name or React elementselectionMode(string): When button is enabled -'single','multi','always'confirmMessage(string|element): Confirmation message before actionhasConfirmMessage(boolean): Whether to show confirmation dialogdisabled(boolean): Disable the buttonvisible(boolean): Show/hide the buttontoggle(boolean): Toggle button styleactive(boolean): Toggle button active state
- Example:
actions={[
{
name: 'Delete',
function: (selectedRows) => handleDelete(selectedRows),
tooltip: 'Delete selected rows',
color: 'red',
icon: 'trash',
selectionMode: 'multi',
hasConfirmMessage: true,
confirmMessage: 'Are you sure you want to delete these rows?'
},
{
name: 'Edit',
function: (selectedRows) => handleEdit(selectedRows),
tooltip: 'Edit selected row',
color: 'blue',
icon: 'edit',
selectionMode: 'single'
},
{
name: 'Add New',
function: () => handleAdd(),
tooltip: 'Add new record',
color: 'green',
icon: 'plus',
selectionMode: 'always'
}
]}enableTopToolbar
- Type:
boolean - Default:
true - Description: Show/hide the top toolbar containing actions and pagination
enableBottomToolbar
- Type:
boolean - Default:
false - Description: Show/hide the bottom toolbar
hasClearFiltersBtn
- Type:
boolean - Default:
true - Description: Show/hide the "Clear Filters" button in toolbar
gridHelper
- Type:
object | null - Default:
null - Description: Adds a help button with custom content
- Required Properties (if defined):
title(string|element, required): Help dialog titlecontent(string|element, required): Help dialog content
- Example:
gridHelper={{
title: 'Grid Instructions',
content: (
<div>
<p>Use the filters to search data</p>
<p>Click rows to select them</p>
</div>
)
}}Export Options
hasExcelExport
- Type:
boolean - Default:
false - Description: Enable Excel export button
excelOption
- Type:
string - Default:
'selectedRows' - Options:
'all','allRows','pageRows','selectedRows' - Description: Determines which rows to export to Excel
hasPdfExport
- Type:
boolean - Default:
false - Description: Enable PDF export button
pdfOption
- Type:
string - Default:
'selectedRows' - Options:
'all','allRows','pageRows','selectedRows' - Description: Determines which rows to export to PDF
Export Options Explained:
'all'- Export all data including hidden columns'allRows'- Export all rows (respects filters)'pageRows'- Export only current page rows'selectedRows'- Export only selected rows
Selection & Interaction
disableSelect
- Type:
boolean - Default:
false - Description: Disable row selection checkboxes and click-to-select behavior completely
enableMultiRowSelection
- Type:
boolean - Default:
true - Description: Allow selecting multiple rows at once
selectAllMode
- Type:
string - Default:
'page' - Options:
'page','all' - Description:
'page'- "Select All" checkbox selects only current page'all'- "Select All" checkbox selects all filtered rows
selectedIds
- Type:
Array - Default:
[] - Description: Array of row IDs that should be pre-selected
- Example:
selectedIds={[1, 5, 10]} // Pre-select rows with these IDsdisableRows
- Type:
Array - Default:
[] - Description: Array of row IDs that should be disabled (cannot be selected)
- Example:
disableRows={[3, 7]} // Disable selection for these rowshasSubRows
- Type:
boolean - Default:
false - Description: Enable support for hierarchical/nested rows
- Note: Requires data with
subRowsproperty
enableExpanding
- Type:
boolean - Default:
false - Description: Show expand/collapse icons for rows with subRows
Pagination & Display
enablePagination
- Type:
boolean - Default:
true - Description: Enable/disable pagination
pagination
- Type:
string - Default:
'both' - Options:
'top','bottom','both' - Description: Position of pagination controls
pageSize
- Type:
number - Default:
150 - Description: Number of rows per page initially
itemsPerPage
- Type:
Array<number> - Default:
[50, 100, 150] - Description: Options for rows per page dropdown
- Example:
itemsPerPage={[10, 25, 50, 100]}Styling & Layout
rowHeight
- Type:
number - Default:
75 - Description: Minimum height of each row in pixels
fontSize
- Type:
number - Default:
14 - Description: Base font size for grid content in pixels
gridHeight
- Type:
number | string - Default:
600 - Description: Maximum height of the grid container
- Examples:
gridHeight={600} // 600px
gridHeight="80vh" // 80% of viewport height
gridHeight="fit-content" // Auto heightenableCompactStyleMode
- Type:
boolean - Default:
false - Description: Enable compact styling with reduced padding and responsive font sizes
- Features:
- Smaller cell padding (2px vs auto)
- Responsive font sizing using clamp()
- Optimized for dense data display
getRowStyle
- Type:
function - Description: Custom function to apply styles to rows based on data
- Signature:
({ row }) => object - Example:
getRowStyle={({ row }) => ({
backgroundColor: row.original.status === 'active' ? '#e8f5e9' : 'white',
color: row.original.priority === 'high' ? 'red' : 'inherit'
})}enableFixedHeader
- Type:
boolean - Default:
true - Description: Pin headers to top when scrolling
enableFixedActions
- Type:
boolean - Default:
false - Description: Pin action toolbar to top when scrolling (requires enableFixedHeader)
Advanced Features
enableGlobalFilter
- Type:
boolean - Default:
false - Description: Show global search input that filters all columns
globalFilterFn
- Type:
string - Default:
'contains' - Options:
'contains','fuzzy','between','equals','greaterThan','lessThan','notEquals','lessThanOrEqualTo','greaterThanOrEqualTo','empty','notEmpty','startsWith','endsWith','betweenInclusive' - Description: Filter function for global search
enableColumnFilterModes
- Type:
boolean - Default:
true - Description: Allow users to change filter type per column (contains, equals, etc.)
enableVirtualization
- Type:
boolean - Default:
false - Description: Enable row and column virtualization for large datasets (improves performance)
- Recommended for: 1000+ rows
enableFullScreenToggle
- Type:
boolean - Default:
false - Description: Show fullscreen toggle button
enableDensityToggle
- Type:
boolean - Default:
false - Description: Show density toggle button (compact/comfortable/spacious)
Cache & Updates
updateCache
- Type:
function - Default:
undefined - Description: Callback function triggered when cache update button is clicked
- Example:
updateCache={() => {
fetchLatestData();
}}cacheUpdateText
- Type:
string - Default:
undefined - Description: Tooltip text for cache update button
- Example:
"Refresh data from server"
cacheUpdating
- Type:
boolean - Default:
false - Description: Shows loading state on cache update button
Callbacks
onVisibleRowsChange
- Type:
function - Description: Called whenever visible rows change (filtering, sorting, pagination)
- Signature:
(visibleRows: Array) => void - Example:
onVisibleRowsChange={(rows) => {
console.log('Currently visible:', rows.length);
}}Column Types
The DataGrid supports various pre-built cell types via the type property in column definitions:
Text Types
text- Plain texttextTitle- Bold texttextDescription- Gray text (#666)textSmall- Small font text
Date Types
date- Date only (no time)datetime- Date with time
Number Types
number- Raw numberinteger- Rounded integercurrency- EUR currency format (€1,234.56)percentage- Percentage format (12.34%)
Link Types
email- Clickable mailto linkphone- Clickable tel linklink- External link (opens in new tab)
Complex Types
array- Comma-separated array valuesjson- Formatted JSON displaycountryFlag- Country flag image (requires ISO2 code)persons- List of persons with "et al." notation
Example with Types
const columns = [
{ accessorKey: 'name', header: 'Name', type: 'textTitle' },
{ accessorKey: 'description', header: 'Description', type: 'textDescription' },
{ accessorKey: 'email', header: 'Email', type: 'email' },
{ accessorKey: 'salary', header: 'Salary', type: 'currency' },
{ accessorKey: 'completion', header: 'Progress', type: 'percentage' },
{ accessorKey: 'createdAt', header: 'Created', type: 'date', isDateColumn: true },
{ accessorKey: 'country', header: 'Country', type: 'countryFlag' },
{ accessorKey: 'tags', header: 'Tags', type: 'array' },
];Custom Cell Renderers with Type Support
You have multiple options for cell rendering:
Option 1: Using Type Alone (Simplest)
const columns = [
{
accessorKey: 'price',
header: 'Price',
type: 'currency' // Automatically formatted as currency
}
];
// No custom Cell needed - formatter is applied automaticallyOption 2: Type + cellClass
const columns = [
{
accessorKey: 'status',
header: 'Status',
type: 'text',
cellClass: 'custom-status' // Formatted text wrapped in <div class="custom-status">
}
];Option 3: Type + Custom Cell (Advanced)
When you need both formatting AND custom logic:
// Custom cell that uses the type formatter and adds custom styling
const CustomStatusCell = ({ typeValue, cell, row }) => {
const value = cell.getValue();
return (
<div style={{
color: value === 'active' ? 'green' : 'red',
fontWeight: 'bold'
}}>
{typeValue || value} {/* Use typeValue (formatted) or fallback to raw value */}
</div>
);
};
const columns = [
{
accessorKey: 'status',
header: 'Status',
type: 'text', // Formatter is applied first
Cell: CustomStatusCell, // Custom component receives typeValue prop
}
];Option 4: Custom Cell Only (No Type)
const CustomCell = ({ cell }) => {
return <strong>{cell.getValue()}</strong>;
};
const columns = [
{
accessorKey: 'name',
header: 'Name',
Cell: CustomCell // No type - full control over rendering
}
];How Cell Rendering Works:
- If
typeis specified,DEFAULT_CELL_TYPES[type]formatter is applied automatically - If
Cellcomponent is also provided, it receives all props includingtypeValue(the formatted result) - If
cellClassis specified, content is wrapped in<div className={cellClass}> - Priority: Custom Cell (with typeValue) > Type formatter > Raw value
Note: You can use type alone without a custom Cell component - the formatter will be applied automatically.
Examples
Example 1: Basic Grid with Selection
import React, { useState } from 'react';
import DataGrid from '@insticc/react-datagrid-2';
function UserGrid() {
const [selected, setSelected] = useState([]);
const columns = [
{ accessorKey: 'id', header: 'ID', type: 'integer' },
{ accessorKey: 'name', header: 'Name', type: 'textTitle' },
{ accessorKey: 'email', header: 'Email', type: 'email' },
{ accessorKey: 'role', header: 'Role', type: 'text' },
];
const users = [
{ id: 1, name: 'John Doe', email: '[email protected]', role: 'Admin' },
{ id: 2, name: 'Jane Smith', email: '[email protected]', role: 'User' },
];
return (
<DataGrid
columns={columns}
createRows={users}
rowKey="id"
selectData={setSelected}
pageSize={50}
itemsPerPage={[25, 50, 100]}
/>
);
}Example 2: Grid with Actions and Exports
function ProductGrid() {
const handleDelete = (rows) => {
const ids = rows.map(r => r.id);
console.log('Deleting:', ids);
};
const handleEdit = (rows) => {
if (rows.length === 1) {
console.log('Editing:', rows[0]);
}
};
const actions = [
{
name: 'Delete',
function: handleDelete,
tooltip: 'Delete selected products',
color: 'red',
icon: 'trash',
selectionMode: 'multi',
hasConfirmMessage: true,
confirmMessage: 'Are you sure you want to delete these products?'
},
{
name: 'Edit',
function: handleEdit,
tooltip: 'Edit product',
color: 'blue',
icon: 'edit',
selectionMode: 'single'
}
];
return (
<DataGrid
columns={productColumns}
createRows={products}
rowKey="productId"
selectData={setSelected}
actions={actions}
hasExcelExport={true}
hasPdfExport={true}
excelOption="selectedRows"
pdfOption="allRows"
/>
);
}Example 3: Hierarchical Data with SubRows
function ProjectGrid() {
const data = [
{
id: 1,
name: 'Project Alpha',
status: 'Active',
subRows: [
{ id: '1.1', name: 'Task 1', status: 'Complete' },
{ id: '1.2', name: 'Task 2', status: 'In Progress' }
]
},
{
id: 2,
name: 'Project Beta',
status: 'Planning',
subRows: [
{ id: '2.1', name: 'Task 1', status: 'Not Started' }
]
}
];
return (
<DataGrid
columns={projectColumns}
createRows={data}
rowKey="id"
selectData={setSelected}
hasSubRows={true}
enableExpanding={true}
/>
);
}Example 4: Custom Styling and Virtualization
function LargeDataGrid() {
// Custom cell with type support
const StatusCell = ({ typeValue, cell }) => {
const value = cell.getValue();
const color = value === 'active' ? 'green' : 'red';
return (
<span style={{ color, fontWeight: 'bold' }}>
{typeValue || value}
</span>
);
};
const getRowStyle = ({ row }) => {
if (row.original.status === 'error') {
return { backgroundColor: '#ffebee' };
}
if (row.original.priority === 'high') {
return { backgroundColor: '#fff3e0' };
}
return {};
};
const columns = [
{ accessorKey: 'id', header: 'ID', type: 'integer' },
{
accessorKey: 'status',
header: 'Status',
type: 'text', // Formatter applied
Cell: StatusCell // Custom cell receives typeValue
},
{ accessorKey: 'name', header: 'Name', type: 'text' },
];
return (
<DataGrid
columns={columns}
createRows={largeDataset} // 10000+ rows
rowKey="id"
selectData={setSelected}
enableVirtualization={true}
enableCompactStyleMode={true}
rowHeight={40}
fontSize={12}
gridHeight="calc(100vh - 200px)"
getRowStyle={getRowStyle}
pageSize={100}
/>
);
}Example 5: Advanced Features
function AdvancedGrid() {
const [cacheLoading, setCacheLoading] = useState(false);
const refreshData = async () => {
setCacheLoading(true);
await fetchLatestData();
setCacheLoading(false);
};
const handleVisibleRowsChange = (rows) => {
console.log('Visible rows count:', rows.length);
};
return (
<DataGrid
columns={columns}
createRows={data}
rowKey="id"
selectData={setSelected}
// Advanced features
enableGlobalFilter={true}
globalFilterFn="fuzzy"
enableColumnFilterModes={true}
enableFixedHeader={true}
enableFixedActions={true}
// Cache management
updateCache={refreshData}
cacheUpdateText="Refresh data from server"
cacheUpdating={cacheLoading}
// Callbacks
onVisibleRowsChange={handleVisibleRowsChange}
// Help
gridHelper={{
title: 'Data Grid Help',
content: (
<div>
<h3>Features</h3>
<ul>
<li>Click rows to select</li>
<li>Use column filters for search</li>
<li>Export to Excel or PDF</li>
</ul>
</div>
)
}}
/>
);
}API Reference
Column Definition Object
{
accessorKey: string; // Required: Key to access data
header: string; // Required: Column header text
type?: string; // Cell type (see Column Types)
enableSorting?: boolean; // Default: true
enableColumnFilter?: boolean; // Default: true
enableColumnFilterModes?: boolean;// Default: true
filterFn?: string; // Default: 'contains'
enableResizing?: boolean; // Default: true
grow?: boolean; // Default: true
enableClickToCopy?: boolean; // Default: false
enableColumnActions?: boolean; // Default: false
isDateColumn?: boolean; // Special date handling
sortingFn?: function; // Custom sorting function
Cell?: Component; // Custom cell renderer (receives typeValue prop)
cellClass?: string; // CSS class wrapping cell content
locale?: string; // Locale for date/number formatting
onlyFlag?: boolean; // For countryFlag type
columnDef?: object; // Additional metadata
}Cell Rendering Priority:
- If
typeis defined:DEFAULT_CELL_TYPES[type]formatter is applied first (becomescontent) - If
Cellis also defined: Custom component receivestypeValue(the formatted result) and can overridecontent - If only
Cellis defined (notype): Custom component has full control - If
cellClassis defined: Final content is wrapped in<div className={cellClass}>
Rendering Flow:
Raw Value → [type formatter] → content → [Custom Cell] → content → [cellClass wrapper] → Final OutputAction Object
{
name: string; // Button label
function: (selectedRows) => void; // Required: Click handler
tooltip?: string; // Hover tooltip
color?: string; // Button color
icon?: string | element; // Button icon
selectionMode?: 'single' | 'multi' | 'always';
confirmMessage?: string | element;
hasConfirmMessage?: boolean;
disabled?: boolean;
visible?: boolean;
toggle?: boolean;
active?: boolean;
key?: string; // Unique key for React
}Performance Tips
Use Virtualization for Large Datasets
enableVirtualization={true} // For 1000+ rowsOptimize Row Height
rowHeight={40} // Smaller = more rows visibleDisable Unused Features
enableDensityToggle={false} enableFullScreenToggle={false} enableGlobalFilter={false}Use Compact Mode
enableCompactStyleMode={true} fontSize={12}Limit Initial Page Size
pageSize={50} // Don't render too many rows initiallyPre-select Rows Carefully
// Only include necessary IDs selectedIds={criticalIds} // vs selecting all rowsOptimize Custom Cell Renderers
// Use typeValue when available to avoid re-computing const MyCell = ({ typeValue, cell }) => { return typeValue || cell.getValue(); // Prefer typeValue };
Browser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
Important Notes
Row Selection Behavior
- Click-to-select: When
disableSelect={false}, clicking anywhere on a row will toggle its selection - Single selection mode: Clicking a row deselects all other rows and selects only the clicked row
- Checkbox behavior: For multi-row selection, use the checkboxes in combination with
enableMultiRowSelection={true} - The selection state is controlled by
rowSelectionand updates through theselectDatacallback
Fixed Header and Actions
enableFixedHeaderpins the column headers when scrollingenableFixedActions(requiresenableFixedHeader={true}) also pins the action toolbar- Both features use CSS positioning and may require adjustments based on your page layout
Date Columns
- Columns with
isDateColumn={true}get automatic date-aware sorting - Use the
typeprop ('date'or'datetime') to format date display - The
localeprop on columns controls date formatting (default: 'pt-PT')
LocalizationProvider
The DataGrid component is wrapped with MUI's LocalizationProvider using AdapterDateFns. This is required for any date-related functionality and doesn't need to be added by the consumer.
Troubleshooting
Common Issues
Issue: Rows not selecting when clicked
- Check that
disableSelect={false}(default) - Verify
selectDatacallback is provided - Ensure
rowKeymatches your data's unique identifier
Issue: Date columns not sorting correctly
- Set
isDateColumn={true}on date columns - Ensure date values are in a valid format (ISO 8601 recommended)
Issue: Fixed headers not working
- Set
enableFixedHeader={true} - Check that
gridHeightis set to a specific value (not 'fit-content') - For fixed actions, also set
enableFixedActions={true}
Issue: Selection state not syncing with parent component
- Use the
selectedIdsprop to control selection from parent - The component will auto-sync when
selectedIdschanges
Issue: Export buttons not appearing
- Set
hasExcelExport={true}and/orhasPdfExport={true} - Check that action buttons have enough space in the toolbar
Issue: Type formatter not working
- Verify column has
typeproperty defined - Check that
typevalue matches a key inDEFAULT_CELL_TYPES(e.g., 'text', 'date', 'currency') - The formatter is applied automatically - no
Cellcomponent needed - If using a custom
Cell, the formatted value is intypeValueprop
Issue: Custom Cell component not receiving typeValue
- Verify the column has a
typeproperty defined - Check that
typematches a key inDEFAULT_CELL_TYPES - Remember:
typeValueis only passed when bothtypeandCellare defined
Dependencies
This component is built on top of:
- Material React Table - Core table functionality
- MUI (Material-UI) - UI components and styling
- Semantic UI React - Additional UI components
- Bootstrap - Base CSS framework
- date-fns - Date manipulation and formatting
License
ISC
