@insticc/react-datagrid-2 1.1.13 → 1.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +1042 -1051
  2. package/package.json +50 -49
package/README.md CHANGED
@@ -1,1051 +1,1042 @@
1
- # DataGrid Component
2
-
3
- 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.
4
-
5
- ## Table of Contents
6
-
7
- - [Installation](#installation)
8
- - [Basic Usage](#basic-usage)
9
- - [Props Reference](#props-reference)
10
- - [Core Props](#core-props)
11
- - [Column Configuration](#column-configuration)
12
- - [Actions & Toolbar](#actions--toolbar)
13
- - [Export Options](#export-options)
14
- - [Selection & Interaction](#selection--interaction)
15
- - [Pagination & Display](#pagination--display)
16
- - [Styling & Layout](#styling--layout)
17
- - [Advanced Features](#advanced-features)
18
- - [Column Types](#column-types)
19
- - [Examples](#examples)
20
- - [API Reference](#api-reference)
21
-
22
- ---
23
-
24
- ## Installation
25
-
26
- ```bash
27
- npm install @insticc/react-datagrid-2
28
- ```
29
-
30
- ### Required Dependencies
31
-
32
- ```bash
33
- npm install react prop-types material-react-table semantic-ui-react @mui/material bootstrap
34
- ```
35
-
36
- ---
37
-
38
- ## Basic Usage
39
-
40
- ```jsx
41
- import React, { useState } from 'react';
42
- import DataGrid from '@insticc/react-datagrid-2';
43
-
44
- function MyComponent() {
45
- const [selectedRows, setSelectedRows] = useState([]);
46
-
47
- const columns = [
48
- { accessorKey: 'id', header: 'ID', type: 'text' },
49
- { accessorKey: 'name', header: 'Name', type: 'text' },
50
- { accessorKey: 'email', header: 'Email', type: 'email' },
51
- { accessorKey: 'createdAt', header: 'Created', type: 'date', isDateColumn: true },
52
- ];
53
-
54
- const data = [
55
- { id: '1', name: 'John Doe', email: 'john@example.com', createdAt: '2025-01-15' },
56
- { id: '2', name: 'Jane Smith', email: 'jane@example.com', createdAt: '2025-02-20' },
57
- ];
58
-
59
- return (
60
- <DataGrid
61
- columns={columns}
62
- createRows={data}
63
- rowKey="id"
64
- selectData={setSelectedRows}
65
- hasExcelExport={true}
66
- hasPdfExport={true}
67
- />
68
- );
69
- }
70
- ```
71
-
72
- ---
73
-
74
- ## Props Reference
75
-
76
- ### Core Props
77
-
78
- #### `columns` (required)
79
- - **Type:** `Array`
80
- - **Description:** Array of column definitions that determine how data is displayed
81
- - **Example:**
82
- ```jsx
83
- const columns = [
84
- {
85
- accessorKey: 'name', // Key to access data
86
- header: 'Full Name', // Column header text
87
- type: 'text', // Cell type - formatter applied automatically
88
- enableSorting: true, // Enable/disable sorting
89
- enableColumnFilter: true, // Enable/disable filtering
90
- filterFn: 'contains', // Filter function type
91
- isDateColumn: false, // Special handling for dates
92
- cellClass: 'custom-class', // CSS class wrapping cell content
93
- Cell: CustomComponent, // Optional: Custom cell renderer (receives typeValue)
94
- }
95
- ];
96
- ```
97
-
98
- **Column Rendering Modes:**
99
- - `type` only: Formatter applied automatically
100
- - `type` + `cellClass`: Formatted content wrapped in div
101
- - `type` + `Cell`: Custom component receives `typeValue` (formatted content)
102
- - `Cell` only: Full custom rendering without type formatter
103
-
104
- #### `createRows` (required)
105
- - **Type:** `Array`
106
- - **Description:** Array of data objects to display in the grid
107
- - **Example:**
108
- ```jsx
109
- const data = [
110
- { id: 1, name: 'John', email: 'john@example.com' },
111
- { id: 2, name: 'Jane', email: 'jane@example.com' }
112
- ];
113
- ```
114
-
115
- #### `rowKey` (required)
116
- - **Type:** `string`
117
- - **Description:** Property name used as unique identifier for each row
118
- - **Default:** `'id'`
119
- - **Example:** `rowKey="id"` or `rowKey="uuid"`
120
-
121
- #### `selectData` (required)
122
- - **Type:** `function`
123
- - **Description:** Callback function that receives selected rows whenever selection changes
124
- - **Signature:** `(selectedRows: Array) => void`
125
- - **Example:**
126
- ```jsx
127
- const handleSelection = (rows) => {
128
- console.log('Selected rows:', rows);
129
- };
130
-
131
- <DataGrid selectData={handleSelection} />
132
- ```
133
-
134
- ---
135
-
136
- ### Column Configuration
137
-
138
- #### `columnVisibilityState`
139
- - **Type:** `object`
140
- - **Default:** `{}`
141
- - **Description:** Controls which columns are visible/hidden
142
- - **Example:**
143
- ```jsx
144
- columnVisibilityState={{
145
- email: false, // Hide email column
146
- phone: true // Show phone column
147
- }}
148
- ```
149
-
150
- #### `columnOrder`
151
- - **Type:** `Array<string>`
152
- - **Default:** `[]`
153
- - **Description:** Defines the order of columns by their accessorKey
154
- - **Example:**
155
- ```jsx
156
- columnOrder={['name', 'email', 'id']}
157
- ```
158
-
159
- ---
160
-
161
- ### Actions & Toolbar
162
-
163
- #### `actions`
164
- - **Type:** `Array<ActionObject>`
165
- - **Default:** `null`
166
- - **Description:** Array of custom action buttons displayed in the toolbar
167
- - **Action Object Properties:**
168
- - `name` (string): Button label
169
- - `function` (function, required): Callback when button is clicked
170
- - `tooltip` (string): Tooltip text on hover
171
- - `color` (string): Button color - one of: `'blue'`, `'red'`, `'green'`, `'yellow'`, `'orange'`, `'black'`, `'grey'`, `'teal'`, `'brown'`, `'violet'`, `'purple'`, `'olive'`, `'pink'`
172
- - `icon` (string|element): Icon name or React element
173
- - `selectionMode` (string): When button is enabled - `'single'`, `'multi'`, `'always'`
174
- - `confirmMessage` (string|element): Confirmation message before action
175
- - `hasConfirmMessage` (boolean): Whether to show confirmation dialog
176
- - `disabled` (boolean): Disable the button
177
- - `visible` (boolean): Show/hide the button
178
- - `toggle` (boolean): Toggle button style
179
- - `active` (boolean): Toggle button active state
180
- - **Example:**
181
- ```jsx
182
- actions={[
183
- {
184
- name: 'Delete',
185
- function: (selectedRows) => handleDelete(selectedRows),
186
- tooltip: 'Delete selected rows',
187
- color: 'red',
188
- icon: 'trash',
189
- selectionMode: 'multi',
190
- hasConfirmMessage: true,
191
- confirmMessage: 'Are you sure you want to delete these rows?'
192
- },
193
- {
194
- name: 'Edit',
195
- function: (selectedRows) => handleEdit(selectedRows),
196
- tooltip: 'Edit selected row',
197
- color: 'blue',
198
- icon: 'edit',
199
- selectionMode: 'single'
200
- },
201
- {
202
- name: 'Add New',
203
- function: () => handleAdd(),
204
- tooltip: 'Add new record',
205
- color: 'green',
206
- icon: 'plus',
207
- selectionMode: 'always'
208
- }
209
- ]}
210
- ```
211
-
212
- #### `enableTopToolbar`
213
- - **Type:** `boolean`
214
- - **Default:** `true`
215
- - **Description:** Show/hide the top toolbar containing actions and pagination
216
-
217
- #### `enableBottomToolbar`
218
- - **Type:** `boolean`
219
- - **Default:** `false`
220
- - **Description:** Show/hide the bottom toolbar
221
-
222
- #### `hasClearFiltersBtn`
223
- - **Type:** `boolean`
224
- - **Default:** `true`
225
- - **Description:** Show/hide the "Clear Filters" button in toolbar
226
-
227
- #### `gridHelper`
228
- - **Type:** `object | null`
229
- - **Default:** `null`
230
- - **Description:** Adds a help button with custom content
231
- - **Required Properties (if defined):**
232
- - `title` (string|element, required): Help dialog title
233
- - `content` (string|element, required): Help dialog content
234
- - **Example:**
235
- ```jsx
236
- gridHelper={{
237
- title: 'Grid Instructions',
238
- content: (
239
- <div>
240
- <p>Use the filters to search data</p>
241
- <p>Click rows to select them</p>
242
- </div>
243
- )
244
- }}
245
- ```
246
-
247
- ---
248
-
249
- ### Export Options
250
-
251
- #### `hasExcelExport`
252
- - **Type:** `boolean`
253
- - **Default:** `false`
254
- - **Description:** Enable Excel export button
255
-
256
- #### `excelOption`
257
- - **Type:** `string`
258
- - **Default:** `'selectedRows'`
259
- - **Options:** `'all'`, `'allRows'`, `'pageRows'`, `'selectedRows'`
260
- - **Description:** Determines which rows to export to Excel
261
-
262
- #### `hasPdfExport`
263
- - **Type:** `boolean`
264
- - **Default:** `false`
265
- - **Description:** Enable PDF export button
266
-
267
- #### `pdfOption`
268
- - **Type:** `string`
269
- - **Default:** `'selectedRows'`
270
- - **Options:** `'all'`, `'allRows'`, `'pageRows'`, `'selectedRows'`
271
- - **Description:** Determines which rows to export to PDF
272
-
273
- **Export Options Explained:**
274
- - `'all'` - Export all data including hidden columns
275
- - `'allRows'` - Export all rows (respects filters)
276
- - `'pageRows'` - Export only current page rows
277
- - `'selectedRows'` - Export only selected rows
278
-
279
- ---
280
-
281
- ### Selection & Interaction
282
-
283
- #### `disableSelect`
284
- - **Type:** `boolean`
285
- - **Default:** `false`
286
- - **Description:** Disable row selection checkboxes and click-to-select behavior completely
287
-
288
- #### `enableMultiRowSelection`
289
- - **Type:** `boolean`
290
- - **Default:** `true`
291
- - **Description:** Allow selecting multiple rows at once
292
-
293
- #### `selectAllMode`
294
- - **Type:** `string`
295
- - **Default:** `'page'`
296
- - **Options:** `'page'`, `'all'`
297
- - **Description:**
298
- - `'page'` - "Select All" checkbox selects only current page
299
- - `'all'` - "Select All" checkbox selects all filtered rows
300
-
301
- #### `selectedIds`
302
- - **Type:** `Array`
303
- - **Default:** `[]`
304
- - **Description:** Array of row IDs that should be pre-selected
305
- - **Example:**
306
- ```jsx
307
- selectedIds={[1, 5, 10]} // Pre-select rows with these IDs
308
- ```
309
-
310
- #### `disableRows`
311
- - **Type:** `Array`
312
- - **Default:** `[]`
313
- - **Description:** Array of row IDs that should be disabled (cannot be selected)
314
- - **Example:**
315
- ```jsx
316
- disableRows={[3, 7]} // Disable selection for these rows
317
- ```
318
-
319
- #### `hasSubRows`
320
- - **Type:** `boolean`
321
- - **Default:** `false`
322
- - **Description:** Enable support for hierarchical/nested rows
323
- - **Note:** Requires data with `subRows` property
324
-
325
- #### `enableExpanding`
326
- - **Type:** `boolean`
327
- - **Default:** `false`
328
- - **Description:** Show expand/collapse icons for rows with subRows
329
-
330
- ---
331
-
332
- ### Pagination & Display
333
-
334
- #### `enablePagination`
335
- - **Type:** `boolean`
336
- - **Default:** `true`
337
- - **Description:** Enable/disable pagination
338
-
339
- #### `pagination`
340
- - **Type:** `string`
341
- - **Default:** `'both'`
342
- - **Options:** `'top'`, `'bottom'`, `'both'`
343
- - **Description:** Position of pagination controls
344
-
345
- #### `pageSize`
346
- - **Type:** `number`
347
- - **Default:** `150`
348
- - **Description:** Number of rows per page initially
349
-
350
- #### `itemsPerPage`
351
- - **Type:** `Array<number>`
352
- - **Default:** `[50, 100, 150]`
353
- - **Description:** Options for rows per page dropdown
354
- - **Example:**
355
- ```jsx
356
- itemsPerPage={[10, 25, 50, 100]}
357
- ```
358
-
359
- ---
360
-
361
- ### Styling & Layout
362
-
363
- #### `rowHeight`
364
- - **Type:** `number`
365
- - **Default:** `75`
366
- - **Description:** Minimum height of each row in pixels
367
-
368
- #### `fontSize`
369
- - **Type:** `number`
370
- - **Default:** `14`
371
- - **Description:** Base font size for grid content in pixels
372
-
373
- #### `gridHeight`
374
- - **Type:** `number | string`
375
- - **Default:** `600`
376
- - **Description:** Maximum height of the grid container
377
- - **Examples:**
378
- ```jsx
379
- gridHeight={600} // 600px
380
- gridHeight="80vh" // 80% of viewport height
381
- gridHeight="fit-content" // Auto height
382
- ```
383
-
384
- #### `enableCompactStyleMode`
385
- - **Type:** `boolean`
386
- - **Default:** `false`
387
- - **Description:** Enable compact styling with reduced padding and responsive font sizes
388
- - **Features:**
389
- - Smaller cell padding (2px vs auto)
390
- - Responsive font sizing using clamp()
391
- - Optimized for dense data display
392
-
393
- #### `getRowStyle`
394
- - **Type:** `function`
395
- - **Description:** Custom function to apply styles to rows based on data
396
- - **Signature:** `({ row }) => object`
397
- - **Example:**
398
- ```jsx
399
- getRowStyle={({ row }) => ({
400
- backgroundColor: row.original.status === 'active' ? '#e8f5e9' : 'white',
401
- color: row.original.priority === 'high' ? 'red' : 'inherit'
402
- })}
403
- ```
404
-
405
- #### `enableFixedHeader`
406
- - **Type:** `boolean`
407
- - **Default:** `true`
408
- - **Description:** Pin headers to top when scrolling
409
-
410
- #### `enableFixedActions`
411
- - **Type:** `boolean`
412
- - **Default:** `false`
413
- - **Description:** Pin action toolbar to top when scrolling (requires enableFixedHeader)
414
-
415
- ---
416
-
417
- ### Advanced Features
418
-
419
- #### `enableGlobalFilter`
420
- - **Type:** `boolean`
421
- - **Default:** `false`
422
- - **Description:** Show global search input that filters all columns
423
-
424
- #### `globalFilterFn`
425
- - **Type:** `string`
426
- - **Default:** `'contains'`
427
- - **Options:** `'contains'`, `'fuzzy'`, `'between'`, `'equals'`, `'greaterThan'`, `'lessThan'`, `'notEquals'`, `'lessThanOrEqualTo'`, `'greaterThanOrEqualTo'`, `'empty'`, `'notEmpty'`, `'startsWith'`, `'endsWith'`, `'betweenInclusive'`
428
- - **Description:** Filter function for global search
429
-
430
- #### `enableColumnFilterModes`
431
- - **Type:** `boolean`
432
- - **Default:** `true`
433
- - **Description:** Allow users to change filter type per column (contains, equals, etc.)
434
-
435
- #### `enableVirtualization`
436
- - **Type:** `boolean`
437
- - **Default:** `false`
438
- - **Description:** Enable row and column virtualization for large datasets (improves performance)
439
- - **Recommended for:** 1000+ rows
440
-
441
- #### `enableFullScreenToggle`
442
- - **Type:** `boolean`
443
- - **Default:** `false`
444
- - **Description:** Show fullscreen toggle button
445
-
446
- #### `enableDensityToggle`
447
- - **Type:** `boolean`
448
- - **Default:** `false`
449
- - **Description:** Show density toggle button (compact/comfortable/spacious)
450
-
451
- ---
452
-
453
- ### Cache & Updates
454
-
455
- #### `updateCache`
456
- - **Type:** `function`
457
- - **Default:** `undefined`
458
- - **Description:** Callback function triggered when cache update button is clicked
459
- - **Example:**
460
- ```jsx
461
- updateCache={() => {
462
- fetchLatestData();
463
- }}
464
- ```
465
-
466
- #### `cacheUpdateText`
467
- - **Type:** `string`
468
- - **Default:** `undefined`
469
- - **Description:** Tooltip text for cache update button
470
- - **Example:** `"Refresh data from server"`
471
-
472
- #### `cacheUpdating`
473
- - **Type:** `boolean`
474
- - **Default:** `false`
475
- - **Description:** Shows loading state on cache update button
476
-
477
- ---
478
-
479
- ### Callbacks
480
-
481
- #### `onVisibleRowsChange`
482
- - **Type:** `function`
483
- - **Description:** Called whenever visible rows change (filtering, sorting, pagination)
484
- - **Signature:** `(visibleRows: Array) => void`
485
- - **Example:**
486
- ```jsx
487
- onVisibleRowsChange={(rows) => {
488
- console.log('Currently visible:', rows.length);
489
- }}
490
- ```
491
-
492
- ---
493
-
494
- ## Column Types
495
-
496
- The DataGrid supports various pre-built cell types via the `type` property in column definitions:
497
-
498
- ### Text Types
499
- - `text` - Plain text
500
- - `textTitle` - Bold text
501
- - `textDescription` - Gray text (#666)
502
- - `textSmall` - Small font text
503
-
504
- ### Date Types
505
- - `date` - Date only (no time)
506
- - `datetime` - Date with time
507
-
508
- ### Number Types
509
- - `number` - Raw number
510
- - `integer` - Rounded integer
511
- - `currency` - EUR currency format (€1,234.56)
512
- - `percentage` - Percentage format (12.34%)
513
-
514
- ### Link Types
515
- - `email` - Clickable mailto link
516
- - `phone` - Clickable tel link
517
- - `link` - External link (opens in new tab)
518
-
519
- ### Complex Types
520
- - `array` - Comma-separated array values
521
- - `json` - Formatted JSON display
522
- - `countryFlag` - Country flag image (requires ISO2 code)
523
- - `persons` - List of persons with "et al." notation
524
-
525
- ### Example with Types
526
-
527
- ```jsx
528
- const columns = [
529
- { accessorKey: 'name', header: 'Name', type: 'textTitle' },
530
- { accessorKey: 'description', header: 'Description', type: 'textDescription' },
531
- { accessorKey: 'email', header: 'Email', type: 'email' },
532
- { accessorKey: 'salary', header: 'Salary', type: 'currency' },
533
- { accessorKey: 'completion', header: 'Progress', type: 'percentage' },
534
- { accessorKey: 'createdAt', header: 'Created', type: 'date', isDateColumn: true },
535
- { accessorKey: 'country', header: 'Country', type: 'countryFlag' },
536
- { accessorKey: 'tags', header: 'Tags', type: 'array' },
537
- ];
538
- ```
539
-
540
- ### Custom Cell Renderers with Type Support
541
-
542
- You have multiple options for cell rendering:
543
-
544
- #### Option 1: Using Type Alone (Simplest)
545
- ```jsx
546
- const columns = [
547
- {
548
- accessorKey: 'price',
549
- header: 'Price',
550
- type: 'currency' // Automatically formatted as currency
551
- }
552
- ];
553
- // No custom Cell needed - formatter is applied automatically
554
- ```
555
-
556
- #### Option 2: Type + cellClass
557
- ```jsx
558
- const columns = [
559
- {
560
- accessorKey: 'status',
561
- header: 'Status',
562
- type: 'text',
563
- cellClass: 'custom-status' // Formatted text wrapped in <div class="custom-status">
564
- }
565
- ];
566
- ```
567
-
568
- #### Option 3: Type + Custom Cell (Advanced)
569
- When you need both formatting AND custom logic:
570
-
571
- ```jsx
572
- // Custom cell that uses the type formatter and adds custom styling
573
- const CustomStatusCell = ({ typeValue, cell, row }) => {
574
- const value = cell.getValue();
575
-
576
- return (
577
- <div style={{
578
- color: value === 'active' ? 'green' : 'red',
579
- fontWeight: 'bold'
580
- }}>
581
- {typeValue || value} {/* Use typeValue (formatted) or fallback to raw value */}
582
- </div>
583
- );
584
- };
585
-
586
- const columns = [
587
- {
588
- accessorKey: 'status',
589
- header: 'Status',
590
- type: 'text', // Formatter is applied first
591
- Cell: CustomStatusCell, // Custom component receives typeValue prop
592
- }
593
- ];
594
- ```
595
-
596
- #### Option 4: Custom Cell Only (No Type)
597
- ```jsx
598
- const CustomCell = ({ cell }) => {
599
- return <strong>{cell.getValue()}</strong>;
600
- };
601
-
602
- const columns = [
603
- {
604
- accessorKey: 'name',
605
- header: 'Name',
606
- Cell: CustomCell // No type - full control over rendering
607
- }
608
- ];
609
- ```
610
-
611
- **How Cell Rendering Works:**
612
- 1. If `type` is specified, `DEFAULT_CELL_TYPES[type]` formatter is applied automatically
613
- 2. If `Cell` component is also provided, it receives all props including `typeValue` (the formatted result)
614
- 3. If `cellClass` is specified, content is wrapped in `<div className={cellClass}>`
615
- 4. Priority: Custom Cell (with typeValue) > Type formatter > Raw value
616
-
617
- **Note:** You can use `type` alone without a custom `Cell` component - the formatter will be applied automatically.
618
-
619
- ---
620
-
621
- ## Examples
622
-
623
- ### Example 1: Basic Grid with Selection
624
-
625
- ```jsx
626
- import React, { useState } from 'react';
627
- import DataGrid from '@insticc/react-datagrid-2';
628
-
629
- function UserGrid() {
630
- const [selected, setSelected] = useState([]);
631
-
632
- const columns = [
633
- { accessorKey: 'id', header: 'ID', type: 'integer' },
634
- { accessorKey: 'name', header: 'Name', type: 'textTitle' },
635
- { accessorKey: 'email', header: 'Email', type: 'email' },
636
- { accessorKey: 'role', header: 'Role', type: 'text' },
637
- ];
638
-
639
- const users = [
640
- { id: 1, name: 'John Doe', email: 'john@company.com', role: 'Admin' },
641
- { id: 2, name: 'Jane Smith', email: 'jane@company.com', role: 'User' },
642
- ];
643
-
644
- return (
645
- <DataGrid
646
- columns={columns}
647
- createRows={users}
648
- rowKey="id"
649
- selectData={setSelected}
650
- pageSize={50}
651
- itemsPerPage={[25, 50, 100]}
652
- />
653
- );
654
- }
655
- ```
656
-
657
- ### Example 2: Grid with Actions and Exports
658
-
659
- ```jsx
660
- function ProductGrid() {
661
- const handleDelete = (rows) => {
662
- const ids = rows.map(r => r.id);
663
- console.log('Deleting:', ids);
664
- };
665
-
666
- const handleEdit = (rows) => {
667
- if (rows.length === 1) {
668
- console.log('Editing:', rows[0]);
669
- }
670
- };
671
-
672
- const actions = [
673
- {
674
- name: 'Delete',
675
- function: handleDelete,
676
- tooltip: 'Delete selected products',
677
- color: 'red',
678
- icon: 'trash',
679
- selectionMode: 'multi',
680
- hasConfirmMessage: true,
681
- confirmMessage: 'Are you sure you want to delete these products?'
682
- },
683
- {
684
- name: 'Edit',
685
- function: handleEdit,
686
- tooltip: 'Edit product',
687
- color: 'blue',
688
- icon: 'edit',
689
- selectionMode: 'single'
690
- }
691
- ];
692
-
693
- return (
694
- <DataGrid
695
- columns={productColumns}
696
- createRows={products}
697
- rowKey="productId"
698
- selectData={setSelected}
699
- actions={actions}
700
- hasExcelExport={true}
701
- hasPdfExport={true}
702
- excelOption="selectedRows"
703
- pdfOption="allRows"
704
- />
705
- );
706
- }
707
- ```
708
-
709
- ### Example 3: Hierarchical Data with SubRows
710
-
711
- ```jsx
712
- function ProjectGrid() {
713
- const data = [
714
- {
715
- id: 1,
716
- name: 'Project Alpha',
717
- status: 'Active',
718
- subRows: [
719
- { id: '1.1', name: 'Task 1', status: 'Complete' },
720
- { id: '1.2', name: 'Task 2', status: 'In Progress' }
721
- ]
722
- },
723
- {
724
- id: 2,
725
- name: 'Project Beta',
726
- status: 'Planning',
727
- subRows: [
728
- { id: '2.1', name: 'Task 1', status: 'Not Started' }
729
- ]
730
- }
731
- ];
732
-
733
- return (
734
- <DataGrid
735
- columns={projectColumns}
736
- createRows={data}
737
- rowKey="id"
738
- selectData={setSelected}
739
- hasSubRows={true}
740
- enableExpanding={true}
741
- />
742
- );
743
- }
744
- ```
745
-
746
- ### Example 4: Custom Styling and Virtualization
747
-
748
- ```jsx
749
- function LargeDataGrid() {
750
- // Custom cell with type support
751
- const StatusCell = ({ typeValue, cell }) => {
752
- const value = cell.getValue();
753
- const color = value === 'active' ? 'green' : 'red';
754
-
755
- return (
756
- <span style={{ color, fontWeight: 'bold' }}>
757
- {typeValue || value}
758
- </span>
759
- );
760
- };
761
-
762
- const getRowStyle = ({ row }) => {
763
- if (row.original.status === 'error') {
764
- return { backgroundColor: '#ffebee' };
765
- }
766
- if (row.original.priority === 'high') {
767
- return { backgroundColor: '#fff3e0' };
768
- }
769
- return {};
770
- };
771
-
772
- const columns = [
773
- { accessorKey: 'id', header: 'ID', type: 'integer' },
774
- {
775
- accessorKey: 'status',
776
- header: 'Status',
777
- type: 'text', // Formatter applied
778
- Cell: StatusCell // Custom cell receives typeValue
779
- },
780
- { accessorKey: 'name', header: 'Name', type: 'text' },
781
- ];
782
-
783
- return (
784
- <DataGrid
785
- columns={columns}
786
- createRows={largeDataset} // 10000+ rows
787
- rowKey="id"
788
- selectData={setSelected}
789
- enableVirtualization={true}
790
- enableCompactStyleMode={true}
791
- rowHeight={40}
792
- fontSize={12}
793
- gridHeight="calc(100vh - 200px)"
794
- getRowStyle={getRowStyle}
795
- pageSize={100}
796
- />
797
- );
798
- }
799
- ```
800
-
801
- ### Example 5: Advanced Features
802
-
803
- ```jsx
804
- function AdvancedGrid() {
805
- const [cacheLoading, setCacheLoading] = useState(false);
806
-
807
- const refreshData = async () => {
808
- setCacheLoading(true);
809
- await fetchLatestData();
810
- setCacheLoading(false);
811
- };
812
-
813
- const handleVisibleRowsChange = (rows) => {
814
- console.log('Visible rows count:', rows.length);
815
- };
816
-
817
- return (
818
- <DataGrid
819
- columns={columns}
820
- createRows={data}
821
- rowKey="id"
822
- selectData={setSelected}
823
-
824
- // Advanced features
825
- enableGlobalFilter={true}
826
- globalFilterFn="fuzzy"
827
- enableColumnFilterModes={true}
828
- enableFixedHeader={true}
829
- enableFixedActions={true}
830
-
831
- // Cache management
832
- updateCache={refreshData}
833
- cacheUpdateText="Refresh data from server"
834
- cacheUpdating={cacheLoading}
835
-
836
- // Callbacks
837
- onVisibleRowsChange={handleVisibleRowsChange}
838
-
839
- // Help
840
- gridHelper={{
841
- title: 'Data Grid Help',
842
- content: (
843
- <div>
844
- <h3>Features</h3>
845
- <ul>
846
- <li>Click rows to select</li>
847
- <li>Use column filters for search</li>
848
- <li>Export to Excel or PDF</li>
849
- </ul>
850
- </div>
851
- )
852
- }}
853
- />
854
- );
855
- }
856
- ```
857
-
858
- ---
859
-
860
- ## API Reference
861
-
862
- ### Column Definition Object
863
-
864
- ```typescript
865
- {
866
- accessorKey: string; // Required: Key to access data
867
- header: string; // Required: Column header text
868
- type?: string; // Cell type (see Column Types)
869
- enableSorting?: boolean; // Default: true
870
- enableColumnFilter?: boolean; // Default: true
871
- enableColumnFilterModes?: boolean;// Default: true
872
- filterFn?: string; // Default: 'contains'
873
- enableResizing?: boolean; // Default: true
874
- grow?: boolean; // Default: true
875
- enableClickToCopy?: boolean; // Default: false
876
- enableColumnActions?: boolean; // Default: false
877
- isDateColumn?: boolean; // Special date handling
878
- sortingFn?: function; // Custom sorting function
879
- Cell?: Component; // Custom cell renderer (receives typeValue prop)
880
- cellClass?: string; // CSS class wrapping cell content
881
- locale?: string; // Locale for date/number formatting
882
- onlyFlag?: boolean; // For countryFlag type
883
- columnDef?: object; // Additional metadata
884
- }
885
- ```
886
-
887
- **Cell Rendering Priority:**
888
- 1. If `type` is defined: `DEFAULT_CELL_TYPES[type]` formatter is applied first (becomes `content`)
889
- 2. If `Cell` is also defined: Custom component receives `typeValue` (the formatted result) and can override `content`
890
- 3. If only `Cell` is defined (no `type`): Custom component has full control
891
- 4. If `cellClass` is defined: Final content is wrapped in `<div className={cellClass}>`
892
-
893
- **Rendering Flow:**
894
- ```
895
- Raw Value [type formatter] content → [Custom Cell] → content → [cellClass wrapper] → Final Output
896
- ```
897
-
898
- ### Action Object
899
-
900
- ```typescript
901
- {
902
- name: string; // Button label
903
- function: (selectedRows) => void; // Required: Click handler
904
- tooltip?: string; // Hover tooltip
905
- color?: string; // Button color
906
- icon?: string | element; // Button icon
907
- selectionMode?: 'single' | 'multi' | 'always';
908
- confirmMessage?: string | element;
909
- hasConfirmMessage?: boolean;
910
- disabled?: boolean;
911
- visible?: boolean;
912
- toggle?: boolean;
913
- active?: boolean;
914
- key?: string; // Unique key for React
915
- }
916
- ```
917
-
918
- ---
919
-
920
- ## Performance Tips
921
-
922
- 1. **Use Virtualization for Large Datasets**
923
- ```jsx
924
- enableVirtualization={true} // For 1000+ rows
925
- ```
926
-
927
- 2. **Optimize Row Height**
928
- ```jsx
929
- rowHeight={40} // Smaller = more rows visible
930
- ```
931
-
932
- 3. **Disable Unused Features**
933
- ```jsx
934
- enableDensityToggle={false}
935
- enableFullScreenToggle={false}
936
- enableGlobalFilter={false}
937
- ```
938
-
939
- 4. **Use Compact Mode**
940
- ```jsx
941
- enableCompactStyleMode={true}
942
- fontSize={12}
943
- ```
944
-
945
- 5. **Limit Initial Page Size**
946
- ```jsx
947
- pageSize={50} // Don't render too many rows initially
948
- ```
949
-
950
- 6. **Pre-select Rows Carefully**
951
- ```jsx
952
- // Only include necessary IDs
953
- selectedIds={criticalIds} // vs selecting all rows
954
- ```
955
-
956
- 7. **Optimize Custom Cell Renderers**
957
- ```jsx
958
- // Use typeValue when available to avoid re-computing
959
- const MyCell = ({ typeValue, cell }) => {
960
- return typeValue || cell.getValue(); // Prefer typeValue
961
- };
962
- ```
963
-
964
- ---
965
-
966
- ## Browser Support
967
-
968
- - Chrome (latest)
969
- - Firefox (latest)
970
- - Safari (latest)
971
- - Edge (latest)
972
-
973
- ---
974
-
975
- ## Important Notes
976
-
977
- ### Row Selection Behavior
978
- - **Click-to-select:** When `disableSelect={false}`, clicking anywhere on a row will toggle its selection
979
- - **Single selection mode:** Clicking a row deselects all other rows and selects only the clicked row
980
- - **Checkbox behavior:** For multi-row selection, use the checkboxes in combination with `enableMultiRowSelection={true}`
981
- - The selection state is controlled by `rowSelection` and updates through the `selectData` callback
982
-
983
- ### Fixed Header and Actions
984
- - `enableFixedHeader` pins the column headers when scrolling
985
- - `enableFixedActions` (requires `enableFixedHeader={true}`) also pins the action toolbar
986
- - Both features use CSS positioning and may require adjustments based on your page layout
987
-
988
- ### Date Columns
989
- - Columns with `isDateColumn={true}` get automatic date-aware sorting
990
- - Use the `type` prop (`'date'` or `'datetime'`) to format date display
991
- - The `locale` prop on columns controls date formatting (default: 'pt-PT')
992
-
993
- ### LocalizationProvider
994
- 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.
995
-
996
- ---
997
-
998
- ## Troubleshooting
999
-
1000
- ### Common Issues
1001
-
1002
- **Issue: Rows not selecting when clicked**
1003
- - Check that `disableSelect={false}` (default)
1004
- - Verify `selectData` callback is provided
1005
- - Ensure `rowKey` matches your data's unique identifier
1006
-
1007
- **Issue: Date columns not sorting correctly**
1008
- - Set `isDateColumn={true}` on date columns
1009
- - Ensure date values are in a valid format (ISO 8601 recommended)
1010
-
1011
- **Issue: Fixed headers not working**
1012
- - Set `enableFixedHeader={true}`
1013
- - Check that `gridHeight` is set to a specific value (not 'fit-content')
1014
- - For fixed actions, also set `enableFixedActions={true}`
1015
-
1016
- **Issue: Selection state not syncing with parent component**
1017
- - Use the `selectedIds` prop to control selection from parent
1018
- - The component will auto-sync when `selectedIds` changes
1019
-
1020
- **Issue: Export buttons not appearing**
1021
- - Set `hasExcelExport={true}` and/or `hasPdfExport={true}`
1022
- - Check that action buttons have enough space in the toolbar
1023
-
1024
- **Issue: Type formatter not working**
1025
- - Verify column has `type` property defined
1026
- - Check that `type` value matches a key in `DEFAULT_CELL_TYPES` (e.g., 'text', 'date', 'currency')
1027
- - The formatter is applied automatically - no `Cell` component needed
1028
- - If using a custom `Cell`, the formatted value is in `typeValue` prop
1029
-
1030
- **Issue: Custom Cell component not receiving typeValue**
1031
- - Verify the column has a `type` property defined
1032
- - Check that `type` matches a key in `DEFAULT_CELL_TYPES`
1033
- - Remember: `typeValue` is only passed when both `type` and `Cell` are defined
1034
-
1035
- ---
1036
-
1037
- ## Dependencies
1038
-
1039
- This component is built on top of:
1040
- - [Material React Table](https://www.material-react-table.com/) - Core table functionality
1041
- - [MUI (Material-UI)](https://mui.com/) - UI components and styling
1042
- - [Semantic UI React](https://react.semantic-ui.com/) - Additional UI components
1043
- - [Bootstrap](https://getbootstrap.com/) - Base CSS framework
1044
- - [date-fns](https://date-fns.org/) - Date manipulation and formatting
1045
-
1046
- ---
1047
-
1048
- ## License
1049
-
1050
- ISC
1051
-
1
+ # DataGrid Component
2
+
3
+ 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.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Installation](#installation)
8
+ - [Basic Usage](#basic-usage)
9
+ - [Props Reference](#props-reference)
10
+ - [Core Props](#core-props)
11
+ - [Column Configuration](#column-configuration)
12
+ - [Actions & Toolbar](#actions--toolbar)
13
+ - [Export Options](#export-options)
14
+ - [Selection & Interaction](#selection--interaction)
15
+ - [Pagination & Display](#pagination--display)
16
+ - [Styling & Layout](#styling--layout)
17
+ - [Advanced Features](#advanced-features)
18
+ - [Column Types](#column-types)
19
+ - [Examples](#examples)
20
+ - [API Reference](#api-reference)
21
+
22
+ ---
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ npm install @insticc/react-datagrid-2
28
+ ```
29
+
30
+ ### Required Dependencies
31
+
32
+ ```bash
33
+ npm install react prop-types material-react-table semantic-ui-react @mui/material bootstrap
34
+ ```
35
+
36
+ ---
37
+
38
+ ## Basic Usage
39
+
40
+ ```jsx
41
+ import React, { useState } from 'react';
42
+ import { DataGrid } from '@insticc/react-datagrid-2';
43
+
44
+ function MyComponent() {
45
+ const [selectedRows, setSelectedRows] = useState([]);
46
+
47
+ const columns = [
48
+ { accessorKey: 'id', header: 'ID', type: 'text' },
49
+ { accessorKey: 'name', header: 'Name', type: 'text' },
50
+ { accessorKey: 'email', header: 'Email', type: 'email' },
51
+ { accessorKey: 'createdAt', header: 'Created', type: 'date', isDateColumn: true },
52
+ ];
53
+
54
+ const data = [
55
+ { id: '1', name: 'John Doe', email: 'john@example.com', createdAt: '2025-01-15' },
56
+ { id: '2', name: 'Jane Smith', email: 'jane@example.com', createdAt: '2025-02-20' },
57
+ ];
58
+
59
+ return (
60
+ <DataGrid
61
+ columns={columns}
62
+ createRows={data}
63
+ rowKey="id"
64
+ selectData={setSelectedRows}
65
+ hasExcelExport={true}
66
+ hasPdfExport={true}
67
+ />
68
+ );
69
+ }
70
+ ```
71
+
72
+ ---
73
+
74
+ ## Props Reference
75
+
76
+ ### Core Props
77
+
78
+ #### `columns` (required)
79
+ - **Type:** `Array`
80
+ - **Description:** Array of column definitions that determine how data is displayed
81
+ - **Example:**
82
+ ```jsx
83
+ const columns = [
84
+ {
85
+ accessorKey: 'name', // Key to access data
86
+ header: 'Full Name', // Column header text
87
+ type: 'text', // Cell type - formatter applied automatically
88
+ enableSorting: true, // Enable/disable sorting
89
+ enableColumnFilter: true, // Enable/disable filtering
90
+ filterFn: 'contains', // Filter function type
91
+ isDateColumn: false, // Special handling for dates
92
+ cellClass: 'custom-class', // CSS class wrapping cell content
93
+ Cell: CustomComponent, // Optional: Custom cell renderer (receives typeValue)
94
+ }
95
+ ];
96
+ ```
97
+
98
+ **Column Rendering Modes:**
99
+ - `type` only: Formatter applied automatically
100
+ - `type` + `cellClass`: Formatted content wrapped in div
101
+ - `type` + `Cell`: Custom component receives `typeValue` (formatted content)
102
+ - `Cell` only: Full custom rendering without type formatter
103
+
104
+ #### `createRows` (required)
105
+ - **Type:** `Array`
106
+ - **Description:** Array of data objects to display in the grid
107
+ - **Example:**
108
+ ```jsx
109
+ const data = [
110
+ { id: 1, name: 'John', email: 'john@example.com' },
111
+ { id: 2, name: 'Jane', email: 'jane@example.com' }
112
+ ];
113
+ ```
114
+
115
+ #### `rowKey` (required)
116
+ - **Type:** `string`
117
+ - **Description:** Property name used as unique identifier for each row
118
+ - **Default:** `'id'`
119
+ - **Example:** `rowKey="id"` or `rowKey="uuid"`
120
+
121
+ #### `selectData` (required)
122
+ - **Type:** `function`
123
+ - **Description:** Callback function that receives selected rows whenever selection changes
124
+ - **Signature:** `(selectedRows: Array) => void`
125
+ - **Example:**
126
+ ```jsx
127
+ const handleSelection = (rows) => {
128
+ console.log('Selected rows:', rows);
129
+ };
130
+
131
+ <DataGrid selectData={handleSelection} />
132
+ ```
133
+
134
+ ---
135
+
136
+ ### Column Configuration
137
+
138
+ #### `columnVisibilityState`
139
+ - **Type:** `object`
140
+ - **Default:** `{}`
141
+ - **Description:** Controls which columns are visible/hidden
142
+ - **Example:**
143
+ ```jsx
144
+ columnVisibilityState={{
145
+ email: false, // Hide email column
146
+ phone: true // Show phone column
147
+ }}
148
+ ```
149
+
150
+ #### `columnOrder`
151
+ - **Type:** `Array<string>`
152
+ - **Default:** `[]`
153
+ - **Description:** Defines the order of columns by their accessorKey
154
+ - **Example:**
155
+ ```jsx
156
+ columnOrder={['name', 'email', 'id']}
157
+ ```
158
+
159
+ ---
160
+
161
+ ### Actions & Toolbar
162
+
163
+ #### `actions`
164
+ - **Type:** `Array<ActionObject>`
165
+ - **Default:** `null`
166
+ - **Description:** Array of custom action buttons displayed in the toolbar
167
+ - **Action Object Properties:**
168
+ - `name` (string): Button label
169
+ - `function` (function, required): Callback when button is clicked
170
+ - `tooltip` (string): Tooltip text on hover
171
+ - `color` (string): Button color - one of: `'blue'`, `'red'`, `'green'`, `'yellow'`, `'orange'`, `'black'`, `'grey'`, `'teal'`, `'brown'`, `'violet'`, `'purple'`, `'olive'`, `'pink'`
172
+ - `icon` (string|element): Icon name or React element
173
+ - `selectionMode` (string): When button is enabled - `'single'`, `'multi'`, `'always'`
174
+ - `confirmMessage` (string|element): Confirmation message before action
175
+ - `hasConfirmMessage` (boolean): Whether to show confirmation dialog
176
+ - `disabled` (boolean): Disable the button
177
+ - `visible` (boolean): Show/hide the button
178
+ - `toggle` (boolean): Toggle button style
179
+ - `active` (boolean): Toggle button active state
180
+ - **Example:**
181
+ ```jsx
182
+ actions={[
183
+ {
184
+ name: 'Delete',
185
+ function: (selectedRows) => handleDelete(selectedRows),
186
+ tooltip: 'Delete selected rows',
187
+ color: 'red',
188
+ icon: 'trash',
189
+ selectionMode: 'multi',
190
+ hasConfirmMessage: true,
191
+ confirmMessage: 'Are you sure you want to delete these rows?'
192
+ },
193
+ {
194
+ name: 'Edit',
195
+ function: (selectedRows) => handleEdit(selectedRows),
196
+ tooltip: 'Edit selected row',
197
+ color: 'blue',
198
+ icon: 'edit',
199
+ selectionMode: 'single'
200
+ },
201
+ {
202
+ name: 'Add New',
203
+ function: () => handleAdd(),
204
+ tooltip: 'Add new record',
205
+ color: 'green',
206
+ icon: 'plus',
207
+ selectionMode: 'always'
208
+ }
209
+ ]}
210
+ ```
211
+
212
+ #### `enableTopToolbar`
213
+ - **Type:** `boolean`
214
+ - **Default:** `true`
215
+ - **Description:** Show/hide the top toolbar containing actions and pagination
216
+
217
+ #### `enableBottomToolbar`
218
+ - **Type:** `boolean`
219
+ - **Default:** `false`
220
+ - **Description:** Show/hide the bottom toolbar
221
+
222
+ #### `hasClearFiltersBtn`
223
+ - **Type:** `boolean`
224
+ - **Default:** `true`
225
+ - **Description:** Show/hide the "Clear Filters" button in toolbar
226
+
227
+ #### `gridHelper`
228
+ - **Type:** `object | null`
229
+ - **Default:** `null`
230
+ - **Description:** Adds a help button with custom content
231
+ - **Required Properties (if defined):**
232
+ - `title` (string|element, required): Help dialog title
233
+ - `content` (string|element, required): Help dialog content
234
+ - **Example:**
235
+ ```jsx
236
+ gridHelper={{
237
+ title: 'Grid Instructions',
238
+ content: (
239
+ <div>
240
+ <p>Use the filters to search data</p>
241
+ <p>Click rows to select them</p>
242
+ </div>
243
+ )
244
+ }}
245
+ ```
246
+
247
+ ---
248
+
249
+ ### Export Options
250
+
251
+ #### `hasExcelExport`
252
+ - **Type:** `boolean`
253
+ - **Default:** `false`
254
+ - **Description:** Enable Excel export button
255
+
256
+ #### `hasPdfExport`
257
+ - **Type:** `boolean`
258
+ - **Default:** `false`
259
+ - **Description:** Enable PDF export button
260
+
261
+ #### `pdfOption`
262
+ - **Type:** `string`
263
+ - **Default:** `'selectedRows'`
264
+ - **Options:** `'all'`, `'allRows'`, `'pageRows'`, `'selectedRows'`
265
+ - **Description:** Determines which rows to export to PDF
266
+
267
+ **Export Options Explained:**
268
+ - `'all'` - Export all data including hidden columns
269
+ - `'allRows'` - Export all rows (respects filters)
270
+ - `'pageRows'` - Export only current page rows
271
+ - `'selectedRows'` - Export only selected rows
272
+
273
+ ---
274
+
275
+ ### Selection & Interaction
276
+
277
+ #### `disableSelect`
278
+ - **Type:** `boolean`
279
+ - **Default:** `false`
280
+ - **Description:** Disable row selection checkboxes and click-to-select behavior completely
281
+
282
+ #### `enableMultiRowSelection`
283
+ - **Type:** `boolean`
284
+ - **Default:** `true`
285
+ - **Description:** Allow selecting multiple rows at once
286
+
287
+ #### `selectAllMode`
288
+ - **Type:** `string`
289
+ - **Default:** `'page'`
290
+ - **Options:** `'page'`, `'all'`
291
+ - **Description:**
292
+ - `'page'` - "Select All" checkbox selects only current page
293
+ - `'all'` - "Select All" checkbox selects all filtered rows
294
+
295
+ #### `selectedIds`
296
+ - **Type:** `Array`
297
+ - **Default:** `[]`
298
+ - **Description:** Array of row IDs that should be pre-selected
299
+ - **Example:**
300
+ ```jsx
301
+ selectedIds={[1, 5, 10]} // Pre-select rows with these IDs
302
+ ```
303
+
304
+ #### `disableRows`
305
+ - **Type:** `Array`
306
+ - **Default:** `[]`
307
+ - **Description:** Array of row IDs that should be disabled (cannot be selected)
308
+ - **Example:**
309
+ ```jsx
310
+ disableRows={[3, 7]} // Disable selection for these rows
311
+ ```
312
+
313
+ #### `hasSubRows`
314
+ - **Type:** `boolean`
315
+ - **Default:** `false`
316
+ - **Description:** Enable support for hierarchical/nested rows
317
+ - **Note:** Requires data with `subRows` property
318
+
319
+ #### `enableExpanding`
320
+ - **Type:** `boolean`
321
+ - **Default:** `false`
322
+ - **Description:** Show expand/collapse icons for rows with subRows
323
+
324
+ ---
325
+
326
+ ### Pagination & Display
327
+
328
+ #### `enablePagination`
329
+ - **Type:** `boolean`
330
+ - **Default:** `true`
331
+ - **Description:** Enable/disable pagination
332
+
333
+ #### `pagination`
334
+ - **Type:** `string`
335
+ - **Default:** `'both'`
336
+ - **Options:** `'top'`, `'bottom'`, `'both'`
337
+ - **Description:** Position of pagination controls
338
+
339
+ #### `pageSize`
340
+ - **Type:** `number`
341
+ - **Default:** `150`
342
+ - **Description:** Number of rows per page initially
343
+
344
+ #### `itemsPerPage`
345
+ - **Type:** `Array<number>`
346
+ - **Default:** `[50, 100, 150]`
347
+ - **Description:** Options for rows per page dropdown
348
+ - **Example:**
349
+ ```jsx
350
+ itemsPerPage={[10, 25, 50, 100]}
351
+ ```
352
+
353
+ ---
354
+
355
+ ### Styling & Layout
356
+
357
+ #### `rowHeight`
358
+ - **Type:** `number`
359
+ - **Default:** `75`
360
+ - **Description:** Minimum height of each row in pixels
361
+
362
+ #### `fontSize`
363
+ - **Type:** `number`
364
+ - **Default:** `14`
365
+ - **Description:** Base font size for grid content in pixels
366
+
367
+ #### `gridHeight`
368
+ - **Type:** `number | string`
369
+ - **Default:** `600`
370
+ - **Description:** Maximum height of the grid container
371
+ - **Examples:**
372
+ ```jsx
373
+ gridHeight={600} // 600px
374
+ gridHeight="80vh" // 80% of viewport height
375
+ gridHeight="fit-content" // Auto height
376
+ ```
377
+
378
+ #### `enableCompactStyleMode`
379
+ - **Type:** `boolean`
380
+ - **Default:** `false`
381
+ - **Description:** Enable compact styling with reduced padding and responsive font sizes
382
+ - **Features:**
383
+ - Smaller cell padding (2px vs auto)
384
+ - Responsive font sizing using clamp()
385
+ - Optimized for dense data display
386
+
387
+ #### `getRowStyle`
388
+ - **Type:** `function`
389
+ - **Description:** Custom function to apply styles to rows based on data
390
+ - **Signature:** `({ row }) => object`
391
+ - **Example:**
392
+ ```jsx
393
+ getRowStyle={({ row }) => ({
394
+ backgroundColor: row.original.status === 'active' ? '#e8f5e9' : 'white',
395
+ color: row.original.priority === 'high' ? 'red' : 'inherit'
396
+ })}
397
+ ```
398
+
399
+ #### `enableFixedHeader`
400
+ - **Type:** `boolean`
401
+ - **Default:** `true`
402
+ - **Description:** Pin headers to top when scrolling
403
+
404
+ #### `enableFixedActions`
405
+ - **Type:** `boolean`
406
+ - **Default:** `false`
407
+ - **Description:** Pin action toolbar to top when scrolling (requires enableFixedHeader)
408
+
409
+ ---
410
+
411
+ ### Advanced Features
412
+
413
+ #### `enableGlobalFilter`
414
+ - **Type:** `boolean`
415
+ - **Default:** `false`
416
+ - **Description:** Show global search input that filters all columns
417
+
418
+ #### `globalFilterFn`
419
+ - **Type:** `string`
420
+ - **Default:** `'contains'`
421
+ - **Options:** `'contains'`, `'fuzzy'`, `'between'`, `'equals'`, `'greaterThan'`, `'lessThan'`, `'notEquals'`, `'lessThanOrEqualTo'`, `'greaterThanOrEqualTo'`, `'empty'`, `'notEmpty'`, `'startsWith'`, `'endsWith'`, `'betweenInclusive'`
422
+ - **Description:** Filter function for global search
423
+
424
+ #### `enableColumnFilterModes`
425
+ - **Type:** `boolean`
426
+ - **Default:** `true`
427
+ - **Description:** Allow users to change filter type per column (contains, equals, etc.)
428
+
429
+ #### `enableVirtualization`
430
+ - **Type:** `boolean`
431
+ - **Default:** `false`
432
+ - **Description:** Enable row and column virtualization for large datasets (improves performance)
433
+ - **Recommended for:** 1000+ rows
434
+
435
+ #### `enableFullScreenToggle`
436
+ - **Type:** `boolean`
437
+ - **Default:** `false`
438
+ - **Description:** Show fullscreen toggle button
439
+
440
+ #### `enableDensityToggle`
441
+ - **Type:** `boolean`
442
+ - **Default:** `false`
443
+ - **Description:** Show density toggle button (compact/comfortable/spacious)
444
+
445
+ ---
446
+
447
+ ### Cache & Updates
448
+
449
+ #### `updateCache`
450
+ - **Type:** `function`
451
+ - **Default:** `undefined`
452
+ - **Description:** Callback function triggered when cache update button is clicked
453
+ - **Example:**
454
+ ```jsx
455
+ updateCache={() => {
456
+ fetchLatestData();
457
+ }}
458
+ ```
459
+
460
+ #### `cacheUpdateText`
461
+ - **Type:** `string`
462
+ - **Default:** `undefined`
463
+ - **Description:** Tooltip text for cache update button
464
+ - **Example:** `"Refresh data from server"`
465
+
466
+ #### `cacheUpdating`
467
+ - **Type:** `boolean`
468
+ - **Default:** `false`
469
+ - **Description:** Shows loading state on cache update button
470
+
471
+ ---
472
+
473
+ ### Callbacks
474
+
475
+ #### `onVisibleRowsChange`
476
+ - **Type:** `function`
477
+ - **Description:** Called whenever visible rows change (filtering, sorting, pagination)
478
+ - **Signature:** `(visibleRows: Array) => void`
479
+ - **Example:**
480
+ ```jsx
481
+ onVisibleRowsChange={(rows) => {
482
+ console.log('Currently visible:', rows.length);
483
+ }}
484
+ ```
485
+
486
+ ---
487
+
488
+ ## Column Types
489
+
490
+ The DataGrid supports various pre-built cell types via the `type` property in column definitions:
491
+
492
+ ### Text Types
493
+ - `text` - Plain text
494
+ - `textTitle` - Bold text
495
+ - `textDescription` - Gray text (#666)
496
+ - `textSmall` - Small font text
497
+
498
+ ### Date Types
499
+ - `date` - Date only (no time)
500
+ - `datetime` - Date with time
501
+
502
+ ### Number Types
503
+ - `number` - Raw number
504
+ - `integer` - Rounded integer
505
+ - `currency` - EUR currency format (€1,234.56)
506
+ - `percentage` - Percentage format (12.34%)
507
+
508
+ ### Link Types
509
+ - `email` - Clickable mailto link
510
+ - `phone` - Clickable tel link
511
+ - `link` - External link (opens in new tab)
512
+
513
+ ### Complex Types
514
+ - `array` - Comma-separated array values
515
+ - `json` - Formatted JSON display
516
+ - `countryFlag` - Country flag image (requires ISO2 code)
517
+ - `persons` - List of persons with "et al." notation
518
+
519
+ ### Example with Types
520
+
521
+ ```jsx
522
+ const columns = [
523
+ { accessorKey: 'name', header: 'Name', type: 'textTitle' },
524
+ { accessorKey: 'description', header: 'Description', type: 'textDescription' },
525
+ { accessorKey: 'email', header: 'Email', type: 'email' },
526
+ { accessorKey: 'salary', header: 'Salary', type: 'currency' },
527
+ { accessorKey: 'completion', header: 'Progress', type: 'percentage' },
528
+ { accessorKey: 'createdAt', header: 'Created', type: 'date', isDateColumn: true },
529
+ { accessorKey: 'country', header: 'Country', type: 'countryFlag' },
530
+ { accessorKey: 'tags', header: 'Tags', type: 'array' },
531
+ ];
532
+ ```
533
+
534
+ ### Custom Cell Renderers with Type Support
535
+
536
+ You have multiple options for cell rendering:
537
+
538
+ #### Option 1: Using Type Alone (Simplest)
539
+ ```jsx
540
+ const columns = [
541
+ {
542
+ accessorKey: 'price',
543
+ header: 'Price',
544
+ type: 'currency' // Automatically formatted as currency
545
+ }
546
+ ];
547
+ // No custom Cell needed - formatter is applied automatically
548
+ ```
549
+
550
+ #### Option 2: Type + cellClass
551
+ ```jsx
552
+ const columns = [
553
+ {
554
+ accessorKey: 'status',
555
+ header: 'Status',
556
+ type: 'text',
557
+ cellClass: 'custom-status' // Formatted text wrapped in <div class="custom-status">
558
+ }
559
+ ];
560
+ ```
561
+
562
+ #### Option 3: Type + Custom Cell (Advanced)
563
+ When you need both formatting AND custom logic:
564
+
565
+ ```jsx
566
+ // Custom cell that uses the type formatter and adds custom styling
567
+ const CustomStatusCell = ({ typeValue, cell, row }) => {
568
+ const value = cell.getValue();
569
+
570
+ return (
571
+ <div style={{
572
+ color: value === 'active' ? 'green' : 'red',
573
+ fontWeight: 'bold'
574
+ }}>
575
+ {typeValue || value} {/* Use typeValue (formatted) or fallback to raw value */}
576
+ </div>
577
+ );
578
+ };
579
+
580
+ const columns = [
581
+ {
582
+ accessorKey: 'status',
583
+ header: 'Status',
584
+ type: 'text', // Formatter is applied first
585
+ Cell: CustomStatusCell, // Custom component receives typeValue prop
586
+ }
587
+ ];
588
+ ```
589
+
590
+ #### Option 4: Custom Cell Only (No Type)
591
+ ```jsx
592
+ const CustomCell = ({ cell }) => {
593
+ return <strong>{cell.getValue()}</strong>;
594
+ };
595
+
596
+ const columns = [
597
+ {
598
+ accessorKey: 'name',
599
+ header: 'Name',
600
+ Cell: CustomCell // No type - full control over rendering
601
+ }
602
+ ];
603
+ ```
604
+
605
+ **How Cell Rendering Works:**
606
+ 1. If `type` is specified, `DEFAULT_CELL_TYPES[type]` formatter is applied automatically
607
+ 2. If `Cell` component is also provided, it receives all props including `typeValue` (the formatted result)
608
+ 3. If `cellClass` is specified, content is wrapped in `<div className={cellClass}>`
609
+ 4. Priority: Custom Cell (with typeValue) > Type formatter > Raw value
610
+
611
+ **Note:** You can use `type` alone without a custom `Cell` component - the formatter will be applied automatically.
612
+
613
+ ---
614
+
615
+ ## Examples
616
+
617
+ ### Example 1: Basic Grid with Selection
618
+
619
+ ```jsx
620
+ import React, { useState } from 'react';
621
+ import DataGrid from '@insticc/react-datagrid-2';
622
+
623
+ function UserGrid() {
624
+ const [selected, setSelected] = useState([]);
625
+
626
+ const columns = [
627
+ { accessorKey: 'id', header: 'ID', type: 'integer' },
628
+ { accessorKey: 'name', header: 'Name', type: 'textTitle' },
629
+ { accessorKey: 'email', header: 'Email', type: 'email' },
630
+ { accessorKey: 'role', header: 'Role', type: 'text' },
631
+ ];
632
+
633
+ const users = [
634
+ { id: 1, name: 'John Doe', email: 'john@company.com', role: 'Admin' },
635
+ { id: 2, name: 'Jane Smith', email: 'jane@company.com', role: 'User' },
636
+ ];
637
+
638
+ return (
639
+ <DataGrid
640
+ columns={columns}
641
+ createRows={users}
642
+ rowKey="id"
643
+ selectData={setSelected}
644
+ pageSize={50}
645
+ itemsPerPage={[25, 50, 100]}
646
+ />
647
+ );
648
+ }
649
+ ```
650
+
651
+ ### Example 2: Grid with Actions and Exports
652
+
653
+ ```jsx
654
+ function ProductGrid() {
655
+ const handleDelete = (rows) => {
656
+ const ids = rows.map(r => r.id);
657
+ console.log('Deleting:', ids);
658
+ };
659
+
660
+ const handleEdit = (rows) => {
661
+ if (rows.length === 1) {
662
+ console.log('Editing:', rows[0]);
663
+ }
664
+ };
665
+
666
+ const actions = [
667
+ {
668
+ name: 'Delete',
669
+ function: handleDelete,
670
+ tooltip: 'Delete selected products',
671
+ color: 'red',
672
+ icon: 'trash',
673
+ selectionMode: 'multi',
674
+ hasConfirmMessage: true,
675
+ confirmMessage: 'Are you sure you want to delete these products?'
676
+ },
677
+ {
678
+ name: 'Edit',
679
+ function: handleEdit,
680
+ tooltip: 'Edit product',
681
+ color: 'blue',
682
+ icon: 'edit',
683
+ selectionMode: 'single'
684
+ }
685
+ ];
686
+
687
+ return (
688
+ <DataGrid
689
+ columns={productColumns}
690
+ createRows={products}
691
+ rowKey="productId"
692
+ selectData={setSelected}
693
+ actions={actions}
694
+ hasExcelExport={true}
695
+ hasPdfExport={true}
696
+ />
697
+ );
698
+ }
699
+ ```
700
+
701
+ ### Example 3: Hierarchical Data with SubRows
702
+
703
+ ```jsx
704
+ function ProjectGrid() {
705
+ const data = [
706
+ {
707
+ id: 1,
708
+ name: 'Project Alpha',
709
+ status: 'Active',
710
+ subRows: [
711
+ { id: '1.1', name: 'Task 1', status: 'Complete' },
712
+ { id: '1.2', name: 'Task 2', status: 'In Progress' }
713
+ ]
714
+ },
715
+ {
716
+ id: 2,
717
+ name: 'Project Beta',
718
+ status: 'Planning',
719
+ subRows: [
720
+ { id: '2.1', name: 'Task 1', status: 'Not Started' }
721
+ ]
722
+ }
723
+ ];
724
+
725
+ return (
726
+ <DataGrid
727
+ columns={projectColumns}
728
+ createRows={data}
729
+ rowKey="id"
730
+ selectData={setSelected}
731
+ hasSubRows={true}
732
+ enableExpanding={true}
733
+ />
734
+ );
735
+ }
736
+ ```
737
+
738
+ ### Example 4: Custom Styling and Virtualization
739
+
740
+ ```jsx
741
+ function LargeDataGrid() {
742
+ // Custom cell with type support
743
+ const StatusCell = ({ typeValue, cell }) => {
744
+ const value = cell.getValue();
745
+ const color = value === 'active' ? 'green' : 'red';
746
+
747
+ return (
748
+ <span style={{ color, fontWeight: 'bold' }}>
749
+ {typeValue || value}
750
+ </span>
751
+ );
752
+ };
753
+
754
+ const getRowStyle = ({ row }) => {
755
+ if (row.original.status === 'error') {
756
+ return { backgroundColor: '#ffebee' };
757
+ }
758
+ if (row.original.priority === 'high') {
759
+ return { backgroundColor: '#fff3e0' };
760
+ }
761
+ return {};
762
+ };
763
+
764
+ const columns = [
765
+ { accessorKey: 'id', header: 'ID', type: 'integer' },
766
+ {
767
+ accessorKey: 'status',
768
+ header: 'Status',
769
+ type: 'text', // Formatter applied
770
+ Cell: StatusCell // Custom cell receives typeValue
771
+ },
772
+ { accessorKey: 'name', header: 'Name', type: 'text' },
773
+ ];
774
+
775
+ return (
776
+ <DataGrid
777
+ columns={columns}
778
+ createRows={largeDataset} // 10000+ rows
779
+ rowKey="id"
780
+ selectData={setSelected}
781
+ enableVirtualization={true}
782
+ enableCompactStyleMode={true}
783
+ rowHeight={40}
784
+ fontSize={12}
785
+ gridHeight="calc(100vh - 200px)"
786
+ getRowStyle={getRowStyle}
787
+ pageSize={100}
788
+ />
789
+ );
790
+ }
791
+ ```
792
+
793
+ ### Example 5: Advanced Features
794
+
795
+ ```jsx
796
+ function AdvancedGrid() {
797
+ const [cacheLoading, setCacheLoading] = useState(false);
798
+
799
+ const refreshData = async () => {
800
+ setCacheLoading(true);
801
+ await fetchLatestData();
802
+ setCacheLoading(false);
803
+ };
804
+
805
+ const handleVisibleRowsChange = (rows) => {
806
+ console.log('Visible rows count:', rows.length);
807
+ };
808
+
809
+ return (
810
+ <DataGrid
811
+ columns={columns}
812
+ createRows={data}
813
+ rowKey="id"
814
+ selectData={setSelected}
815
+
816
+ // Advanced features
817
+ enableGlobalFilter={true}
818
+ globalFilterFn="fuzzy"
819
+ enableColumnFilterModes={true}
820
+ enableFixedHeader={true}
821
+ enableFixedActions={true}
822
+
823
+ // Cache management
824
+ updateCache={refreshData}
825
+ cacheUpdateText="Refresh data from server"
826
+ cacheUpdating={cacheLoading}
827
+
828
+ // Callbacks
829
+ onVisibleRowsChange={handleVisibleRowsChange}
830
+
831
+ // Help
832
+ gridHelper={{
833
+ title: 'Data Grid Help',
834
+ content: (
835
+ <div>
836
+ <h3>Features</h3>
837
+ <ul>
838
+ <li>Click rows to select</li>
839
+ <li>Use column filters for search</li>
840
+ <li>Export to Excel or PDF</li>
841
+ </ul>
842
+ </div>
843
+ )
844
+ }}
845
+ />
846
+ );
847
+ }
848
+ ```
849
+
850
+ ---
851
+
852
+ ## API Reference
853
+
854
+ ### Column Definition Object
855
+
856
+ ```typescript
857
+ {
858
+ accessorKey: string; // Required: Key to access data
859
+ header: string; // Required: Column header text
860
+ type?: string; // Cell type (see Column Types)
861
+ enableSorting?: boolean; // Default: true
862
+ enableColumnFilter?: boolean; // Default: true
863
+ enableColumnFilterModes?: boolean;// Default: true
864
+ filterFn?: string; // Default: 'contains'
865
+ enableResizing?: boolean; // Default: true
866
+ grow?: boolean; // Default: true
867
+ enableClickToCopy?: boolean; // Default: false
868
+ enableColumnActions?: boolean; // Default: false
869
+ isDateColumn?: boolean; // Special date handling
870
+ sortingFn?: function; // Custom sorting function
871
+ Cell?: Component; // Custom cell renderer (receives typeValue prop)
872
+ cellClass?: string; // CSS class wrapping cell content
873
+ locale?: string; // Locale for date/number formatting
874
+ onlyFlag?: boolean; // For countryFlag type
875
+ columnDef?: object; // Additional metadata
876
+ }
877
+ ```
878
+
879
+ **Cell Rendering Priority:**
880
+ 1. If `type` is defined: `DEFAULT_CELL_TYPES[type]` formatter is applied first (becomes `content`)
881
+ 2. If `Cell` is also defined: Custom component receives `typeValue` (the formatted result) and can override `content`
882
+ 3. If only `Cell` is defined (no `type`): Custom component has full control
883
+ 4. If `cellClass` is defined: Final content is wrapped in `<div className={cellClass}>`
884
+
885
+ **Rendering Flow:**
886
+ ```
887
+ Raw Value → [type formatter] → content → [Custom Cell] content → [cellClass wrapper] → Final Output
888
+ ```
889
+
890
+ ### Action Object
891
+
892
+ ```typescript
893
+ {
894
+ name: string; // Button label
895
+ function: (selectedRows) => void; // Required: Click handler
896
+ tooltip?: string; // Hover tooltip
897
+ color?: string; // Button color
898
+ icon?: string | element; // Button icon
899
+ selectionMode?: 'single' | 'multi' | 'always';
900
+ confirmMessage?: string | element;
901
+ hasConfirmMessage?: boolean;
902
+ disabled?: boolean;
903
+ visible?: boolean;
904
+ toggle?: boolean;
905
+ active?: boolean;
906
+ key?: string; // Unique key for React
907
+ }
908
+ ```
909
+
910
+ ---
911
+
912
+ ## Performance Tips
913
+
914
+ 1. **Use Virtualization for Large Datasets**
915
+ ```jsx
916
+ enableVirtualization={true} // For 1000+ rows
917
+ ```
918
+
919
+ 2. **Optimize Row Height**
920
+ ```jsx
921
+ rowHeight={40} // Smaller = more rows visible
922
+ ```
923
+
924
+ 3. **Disable Unused Features**
925
+ ```jsx
926
+ enableDensityToggle={false}
927
+ enableFullScreenToggle={false}
928
+ enableGlobalFilter={false}
929
+ ```
930
+
931
+ 4. **Use Compact Mode**
932
+ ```jsx
933
+ enableCompactStyleMode={true}
934
+ fontSize={12}
935
+ ```
936
+
937
+ 5. **Limit Initial Page Size**
938
+ ```jsx
939
+ pageSize={50} // Don't render too many rows initially
940
+ ```
941
+
942
+ 6. **Pre-select Rows Carefully**
943
+ ```jsx
944
+ // Only include necessary IDs
945
+ selectedIds={criticalIds} // vs selecting all rows
946
+ ```
947
+
948
+ 7. **Optimize Custom Cell Renderers**
949
+ ```jsx
950
+ // Use typeValue when available to avoid re-computing
951
+ const MyCell = ({ typeValue, cell }) => {
952
+ return typeValue || cell.getValue(); // Prefer typeValue
953
+ };
954
+ ```
955
+
956
+ ---
957
+
958
+ ## Browser Support
959
+
960
+ - Chrome (latest)
961
+ - Firefox (latest)
962
+ - Safari (latest)
963
+ - Edge (latest)
964
+
965
+ ---
966
+
967
+ ## Important Notes
968
+
969
+ ### Row Selection Behavior
970
+ - **Click-to-select:** When `disableSelect={false}`, clicking anywhere on a row will toggle its selection
971
+ - **Single selection mode:** Clicking a row deselects all other rows and selects only the clicked row
972
+ - **Checkbox behavior:** For multi-row selection, use the checkboxes in combination with `enableMultiRowSelection={true}`
973
+ - The selection state is controlled by `rowSelection` and updates through the `selectData` callback
974
+
975
+ ### Fixed Header and Actions
976
+ - `enableFixedHeader` pins the column headers when scrolling
977
+ - `enableFixedActions` (requires `enableFixedHeader={true}`) also pins the action toolbar
978
+ - Both features use CSS positioning and may require adjustments based on your page layout
979
+
980
+ ### Date Columns
981
+ - Columns with `isDateColumn={true}` get automatic date-aware sorting
982
+ - Use the `type` prop (`'date'` or `'datetime'`) to format date display
983
+ - The `locale` prop on columns controls date formatting (default: 'pt-PT')
984
+
985
+ ### LocalizationProvider
986
+ 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.
987
+
988
+ ---
989
+
990
+ ## Troubleshooting
991
+
992
+ ### Common Issues
993
+
994
+ **Issue: Rows not selecting when clicked**
995
+ - Check that `disableSelect={false}` (default)
996
+ - Verify `selectData` callback is provided
997
+ - Ensure `rowKey` matches your data's unique identifier
998
+
999
+ **Issue: Date columns not sorting correctly**
1000
+ - Set `isDateColumn={true}` on date columns
1001
+ - Ensure date values are in a valid format (ISO 8601 recommended)
1002
+
1003
+ **Issue: Fixed headers not working**
1004
+ - Set `enableFixedHeader={true}`
1005
+ - Check that `gridHeight` is set to a specific value (not 'fit-content')
1006
+ - For fixed actions, also set `enableFixedActions={true}`
1007
+
1008
+ **Issue: Selection state not syncing with parent component**
1009
+ - Use the `selectedIds` prop to control selection from parent
1010
+ - The component will auto-sync when `selectedIds` changes
1011
+
1012
+ **Issue: Export buttons not appearing**
1013
+ - Set `hasExcelExport={true}` and/or `hasPdfExport={true}`
1014
+ - Check that action buttons have enough space in the toolbar
1015
+
1016
+ **Issue: Type formatter not working**
1017
+ - Verify column has `type` property defined
1018
+ - Check that `type` value matches a key in `DEFAULT_CELL_TYPES` (e.g., 'text', 'date', 'currency')
1019
+ - The formatter is applied automatically - no `Cell` component needed
1020
+ - If using a custom `Cell`, the formatted value is in `typeValue` prop
1021
+
1022
+ **Issue: Custom Cell component not receiving typeValue**
1023
+ - Verify the column has a `type` property defined
1024
+ - Check that `type` matches a key in `DEFAULT_CELL_TYPES`
1025
+ - Remember: `typeValue` is only passed when both `type` and `Cell` are defined
1026
+
1027
+ ---
1028
+
1029
+ ## Dependencies
1030
+
1031
+ This component is built on top of:
1032
+ - [Material React Table](https://www.material-react-table.com/) - Core table functionality
1033
+ - [MUI (Material-UI)](https://mui.com/) - UI components and styling
1034
+ - [Semantic UI React](https://react.semantic-ui.com/) - Additional UI components
1035
+ - [Bootstrap](https://getbootstrap.com/) - Base CSS framework
1036
+ - [date-fns](https://date-fns.org/) - Date manipulation and formatting
1037
+
1038
+ ---
1039
+
1040
+ ## License
1041
+
1042
+ ISC