@ackplus/react-tanstack-data-table 1.0.19-beta-0.15 → 1.0.20

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 (46) hide show
  1. package/README.md +868 -38
  2. package/package.json +1 -1
  3. package/src/index.d.ts +1 -4
  4. package/src/index.js +2 -9
  5. package/src/lib/components/filters/filter-value-input.d.ts +8 -1
  6. package/src/lib/components/filters/filter-value-input.js +14 -31
  7. package/src/lib/components/headers/draggable-header.d.ts +6 -2
  8. package/src/lib/components/headers/draggable-header.js +42 -50
  9. package/src/lib/components/headers/table-header.d.ts +8 -2
  10. package/src/lib/components/headers/table-header.js +24 -18
  11. package/src/lib/components/pagination/data-table-pagination.d.ts +8 -2
  12. package/src/lib/components/pagination/data-table-pagination.js +27 -15
  13. package/src/lib/components/rows/data-table-row.d.ts +9 -2
  14. package/src/lib/components/rows/data-table-row.js +21 -7
  15. package/src/lib/components/rows/empty-data-row.d.ts +11 -4
  16. package/src/lib/components/rows/empty-data-row.js +14 -2
  17. package/src/lib/components/rows/loading-rows.d.ts +9 -2
  18. package/src/lib/components/rows/loading-rows.js +29 -19
  19. package/src/lib/components/table/data-table.js +27 -32
  20. package/src/lib/components/table/data-table.types.d.ts +0 -18
  21. package/src/lib/components/toolbar/bulk-actions-toolbar.d.ts +9 -3
  22. package/src/lib/components/toolbar/bulk-actions-toolbar.js +15 -10
  23. package/src/lib/components/toolbar/column-filter-control.d.ts +14 -1
  24. package/src/lib/components/toolbar/column-filter-control.js +14 -12
  25. package/src/lib/components/toolbar/column-pinning-control.d.ts +12 -1
  26. package/src/lib/components/toolbar/column-pinning-control.js +24 -42
  27. package/src/lib/components/toolbar/column-reset-control.d.ts +8 -1
  28. package/src/lib/components/toolbar/column-reset-control.js +34 -6
  29. package/src/lib/components/toolbar/column-visibility-control.d.ts +10 -1
  30. package/src/lib/components/toolbar/column-visibility-control.js +7 -7
  31. package/src/lib/components/toolbar/data-table-toolbar.d.ts +9 -2
  32. package/src/lib/components/toolbar/data-table-toolbar.js +15 -2
  33. package/src/lib/components/toolbar/table-export-control.d.ts +7 -1
  34. package/src/lib/components/toolbar/table-export-control.js +24 -68
  35. package/src/lib/components/toolbar/table-search-control.d.ts +12 -1
  36. package/src/lib/components/toolbar/table-search-control.js +24 -11
  37. package/src/lib/components/toolbar/table-size-control.d.ts +9 -1
  38. package/src/lib/components/toolbar/table-size-control.js +17 -9
  39. package/src/lib/examples/index.d.ts +2 -0
  40. package/src/lib/examples/index.js +5 -1
  41. package/src/lib/examples/simple-slots-example.d.ts +1 -0
  42. package/src/lib/examples/simple-slots-example.js +115 -0
  43. package/src/lib/types/data-table-api.d.ts +4 -1
  44. package/src/lib/types/slots.types.d.ts +142 -137
  45. package/src/lib/utils/slot-helpers.d.ts +12 -6
  46. package/src/lib/utils/slot-helpers.js +86 -12
package/README.md CHANGED
@@ -132,7 +132,9 @@ function MyDataTable() {
132
132
  |------|------|---------|-------------|
133
133
  | `enableRowSelection` | `boolean \| ((row) => boolean)` | `false` | Enable row selection |
134
134
  | `enableMultiRowSelection` | `boolean` | `true` | Allow multiple row selection |
135
- | `onRowSelectionChange` | `(selectedRows: T[]) => void` | - | Selection change callback |
135
+ | `selectMode` | `'page' \| 'all'` | `'page'` | Selection scope (page or all data) |
136
+ | `isRowSelectable` | `(params: {row: T, id: string}) => boolean` | - | Control if specific row is selectable |
137
+ | `onSelectionChange` | `(selection: SelectionState) => void` | - | Selection state change callback |
136
138
  | `enableBulkActions` | `boolean` | `false` | Enable bulk actions toolbar |
137
139
  | `bulkActions` | `(selectionState: SelectionState) => ReactNode` | - | Custom bulk actions component |
138
140
 
@@ -158,6 +160,7 @@ This allows for efficient handling of large datasets where you might select "all
158
160
  |------|------|---------|-------------|
159
161
  | `enablePagination` | `boolean` | `true` | Enable pagination |
160
162
  | `paginationMode` | `'client' \| 'server'` | `'client'` | Pagination mode |
163
+ | `onPaginationChange` | `(pagination: PaginationState) => void` | - | Pagination change callback |
161
164
  | `initialState.pagination` | `{pageIndex: number, pageSize: number}` | `{pageIndex: 0, pageSize: 50}` | Initial pagination state |
162
165
 
163
166
  ### Filtering & Search
@@ -167,7 +170,9 @@ This allows for efficient handling of large datasets where you might select "all
167
170
  | `enableGlobalFilter` | `boolean` | `true` | Enable global search |
168
171
  | `enableColumnFilter` | `boolean` | `false` | Enable individual column filters |
169
172
  | `filterMode` | `'client' \| 'server'` | `'client'` | Filtering mode |
170
- | `onColumnFiltersChange` | `(filters) => void` | - | Column filters change callback |
173
+ | `onColumnFiltersChange` | `(filterState: ColumnFilterState) => void` | - | Column filters change callback |
174
+ | `onGlobalFilterChange` | `(globalFilter: string) => void` | - | Global filter change callback |
175
+ | `onColumnFilterChange` | `(columnFilter: ColumnFilterState) => void` | - | Column filter change callback |
171
176
  | `extraFilter` | `ReactNode` | - | Additional filter components |
172
177
 
173
178
  ### Sorting
@@ -184,10 +189,11 @@ This allows for efficient handling of large datasets where you might select "all
184
189
  |------|------|---------|-------------|
185
190
  | `enableColumnVisibility` | `boolean` | `true` | Show/hide columns control |
186
191
  | `enableColumnResizing` | `boolean` | `false` | Allow column resizing |
192
+ | `columnResizeMode` | `ColumnResizeMode` | `'onChange'` | Column resize mode |
187
193
  | `enableColumnPinning` | `boolean` | `false` | Allow column pinning |
188
- | `draggable` | `boolean` | `false` | Enable column reordering |
194
+ | `enableColumnDragging` | `boolean` | `false` | Enable column reordering |
189
195
  | `onColumnDragEnd` | `(order: string[]) => void` | - | Column reorder callback |
190
- | `onColumnPinningChange` | `(pinning) => void` | - | Column pinning callback |
196
+ | `onColumnPinningChange` | `(pinning: ColumnPinningState) => void` | - | Column pinning callback |
191
197
 
192
198
  ### Export Features
193
199
 
@@ -195,12 +201,15 @@ This allows for efficient handling of large datasets where you might select "all
195
201
  |------|------|---------|-------------|
196
202
  | `enableExport` | `boolean` | `true` | Enable data export |
197
203
  | `exportFilename` | `string` | `'export'` | Default export filename |
198
- | `onExportProgress` | `(progress) => void` | - | Export progress callback |
199
- | `onExportComplete` | `(result) => void` | - | Export completion callback |
200
- | `onExportError` | `(error) => void` | - | Export error callback |
201
- | `onServerExport` | `(filters) => Promise<{data, total}>` | - | Server-side export handler |
204
+ | `onExportProgress` | `(progress: {processedRows?, totalRows?, percentage?}) => void` | - | Export progress callback |
205
+ | `onExportComplete` | `(result: {success: boolean, filename: string, totalRows: number}) => void` | - | Export completion callback |
206
+ | `onExportError` | `(error: {message: string, code: string}) => void` | - | Export error callback |
207
+ | `onServerExport` | `(filters?: Partial<TableState>, selection?: SelectionState) => Promise<{data: any[], total: number}>` | - | Server-side export handler |
208
+ | `onExportCancel` | `() => void` | - | Export cancellation callback |
202
209
 
203
- ### Expandable Rows
210
+ ### Expandable Rows (Enhanced Slot System)
211
+
212
+ Expandable rows are now fully integrated with the enhanced slot system, providing better customization and type safety.
204
213
 
205
214
  | Prop | Type | Default | Description |
206
215
  |------|------|---------|-------------|
@@ -208,6 +217,8 @@ This allows for efficient handling of large datasets where you might select "all
208
217
  | `getRowCanExpand` | `(row) => boolean` | - | Determine if row can expand |
209
218
  | `renderSubComponent` | `(row) => ReactNode` | - | Render expanded row content |
210
219
 
220
+ The expanding column is automatically added and can be customized through `slotProps.expandColumn` (see Special Column Configuration section above).
221
+
211
222
  ### Styling & Layout
212
223
 
213
224
  | Prop | Type | Default | Description |
@@ -218,6 +229,8 @@ This allows for efficient handling of large datasets where you might select "all
218
229
  | `fitToScreen` | `boolean` | `true` | Fit table to container width |
219
230
  | `enableStickyHeaderOrFooter` | `boolean` | `false` | Sticky header/footer |
220
231
  | `maxHeight` | `string \| number` | `'400px'` | Max table height |
232
+ | `tableContainerProps` | `object` | `{}` | Props for table container |
233
+ | `tableProps` | `object` | `{}` | Props for table element |
221
234
 
222
235
  ### Virtualization
223
236
 
@@ -232,8 +245,243 @@ This allows for efficient handling of large datasets where you might select "all
232
245
  |------|------|---------|-------------|
233
246
  | `slots` | `Partial<DataTableSlots<T>>` | `{}` | Custom component slots |
234
247
  | `slotProps` | `PartialSlotProps<T>` | `{}` | Props for slot components |
235
- | `tableContainerProps` | `object` | `{}` | Props for table container |
236
- | `tableProps` | `object` | `{}` | Props for table element |
248
+ | `initialState` | `Partial<TableState>` | `{}` | Initial table state |
249
+ | `skeletonRows` | `number` | `5` | Number of skeleton rows for loading state |
250
+ | `footerFilter` | `ReactNode` | - | Additional filter components in footer |
251
+
252
+ ### Special Column Configuration (Enhanced Slot System)
253
+
254
+ Special columns (selection and expanding) are now handled through the enhanced slot system, providing better customization and type safety.
255
+
256
+ #### Selection Column Configuration
257
+
258
+ The selection column is automatically added when `enableRowSelection` is true and can be customized through `slotProps.selectionColumn`:
259
+
260
+ ```tsx
261
+ <DataTable
262
+ data={data}
263
+ columns={columns}
264
+ enableRowSelection
265
+ enableMultiRowSelection
266
+ slotProps={{
267
+ selectionColumn: {
268
+ width: 80,
269
+ pinLeft: true,
270
+ id: 'custom-selection',
271
+ // Custom column configuration
272
+ header: ({ table }) => (
273
+ <Checkbox
274
+ checked={table.getIsAllRowsSelected()}
275
+ indeterminate={table.getIsSomeRowsSelected()}
276
+ onChange={() => table.toggleAllRowsSelected()}
277
+ sx={{ color: 'primary.main' }}
278
+ />
279
+ ),
280
+ cell: ({ row, table }) => (
281
+ <Checkbox
282
+ checked={table.getIsRowSelected(row.id)}
283
+ onChange={() => table.toggleRowSelected(row.id)}
284
+ sx={{ color: 'secondary.main' }}
285
+ />
286
+ ),
287
+ },
288
+ }}
289
+ />
290
+ ```
291
+
292
+ #### Expanding Column Configuration
293
+
294
+ The expanding column is automatically added when `enableExpanding` is true and can be customized through `slotProps.expandColumn`:
295
+
296
+ ```tsx
297
+ <DataTable
298
+ data={data}
299
+ columns={columns}
300
+ enableExpanding
301
+ getRowCanExpand={(row) => row.original.details != null}
302
+ renderSubComponent={(row) => (
303
+ <Box p={2}>
304
+ <Typography variant="h6">Details</Typography>
305
+ <pre>{JSON.stringify(row.original.details, null, 2)}</pre>
306
+ </Box>
307
+ )}
308
+ slotProps={{
309
+ expandColumn: {
310
+ width: 60,
311
+ pinLeft: true,
312
+ id: 'custom-expand',
313
+ // Custom column configuration
314
+ header: 'Expand',
315
+ cell: ({ row }) => (
316
+ <IconButton
317
+ onClick={row.getToggleExpandedHandler()}
318
+ size="small"
319
+ sx={{ color: 'primary.main' }}
320
+ >
321
+ {row.getIsExpanded() ? <ExpandLessIcon /> : <ExpandMoreIcon />}
322
+ </IconButton>
323
+ ),
324
+ },
325
+ }}
326
+ />
327
+ ```
328
+
329
+ #### Advanced Special Column Customization
330
+
331
+ You can completely replace the special column components using the slots system:
332
+
333
+ ```tsx
334
+ import { createSelectionColumn, createExpandingColumn } from '@ackplus/react-tanstack-data-table';
335
+
336
+ function CustomTable() {
337
+ // Create custom selection column
338
+ const customSelectionColumn = createSelectionColumn({
339
+ width: 100,
340
+ pinLeft: true,
341
+ header: ({ table }) => (
342
+ <Tooltip title="Select All">
343
+ <Checkbox
344
+ checked={table.getIsAllRowsSelected()}
345
+ indeterminate={table.getIsSomeRowsSelected()}
346
+ onChange={() => table.toggleAllRowsSelected()}
347
+ sx={{
348
+ color: 'primary.main',
349
+ '&.Mui-checked': { color: 'primary.main' }
350
+ }}
351
+ />
352
+ </Tooltip>
353
+ ),
354
+ cell: ({ row, table }) => (
355
+ <Tooltip title="Select Row">
356
+ <Checkbox
357
+ checked={table.getIsRowSelected(row.id)}
358
+ onChange={() => table.toggleRowSelected(row.id)}
359
+ sx={{
360
+ color: 'secondary.main',
361
+ '&.Mui-checked': { color: 'secondary.main' }
362
+ }}
363
+ />
364
+ </Tooltip>
365
+ ),
366
+ });
367
+
368
+ // Create custom expanding column
369
+ const customExpandingColumn = createExpandingColumn({
370
+ width: 80,
371
+ pinLeft: true,
372
+ header: 'Details',
373
+ cell: ({ row }) => (
374
+ <Tooltip title={row.getIsExpanded() ? "Collapse" : "Expand"}>
375
+ <IconButton
376
+ onClick={row.getToggleExpandedHandler()}
377
+ size="small"
378
+ sx={{
379
+ color: 'primary.main',
380
+ transition: 'transform 0.2s',
381
+ transform: row.getIsExpanded() ? 'rotate(180deg)' : 'rotate(0deg)',
382
+ }}
383
+ >
384
+ <KeyboardArrowDownIcon />
385
+ </IconButton>
386
+ </Tooltip>
387
+ ),
388
+ });
389
+
390
+ return (
391
+ <DataTable
392
+ data={data}
393
+ columns={[customSelectionColumn, customExpandingColumn, ...columns]}
394
+ enableRowSelection
395
+ enableExpanding
396
+ // ... other props
397
+ />
398
+ );
399
+ }
400
+ ```
401
+
402
+ #### Special Column Configuration Options
403
+
404
+ | Property | Type | Default | Description |
405
+ |----------|------|---------|-------------|
406
+ | `width` | `number` | `60` | Column width in pixels |
407
+ | `pinLeft` | `boolean` | `false` | Pin column to the left |
408
+ | `id` | `string` | Auto-generated | Custom column ID |
409
+ | `header` | `ReactNode \| (props) => ReactNode` | Default header | Custom header component |
410
+ | `cell` | `(props) => ReactNode` | Default cell | Custom cell component |
411
+ | `sx` | `SxProps` | `{}` | Custom styling |
412
+ | `className` | `string` | - | Custom CSS class |
413
+ | `style` | `CSSProperties` | - | Custom inline styles |
414
+
415
+ #### Utility Functions for Special Columns
416
+
417
+ The library provides utility functions to create custom special columns:
418
+
419
+ > **Note**: Special columns are now handled through the enhanced slot system instead of table props. This provides better type safety, more customization options, and consistent behavior with the rest of the component system.
420
+
421
+ ```tsx
422
+ import { createSelectionColumn, createExpandingColumn } from '@ackplus/react-tanstack-data-table';
423
+
424
+ // Create a custom selection column
425
+ const customSelectionColumn = createSelectionColumn({
426
+ width: 100,
427
+ pinLeft: true,
428
+ multiSelect: true, // Enable multi-select
429
+ header: ({ table }) => (
430
+ <Tooltip title="Select All Rows">
431
+ <Checkbox
432
+ checked={table.getIsAllRowsSelected()}
433
+ indeterminate={table.getIsSomeRowsSelected()}
434
+ onChange={() => table.toggleAllRowsSelected()}
435
+ sx={{ color: 'primary.main' }}
436
+ />
437
+ </Tooltip>
438
+ ),
439
+ cell: ({ row, table }) => (
440
+ <Tooltip title="Select Row">
441
+ <Checkbox
442
+ checked={table.getIsRowSelected(row.id)}
443
+ onChange={() => table.toggleRowSelected(row.id)}
444
+ sx={{ color: 'secondary.main' }}
445
+ />
446
+ </Tooltip>
447
+ ),
448
+ });
449
+
450
+ // Create a custom expanding column
451
+ const customExpandingColumn = createExpandingColumn({
452
+ width: 80,
453
+ pinLeft: true,
454
+ header: 'Details',
455
+ cell: ({ row }) => (
456
+ <Tooltip title={row.getIsExpanded() ? "Collapse Details" : "Expand Details"}>
457
+ <IconButton
458
+ onClick={row.getToggleExpandedHandler()}
459
+ size="small"
460
+ sx={{
461
+ color: 'primary.main',
462
+ transition: 'all 0.2s ease',
463
+ transform: row.getIsExpanded() ? 'rotate(180deg)' : 'rotate(0deg)',
464
+ '&:hover': {
465
+ backgroundColor: 'primary.light',
466
+ color: 'primary.contrastText',
467
+ },
468
+ }}
469
+ >
470
+ <KeyboardArrowDownIcon />
471
+ </IconButton>
472
+ </Tooltip>
473
+ ),
474
+ });
475
+
476
+ // Use in your table
477
+ <DataTable
478
+ columns={[customSelectionColumn, customExpandingColumn, ...columns]}
479
+ data={data}
480
+ enableRowSelection
481
+ enableExpanding
482
+ // ... other props
483
+ />
484
+ ```
237
485
 
238
486
  ## 🔥 Advanced Examples
239
487
 
@@ -278,9 +526,11 @@ function ServerSideTable() {
278
526
  }
279
527
  ```
280
528
 
281
- ### Row Selection with Bulk Actions
529
+ ### Row Selection with Bulk Actions and Enhanced Slot System
282
530
 
283
531
  ```tsx
532
+ import { CheckCircleIcon, RadioButtonUncheckedIcon } from '@mui/icons-material';
533
+
284
534
  function SelectableTable() {
285
535
  const [selectedUsers, setSelectedUsers] = useState([]);
286
536
 
@@ -322,7 +572,34 @@ function SelectableTable() {
322
572
  enableMultiRowSelection
323
573
  enableBulkActions
324
574
  bulkActions={bulkActions}
325
- onRowSelectionChange={setSelectedUsers}
575
+ onSelectionChange={setSelectedUsers}
576
+ slotProps={{
577
+ selectionColumn: {
578
+ width: 80,
579
+ pinLeft: true,
580
+ header: ({ table }) => (
581
+ <Checkbox
582
+ checked={table.getIsAllRowsSelected()}
583
+ indeterminate={table.getIsSomeRowsSelected()}
584
+ onChange={() => table.toggleAllRowsSelected()}
585
+ sx={{
586
+ color: 'primary.main',
587
+ '&.Mui-checked': { color: 'primary.main' }
588
+ }}
589
+ />
590
+ ),
591
+ cell: ({ row, table }) => (
592
+ <Checkbox
593
+ checked={table.getIsRowSelected(row.id)}
594
+ onChange={() => table.toggleRowSelected(row.id)}
595
+ sx={{
596
+ color: 'secondary.main',
597
+ '&.Mui-checked': { color: 'secondary.main' }
598
+ }}
599
+ />
600
+ ),
601
+ },
602
+ }}
326
603
  />
327
604
  );
328
605
  }
@@ -369,9 +646,11 @@ function FilterableTable() {
369
646
  }
370
647
  ```
371
648
 
372
- ### Expandable Rows
649
+ ### Expandable Rows with Enhanced Slot System
373
650
 
374
651
  ```tsx
652
+ import { ExpandMoreIcon, ExpandLessIcon } from '@mui/icons-material';
653
+
375
654
  function ExpandableTable() {
376
655
  const renderSubComponent = (row) => (
377
656
  <Box p={2}>
@@ -396,6 +675,26 @@ function ExpandableTable() {
396
675
  enableExpanding
397
676
  getRowCanExpand={(row) => row.original.details != null}
398
677
  renderSubComponent={renderSubComponent}
678
+ slotProps={{
679
+ expandColumn: {
680
+ width: 60,
681
+ pinLeft: true,
682
+ header: 'Details',
683
+ cell: ({ row }) => (
684
+ <IconButton
685
+ onClick={row.getToggleExpandedHandler()}
686
+ size="small"
687
+ sx={{
688
+ color: 'primary.main',
689
+ transition: 'transform 0.2s',
690
+ transform: row.getIsExpanded() ? 'rotate(180deg)' : 'rotate(0deg)',
691
+ }}
692
+ >
693
+ {row.getIsExpanded() ? <ExpandLessIcon /> : <ExpandMoreIcon />}
694
+ </IconButton>
695
+ ),
696
+ },
697
+ }}
399
698
  />
400
699
  );
401
700
  }
@@ -487,6 +786,137 @@ interface DataTableColumn<T> extends ColumnDef<T> {
487
786
  }
488
787
  ```
489
788
 
789
+ ### DataTable API
790
+
791
+ The DataTable exposes a comprehensive API through refs for programmatic control:
792
+
793
+ ```tsx
794
+ import { useRef } from 'react';
795
+ import { DataTable, DataTableApi } from '@ackplus/react-tanstack-data-table';
796
+
797
+ function MyComponent() {
798
+ const tableRef = useRef<DataTableApi<User>>(null);
799
+
800
+ const handleGetData = () => {
801
+ const allData = tableRef.current?.data.getAllData();
802
+ };
803
+
804
+ return (
805
+ <DataTable
806
+ ref={tableRef}
807
+ columns={columns}
808
+ data={data}
809
+ />
810
+ );
811
+ }
812
+ ```
813
+
814
+ #### Available API Methods
815
+
816
+ **Column Management:**
817
+ - `columnVisibility.showColumn(columnId)` - Show specific column
818
+ - `columnVisibility.hideColumn(columnId)` - Hide specific column
819
+ - `columnVisibility.toggleColumn(columnId)` - Toggle column visibility
820
+ - `columnVisibility.showAllColumns()` - Show all columns
821
+ - `columnVisibility.hideAllColumns()` - Hide all columns
822
+ - `columnVisibility.resetColumnVisibility()` - Reset to default visibility
823
+
824
+ **Column Ordering:**
825
+ - `columnOrdering.setColumnOrder(order)` - Set column order
826
+ - `columnOrdering.moveColumn(columnId, toIndex)` - Move column to position
827
+ - `columnOrdering.resetColumnOrder()` - Reset to default order
828
+
829
+ **Column Pinning:**
830
+ - `columnPinning.pinColumnLeft(columnId)` - Pin column to left
831
+ - `columnPinning.pinColumnRight(columnId)` - Pin column to right
832
+ - `columnPinning.unpinColumn(columnId)` - Unpin column
833
+ - `columnPinning.setPinning(pinning)` - Set pinning state
834
+ - `columnPinning.resetColumnPinning()` - Reset pinning
835
+
836
+ **Column Resizing:**
837
+ - `columnResizing.resizeColumn(columnId, width)` - Resize column
838
+ - `columnResizing.autoSizeColumn(columnId)` - Auto-size column
839
+ - `columnResizing.autoSizeAllColumns()` - Auto-size all columns
840
+ - `columnResizing.resetColumnSizing()` - Reset column sizing
841
+
842
+ **Filtering:**
843
+ - `filtering.setGlobalFilter(filter)` - Set global filter
844
+ - `filtering.clearGlobalFilter()` - Clear global filter
845
+ - `filtering.setColumnFilters(filters)` - Set column filters
846
+ - `filtering.addColumnFilter(columnId, operator, value)` - Add column filter
847
+ - `filtering.removeColumnFilter(filterId)` - Remove column filter
848
+ - `filtering.clearAllFilters()` - Clear all filters
849
+ - `filtering.resetFilters()` - Reset all filters
850
+
851
+ **Sorting:**
852
+ - `sorting.setSorting(sortingState)` - Set sorting state
853
+ - `sorting.sortColumn(columnId, direction)` - Sort specific column
854
+ - `sorting.clearSorting()` - Clear all sorting
855
+ - `sorting.resetSorting()` - Reset sorting
856
+
857
+ **Pagination:**
858
+ - `pagination.goToPage(pageIndex)` - Go to specific page
859
+ - `pagination.nextPage()` - Go to next page
860
+ - `pagination.previousPage()` - Go to previous page
861
+ - `pagination.setPageSize(pageSize)` - Set page size
862
+ - `pagination.goToFirstPage()` - Go to first page
863
+ - `pagination.goToLastPage()` - Go to last page
864
+
865
+ **Selection:**
866
+ - `selection.selectRow(rowId)` - Select specific row
867
+ - `selection.deselectRow(rowId)` - Deselect specific row
868
+ - `selection.toggleRowSelection(rowId)` - Toggle row selection
869
+ - `selection.selectAll()` - Select all rows
870
+ - `selection.deselectAll()` - Deselect all rows
871
+ - `selection.toggleSelectAll()` - Toggle select all
872
+ - `selection.getSelectionState()` - Get current selection state
873
+ - `selection.getSelectedRows()` - Get selected rows
874
+ - `selection.getSelectedCount()` - Get selected count
875
+ - `selection.isRowSelected(rowId)` - Check if row is selected
876
+
877
+ **Data Management:**
878
+ - `data.refresh()` - Refresh data
879
+ - `data.reload()` - Reload data
880
+ - `data.getAllData()` - Get all data
881
+ - `data.getRowData(rowId)` - Get specific row data
882
+ - `data.getRowByIndex(index)` - Get row by index
883
+ - `data.updateRow(rowId, updates)` - Update specific row
884
+ - `data.updateRowByIndex(index, updates)` - Update row by index
885
+ - `data.insertRow(newRow, index?)` - Insert new row
886
+ - `data.deleteRow(rowId)` - Delete specific row
887
+ - `data.deleteRowByIndex(index)` - Delete row by index
888
+ - `data.deleteSelectedRows()` - Delete selected rows
889
+ - `data.replaceAllData(newData)` - Replace all data
890
+ - `data.updateMultipleRows(updates)` - Update multiple rows
891
+ - `data.insertMultipleRows(newRows, startIndex?)` - Insert multiple rows
892
+ - `data.deleteMultipleRows(rowIds)` - Delete multiple rows
893
+ - `data.updateField(rowId, fieldName, value)` - Update specific field
894
+ - `data.updateFieldByIndex(index, fieldName, value)` - Update field by index
895
+ - `data.findRows(predicate)` - Find rows by predicate
896
+ - `data.findRowIndex(predicate)` - Find row index by predicate
897
+ - `data.getDataCount()` - Get data count
898
+ - `data.getFilteredDataCount()` - Get filtered data count
899
+
900
+ **Layout Management:**
901
+ - `layout.resetLayout()` - Reset layout
902
+ - `layout.resetAll()` - Reset everything
903
+ - `layout.saveLayout()` - Save current layout
904
+ - `layout.restoreLayout(layout)` - Restore saved layout
905
+
906
+ **Export:**
907
+ - `export.exportCSV(options?)` - Export to CSV
908
+ - `export.exportExcel(options?)` - Export to Excel
909
+ - `export.exportServerData(options)` - Server-side export
910
+ - `export.isExporting()` - Check if exporting
911
+ - `export.cancelExport()` - Cancel export
912
+
913
+ **Table State:**
914
+ - `state.getTableState()` - Get current table state
915
+ - `state.getCurrentFilters()` - Get current filters
916
+ - `state.getCurrentSorting()` - Get current sorting
917
+ - `state.getCurrentPagination()` - Get current pagination
918
+ - `state.getCurrentSelection()` - Get current selection
919
+
490
920
  ### useDataTableApi Hook
491
921
 
492
922
  Access the table's imperative API:
@@ -512,46 +942,446 @@ function MyComponent() {
512
942
  }
513
943
  ```
514
944
 
515
- ## 🎨 Customization
945
+ ## 🎨 Enhanced Customization with Slots System
946
+
947
+ The enhanced slot system provides powerful customization capabilities for DataTable components without limitations. This system allows you to override any component with full prop control and proper TypeScript support.
948
+
949
+ ### Key Features
516
950
 
517
- ### Slots System
951
+ - **Full Component Customization**: Replace any component without limitations
952
+ - **Intelligent Prop Merging**: Special handling for `sx`, `style`, and `className` props
953
+ - **Enhanced Type Safety**: Better TypeScript inference and proper component prop typing
954
+ - **Performance Optimized**: Efficient prop merging and component creation
955
+ - **Easy Migration**: Works with existing code while providing enhanced capabilities
518
956
 
519
- Customize any part of the table using the slots system:
957
+ ### Basic Slot Customization
520
958
 
521
959
  ```tsx
522
- const customSlots = {
523
- toolbar: MyCustomToolbar,
524
- pagination: MyCustomPagination,
525
- loadingRow: MyCustomLoadingRow,
526
- emptyRow: MyCustomEmptyRow,
527
- };
960
+ import { DataTable } from '@ackplus/react-tanstack-data-table';
961
+ import { Star as StarIcon } from '@mui/icons-material';
528
962
 
529
- <DataTable
530
- columns={columns}
531
- data={data}
532
- slots={customSlots}
533
- slotProps={{
534
- toolbar: { customProp: 'value' },
535
- pagination: { showFirstLastButtons: true },
536
- }}
537
- />
963
+ // Custom icon component
964
+ const CustomSearchIcon = (props) => (
965
+ <StarIcon {...props} sx={{ color: 'warning.main', ...props.sx }} />
966
+ );
967
+
968
+ function MyTable() {
969
+ return (
970
+ <DataTable
971
+ data={data}
972
+ columns={columns}
973
+ slots={{
974
+ searchIcon: CustomSearchIcon,
975
+ }}
976
+ slotProps={{
977
+ searchIcon: {
978
+ fontSize: 'large',
979
+ sx: {
980
+ animation: 'pulse 2s infinite',
981
+ '@keyframes pulse': {
982
+ '0%': { transform: 'scale(1)' },
983
+ '50%': { transform: 'scale(1.1)' },
984
+ '100%': { transform: 'scale(1)' },
985
+ },
986
+ },
987
+ },
988
+ }}
989
+ />
990
+ );
991
+ }
992
+ ```
993
+
994
+ ### Advanced Component Replacement
995
+
996
+ ```tsx
997
+ import { styled, alpha } from '@mui/material/styles';
998
+
999
+ const CustomToolbar = styled(Box)(({ theme }) => ({
1000
+ display: 'flex',
1001
+ justifyContent: 'space-between',
1002
+ alignItems: 'center',
1003
+ padding: theme.spacing(2),
1004
+ backgroundColor: alpha(theme.palette.primary.main, 0.05),
1005
+ borderRadius: theme.shape.borderRadius,
1006
+ }));
1007
+
1008
+ const CustomSearchInput = styled('input')(({ theme }) => ({
1009
+ padding: theme.spacing(1, 2),
1010
+ border: `1px solid ${theme.palette.divider}`,
1011
+ borderRadius: theme.shape.borderRadius,
1012
+ fontSize: theme.typography.body2.fontSize,
1013
+ '&:focus': {
1014
+ outline: 'none',
1015
+ borderColor: theme.palette.primary.main,
1016
+ boxShadow: `0 0 0 2px ${alpha(theme.palette.primary.main, 0.2)}`,
1017
+ },
1018
+ }));
1019
+
1020
+ function AdvancedTable() {
1021
+ return (
1022
+ <DataTable
1023
+ data={data}
1024
+ columns={columns}
1025
+ slots={{
1026
+ toolbar: CustomToolbar,
1027
+ searchInput: ({ value, onChange, placeholder, ...props }) => (
1028
+ <CustomSearchInput
1029
+ type="text"
1030
+ value={value}
1031
+ onChange={(e) => onChange(e.target.value)}
1032
+ placeholder={placeholder}
1033
+ {...props}
1034
+ />
1035
+ ),
1036
+ }}
1037
+ slotProps={{
1038
+ toolbar: {
1039
+ sx: {
1040
+ background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
1041
+ color: 'white',
1042
+ },
1043
+ },
1044
+ searchInput: {
1045
+ placeholder: 'Search anything...',
1046
+ style: {
1047
+ minWidth: '300px',
1048
+ },
1049
+ },
1050
+ }}
1051
+ />
1052
+ );
1053
+ }
1054
+ ```
1055
+
1056
+ ### Complete Customization Example
1057
+
1058
+ ```tsx
1059
+ function FullyCustomizedTable() {
1060
+ const theme = useTheme();
1061
+
1062
+ return (
1063
+ <DataTable
1064
+ data={data}
1065
+ columns={columns}
1066
+ slots={{
1067
+ // Custom toolbar with complete styling freedom
1068
+ toolbar: CustomToolbar,
1069
+
1070
+ // Custom search input with full control
1071
+ searchInput: ({ value, onChange, placeholder, ...props }) => (
1072
+ <CustomSearchInput
1073
+ type="text"
1074
+ value={value}
1075
+ onChange={(e) => onChange(e.target.value)}
1076
+ placeholder={placeholder || 'Search anything...'}
1077
+ {...props}
1078
+ />
1079
+ ),
1080
+
1081
+ // Custom column visibility control
1082
+ columnVisibilityControl: (props) => {
1083
+ const { table, color, ...buttonProps } = props;
1084
+ return (
1085
+ <CustomButton
1086
+ variant="outlined"
1087
+ startIcon={<VisibilityIcon />}
1088
+ {...buttonProps}
1089
+ >
1090
+ Columns
1091
+ </CustomButton>
1092
+ );
1093
+ },
1094
+
1095
+ // Custom export button
1096
+ exportButton: (props) => {
1097
+ const { table, color, ...buttonProps } = props;
1098
+ return (
1099
+ <CustomButton
1100
+ variant="contained"
1101
+ startIcon={<ExportIcon />}
1102
+ sx={{
1103
+ background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
1104
+ color: 'white',
1105
+ ...buttonProps.sx
1106
+ }}
1107
+ {...buttonProps}
1108
+ >
1109
+ Export Data
1110
+ </CustomButton>
1111
+ );
1112
+ },
1113
+
1114
+ // Custom table with enhanced styling
1115
+ table: ({ children, ...props }) => (
1116
+ <Paper
1117
+ elevation={3}
1118
+ sx={{
1119
+ borderRadius: 2,
1120
+ overflow: 'hidden',
1121
+ border: `2px solid ${theme.palette.primary.main}`,
1122
+ }}
1123
+ >
1124
+ <table {...props} style={{ width: '100%' }}>
1125
+ {children}
1126
+ </table>
1127
+ </Paper>
1128
+ ),
1129
+
1130
+ // Custom row with hover effects
1131
+ row: ({ children, row, ...props }) => (
1132
+ <tr
1133
+ {...props}
1134
+ style={{
1135
+ backgroundColor: row.index % 2 === 0 ? alpha(theme.palette.primary.main, 0.03) : 'transparent',
1136
+ transition: 'background-color 0.2s ease',
1137
+ cursor: 'pointer',
1138
+ ...props.style,
1139
+ }}
1140
+ onMouseEnter={(e) => {
1141
+ e.currentTarget.style.backgroundColor = alpha(theme.palette.primary.main, 0.1);
1142
+ }}
1143
+ onMouseLeave={(e) => {
1144
+ e.currentTarget.style.backgroundColor = row.index % 2 === 0 ? alpha(theme.palette.primary.main, 0.03) : 'transparent';
1145
+ }}
1146
+ >
1147
+ {children}
1148
+ </tr>
1149
+ ),
1150
+ }}
1151
+
1152
+ slotProps={{
1153
+ // Customize toolbar props
1154
+ toolbar: {
1155
+ title: 'Custom Users Table',
1156
+ subtitle: 'Manage your users with enhanced controls',
1157
+ sx: {
1158
+ background: `linear-gradient(135deg, ${alpha(theme.palette.primary.main, 0.1)} 0%, ${alpha(theme.palette.secondary.main, 0.1)} 100%)`,
1159
+ border: `1px solid ${alpha(theme.palette.primary.main, 0.2)}`,
1160
+ },
1161
+ },
1162
+
1163
+ // Customize search input
1164
+ searchInput: {
1165
+ placeholder: 'Search users by name, email, or role...',
1166
+ style: {
1167
+ minWidth: '300px',
1168
+ fontSize: '14px',
1169
+ },
1170
+ },
1171
+
1172
+ // Customize column visibility control
1173
+ columnVisibilityControl: {
1174
+ title: 'Manage Columns',
1175
+ menuSx: {
1176
+ minWidth: 250,
1177
+ maxHeight: 400,
1178
+ },
1179
+ titleSx: {
1180
+ color: theme.palette.primary.main,
1181
+ fontWeight: 'bold',
1182
+ },
1183
+ checkboxProps: {
1184
+ color: 'primary',
1185
+ },
1186
+ },
1187
+
1188
+ // Customize table container
1189
+ tableContainer: {
1190
+ sx: {
1191
+ maxHeight: '600px',
1192
+ '&::-webkit-scrollbar': {
1193
+ width: '8px',
1194
+ },
1195
+ '&::-webkit-scrollbar-track': {
1196
+ backgroundColor: alpha(theme.palette.grey[300], 0.5),
1197
+ borderRadius: '4px',
1198
+ },
1199
+ '&::-webkit-scrollbar-thumb': {
1200
+ backgroundColor: theme.palette.primary.main,
1201
+ borderRadius: '4px',
1202
+ '&:hover': {
1203
+ backgroundColor: theme.palette.primary.dark,
1204
+ },
1205
+ },
1206
+ },
1207
+ },
1208
+
1209
+ // Customize pagination
1210
+ pagination: {
1211
+ rowsPerPageOptions: [10, 25, 50, 100, 300, 500, 1000],
1212
+ sx: {
1213
+ '& .MuiTablePagination-toolbar': {
1214
+ backgroundColor: alpha(theme.palette.primary.main, 0.05),
1215
+ borderTop: `1px solid ${theme.palette.divider}`,
1216
+ },
1217
+ '& .MuiTablePagination-selectLabel, & .MuiTablePagination-displayedRows': {
1218
+ color: theme.palette.primary.main,
1219
+ fontWeight: 'medium',
1220
+ },
1221
+ },
1222
+ },
1223
+ }}
1224
+ />
1225
+ );
1226
+ }
538
1227
  ```
539
1228
 
540
1229
  ### Available Slots
541
1230
 
542
- - `root` - Root container
543
- - `toolbar` - Main toolbar
544
- - `bulkActionsToolbar` - Bulk actions toolbar
545
- - `tableContainer` - Table container
1231
+ #### Container Slots
1232
+ - `root` - Main container
1233
+ - `tableContainer` - Table container wrapper
546
1234
  - `table` - Table element
1235
+
1236
+ #### Header Slots
1237
+ - `toolbar` - Main toolbar
547
1238
  - `header` - Table header
1239
+ - `headerRow` - Header row
1240
+ - `headerCell` - Header cell
1241
+
1242
+ #### Body Slots
548
1243
  - `body` - Table body
549
1244
  - `row` - Table row
550
1245
  - `cell` - Table cell
551
- - `footer` - Table footer
552
- - `pagination` - Pagination component
1246
+
1247
+ #### Control Slots
1248
+ - `searchInput` - Search input component
1249
+ - `columnVisibilityControl` - Column visibility control
1250
+ - `columnCustomFilterControl` - Column filter control
1251
+ - `columnPinningControl` - Column pinning control
1252
+ - `exportButton` - Export button
1253
+ - `resetButton` - Reset button
1254
+ - `tableSizeControl` - Table size control
1255
+ - `bulkActionsToolbar` - Bulk actions toolbar
1256
+
1257
+ #### Icon Slots
1258
+ - `searchIcon` - Search icon
1259
+ - `filterIcon` - Filter icon
1260
+ - `exportIcon` - Export icon
1261
+ - `columnIcon` - Column visibility icon
1262
+ - `resetIcon` - Reset icon
1263
+ - `pinIcon` - Pin column icon
1264
+ - `unpinIcon` - Unpin column icon
1265
+ - `csvIcon` - CSV export icon
1266
+ - `excelIcon` - Excel export icon
1267
+ - `viewComfortableIcon` - Comfortable view icon
1268
+ - `viewCompactIcon` - Compact view icon
1269
+
1270
+ #### Special Slots
553
1271
  - `loadingRow` - Loading state row
554
1272
  - `emptyRow` - Empty state row
1273
+ - `footer` - Table footer
1274
+ - `pagination` - Pagination component
1275
+
1276
+ ### Best Practices
1277
+
1278
+ #### 1. Component Composition
1279
+ ```tsx
1280
+ // Good: Compose components properly
1281
+ const CustomControl = ({ children, ...props }) => (
1282
+ <Box sx={{ display: 'flex', gap: 1 }} {...props}>
1283
+ {children}
1284
+ </Box>
1285
+ );
1286
+
1287
+ // Usage
1288
+ slots={{
1289
+ toolbar: ({ children, ...props }) => (
1290
+ <CustomControl {...props}>
1291
+ {children}
1292
+ </CustomControl>
1293
+ ),
1294
+ }}
1295
+ ```
1296
+
1297
+ #### 2. Prop Forwarding
1298
+ ```tsx
1299
+ // Good: Always forward props
1300
+ const CustomIcon = (props) => (
1301
+ <StarIcon {...props} sx={{ color: 'primary.main', ...props.sx }} />
1302
+ );
1303
+
1304
+ // Bad: Not forwarding props
1305
+ const CustomIcon = () => <StarIcon color="primary" />;
1306
+ ```
1307
+
1308
+ #### 3. TypeScript Support
1309
+ ```tsx
1310
+ // Good: Use proper typing
1311
+ interface CustomButtonProps {
1312
+ onClick?: () => void;
1313
+ children: React.ReactNode;
1314
+ [key: string]: any; // Allow additional props
1315
+ }
1316
+
1317
+ const CustomButton: React.FC<CustomButtonProps> = ({ children, ...props }) => (
1318
+ <Button {...props}>{children}</Button>
1319
+ );
1320
+ ```
1321
+
1322
+ #### 4. Performance Considerations
1323
+ ```tsx
1324
+ // Good: Memoize expensive components
1325
+ const CustomToolbar = React.memo(({ children, ...props }) => (
1326
+ <Box {...props}>{children}</Box>
1327
+ ));
1328
+
1329
+ // Good: Use callbacks for event handlers
1330
+ const handleClick = useCallback(() => {
1331
+ // Handle click
1332
+ }, []);
1333
+ ```
1334
+
1335
+ ### Migration from Basic Slots
1336
+
1337
+ ```tsx
1338
+ // Before
1339
+ <DataTable
1340
+ slots={{
1341
+ searchIcon: MyIcon,
1342
+ }}
1343
+ slotProps={{
1344
+ searchIcon: { color: 'primary' },
1345
+ }}
1346
+ />
1347
+
1348
+ // After (Enhanced)
1349
+ <DataTable
1350
+ slots={{
1351
+ searchIcon: MyIcon,
1352
+ }}
1353
+ slotProps={{
1354
+ searchIcon: {
1355
+ color: 'primary',
1356
+ sx: { fontSize: 20 }, // Now supports sx prop merging
1357
+ },
1358
+ }}
1359
+ />
1360
+ ```
1361
+
1362
+ ### Troubleshooting
1363
+
1364
+ #### Common Issues
1365
+
1366
+ 1. **Props not merging correctly**
1367
+ - Ensure you're using the enhanced slot system
1368
+ - Check prop priority order (user > slot > default)
1369
+
1370
+ 2. **TypeScript errors**
1371
+ - Use `[key: string]: any` for flexible prop interfaces
1372
+ - Ensure proper prop forwarding with spread operator
1373
+ - Filter out incompatible props like `table` and `color` for Button components
1374
+
1375
+ 3. **Styling conflicts**
1376
+ - Check sx prop merging order
1377
+ - Use proper CSS specificity
1378
+
1379
+ 4. **Performance issues**
1380
+ - Memoize expensive components
1381
+ - Use callbacks for event handlers
1382
+ - Avoid inline function definitions
1383
+
1384
+ The enhanced slot system provides unprecedented flexibility for customizing DataTable components. With proper prop merging, full TypeScript support, and intelligent component composition, you can create highly customized tables without limitations.
555
1385
 
556
1386
  ## 🔧 Migration Guide
557
1387