@ackplus/react-tanstack-data-table 1.0.22 → 1.0.23

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.
package/README.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  A powerful, feature-rich, and highly customizable React data table component built with Material-UI (MUI) and TanStack Table. Perfect for building modern data-intensive applications with advanced table functionality.
4
4
 
5
+ ## 🚀 Live Demo
6
+
7
+ **[View Live Demo](https://ack-solutions.github.io/react-tanstack-data-table/)**
8
+
9
+ Experience all the features in action with our interactive demo showcasing advanced table functionality, filtering, sorting, pagination, and more.
10
+
5
11
  ## ✨ Features
6
12
 
7
13
  - 🚀 **High Performance**: Built on TanStack Table for excellent performance with large datasets
@@ -18,6 +24,7 @@ A powerful, feature-rich, and highly customizable React data table component bui
18
24
  - 🎛️ **Highly Customizable**: Extensive customization through slots and props
19
25
  - 📝 **TypeScript**: Full TypeScript support with comprehensive type definitions
20
26
  - 🔌 **Extensible**: Plugin architecture with custom components and hooks
27
+ - 🛠️ **Debug Logging**: Configurable console instrumentation with global or per-table controls
21
28
 
22
29
  ## 📦 Installation
23
30
 
@@ -1359,6 +1366,34 @@ const handleClick = useCallback(() => {
1359
1366
  />
1360
1367
  ```
1361
1368
 
1369
+ ### Logging & Debugging
1370
+
1371
+ Use the built-in logger to trace pagination, server calls, and state transitions without sprinkling `console.log` statements throughout your app.
1372
+
1373
+ ```tsx
1374
+ import { DataTable, configureDataTableLogging } from '@ackplus/react-tanstack-data-table';
1375
+
1376
+ configureDataTableLogging({
1377
+ enabled: true,
1378
+ level: 'debug',
1379
+ includeTimestamp: true,
1380
+ });
1381
+
1382
+ <DataTable
1383
+ columns={columns}
1384
+ data={rows}
1385
+ logging={{
1386
+ enabled: true,
1387
+ level: 'info',
1388
+ prefix: 'OrdersTable',
1389
+ }}
1390
+ />
1391
+ ```
1392
+
1393
+ - Call `configureDataTableLogging` once (for example in your app bootstrap) to set global defaults.
1394
+ - Use the `logging` prop to override settings per table or disable instrumentation for specific instances.
1395
+ - When `logging` is omitted, instances inherit the global configuration.
1396
+
1362
1397
  ### Troubleshooting
1363
1398
 
1364
1399
  #### Common Issues
@@ -1422,6 +1457,7 @@ MIT © [ACK Solutions](https://github.com/ack-solutions)
1422
1457
 
1423
1458
  ## 🆘 Support
1424
1459
 
1460
+ - 🚀 [Live Demo](https://ack-solutions.github.io/react-tanstack-data-table/) - Interactive examples and playground
1425
1461
  - 📖 [Documentation](https://github.com/ack-solutions/react-tanstack-data-table)
1426
1462
  - 🐛 [Issue Tracker](https://github.com/ack-solutions/react-tanstack-data-table/issues)
1427
1463
  - 💬 [Discussions](https://github.com/ack-solutions/react-tanstack-data-table/discussions)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ackplus/react-tanstack-data-table",
3
3
  "type": "commonjs",
4
- "version": "1.0.22",
4
+ "version": "1.0.23",
5
5
  "description": "A powerful React data table component built with MUI and TanStack Table",
6
6
  "keywords": [
7
7
  "react",
package/src/index.d.ts CHANGED
@@ -10,6 +10,7 @@ export type { BulkActionsToolbarProps } from './lib/components/toolbar';
10
10
  export * from './lib/utils/styling-helpers';
11
11
  export * from './lib/utils/column-helpers';
12
12
  export * from './lib/utils/table-helpers';
13
+ export * from './lib/utils/logger';
13
14
  export * from './lib/hooks';
14
15
  export * from './lib/types';
15
16
  export type { Column, ColumnDef, Row, Table, Header, Cell, SortingState, ColumnFiltersState, VisibilityState, ColumnOrderState, ColumnPinningState, PaginationState, } from '@tanstack/react-table';
package/src/index.js CHANGED
@@ -20,6 +20,7 @@ Object.defineProperty(exports, "DataTableToolbar", { enumerable: true, get: func
20
20
  tslib_1.__exportStar(require("./lib/utils/styling-helpers"), exports);
21
21
  tslib_1.__exportStar(require("./lib/utils/column-helpers"), exports);
22
22
  tslib_1.__exportStar(require("./lib/utils/table-helpers"), exports);
23
+ tslib_1.__exportStar(require("./lib/utils/logger"), exports);
23
24
  tslib_1.__exportStar(require("./lib/hooks"), exports);
24
25
  tslib_1.__exportStar(require("./lib/types"), exports);
25
26
  tslib_1.__exportStar(require("./lib/features"), exports);
@@ -10,7 +10,6 @@ const features_1 = require("../../features");
10
10
  const react_virtual_1 = require("@tanstack/react-virtual");
11
11
  const react_1 = require("react");
12
12
  const data_table_context_1 = require("../../contexts/data-table-context");
13
- const use_data_table_api_1 = require("../../hooks/use-data-table-api");
14
13
  const utils_1 = require("../../utils");
15
14
  const debounced_fetch_utils_1 = require("../../utils/debounced-fetch.utils");
16
15
  const slot_helpers_1 = require("../../utils/slot-helpers");
@@ -40,12 +39,31 @@ const DEFAULT_INITIAL_STATE = {
40
39
  pendingLogic: 'AND',
41
40
  },
42
41
  };
43
- exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, columns, data = [], totalRow = 0, idKey = 'id', extraFilter = null, footerFilter = null, dataMode = 'client', initialLoadData = true, onFetchData, onDataStateChange, enableRowSelection = false, enableMultiRowSelection = true, selectMode = 'page', isRowSelectable, onSelectionChange, enableBulkActions = false, bulkActions, enableColumnResizing = false, columnResizeMode = 'onChange', enableColumnDragging = false, onColumnDragEnd, enableColumnPinning = false, onColumnPinningChange, enableExpanding = false, getRowCanExpand, renderSubComponent, enablePagination = true, paginationMode = 'client', enableGlobalFilter = true, enableColumnFilter = false, filterMode = 'client', enableSorting = true, sortingMode = 'client', onSortingChange, exportFilename = 'export', onExportProgress, onExportComplete, onExportError, onServerExport, onExportCancel, enableHover = true, enableStripes = false, tableContainerProps = {}, tableProps = {}, fitToScreen = true, tableSize: initialTableSize = 'medium', enableStickyHeaderOrFooter = false, maxHeight = '400px', enableVirtualization = false, estimateRowHeight = 52, enableColumnVisibility = true, enableTableSizeControl = true, enableExport = true, enableReset = true, loading = false, emptyMessage = 'No data available', skeletonRows = 5, onColumnFiltersChange, onPaginationChange, onGlobalFilterChange, slots = {}, slotProps = {}, }, ref) {
42
+ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, columns, data = [], totalRow = 0, idKey = 'id', extraFilter = null, footerFilter = null, dataMode = 'client', initialLoadData = true, onFetchData, onDataStateChange, enableRowSelection = false, enableMultiRowSelection = true, selectMode = 'page', isRowSelectable, onSelectionChange, enableBulkActions = false, bulkActions, enableColumnResizing = false, columnResizeMode = 'onChange', enableColumnDragging = false, onColumnDragEnd, enableColumnPinning = false, onColumnPinningChange, enableExpanding = false, getRowCanExpand, renderSubComponent, enablePagination = true, paginationMode = 'client', enableGlobalFilter = true, enableColumnFilter = false, filterMode = 'client', enableSorting = true, sortingMode = 'client', onSortingChange, exportFilename = 'export', onExportProgress, onExportComplete, onExportError, onServerExport, onExportCancel, enableHover = true, enableStripes = false, tableContainerProps = {}, tableProps = {}, fitToScreen = true, tableSize: initialTableSize = 'medium', enableStickyHeaderOrFooter = false, maxHeight = '400px', enableVirtualization = false, estimateRowHeight = 52, enableColumnVisibility = true, enableTableSizeControl = true, enableExport = true, enableReset = true, loading = false, emptyMessage = 'No data available', skeletonRows = 5, onColumnFiltersChange, onPaginationChange, onGlobalFilterChange, slots = {}, slotProps = {}, logging, }, ref) {
44
43
  var _a;
45
44
  const isServerMode = dataMode === 'server';
46
45
  const isServerPagination = paginationMode === 'server' || isServerMode;
47
46
  const isServerFiltering = filterMode === 'server' || isServerMode;
48
47
  const isServerSorting = sortingMode === 'server' || isServerMode;
48
+ const logger = (0, react_1.useMemo)(() => (0, utils_1.createLogger)('DataTable', logging), [logging]);
49
+ const fetchLogger = (0, react_1.useMemo)(() => logger.child('fetch'), [logger]);
50
+ const paginationLogger = (0, react_1.useMemo)(() => logger.child('pagination'), [logger]);
51
+ const stateLogger = (0, react_1.useMemo)(() => logger.child('state'), [logger]);
52
+ (0, react_1.useEffect)(() => {
53
+ if (logger.isLevelEnabled('info')) {
54
+ logger.info('mounted', {
55
+ dataMode,
56
+ paginationMode,
57
+ filterMode,
58
+ sortingMode,
59
+ });
60
+ }
61
+ return () => {
62
+ if (logger.isLevelEnabled('info')) {
63
+ logger.info('unmounted');
64
+ }
65
+ };
66
+ }, [logger, dataMode, paginationMode, filterMode, sortingMode]);
49
67
  const initialStateConfig = (0, react_1.useMemo)(() => {
50
68
  return Object.assign(Object.assign({}, DEFAULT_INITIAL_STATE), initialState);
51
69
  }, [initialState]);
@@ -124,16 +142,40 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
124
142
  minWidth: '100%',
125
143
  }), [tableWidth]);
126
144
  const fetchData = (0, react_1.useCallback)((...args_1) => tslib_1.__awaiter(this, [...args_1], void 0, function* (overrides = {}) {
127
- if (!onFetchData)
145
+ var _a, _b;
146
+ if (!onFetchData) {
147
+ if (fetchLogger.isLevelEnabled('debug')) {
148
+ fetchLogger.debug('onFetchData not provided, skipping fetch', { overrides });
149
+ }
128
150
  return;
151
+ }
129
152
  const filters = Object.assign({ globalFilter,
130
153
  pagination,
131
154
  columnFilter,
132
155
  sorting }, overrides);
133
- const result = yield debouncedFetch(filters);
134
- if ((result === null || result === void 0 ? void 0 : result.data) && (result === null || result === void 0 ? void 0 : result.total) !== undefined) {
135
- setServerData(result.data);
136
- setServerTotal(result.total);
156
+ if (fetchLogger.isLevelEnabled('debug')) {
157
+ fetchLogger.debug('Requesting data', { filters });
158
+ }
159
+ try {
160
+ const result = yield debouncedFetch(filters);
161
+ if (fetchLogger.isLevelEnabled('debug')) {
162
+ fetchLogger.debug('Fetch resolved', {
163
+ rows: (_b = (_a = result === null || result === void 0 ? void 0 : result.data) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0,
164
+ total: result === null || result === void 0 ? void 0 : result.total,
165
+ });
166
+ }
167
+ if ((result === null || result === void 0 ? void 0 : result.data) && (result === null || result === void 0 ? void 0 : result.total) !== undefined) {
168
+ setServerData(result.data);
169
+ setServerTotal(result.total);
170
+ }
171
+ else if (fetchLogger.isLevelEnabled('warn')) {
172
+ fetchLogger.warn('Fetch handler returned unexpected shape', result);
173
+ }
174
+ return result;
175
+ }
176
+ catch (error) {
177
+ fetchLogger.error('Fetch failed', error);
178
+ throw error;
137
179
  }
138
180
  }), [
139
181
  onFetchData,
@@ -142,6 +184,7 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
142
184
  columnFilter,
143
185
  sorting,
144
186
  debouncedFetch,
187
+ fetchLogger,
145
188
  ]);
146
189
  const handleSelectionStateChange = (0, react_1.useCallback)((updaterOrValue) => {
147
190
  setSelectionState((prevState) => {
@@ -162,15 +205,22 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
162
205
  }
163
206
  }, [onColumnFiltersChange]);
164
207
  const tableStateChange = (0, react_1.useCallback)((overrides = {}) => {
165
- if (onDataStateChange) {
166
- const currentState = Object.assign({ globalFilter,
167
- columnFilter,
168
- sorting,
169
- pagination,
170
- columnOrder,
171
- columnPinning }, overrides);
172
- onDataStateChange(currentState);
208
+ if (!onDataStateChange) {
209
+ if (stateLogger.isLevelEnabled('debug')) {
210
+ stateLogger.debug('No onDataStateChange handler registered; skipping state update notification', { overrides });
211
+ }
212
+ return;
173
213
  }
214
+ const currentState = Object.assign({ globalFilter,
215
+ columnFilter,
216
+ sorting,
217
+ pagination,
218
+ columnOrder,
219
+ columnPinning }, overrides);
220
+ if (stateLogger.isLevelEnabled('debug')) {
221
+ stateLogger.debug('Emitting tableStateChange', currentState);
222
+ }
223
+ onDataStateChange(currentState);
174
224
  }, [
175
225
  onDataStateChange,
176
226
  globalFilter,
@@ -179,6 +229,7 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
179
229
  pagination,
180
230
  columnOrder,
181
231
  columnPinning,
232
+ stateLogger,
182
233
  ]);
183
234
  const handleSortingChange = (0, react_1.useCallback)((updaterOrValue) => {
184
235
  let newSorting = typeof updaterOrValue === 'function'
@@ -187,8 +238,18 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
187
238
  newSorting = newSorting.filter((sort) => sort.id);
188
239
  setSorting(newSorting);
189
240
  onSortingChange === null || onSortingChange === void 0 ? void 0 : onSortingChange(newSorting);
241
+ if (stateLogger.isLevelEnabled('debug')) {
242
+ stateLogger.debug('Sorting change applied', {
243
+ sorting: newSorting,
244
+ serverMode: isServerMode,
245
+ serverSorting: isServerSorting,
246
+ });
247
+ }
190
248
  if (isServerMode || isServerSorting) {
191
249
  const pagination = resetPageToFirst();
250
+ if (stateLogger.isLevelEnabled('debug')) {
251
+ stateLogger.debug('Sorting change triggered server fetch', { pagination, sorting: newSorting });
252
+ }
192
253
  tableStateChange({ sorting: newSorting, pagination });
193
254
  fetchData({
194
255
  sorting: newSorting,
@@ -198,6 +259,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
198
259
  else if (onDataStateChange) {
199
260
  const pagination = resetPageToFirst();
200
261
  setTimeout(() => {
262
+ if (stateLogger.isLevelEnabled('debug')) {
263
+ stateLogger.debug('Sorting change notified client state change', { pagination, sorting: newSorting });
264
+ }
201
265
  tableStateChange({ sorting: newSorting, pagination });
202
266
  }, 0);
203
267
  }
@@ -209,6 +273,7 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
209
273
  isServerSorting,
210
274
  onDataStateChange,
211
275
  tableStateChange,
276
+ stateLogger,
212
277
  ]);
213
278
  const handleColumnOrderChange = (0, react_1.useCallback)((updatedColumnOrder) => {
214
279
  const newColumnOrder = typeof updatedColumnOrder === 'function'
@@ -229,30 +294,67 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
229
294
  }
230
295
  }, [onColumnPinningChange, columnPinning]);
231
296
  const handlePaginationChange = (0, react_1.useCallback)((updater) => {
232
- setPagination(updater);
233
297
  const newPagination = typeof updater === 'function' ? updater(pagination) : updater;
298
+ if (paginationLogger.isLevelEnabled('debug')) {
299
+ paginationLogger.debug('Pagination change requested', {
300
+ previous: pagination,
301
+ next: newPagination,
302
+ serverSide: isServerMode || isServerPagination,
303
+ });
304
+ }
305
+ setPagination(newPagination);
306
+ onPaginationChange === null || onPaginationChange === void 0 ? void 0 : onPaginationChange(newPagination);
307
+ if (paginationLogger.isLevelEnabled('debug')) {
308
+ paginationLogger.debug('Pagination state updated', newPagination);
309
+ }
234
310
  if (isServerMode || isServerPagination) {
235
311
  setTimeout(() => {
312
+ if (paginationLogger.isLevelEnabled('debug')) {
313
+ paginationLogger.debug('Notifying server-side pagination change', newPagination);
314
+ }
236
315
  tableStateChange({ pagination: newPagination });
237
316
  fetchData({ pagination: newPagination });
238
317
  }, 0);
239
318
  }
240
319
  else if (onDataStateChange) {
241
320
  setTimeout(() => {
321
+ if (paginationLogger.isLevelEnabled('debug')) {
322
+ paginationLogger.debug('Notifying client-side pagination change', newPagination);
323
+ }
242
324
  tableStateChange({ pagination: newPagination });
243
325
  }, 0);
244
326
  }
245
- setPagination(newPagination);
246
- onPaginationChange === null || onPaginationChange === void 0 ? void 0 : onPaginationChange(newPagination);
247
- }, [pagination, isServerMode, isServerPagination, onDataStateChange, fetchData, tableStateChange]);
327
+ }, [
328
+ pagination,
329
+ isServerMode,
330
+ isServerPagination,
331
+ onDataStateChange,
332
+ fetchData,
333
+ tableStateChange,
334
+ paginationLogger,
335
+ onPaginationChange,
336
+ ]);
248
337
  const handleGlobalFilterChange = (0, react_1.useCallback)((updaterOrValue) => {
249
338
  const newFilter = typeof updaterOrValue === 'function'
250
339
  ? updaterOrValue(globalFilter)
251
340
  : updaterOrValue;
252
341
  setGlobalFilter(newFilter);
342
+ if (stateLogger.isLevelEnabled('debug')) {
343
+ stateLogger.debug('Global filter change applied', {
344
+ value: newFilter,
345
+ serverMode: isServerMode,
346
+ serverFiltering: isServerFiltering,
347
+ });
348
+ }
253
349
  if (isServerMode || isServerFiltering) {
254
350
  const pagination = resetPageToFirst();
255
351
  setTimeout(() => {
352
+ if (stateLogger.isLevelEnabled('debug')) {
353
+ stateLogger.debug('Global filter change triggering server fetch', {
354
+ pagination,
355
+ value: newFilter,
356
+ });
357
+ }
256
358
  tableStateChange({ globalFilter: newFilter, pagination });
257
359
  fetchData({ globalFilter: newFilter, pagination });
258
360
  }, 0);
@@ -260,11 +362,17 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
260
362
  else if (onDataStateChange) {
261
363
  const pagination = resetPageToFirst();
262
364
  setTimeout(() => {
365
+ if (stateLogger.isLevelEnabled('debug')) {
366
+ stateLogger.debug('Global filter change notifying client listeners', {
367
+ pagination,
368
+ value: newFilter,
369
+ });
370
+ }
263
371
  tableStateChange({ globalFilter: newFilter, pagination });
264
372
  }, 0);
265
373
  }
266
374
  onGlobalFilterChange === null || onGlobalFilterChange === void 0 ? void 0 : onGlobalFilterChange(newFilter);
267
- }, [globalFilter, isServerMode, isServerFiltering, onDataStateChange, fetchData, tableStateChange]);
375
+ }, [globalFilter, isServerMode, isServerFiltering, onDataStateChange, fetchData, tableStateChange, stateLogger]);
268
376
  const onColumnFilterChangeHandler = (0, react_1.useCallback)((updater) => {
269
377
  const currentState = columnFilter;
270
378
  const newState = typeof updater === 'function'
@@ -312,6 +420,12 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
312
420
  enabled: enableVirtualization && !enablePagination && rows.length > 0,
313
421
  });
314
422
  const resetPageToFirst = () => {
423
+ if (paginationLogger.isLevelEnabled('info')) {
424
+ paginationLogger.info('Resetting to first page due to state change', {
425
+ previousPageIndex: pagination.pageIndex,
426
+ pageSize: pagination.pageSize,
427
+ });
428
+ }
315
429
  const newPagination = { pageIndex: 0, pageSize: pagination.pageSize };
316
430
  setPagination(newPagination);
317
431
  onPaginationChange === null || onPaginationChange === void 0 ? void 0 : onPaginationChange(newPagination);
@@ -355,29 +469,6 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
355
469
  setColumnOrder(initialOrder);
356
470
  }
357
471
  }, [enableColumnDragging, enhancedColumns, columnOrder.length]);
358
- (0, use_data_table_api_1.useDataTableApi)({
359
- table,
360
- idKey,
361
- enhancedColumns,
362
- enablePagination,
363
- enableColumnPinning,
364
- initialStateConfig: Object.assign(Object.assign({}, DEFAULT_INITIAL_STATE), initialState),
365
- selectMode,
366
- onSelectionChange: handleSelectionStateChange,
367
- handleColumnFilterStateChange,
368
- onDataStateChange,
369
- onFetchData: fetchData,
370
- exportFilename,
371
- onExportProgress,
372
- onExportComplete,
373
- onExportError,
374
- onServerExport,
375
- exportController,
376
- setExportController,
377
- isExporting,
378
- onDataChange: setServerData,
379
- dataMode,
380
- }, internalApiRef);
381
472
  (0, react_1.useImperativeHandle)(ref, () => internalApiRef.current, []);
382
473
  (0, react_1.useImperativeHandle)(ref, () => ({
383
474
  table: {
@@ -505,6 +596,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
505
596
  pendingFilters: columnFilter.pendingFilters || [],
506
597
  pendingLogic: columnFilter.pendingLogic || 'AND',
507
598
  });
599
+ if (stateLogger.isLevelEnabled('debug')) {
600
+ stateLogger.debug(`Adding column filter ${columnId} ${operator} ${value}`, newFilters);
601
+ }
508
602
  },
509
603
  removeColumnFilter: (filterId) => {
510
604
  const columnFilter = table.getState().columnFilter;
@@ -516,6 +610,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
516
610
  pendingFilters: columnFilter.pendingFilters || [],
517
611
  pendingLogic: columnFilter.pendingLogic || 'AND',
518
612
  });
613
+ if (stateLogger.isLevelEnabled('debug')) {
614
+ stateLogger.debug(`Removing column filter ${filterId}`, newFilters);
615
+ }
519
616
  },
520
617
  clearAllFilters: () => {
521
618
  table.setGlobalFilter('');
@@ -534,11 +631,17 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
534
631
  pendingFilters: [],
535
632
  pendingLogic: 'AND',
536
633
  });
634
+ if (stateLogger.isLevelEnabled('debug')) {
635
+ stateLogger.debug('Resetting filters');
636
+ }
537
637
  },
538
638
  },
539
639
  sorting: {
540
640
  setSorting: (sortingState) => {
541
641
  table.setSorting(sortingState);
642
+ if (stateLogger.isLevelEnabled('debug')) {
643
+ stateLogger.debug(`Setting sorting`, sortingState);
644
+ }
542
645
  },
543
646
  sortColumn: (columnId, direction) => {
544
647
  const column = table.getColumn(columnId);
@@ -561,23 +664,41 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
561
664
  pagination: {
562
665
  goToPage: (pageIndex) => {
563
666
  table.setPageIndex(pageIndex);
667
+ if (paginationLogger.isLevelEnabled('debug')) {
668
+ paginationLogger.debug(`Going to page ${pageIndex}`);
669
+ }
564
670
  },
565
671
  nextPage: () => {
566
672
  table.nextPage();
673
+ if (paginationLogger.isLevelEnabled('debug')) {
674
+ paginationLogger.debug('Next page');
675
+ }
567
676
  },
568
677
  previousPage: () => {
569
678
  table.previousPage();
679
+ if (paginationLogger.isLevelEnabled('debug')) {
680
+ paginationLogger.debug('Previous page');
681
+ }
570
682
  },
571
683
  setPageSize: (pageSize) => {
572
684
  table.setPageSize(pageSize);
685
+ if (paginationLogger.isLevelEnabled('debug')) {
686
+ paginationLogger.debug(`Setting page size to ${pageSize}`);
687
+ }
573
688
  },
574
689
  goToFirstPage: () => {
575
690
  table.setPageIndex(0);
691
+ if (paginationLogger.isLevelEnabled('debug')) {
692
+ paginationLogger.debug('Going to first page');
693
+ }
576
694
  },
577
695
  goToLastPage: () => {
578
696
  const pageCount = table.getPageCount();
579
697
  if (pageCount > 0) {
580
698
  table.setPageIndex(pageCount - 1);
699
+ if (paginationLogger.isLevelEnabled('debug')) {
700
+ paginationLogger.debug(`Going to last page ${pageCount - 1}`);
701
+ }
581
702
  }
582
703
  },
583
704
  },
@@ -605,11 +726,17 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
605
726
  setPagination(pagination);
606
727
  onDataStateChange === null || onDataStateChange === void 0 ? void 0 : onDataStateChange(allState);
607
728
  fetchData === null || fetchData === void 0 ? void 0 : fetchData({ pagination });
729
+ if (fetchLogger.isLevelEnabled('debug')) {
730
+ fetchLogger.debug('Refreshing data', { pagination, allState });
731
+ }
608
732
  },
609
733
  reload: () => {
610
734
  const allState = table.getState();
611
735
  onDataStateChange === null || onDataStateChange === void 0 ? void 0 : onDataStateChange(allState);
612
736
  onFetchData === null || onFetchData === void 0 ? void 0 : onFetchData({});
737
+ if (fetchLogger.isLevelEnabled('debug')) {
738
+ fetchLogger.debug('Reloading data', allState);
739
+ }
613
740
  },
614
741
  getAllData: () => {
615
742
  var _a;
@@ -628,6 +755,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
628
755
  const newData = (_a = table.getRowModel().rows) === null || _a === void 0 ? void 0 : _a.map(row => String(row.original[idKey]) === rowId
629
756
  ? Object.assign(Object.assign({}, row.original), updates) : row.original);
630
757
  setServerData === null || setServerData === void 0 ? void 0 : setServerData(newData || []);
758
+ if (fetchLogger.isLevelEnabled('debug')) {
759
+ fetchLogger.debug(`Updating row ${rowId}`, updates);
760
+ }
631
761
  },
632
762
  updateRowByIndex: (index, updates) => {
633
763
  var _a;
@@ -635,6 +765,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
635
765
  if (newData === null || newData === void 0 ? void 0 : newData[index]) {
636
766
  newData[index] = Object.assign(Object.assign({}, newData[index]), updates);
637
767
  setServerData(newData);
768
+ if (fetchLogger.isLevelEnabled('debug')) {
769
+ fetchLogger.debug(`Updating row by index ${index}`, updates);
770
+ }
638
771
  }
639
772
  },
640
773
  insertRow: (newRow, index) => {
@@ -647,17 +780,26 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
647
780
  newData.push(newRow);
648
781
  }
649
782
  setServerData(newData || []);
783
+ if (fetchLogger.isLevelEnabled('debug')) {
784
+ fetchLogger.debug(`Inserting row`, newRow);
785
+ }
650
786
  },
651
787
  deleteRow: (rowId) => {
652
788
  var _a;
653
789
  const newData = (_a = (table.getRowModel().rows || [])) === null || _a === void 0 ? void 0 : _a.filter(row => String(row.original[idKey]) !== rowId);
654
790
  setServerData === null || setServerData === void 0 ? void 0 : setServerData((newData === null || newData === void 0 ? void 0 : newData.map(row => row.original)) || []);
791
+ if (fetchLogger.isLevelEnabled('debug')) {
792
+ fetchLogger.debug(`Deleting row ${rowId}`);
793
+ }
655
794
  },
656
795
  deleteRowByIndex: (index) => {
657
796
  var _a;
658
797
  const newData = (_a = (table.getRowModel().rows || [])) === null || _a === void 0 ? void 0 : _a.map(row => row.original);
659
798
  newData.splice(index, 1);
660
799
  setServerData(newData);
800
+ if (fetchLogger.isLevelEnabled('debug')) {
801
+ fetchLogger.debug(`Deleting row by index ${index}`);
802
+ }
661
803
  },
662
804
  deleteSelectedRows: () => {
663
805
  var _a;
@@ -666,6 +808,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
666
808
  const newData = (_a = (table.getRowModel().rows || [])) === null || _a === void 0 ? void 0 : _a.filter(row => !selectedRowIds.includes(String(row.original[idKey])));
667
809
  setServerData((newData === null || newData === void 0 ? void 0 : newData.map(row => row.original)) || []);
668
810
  table.resetRowSelection();
811
+ if (fetchLogger.isLevelEnabled('debug')) {
812
+ fetchLogger.debug('Deleting selected rows');
813
+ }
669
814
  },
670
815
  replaceAllData: (newData) => {
671
816
  setServerData === null || setServerData === void 0 ? void 0 : setServerData(newData);
@@ -822,6 +967,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
822
967
  sorting: table.getState().sorting,
823
968
  pagination: table.getState().pagination,
824
969
  };
970
+ if (stateLogger.isLevelEnabled('debug')) {
971
+ stateLogger.debug('Server export CSV', { currentFilters });
972
+ }
825
973
  yield (0, utils_1.exportServerData)(table, {
826
974
  format: 'csv',
827
975
  filename,
@@ -841,6 +989,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
841
989
  onComplete: onExportComplete,
842
990
  onError: onExportError,
843
991
  });
992
+ if (stateLogger.isLevelEnabled('debug')) {
993
+ stateLogger.debug('Client export CSV', filename);
994
+ }
844
995
  }
845
996
  }
846
997
  catch (error) {
@@ -866,6 +1017,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
866
1017
  sorting: table.getState().sorting,
867
1018
  pagination: table.getState().pagination,
868
1019
  };
1020
+ if (stateLogger.isLevelEnabled('debug')) {
1021
+ stateLogger.debug('Server export Excel', { currentFilters });
1022
+ }
869
1023
  yield (0, utils_1.exportServerData)(table, {
870
1024
  format: 'excel',
871
1025
  filename,
@@ -885,6 +1039,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
885
1039
  onComplete: onExportComplete,
886
1040
  onError: onExportError,
887
1041
  });
1042
+ if (stateLogger.isLevelEnabled('debug')) {
1043
+ stateLogger.debug('Client export Excel', filename);
1044
+ }
888
1045
  }
889
1046
  }
890
1047
  catch (error) {
@@ -892,6 +1049,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
892
1049
  message: error.message || 'Export failed',
893
1050
  code: 'EXPORT_ERROR',
894
1051
  });
1052
+ if (stateLogger.isLevelEnabled('debug')) {
1053
+ stateLogger.debug('Server export Excel failed', error);
1054
+ }
895
1055
  }
896
1056
  finally {
897
1057
  setExportController === null || setExportController === void 0 ? void 0 : setExportController(null);
@@ -905,6 +1065,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
905
1065
  message: 'No server export function provided',
906
1066
  code: 'NO_SERVER_EXPORT',
907
1067
  });
1068
+ if (stateLogger.isLevelEnabled('debug')) {
1069
+ stateLogger.debug('Server export data failed', 'No server export function provided');
1070
+ }
908
1071
  return;
909
1072
  }
910
1073
  try {
@@ -916,6 +1079,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
916
1079
  sorting: table.getState().sorting,
917
1080
  pagination: table.getState().pagination,
918
1081
  };
1082
+ if (stateLogger.isLevelEnabled('debug')) {
1083
+ stateLogger.debug('Server export data', { currentFilters });
1084
+ }
919
1085
  yield (0, utils_1.exportServerData)(table, {
920
1086
  format,
921
1087
  filename,
@@ -932,6 +1098,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
932
1098
  message: error.message || 'Export failed',
933
1099
  code: 'EXPORT_ERROR',
934
1100
  });
1101
+ if (stateLogger.isLevelEnabled('debug')) {
1102
+ stateLogger.debug('Server export data failed', error);
1103
+ }
935
1104
  }
936
1105
  finally {
937
1106
  setExportController === null || setExportController === void 0 ? void 0 : setExportController(null);
@@ -941,6 +1110,9 @@ exports.DataTable = (0, react_1.forwardRef)(function DataTable({ initialState, c
941
1110
  cancelExport: () => {
942
1111
  exportController === null || exportController === void 0 ? void 0 : exportController.abort();
943
1112
  setExportController === null || setExportController === void 0 ? void 0 : setExportController(null);
1113
+ if (stateLogger.isLevelEnabled('debug')) {
1114
+ stateLogger.debug('Export cancelled');
1115
+ }
944
1116
  },
945
1117
  },
946
1118
  }), [
@@ -1,17 +1,17 @@
1
- import { Row, SortingState, ColumnResizeMode, ColumnPinningState, RowData, PaginationState } from '@tanstack/react-table';
1
+ import { Row, SortingState, ColumnResizeMode, ColumnPinningState, RowData, PaginationState, ColumnDef } from '@tanstack/react-table';
2
2
  import { ReactNode } from 'react';
3
3
  import type { ColumnFilterState, TableFilters, TableState } from '../../types';
4
- import { DataTableColumn } from '../../types';
5
4
  import { DataTableSlots, PartialSlotProps } from '../../types/slots.types';
6
5
  import { DataTableSize } from '../../utils/table-helpers';
7
6
  import { SelectionState } from '../../features';
7
+ import { DataTableLoggingOptions } from '../../utils/logger';
8
8
  export type SelectMode = 'page' | 'all';
9
9
  declare module '@tanstack/table-core' {
10
10
  interface ColumnMeta<TData extends RowData, TValue> {
11
11
  }
12
12
  }
13
13
  export interface DataTableProps<T> {
14
- columns: DataTableColumn<T>[];
14
+ columns: ColumnDef<T, any>[];
15
15
  data?: T[];
16
16
  totalRow?: number;
17
17
  idKey?: keyof T;
@@ -95,4 +95,5 @@ export interface DataTableProps<T> {
95
95
  onColumnFilterChange?: (columnFilter: ColumnFilterState) => void;
96
96
  slots?: Partial<DataTableSlots<T>>;
97
97
  slotProps?: PartialSlotProps<T>;
98
+ logging?: boolean | DataTableLoggingOptions;
98
99
  }
@@ -6,6 +6,7 @@ const react_1 = require("react");
6
6
  const material_1 = require("@mui/material");
7
7
  const icons_material_1 = require("@mui/icons-material");
8
8
  const components_1 = require("../components");
9
+ const types_1 = require("../types");
9
10
  const generateEmployeeData = () => {
10
11
  const departments = [
11
12
  { id: 1, name: 'Engineering', color: '#2196F3' },
@@ -218,6 +219,10 @@ function AdvancedFeaturesExample() {
218
219
  pageIndex: 0,
219
220
  pageSize: 10,
220
221
  },
222
+ columnPinning: {
223
+ left: [types_1.DEFAULT_SELECTION_COLUMN_NAME],
224
+ right: ['actions'],
225
+ },
221
226
  columnOrder: ['name', 'department.name', 'salary', 'performance.rating', 'skills'],
222
227
  }, tableContainerProps: {
223
228
  sx: {
@@ -3,6 +3,7 @@ import { Ref } from 'react';
3
3
  import { ColumnFilterState, TableFilters, TableState } from '../types';
4
4
  import { DataTableApi } from '../types/data-table-api';
5
5
  import { SelectionState } from '../features';
6
+ import { DataTableLoggingOptions } from '../utils/logger';
6
7
  interface UseDataTableApiProps<T> {
7
8
  table: Table<T>;
8
9
  idKey: keyof T;
@@ -39,6 +40,7 @@ interface UseDataTableApiProps<T> {
39
40
  setExportController?: (controller: AbortController | null) => void;
40
41
  isExporting?: boolean;
41
42
  dataMode?: 'client' | 'server';
43
+ logging?: boolean | DataTableLoggingOptions;
42
44
  }
43
45
  export declare function useDataTableApi<T extends Record<string, any>>(props: UseDataTableApiProps<T>, ref: Ref<DataTableApi<T>>): void;
44
46
  export {};
@@ -4,8 +4,13 @@ exports.useDataTableApi = useDataTableApi;
4
4
  const tslib_1 = require("tslib");
5
5
  const react_1 = require("react");
6
6
  const export_utils_1 = require("../utils/export-utils");
7
+ const logger_1 = require("../utils/logger");
7
8
  function useDataTableApi(props, ref) {
8
- const { table, idKey, enhancedColumns, enablePagination, enableColumnPinning, initialStateConfig, selectMode = 'page', onSelectionChange, handleColumnFilterStateChange, onDataStateChange, onFetchData, onDataChange, exportFilename = 'export', onExportProgress, onExportComplete, onExportError, onServerExport, exportController, setExportController, isExporting, dataMode = 'client', } = props;
9
+ const { table, idKey, enhancedColumns, enablePagination, enableColumnPinning, initialStateConfig, selectMode = 'page', onSelectionChange, handleColumnFilterStateChange, onDataStateChange, onFetchData, onDataChange, exportFilename = 'export', onExportProgress, onExportComplete, onExportError, onServerExport, exportController, setExportController, isExporting, dataMode = 'client', logging, } = props;
10
+ const logger = (0, react_1.useMemo)(() => (0, logger_1.createLogger)('DataTableApi', logging), [logging]);
11
+ const fetchLogger = (0, react_1.useMemo)(() => logger.child('fetch'), [logger]);
12
+ const paginationLogger = (0, react_1.useMemo)(() => logger.child('pagination'), [logger]);
13
+ const stateLogger = (0, react_1.useMemo)(() => logger.child('state'), [logger]);
9
14
  const getTableFilters = (0, react_1.useCallback)((withAllState = false) => {
10
15
  const state = table.getState();
11
16
  return Object.assign({ sorting: state.sorting, globalFilter: state.globalFilter, columnFilter: state.columnFilter, pagination: state.pagination }, (withAllState ? {
@@ -55,6 +60,9 @@ function useDataTableApi(props, ref) {
55
60
  newOrder.splice(currentIndex, 1);
56
61
  newOrder.splice(toIndex, 0, columnId);
57
62
  table.setColumnOrder(newOrder);
63
+ if (stateLogger.isLevelEnabled('debug')) {
64
+ stateLogger.debug('Column order updated', `${columnId} from ${currentIndex} to ${toIndex}`);
65
+ }
58
66
  },
59
67
  resetColumnOrder: () => {
60
68
  const initialOrder = enhancedColumns.map((col, index) => {
@@ -67,6 +75,9 @@ function useDataTableApi(props, ref) {
67
75
  return `column_${index}`;
68
76
  });
69
77
  table.setColumnOrder(initialOrder);
78
+ if (stateLogger.isLevelEnabled('debug')) {
79
+ stateLogger.debug('Column order reset', initialOrder);
80
+ }
70
81
  },
71
82
  },
72
83
  columnPinning: {
@@ -76,6 +87,9 @@ function useDataTableApi(props, ref) {
76
87
  newPinning.right = (newPinning.right || []).filter(id => id !== columnId);
77
88
  newPinning.left = [...(newPinning.left || []).filter(id => id !== columnId), columnId];
78
89
  table.setColumnPinning(newPinning);
90
+ if (stateLogger.isLevelEnabled('debug')) {
91
+ stateLogger.debug('Column pinned left', `${columnId}`);
92
+ }
79
93
  },
80
94
  pinColumnRight: (columnId) => {
81
95
  const currentPinning = table.getState().columnPinning;
@@ -83,6 +97,9 @@ function useDataTableApi(props, ref) {
83
97
  newPinning.left = (newPinning.left || []).filter(id => id !== columnId);
84
98
  newPinning.right = [...(newPinning.right || []).filter(id => id !== columnId), columnId];
85
99
  table.setColumnPinning(newPinning);
100
+ if (stateLogger.isLevelEnabled('debug')) {
101
+ stateLogger.debug('Column pinned right', `${columnId}`);
102
+ }
86
103
  },
87
104
  unpinColumn: (columnId) => {
88
105
  const currentPinning = table.getState().columnPinning;
@@ -118,12 +135,21 @@ function useDataTableApi(props, ref) {
118
135
  filtering: {
119
136
  setGlobalFilter: (filter) => {
120
137
  table.setGlobalFilter(filter);
138
+ if (stateLogger.isLevelEnabled('debug')) {
139
+ stateLogger.debug('Global filter set', `${filter}`);
140
+ }
121
141
  },
122
142
  clearGlobalFilter: () => {
123
143
  table.setGlobalFilter('');
144
+ if (stateLogger.isLevelEnabled('debug')) {
145
+ stateLogger.debug('Global filter cleared');
146
+ }
124
147
  },
125
148
  setColumnFilters: (filters) => {
126
149
  handleColumnFilterStateChange(filters);
150
+ if (stateLogger.isLevelEnabled('debug')) {
151
+ stateLogger.debug('Column filters set', `${filters}`);
152
+ }
127
153
  },
128
154
  addColumnFilter: (columnId, operator, value) => {
129
155
  const newFilter = {
@@ -141,6 +167,9 @@ function useDataTableApi(props, ref) {
141
167
  pendingFilters: columnFilter.pendingFilters || [],
142
168
  pendingLogic: columnFilter.pendingLogic || 'AND',
143
169
  });
170
+ if (stateLogger.isLevelEnabled('debug')) {
171
+ stateLogger.debug(`Column filter added ${columnId} ${operator} ${value}`, newFilters);
172
+ }
144
173
  },
145
174
  removeColumnFilter: (filterId) => {
146
175
  const columnFilter = table.getState().columnFilter;
@@ -152,6 +181,9 @@ function useDataTableApi(props, ref) {
152
181
  pendingFilters: columnFilter.pendingFilters || [],
153
182
  pendingLogic: columnFilter.pendingLogic || 'AND',
154
183
  });
184
+ if (stateLogger.isLevelEnabled('debug')) {
185
+ stateLogger.debug(`Column filter removed ${filterId}`, newFilters);
186
+ }
155
187
  },
156
188
  clearAllFilters: () => {
157
189
  table.setGlobalFilter('');
@@ -161,6 +193,9 @@ function useDataTableApi(props, ref) {
161
193
  pendingFilters: [],
162
194
  pendingLogic: 'AND',
163
195
  });
196
+ if (stateLogger.isLevelEnabled('debug')) {
197
+ stateLogger.debug('Filters reset');
198
+ }
164
199
  },
165
200
  resetFilters: () => {
166
201
  table.resetGlobalFilter();
@@ -175,6 +210,9 @@ function useDataTableApi(props, ref) {
175
210
  sorting: {
176
211
  setSorting: (sortingState) => {
177
212
  table.setSorting(sortingState);
213
+ if (stateLogger.isLevelEnabled('debug')) {
214
+ stateLogger.debug('Sorting set', `${sortingState}`);
215
+ }
178
216
  },
179
217
  sortColumn: (columnId, direction) => {
180
218
  const column = table.getColumn(columnId);
@@ -197,24 +235,42 @@ function useDataTableApi(props, ref) {
197
235
  pagination: {
198
236
  goToPage: (pageIndex) => {
199
237
  table.setPageIndex(pageIndex);
238
+ if (paginationLogger.isLevelEnabled('debug')) {
239
+ paginationLogger.debug('Page index set', `${pageIndex}`);
240
+ }
200
241
  },
201
242
  nextPage: () => {
202
243
  table.nextPage();
244
+ if (paginationLogger.isLevelEnabled('debug')) {
245
+ paginationLogger.debug('Next page');
246
+ }
203
247
  },
204
248
  previousPage: () => {
205
249
  table.previousPage();
250
+ if (paginationLogger.isLevelEnabled('debug')) {
251
+ paginationLogger.debug('Previous page');
252
+ }
206
253
  },
207
254
  setPageSize: (pageSize) => {
208
255
  table.setPageSize(pageSize);
256
+ if (paginationLogger.isLevelEnabled('debug')) {
257
+ paginationLogger.debug('Page size set', `${pageSize}`);
258
+ }
209
259
  },
210
260
  goToFirstPage: () => {
211
261
  table.setPageIndex(0);
262
+ if (paginationLogger.isLevelEnabled('debug')) {
263
+ paginationLogger.debug('Page index set to 0');
264
+ }
212
265
  },
213
266
  goToLastPage: () => {
214
267
  const pageCount = table.getPageCount();
215
268
  if (pageCount > 0) {
216
269
  table.setPageIndex(pageCount - 1);
217
270
  }
271
+ if (paginationLogger.isLevelEnabled('debug')) {
272
+ paginationLogger.debug('Page index set to last page', `${pageCount - 1}`);
273
+ }
218
274
  },
219
275
  },
220
276
  selection: {
@@ -240,12 +296,18 @@ function useDataTableApi(props, ref) {
240
296
  const allState = getTableFilters(true);
241
297
  onDataStateChange === null || onDataStateChange === void 0 ? void 0 : onDataStateChange(allState);
242
298
  onFetchData === null || onFetchData === void 0 ? void 0 : onFetchData(filters);
299
+ if (fetchLogger.isLevelEnabled('debug')) {
300
+ fetchLogger.debug('Data refreshed', filters);
301
+ }
243
302
  },
244
303
  reload: () => {
245
304
  const filters = getTableFilters();
246
305
  const allState = getTableFilters(true);
247
306
  onDataStateChange === null || onDataStateChange === void 0 ? void 0 : onDataStateChange(allState);
248
307
  onFetchData === null || onFetchData === void 0 ? void 0 : onFetchData(filters);
308
+ if (fetchLogger.isLevelEnabled('debug')) {
309
+ fetchLogger.debug('Data reloaded', filters);
310
+ }
249
311
  },
250
312
  getAllData: () => {
251
313
  var _a;
@@ -264,6 +326,9 @@ function useDataTableApi(props, ref) {
264
326
  const newData = (_a = table.getRowModel().rows) === null || _a === void 0 ? void 0 : _a.map(row => String(row.original[idKey]) === rowId
265
327
  ? Object.assign(Object.assign({}, row.original), updates) : row.original);
266
328
  onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newData || []);
329
+ if (fetchLogger.isLevelEnabled('debug')) {
330
+ fetchLogger.debug('Row updated', `${rowId}`, updates);
331
+ }
267
332
  },
268
333
  updateRowByIndex: (index, updates) => {
269
334
  var _a;
@@ -283,11 +348,17 @@ function useDataTableApi(props, ref) {
283
348
  newData.push(newRow);
284
349
  }
285
350
  onDataChange(newData || []);
351
+ if (stateLogger.isLevelEnabled('debug')) {
352
+ stateLogger.debug('Row inserted', `${newRow}`, index);
353
+ }
286
354
  },
287
355
  deleteRow: (rowId) => {
288
356
  var _a;
289
357
  const newData = (_a = (table.getRowModel().rows || [])) === null || _a === void 0 ? void 0 : _a.filter(row => String(row.original[idKey]) !== rowId);
290
358
  onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange((newData === null || newData === void 0 ? void 0 : newData.map(row => row.original)) || []);
359
+ if (stateLogger.isLevelEnabled('debug')) {
360
+ stateLogger.debug('Row deleted', `${rowId}`);
361
+ }
291
362
  },
292
363
  deleteRowByIndex: (index) => {
293
364
  var _a;
@@ -302,6 +373,9 @@ function useDataTableApi(props, ref) {
302
373
  const newData = (_a = (table.getRowModel().rows || [])) === null || _a === void 0 ? void 0 : _a.filter(row => !selectedRowIds.includes(String(row.original[idKey])));
303
374
  onDataChange((newData === null || newData === void 0 ? void 0 : newData.map(row => row.original)) || []);
304
375
  table.resetRowSelection();
376
+ if (stateLogger.isLevelEnabled('debug')) {
377
+ stateLogger.debug('Selected rows deleted', selectedRowIds);
378
+ }
305
379
  },
306
380
  replaceAllData: (newData) => {
307
381
  onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newData);
@@ -315,6 +389,9 @@ function useDataTableApi(props, ref) {
315
389
  return updateData ? Object.assign(Object.assign({}, row.original), updateData) : row.original;
316
390
  });
317
391
  onDataChange(newData || []);
392
+ if (stateLogger.isLevelEnabled('debug')) {
393
+ stateLogger.debug('Multiple rows updated', updates);
394
+ }
318
395
  },
319
396
  insertMultipleRows: (newRows, startIndex) => {
320
397
  var _a;
@@ -326,12 +403,18 @@ function useDataTableApi(props, ref) {
326
403
  newData.push(...newRows);
327
404
  }
328
405
  onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newData);
406
+ if (stateLogger.isLevelEnabled('debug')) {
407
+ stateLogger.debug('Multiple rows inserted', newRows);
408
+ }
329
409
  },
330
410
  deleteMultipleRows: (rowIds) => {
331
411
  var _a, _b;
332
412
  const idsToDelete = new Set(rowIds);
333
413
  const newData = (_b = (_a = (table.getRowModel().rows || [])) === null || _a === void 0 ? void 0 : _a.filter(row => !idsToDelete.has(String(row.original[idKey])))) === null || _b === void 0 ? void 0 : _b.map(row => row.original);
334
414
  onDataChange(newData);
415
+ if (stateLogger.isLevelEnabled('debug')) {
416
+ stateLogger.debug('Multiple rows deleted', rowIds);
417
+ }
335
418
  },
336
419
  updateField: (rowId, fieldName, value) => {
337
420
  var _a;
@@ -458,6 +541,9 @@ function useDataTableApi(props, ref) {
458
541
  sorting: table.getState().sorting,
459
542
  pagination: table.getState().pagination,
460
543
  };
544
+ if (stateLogger.isLevelEnabled('debug')) {
545
+ stateLogger.debug('Server export CSV', { currentFilters });
546
+ }
461
547
  yield (0, export_utils_1.exportServerData)(table, {
462
548
  format: 'csv',
463
549
  filename,
@@ -5,3 +5,4 @@ export * from './export-utils';
5
5
  export * from './special-columns.utils';
6
6
  export * from './debounced-fetch.utils';
7
7
  export * from './slot-helpers';
8
+ export * from './logger';
@@ -8,3 +8,4 @@ tslib_1.__exportStar(require("./export-utils"), exports);
8
8
  tslib_1.__exportStar(require("./special-columns.utils"), exports);
9
9
  tslib_1.__exportStar(require("./debounced-fetch.utils"), exports);
10
10
  tslib_1.__exportStar(require("./slot-helpers"), exports);
11
+ tslib_1.__exportStar(require("./logger"), exports);
@@ -0,0 +1,34 @@
1
+ export type LogLevel = 'silent' | 'error' | 'warn' | 'info' | 'debug';
2
+ interface ConsoleLike {
3
+ debug?: (...args: unknown[]) => void;
4
+ info?: (...args: unknown[]) => void;
5
+ warn?: (...args: unknown[]) => void;
6
+ error?: (...args: unknown[]) => void;
7
+ log?: (...args: unknown[]) => void;
8
+ }
9
+ export interface DataTableLoggingOptions {
10
+ enabled?: boolean;
11
+ level?: LogLevel;
12
+ prefix?: string;
13
+ scope?: string;
14
+ includeTimestamp?: boolean;
15
+ logger?: ConsoleLike;
16
+ }
17
+ type LoggerInput = boolean | DataTableLoggingOptions;
18
+ type ResolvedLoggerConfig = Required<Omit<DataTableLoggingOptions, 'logger'>> & {
19
+ logger: ConsoleLike;
20
+ };
21
+ type LogMethodLevel = Exclude<LogLevel, 'silent'>;
22
+ export interface LoggerInstance {
23
+ debug: (...args: unknown[]) => void;
24
+ info: (...args: unknown[]) => void;
25
+ warn: (...args: unknown[]) => void;
26
+ error: (...args: unknown[]) => void;
27
+ child: (scope: string, overrides?: LoggerInput) => LoggerInstance;
28
+ isLevelEnabled: (level: LogMethodLevel) => boolean;
29
+ config: ResolvedLoggerConfig;
30
+ }
31
+ export declare const createLogger: (scope?: string, input?: LoggerInput, parentConfig?: ResolvedLoggerConfig) => LoggerInstance;
32
+ export declare const configureDataTableLogging: (options: DataTableLoggingOptions) => void;
33
+ export declare const getDataTableLoggingConfig: () => ResolvedLoggerConfig;
34
+ export {};
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getDataTableLoggingConfig = exports.configureDataTableLogging = exports.createLogger = void 0;
4
+ const LOG_LEVEL_ORDER = {
5
+ silent: 0,
6
+ error: 1,
7
+ warn: 2,
8
+ info: 3,
9
+ debug: 4,
10
+ };
11
+ const defaultConsole = typeof console !== 'undefined'
12
+ ? console
13
+ : {
14
+ log: () => undefined,
15
+ debug: () => undefined,
16
+ info: () => undefined,
17
+ warn: () => undefined,
18
+ error: () => undefined,
19
+ };
20
+ let globalConfig = {
21
+ enabled: false,
22
+ level: 'warn',
23
+ prefix: 'DataTable',
24
+ scope: '',
25
+ includeTimestamp: false,
26
+ logger: defaultConsole,
27
+ };
28
+ const isLevelEnabled = (level, config) => {
29
+ if (!config.enabled) {
30
+ return false;
31
+ }
32
+ return LOG_LEVEL_ORDER[level] <= LOG_LEVEL_ORDER[config.level];
33
+ };
34
+ const formatPrefix = (level, config) => {
35
+ const segments = [];
36
+ if (config.prefix) {
37
+ segments.push(config.prefix);
38
+ }
39
+ if (config.scope) {
40
+ segments.push(config.scope);
41
+ }
42
+ const prefix = segments.length > 0 ? `[${segments.join(':')}]` : '';
43
+ return config.includeTimestamp
44
+ ? `[${new Date().toISOString()}]${prefix ? ` ${prefix}` : ''} [${level.toUpperCase()}]`
45
+ : `${prefix ? `${prefix} ` : ''}[${level.toUpperCase()}]`;
46
+ };
47
+ const getConsoleMethod = (level, logger) => {
48
+ var _a, _b, _c;
49
+ const methodName = level === 'debug' ? 'debug' : level;
50
+ return (_c = (_b = (_a = logger[methodName]) !== null && _a !== void 0 ? _a : logger.log) !== null && _b !== void 0 ? _b : defaultConsole.log) !== null && _c !== void 0 ? _c : (() => undefined);
51
+ };
52
+ const normaliseInput = (input) => {
53
+ if (typeof input === 'boolean') {
54
+ return { enabled: input };
55
+ }
56
+ return input !== null && input !== void 0 ? input : {};
57
+ };
58
+ const resolveConfig = (scope, input, parent) => {
59
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
60
+ const overrides = normaliseInput(input);
61
+ const base = parent !== null && parent !== void 0 ? parent : globalConfig;
62
+ return {
63
+ enabled: (_a = overrides.enabled) !== null && _a !== void 0 ? _a : base.enabled,
64
+ level: (_b = overrides.level) !== null && _b !== void 0 ? _b : base.level,
65
+ prefix: (_c = overrides.prefix) !== null && _c !== void 0 ? _c : base.prefix,
66
+ scope: (_f = (_e = (_d = overrides.scope) !== null && _d !== void 0 ? _d : scope) !== null && _e !== void 0 ? _e : base.scope) !== null && _f !== void 0 ? _f : '',
67
+ includeTimestamp: (_g = overrides.includeTimestamp) !== null && _g !== void 0 ? _g : base.includeTimestamp,
68
+ logger: (_j = (_h = overrides.logger) !== null && _h !== void 0 ? _h : base.logger) !== null && _j !== void 0 ? _j : defaultConsole,
69
+ };
70
+ };
71
+ const createLoggerMethods = (config) => {
72
+ const logWithLevel = (level) => {
73
+ const consoleMethod = getConsoleMethod(level, config.logger);
74
+ return (...args) => {
75
+ if (!isLevelEnabled(level, config)) {
76
+ return;
77
+ }
78
+ const prefix = formatPrefix(level, config);
79
+ consoleMethod(prefix, ...args);
80
+ };
81
+ };
82
+ return {
83
+ debug: logWithLevel('debug'),
84
+ info: logWithLevel('info'),
85
+ warn: logWithLevel('warn'),
86
+ error: logWithLevel('error'),
87
+ };
88
+ };
89
+ const createLogger = (scope, input, parentConfig) => {
90
+ const resolvedConfig = resolveConfig(scope, input, parentConfig);
91
+ const methods = createLoggerMethods(resolvedConfig);
92
+ const child = (childScope, overrides) => {
93
+ const combinedScope = childScope
94
+ ? (resolvedConfig.scope ? `${resolvedConfig.scope}.${childScope}` : childScope)
95
+ : resolvedConfig.scope;
96
+ return (0, exports.createLogger)(combinedScope, overrides, resolvedConfig);
97
+ };
98
+ return Object.assign(Object.assign({}, methods), { child, isLevelEnabled: (level) => isLevelEnabled(level, resolvedConfig), config: resolvedConfig });
99
+ };
100
+ exports.createLogger = createLogger;
101
+ const configureDataTableLogging = (options) => {
102
+ globalConfig = resolveConfig(options.scope, options, globalConfig);
103
+ };
104
+ exports.configureDataTableLogging = configureDataTableLogging;
105
+ const getDataTableLoggingConfig = () => (Object.assign({}, globalConfig));
106
+ exports.getDataTableLoggingConfig = getDataTableLoggingConfig;