@ackplus/mui-tanstack-data-grid 1.0.0

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 (119) hide show
  1. package/README.md +22 -0
  2. package/dist/components/data-table.d.ts +4 -0
  3. package/dist/components/data-table.d.ts.map +1 -0
  4. package/dist/components/data-table.js +24 -0
  5. package/dist/components/filters/filter-value-input.d.ts +10 -0
  6. package/dist/components/filters/filter-value-input.d.ts.map +1 -0
  7. package/dist/components/filters/filter-value-input.js +39 -0
  8. package/dist/components/filters/index.d.ts +3 -0
  9. package/dist/components/filters/index.d.ts.map +1 -0
  10. package/dist/components/filters/index.js +18 -0
  11. package/dist/components/filters/operators.d.ts +93 -0
  12. package/dist/components/filters/operators.d.ts.map +1 -0
  13. package/dist/components/filters/operators.js +42 -0
  14. package/dist/components/grid/grid-view.d.ts +8 -0
  15. package/dist/components/grid/grid-view.d.ts.map +1 -0
  16. package/dist/components/grid/grid-view.js +151 -0
  17. package/dist/components/grid/styled.d.ts +17 -0
  18. package/dist/components/grid/styled.d.ts.map +1 -0
  19. package/dist/components/grid/styled.js +68 -0
  20. package/dist/components/index.d.ts +8 -0
  21. package/dist/components/index.d.ts.map +1 -0
  22. package/dist/components/index.js +23 -0
  23. package/dist/components/toolbar/bulk-actions-toolbar.d.ts +10 -0
  24. package/dist/components/toolbar/bulk-actions-toolbar.d.ts.map +1 -0
  25. package/dist/components/toolbar/bulk-actions-toolbar.js +20 -0
  26. package/dist/components/toolbar/column-filter-control.d.ts +8 -0
  27. package/dist/components/toolbar/column-filter-control.d.ts.map +1 -0
  28. package/dist/components/toolbar/column-filter-control.js +93 -0
  29. package/dist/components/toolbar/data-table-toolbar.d.ts +16 -0
  30. package/dist/components/toolbar/data-table-toolbar.d.ts.map +1 -0
  31. package/dist/components/toolbar/data-table-toolbar.js +44 -0
  32. package/dist/core/index.d.ts +2 -0
  33. package/dist/core/index.d.ts.map +1 -0
  34. package/dist/core/index.js +17 -0
  35. package/dist/core/use-data-table.d.ts +83 -0
  36. package/dist/core/use-data-table.d.ts.map +1 -0
  37. package/dist/core/use-data-table.js +1081 -0
  38. package/dist/features/column-filter.feature.d.ts +48 -0
  39. package/dist/features/column-filter.feature.d.ts.map +1 -0
  40. package/dist/features/column-filter.feature.js +270 -0
  41. package/dist/features/index.d.ts +3 -0
  42. package/dist/features/index.d.ts.map +1 -0
  43. package/dist/features/index.js +18 -0
  44. package/dist/features/selection.feature.d.ts +49 -0
  45. package/dist/features/selection.feature.d.ts.map +1 -0
  46. package/dist/features/selection.feature.js +159 -0
  47. package/dist/index.d.ts +13 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +34 -0
  50. package/dist/theme/create-data-table-theme.d.ts +16 -0
  51. package/dist/theme/create-data-table-theme.d.ts.map +1 -0
  52. package/dist/theme/create-data-table-theme.js +18 -0
  53. package/dist/theme/index.d.ts +7 -0
  54. package/dist/theme/index.d.ts.map +1 -0
  55. package/dist/theme/index.js +22 -0
  56. package/dist/theme/mui-augmentation.d.ts +40 -0
  57. package/dist/theme/mui-augmentation.d.ts.map +1 -0
  58. package/dist/theme/mui-augmentation.js +2 -0
  59. package/dist/theme/palette.d.ts +24 -0
  60. package/dist/theme/palette.d.ts.map +1 -0
  61. package/dist/theme/palette.js +23 -0
  62. package/dist/theme/tokens.d.ts +43 -0
  63. package/dist/theme/tokens.d.ts.map +1 -0
  64. package/dist/theme/tokens.js +40 -0
  65. package/dist/theme/use-data-table-tokens.d.ts +4 -0
  66. package/dist/theme/use-data-table-tokens.d.ts.map +1 -0
  67. package/dist/theme/use-data-table-tokens.js +42 -0
  68. package/dist/types/api.types.d.ts +156 -0
  69. package/dist/types/api.types.d.ts.map +1 -0
  70. package/dist/types/api.types.js +2 -0
  71. package/dist/types/column.types.d.ts +60 -0
  72. package/dist/types/column.types.d.ts.map +1 -0
  73. package/dist/types/column.types.js +7 -0
  74. package/dist/types/data-table.types.d.ts +161 -0
  75. package/dist/types/data-table.types.d.ts.map +1 -0
  76. package/dist/types/data-table.types.js +2 -0
  77. package/dist/types/export.types.d.ts +32 -0
  78. package/dist/types/export.types.d.ts.map +1 -0
  79. package/dist/types/export.types.js +2 -0
  80. package/dist/types/filter.types.d.ts +15 -0
  81. package/dist/types/filter.types.d.ts.map +1 -0
  82. package/dist/types/filter.types.js +2 -0
  83. package/dist/types/index.d.ts +10 -0
  84. package/dist/types/index.d.ts.map +1 -0
  85. package/dist/types/index.js +25 -0
  86. package/dist/types/logging.types.d.ts +23 -0
  87. package/dist/types/logging.types.d.ts.map +1 -0
  88. package/dist/types/logging.types.js +2 -0
  89. package/dist/types/selection.types.d.ts +7 -0
  90. package/dist/types/selection.types.d.ts.map +1 -0
  91. package/dist/types/selection.types.js +2 -0
  92. package/dist/types/slots.types.d.ts +41 -0
  93. package/dist/types/slots.types.d.ts.map +1 -0
  94. package/dist/types/slots.types.js +2 -0
  95. package/dist/types/state.types.d.ts +46 -0
  96. package/dist/types/state.types.d.ts.map +1 -0
  97. package/dist/types/state.types.js +2 -0
  98. package/dist/utils/column-helpers.d.ts +9 -0
  99. package/dist/utils/column-helpers.d.ts.map +1 -0
  100. package/dist/utils/column-helpers.js +46 -0
  101. package/dist/utils/debounced-fetch.utils.d.ts +22 -0
  102. package/dist/utils/debounced-fetch.utils.d.ts.map +1 -0
  103. package/dist/utils/debounced-fetch.utils.js +85 -0
  104. package/dist/utils/export-utils.d.ts +49 -0
  105. package/dist/utils/export-utils.d.ts.map +1 -0
  106. package/dist/utils/export-utils.js +372 -0
  107. package/dist/utils/index.d.ts +7 -0
  108. package/dist/utils/index.d.ts.map +1 -0
  109. package/dist/utils/index.js +22 -0
  110. package/dist/utils/logger.d.ts +24 -0
  111. package/dist/utils/logger.d.ts.map +1 -0
  112. package/dist/utils/logger.js +107 -0
  113. package/dist/utils/special-columns.d.ts +9 -0
  114. package/dist/utils/special-columns.d.ts.map +1 -0
  115. package/dist/utils/special-columns.js +80 -0
  116. package/dist/utils/table-helpers.d.ts +16 -0
  117. package/dist/utils/table-helpers.d.ts.map +1 -0
  118. package/dist/utils/table-helpers.js +50 -0
  119. package/package.json +74 -0
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Export subsystem — CSV + Excel, client + server (chunked), with cancellation
3
+ * and progress/state callbacks. Ported from v1; `xlsx` is now **lazy-loaded**
4
+ * via dynamic `import()` inside the Excel branch, so it's not pulled into the
5
+ * initial bundle and only loads when an Excel export actually runs.
6
+ */
7
+ import type { Table } from '@tanstack/react-table';
8
+ import type { SelectionState } from '../types/selection.types';
9
+ import type { ExportPhase, ServerExportResult } from '../types/export.types';
10
+ export interface ExportOptions {
11
+ format: 'csv' | 'excel';
12
+ filename: string;
13
+ onProgress?: (progress: {
14
+ processedRows?: number;
15
+ totalRows?: number;
16
+ percentage?: number;
17
+ }) => void;
18
+ onComplete?: (result: {
19
+ success: boolean;
20
+ filename: string;
21
+ totalRows: number;
22
+ }) => void;
23
+ onError?: (error: {
24
+ message: string;
25
+ code: string;
26
+ }) => void;
27
+ onStateChange?: (state: {
28
+ phase: ExportPhase;
29
+ processedRows?: number;
30
+ totalRows?: number;
31
+ percentage?: number;
32
+ message?: string;
33
+ code?: string;
34
+ }) => void;
35
+ signal?: AbortSignal;
36
+ sanitizeCSV?: boolean;
37
+ }
38
+ export interface ServerExportOptions extends ExportOptions {
39
+ fetchData: (filters?: any, selection?: SelectionState, signal?: AbortSignal) => Promise<ServerExportResult<any>>;
40
+ currentFilters?: any;
41
+ selection?: SelectionState;
42
+ chunkSize?: number;
43
+ strictTotalCheck?: boolean;
44
+ }
45
+ /** Client export: selected rows if any, else filtered rows; visible non-hidden columns. */
46
+ export declare function exportClientData<TData>(table: Table<TData>, options: ExportOptions): Promise<void>;
47
+ /** Server export: chunked fetch (or direct blob/fileUrl), then build the file. */
48
+ export declare function exportServerData<TData>(table: Table<TData>, options: ServerExportOptions): Promise<void>;
49
+ //# sourceMappingURL=export-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export-utils.d.ts","sourceRoot":"","sources":["../../src/utils/export-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE7E,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,KAAK,GAAG,OAAO,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACrG,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACzF,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC7D,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE;QACpB,KAAK,EAAE,WAAW,CAAC;QACnB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,KAAK,IAAI,CAAC;IACX,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACtD,SAAS,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC;IACjH,cAAc,CAAC,EAAE,GAAG,CAAC;IACrB,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B;AA4FD,2FAA2F;AAC3F,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDxG;AAED,kFAAkF;AAClF,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4H9G"}
@@ -0,0 +1,372 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.exportClientData = exportClientData;
37
+ exports.exportServerData = exportServerData;
38
+ const EXPORT_CANCELLED_CODE = 'CANCELLED';
39
+ const DEFAULT_CHUNK_SIZE = 1000;
40
+ const MAX_SERVER_EXPORT_PAGES = 10000;
41
+ function createCancelledExportError() {
42
+ const error = new Error('Export cancelled');
43
+ error.name = 'AbortError';
44
+ error.code = EXPORT_CANCELLED_CODE;
45
+ return error;
46
+ }
47
+ function isCancelledError(error) {
48
+ if (!(error instanceof Error))
49
+ return false;
50
+ return error.name === 'AbortError' || error.code === EXPORT_CANCELLED_CODE;
51
+ }
52
+ function throwIfExportCancelled(signal) {
53
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted)
54
+ throw createCancelledExportError();
55
+ }
56
+ function waitWithAbort(ms, signal) {
57
+ if (!signal)
58
+ return new Promise((resolve) => setTimeout(resolve, ms));
59
+ return new Promise((resolve, reject) => {
60
+ const timer = setTimeout(() => {
61
+ signal.removeEventListener('abort', onAbort);
62
+ resolve();
63
+ }, ms);
64
+ const onAbort = () => {
65
+ clearTimeout(timer);
66
+ signal.removeEventListener('abort', onAbort);
67
+ reject(createCancelledExportError());
68
+ };
69
+ signal.addEventListener('abort', onAbort, { once: true });
70
+ });
71
+ }
72
+ function notifyState(onStateChange, state) {
73
+ onStateChange === null || onStateChange === void 0 ? void 0 : onStateChange(state);
74
+ }
75
+ function isServerExportDataResult(result) {
76
+ return !!result && typeof result === 'object' && 'data' in result && Array.isArray(result.data);
77
+ }
78
+ function isServerExportBlobResult(result) {
79
+ return !!result && typeof result === 'object' && 'blob' in result && result.blob instanceof Blob;
80
+ }
81
+ function isServerExportFileUrlResult(result) {
82
+ return !!result && typeof result === 'object' && typeof result.fileUrl === 'string';
83
+ }
84
+ function resolveExportHeader(columnDef, columnId) {
85
+ var _a;
86
+ const defaultHeader = typeof (columnDef === null || columnDef === void 0 ? void 0 : columnDef.header) === 'string' ? columnDef.header : columnId;
87
+ if ((columnDef === null || columnDef === void 0 ? void 0 : columnDef.exportHeader) === undefined || (columnDef === null || columnDef === void 0 ? void 0 : columnDef.exportHeader) === null)
88
+ return defaultHeader;
89
+ if (typeof columnDef.exportHeader === 'function') {
90
+ return String((_a = columnDef.exportHeader({ columnId, defaultHeader, columnDef })) !== null && _a !== void 0 ? _a : defaultHeader);
91
+ }
92
+ return String(columnDef.exportHeader);
93
+ }
94
+ function applyExportValueTransform(columnDef, value, row, rowIndex, columnId) {
95
+ if (typeof (columnDef === null || columnDef === void 0 ? void 0 : columnDef.exportValue) === 'function') {
96
+ return columnDef.exportValue({ value, row, rowIndex, columnId, columnDef });
97
+ }
98
+ return value;
99
+ }
100
+ function applyExportFormatTransform(columnDef, value, row, rowIndex, columnId) {
101
+ const format = columnDef === null || columnDef === void 0 ? void 0 : columnDef.exportFormat;
102
+ if (!format || format === 'auto')
103
+ return value;
104
+ if (typeof format === 'function')
105
+ return format({ value, row, rowIndex, columnId, columnDef });
106
+ if (value === null || value === undefined)
107
+ return '';
108
+ switch (format) {
109
+ case 'string': return String(value);
110
+ case 'number': return Number(value);
111
+ case 'boolean': return Boolean(value);
112
+ case 'json': return JSON.stringify(value);
113
+ case 'date': return value instanceof Date ? value.toISOString() : String(value);
114
+ default: return value;
115
+ }
116
+ }
117
+ function normalizeExportValue(value) {
118
+ if (value === null || value === undefined)
119
+ return '';
120
+ if (value instanceof Date)
121
+ return value.toISOString();
122
+ if (typeof value === 'object')
123
+ return JSON.stringify(value);
124
+ return value;
125
+ }
126
+ /** Client export: selected rows if any, else filtered rows; visible non-hidden columns. */
127
+ async function exportClientData(table, options) {
128
+ var _a;
129
+ const { format, filename, onProgress, onComplete, onError, onStateChange, signal, sanitizeCSV = true } = options;
130
+ try {
131
+ throwIfExportCancelled(signal);
132
+ notifyState(onStateChange, { phase: 'starting' });
133
+ const selectedRows = table.getSelectedRows ? table.getSelectedRows() : [];
134
+ const rowsToExport = selectedRows.length > 0 ? selectedRows : table.getFilteredRowModel().rows;
135
+ const exportData = [];
136
+ const visibleColumns = table.getVisibleLeafColumns().filter((col) => col.columnDef.hideInExport !== true);
137
+ for (let index = 0; index < rowsToExport.length; index++) {
138
+ throwIfExportCancelled(signal);
139
+ const row = rowsToExport[index];
140
+ const percentage = Math.round(((index + 1) / rowsToExport.length) * 100);
141
+ onProgress === null || onProgress === void 0 ? void 0 : onProgress({ processedRows: index + 1, totalRows: rowsToExport.length, percentage });
142
+ notifyState(onStateChange, { phase: 'processing', processedRows: index + 1, totalRows: rowsToExport.length, percentage });
143
+ const rowData = {};
144
+ for (const column of visibleColumns) {
145
+ const columnDef = column.columnDef;
146
+ const header = resolveExportHeader(columnDef, column.id);
147
+ const cell = row.getVisibleCells().find((c) => c.column.id === column.id);
148
+ const baseValue = cell ? cell.getValue() : (_a = row === null || row === void 0 ? void 0 : row.original) === null || _a === void 0 ? void 0 : _a[column.id];
149
+ const transformedValue = applyExportFormatTransform(columnDef, applyExportValueTransform(columnDef, baseValue, row.original, index, column.id), row.original, index, column.id);
150
+ rowData[header] = normalizeExportValue(transformedValue);
151
+ }
152
+ exportData.push(rowData);
153
+ }
154
+ notifyState(onStateChange, { phase: 'downloading', processedRows: exportData.length, totalRows: exportData.length, percentage: 100 });
155
+ await exportToFile(exportData, format, filename, signal, sanitizeCSV);
156
+ const resolvedName = `${filename}.${format === 'excel' ? 'xlsx' : 'csv'}`;
157
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete({ success: true, filename: resolvedName, totalRows: exportData.length });
158
+ notifyState(onStateChange, { phase: 'completed', processedRows: exportData.length, totalRows: exportData.length, percentage: 100 });
159
+ }
160
+ catch (error) {
161
+ if (isCancelledError(error)) {
162
+ notifyState(onStateChange, { phase: 'cancelled', code: EXPORT_CANCELLED_CODE });
163
+ return;
164
+ }
165
+ // eslint-disable-next-line no-console
166
+ console.error('Client export failed:', error);
167
+ const message = error instanceof Error ? error.message : 'Export failed';
168
+ notifyState(onStateChange, { phase: 'error', message, code: 'CLIENT_EXPORT_ERROR' });
169
+ onError === null || onError === void 0 ? void 0 : onError({ message, code: 'CLIENT_EXPORT_ERROR' });
170
+ }
171
+ }
172
+ /** Server export: chunked fetch (or direct blob/fileUrl), then build the file. */
173
+ async function exportServerData(table, options) {
174
+ var _a, _b, _c, _d;
175
+ const { format, filename, fetchData, currentFilters, selection, onProgress, onComplete, onError, onStateChange, signal, chunkSize = DEFAULT_CHUNK_SIZE, strictTotalCheck = false, sanitizeCSV = true, } = options;
176
+ try {
177
+ throwIfExportCancelled(signal);
178
+ notifyState(onStateChange, { phase: 'starting' });
179
+ onProgress === null || onProgress === void 0 ? void 0 : onProgress({});
180
+ notifyState(onStateChange, { phase: 'fetching' });
181
+ const initialResponse = await fetchData({ ...currentFilters, pagination: { pageIndex: 0, pageSize: 1 } }, selection, signal);
182
+ if (isServerExportBlobResult(initialResponse)) {
183
+ throwIfExportCancelled(signal);
184
+ const resolvedName = initialResponse.filename || `${filename}.${format === 'excel' ? 'xlsx' : 'csv'}`;
185
+ notifyState(onStateChange, { phase: 'downloading' });
186
+ downloadFile(initialResponse.blob, resolvedName, initialResponse.mimeType || initialResponse.blob.type || 'application/octet-stream');
187
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete({ success: true, filename: resolvedName, totalRows: (_a = initialResponse.total) !== null && _a !== void 0 ? _a : 0 });
188
+ notifyState(onStateChange, { phase: 'completed' });
189
+ return;
190
+ }
191
+ if (isServerExportFileUrlResult(initialResponse)) {
192
+ throwIfExportCancelled(signal);
193
+ const resolvedName = initialResponse.filename || `${filename}.${format === 'excel' ? 'xlsx' : 'csv'}`;
194
+ notifyState(onStateChange, { phase: 'downloading' });
195
+ await downloadFromUrl(initialResponse.fileUrl, resolvedName, initialResponse.mimeType || 'application/octet-stream', signal);
196
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete({ success: true, filename: resolvedName, totalRows: (_b = initialResponse.total) !== null && _b !== void 0 ? _b : 0 });
197
+ notifyState(onStateChange, { phase: 'completed' });
198
+ return;
199
+ }
200
+ if (!isServerExportDataResult(initialResponse))
201
+ throw new Error('Invalid data received from server');
202
+ const totalRows = typeof initialResponse.total === 'number' ? initialResponse.total : initialResponse.data.length;
203
+ const hasTotal = typeof totalRows === 'number' && totalRows >= 0;
204
+ let allData = [];
205
+ for (let page = 0; page < MAX_SERVER_EXPORT_PAGES; page++) {
206
+ throwIfExportCancelled(signal);
207
+ const chunkResponse = await fetchData({ ...currentFilters, pagination: { pageIndex: page, pageSize: chunkSize } }, selection, signal);
208
+ if (isServerExportBlobResult(chunkResponse)) {
209
+ throwIfExportCancelled(signal);
210
+ const resolvedName = chunkResponse.filename || `${filename}.${format === 'excel' ? 'xlsx' : 'csv'}`;
211
+ notifyState(onStateChange, { phase: 'downloading' });
212
+ downloadFile(chunkResponse.blob, resolvedName, chunkResponse.mimeType || chunkResponse.blob.type || 'application/octet-stream');
213
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete({ success: true, filename: resolvedName, totalRows: (_c = chunkResponse.total) !== null && _c !== void 0 ? _c : allData.length });
214
+ notifyState(onStateChange, { phase: 'completed' });
215
+ return;
216
+ }
217
+ if (isServerExportFileUrlResult(chunkResponse)) {
218
+ throwIfExportCancelled(signal);
219
+ const resolvedName = chunkResponse.filename || `${filename}.${format === 'excel' ? 'xlsx' : 'csv'}`;
220
+ notifyState(onStateChange, { phase: 'downloading' });
221
+ await downloadFromUrl(chunkResponse.fileUrl, resolvedName, chunkResponse.mimeType || 'application/octet-stream', signal);
222
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete({ success: true, filename: resolvedName, totalRows: (_d = chunkResponse.total) !== null && _d !== void 0 ? _d : allData.length });
223
+ notifyState(onStateChange, { phase: 'completed' });
224
+ return;
225
+ }
226
+ if (!isServerExportDataResult(chunkResponse))
227
+ throw new Error(`Failed to fetch chunk ${page + 1}`);
228
+ const chunkData = chunkResponse.data;
229
+ if (chunkData.length === 0)
230
+ break;
231
+ allData.push(...chunkData);
232
+ const percentage = hasTotal && totalRows > 0 ? Math.min(100, Math.round((allData.length / totalRows) * 100)) : undefined;
233
+ onProgress === null || onProgress === void 0 ? void 0 : onProgress({ processedRows: allData.length, totalRows: hasTotal ? totalRows : undefined, percentage });
234
+ notifyState(onStateChange, { phase: 'fetching', processedRows: allData.length, totalRows: hasTotal ? totalRows : undefined, percentage });
235
+ if (hasTotal) {
236
+ if (allData.length >= totalRows)
237
+ break;
238
+ }
239
+ else if (chunkData.length < chunkSize) {
240
+ break;
241
+ }
242
+ await waitWithAbort(100, signal);
243
+ }
244
+ if (hasTotal && allData.length > totalRows)
245
+ allData = allData.slice(0, totalRows);
246
+ if (hasTotal && strictTotalCheck && allData.length < totalRows) {
247
+ throw new Error(`Expected ${totalRows} rows for export but received ${allData.length}`);
248
+ }
249
+ throwIfExportCancelled(signal);
250
+ const visibleColumns = table.getVisibleLeafColumns().filter((col) => col.getIsVisible() && col.columnDef.hideInExport !== true);
251
+ const exportData = [];
252
+ for (let index = 0; index < allData.length; index++) {
253
+ throwIfExportCancelled(signal);
254
+ const rowData = allData[index];
255
+ const exportRow = {};
256
+ visibleColumns.forEach((column) => {
257
+ const columnDef = column.columnDef;
258
+ const header = resolveExportHeader(columnDef, column.id);
259
+ let value = rowData[column.id];
260
+ if (typeof column.accessorFn === 'function')
261
+ value = column.accessorFn(rowData, index);
262
+ value = applyExportValueTransform(columnDef, value, rowData, index, column.id);
263
+ value = applyExportFormatTransform(columnDef, value, rowData, index, column.id);
264
+ exportRow[header] = normalizeExportValue(value);
265
+ });
266
+ exportData.push(exportRow);
267
+ if (allData.length > 0) {
268
+ notifyState(onStateChange, { phase: 'processing', processedRows: index + 1, totalRows: allData.length, percentage: Math.round(((index + 1) / allData.length) * 100) });
269
+ }
270
+ }
271
+ notifyState(onStateChange, { phase: 'downloading' });
272
+ await exportToFile(exportData, format, filename, signal, sanitizeCSV);
273
+ const resolvedName = `${filename}.${format === 'excel' ? 'xlsx' : 'csv'}`;
274
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete({ success: true, filename: resolvedName, totalRows: exportData.length });
275
+ notifyState(onStateChange, { phase: 'completed', processedRows: exportData.length, totalRows: exportData.length, percentage: 100 });
276
+ }
277
+ catch (error) {
278
+ if (isCancelledError(error)) {
279
+ notifyState(onStateChange, { phase: 'cancelled', code: EXPORT_CANCELLED_CODE });
280
+ return;
281
+ }
282
+ // eslint-disable-next-line no-console
283
+ console.error('Server export failed:', error);
284
+ const message = error instanceof Error ? error.message : 'Export failed';
285
+ notifyState(onStateChange, { phase: 'error', message, code: 'SERVER_EXPORT_ERROR' });
286
+ onError === null || onError === void 0 ? void 0 : onError({ message, code: 'SERVER_EXPORT_ERROR' });
287
+ }
288
+ }
289
+ async function exportToFile(data, format, filename, signal, sanitizeCSV = true) {
290
+ throwIfExportCancelled(signal);
291
+ if (data.length === 0)
292
+ throw new Error('No data to export');
293
+ if (format === 'csv') {
294
+ const csv = convertToCSV(data, sanitizeCSV);
295
+ throwIfExportCancelled(signal);
296
+ downloadFile(csv, `${filename}.csv`, 'text/csv');
297
+ }
298
+ else {
299
+ // Lazy-load xlsx only when an Excel export actually runs.
300
+ const XLSX = await Promise.resolve().then(() => __importStar(require('xlsx')));
301
+ const workbook = XLSX.utils.book_new();
302
+ const worksheet = XLSX.utils.json_to_sheet(data);
303
+ XLSX.utils.book_append_sheet(workbook, worksheet, 'Data');
304
+ const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
305
+ const blob = new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
306
+ throwIfExportCancelled(signal);
307
+ downloadFile(blob, `${filename}.xlsx`, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
308
+ }
309
+ }
310
+ function convertToCSV(data, sanitizeCSV) {
311
+ if (data.length === 0)
312
+ return '';
313
+ const headers = Object.keys(data[0]);
314
+ const csvRows = [headers.join(',')];
315
+ for (const row of data) {
316
+ const values = headers.map((header) => {
317
+ var _a;
318
+ const rawValue = (_a = row[header]) !== null && _a !== void 0 ? _a : '';
319
+ const normalizedValue = sanitizeCSV ? sanitizeCSVCellValue(rawValue) : rawValue;
320
+ const value = normalizedValue === null || normalizedValue === undefined ? '' : String(normalizedValue);
321
+ if (value.includes(',') || value.includes('"') || value.includes('\n')) {
322
+ return `"${value.replace(/"/g, '""')}"`;
323
+ }
324
+ return value;
325
+ });
326
+ csvRows.push(values.join(','));
327
+ }
328
+ return csvRows.join('\n');
329
+ }
330
+ function sanitizeCSVCellValue(value) {
331
+ if (typeof value !== 'string' || value.length === 0)
332
+ return value;
333
+ const first = value[0];
334
+ if (first === '=' || first === '+' || first === '-' || first === '@')
335
+ return `'${value}`;
336
+ return value;
337
+ }
338
+ async function downloadFromUrl(url, filename, mimeType, signal) {
339
+ throwIfExportCancelled(signal);
340
+ try {
341
+ const response = await fetch(url, { signal });
342
+ if (!response.ok)
343
+ throw new Error(`Failed to download export file from URL (${response.status})`);
344
+ const blob = await response.blob();
345
+ throwIfExportCancelled(signal);
346
+ downloadFile(blob, filename, mimeType || blob.type || 'application/octet-stream');
347
+ }
348
+ catch (error) {
349
+ if (isCancelledError(error))
350
+ throw error;
351
+ // Fallback for URLs that block fetch (CORS) — let the browser handle it.
352
+ const link = document.createElement('a');
353
+ link.href = url;
354
+ link.download = filename;
355
+ link.style.display = 'none';
356
+ document.body.appendChild(link);
357
+ link.click();
358
+ document.body.removeChild(link);
359
+ }
360
+ }
361
+ function downloadFile(content, filename, mimeType) {
362
+ const blob = content instanceof Blob ? content : new Blob([content], { type: mimeType });
363
+ const url = URL.createObjectURL(blob);
364
+ const link = document.createElement('a');
365
+ link.href = url;
366
+ link.download = filename;
367
+ link.style.display = 'none';
368
+ document.body.appendChild(link);
369
+ link.click();
370
+ document.body.removeChild(link);
371
+ URL.revokeObjectURL(url);
372
+ }
@@ -0,0 +1,7 @@
1
+ export * from './table-helpers';
2
+ export * from './debounced-fetch.utils';
3
+ export * from './column-helpers';
4
+ export * from './special-columns';
5
+ export * from './logger';
6
+ export * from './export-utils';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./table-helpers"), exports);
18
+ __exportStar(require("./debounced-fetch.utils"), exports);
19
+ __exportStar(require("./column-helpers"), exports);
20
+ __exportStar(require("./special-columns"), exports);
21
+ __exportStar(require("./logger"), exports);
22
+ __exportStar(require("./export-utils"), exports);
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Lightweight, configurable console wrapper (global or per-instance). Ported
3
+ * from v1 unchanged; option/level types now live in `../types/logging.types`.
4
+ */
5
+ import type { LogLevel, ConsoleLike, DataTableLoggingOptions } from '../types/logging.types';
6
+ type LoggerInput = boolean | DataTableLoggingOptions;
7
+ type ResolvedLoggerConfig = Required<Omit<DataTableLoggingOptions, 'logger'>> & {
8
+ logger: ConsoleLike;
9
+ };
10
+ type LogMethodLevel = Exclude<LogLevel, 'silent'>;
11
+ export interface LoggerInstance {
12
+ debug: (...args: unknown[]) => void;
13
+ info: (...args: unknown[]) => void;
14
+ warn: (...args: unknown[]) => void;
15
+ error: (...args: unknown[]) => void;
16
+ child: (scope: string, overrides?: LoggerInput) => LoggerInstance;
17
+ isLevelEnabled: (level: LogMethodLevel) => boolean;
18
+ config: ResolvedLoggerConfig;
19
+ }
20
+ export declare const createLogger: (scope?: string, input?: LoggerInput, parentConfig?: ResolvedLoggerConfig) => LoggerInstance;
21
+ export declare const configureDataTableLogging: (options: DataTableLoggingOptions) => void;
22
+ export declare const getDataTableLoggingConfig: () => ResolvedLoggerConfig;
23
+ export {};
24
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAE7F,KAAK,WAAW,GAAG,OAAO,GAAG,uBAAuB,CAAC;AAErD,KAAK,oBAAoB,GAAG,QAAQ,CAAC,IAAI,CAAC,uBAAuB,EAAE,QAAQ,CAAC,CAAC,GAAG;IAC5E,MAAM,EAAE,WAAW,CAAC;CACvB,CAAC;AAEF,KAAK,cAAc,GAAG,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAwElD,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACnC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACnC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,WAAW,KAAK,cAAc,CAAC;IAClE,cAAc,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC;IACnD,MAAM,EAAE,oBAAoB,CAAC;CAChC;AAoBD,eAAO,MAAM,YAAY,GACrB,QAAQ,MAAM,EACd,QAAQ,WAAW,EACnB,eAAe,oBAAoB,KACpC,cAiBF,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,SAAS,uBAAuB,SAEzE,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAAO,oBAA6C,CAAC"}
@@ -0,0 +1,107 @@
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
+ return LOG_LEVEL_ORDER[level] <= LOG_LEVEL_ORDER[config.level];
32
+ };
33
+ const formatPrefix = (level, config) => {
34
+ const segments = [];
35
+ if (config.prefix)
36
+ segments.push(config.prefix);
37
+ if (config.scope)
38
+ segments.push(config.scope);
39
+ const prefix = segments.length > 0 ? `[${segments.join(':')}]` : '';
40
+ return config.includeTimestamp
41
+ ? `[${new Date().toISOString()}]${prefix ? ` ${prefix}` : ''} [${level.toUpperCase()}]`
42
+ : `${prefix ? `${prefix} ` : ''}[${level.toUpperCase()}]`;
43
+ };
44
+ const getConsoleMethod = (level, logger) => {
45
+ var _a, _b, _c;
46
+ const methodName = level === 'debug' ? 'debug' : level;
47
+ 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);
48
+ };
49
+ const normaliseInput = (input) => {
50
+ if (typeof input === 'boolean')
51
+ return { enabled: input };
52
+ return input !== null && input !== void 0 ? input : {};
53
+ };
54
+ const resolveConfig = (scope, input, parent) => {
55
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
56
+ const overrides = normaliseInput(input);
57
+ const base = parent !== null && parent !== void 0 ? parent : globalConfig;
58
+ return {
59
+ enabled: (_a = overrides.enabled) !== null && _a !== void 0 ? _a : base.enabled,
60
+ level: (_b = overrides.level) !== null && _b !== void 0 ? _b : base.level,
61
+ prefix: (_c = overrides.prefix) !== null && _c !== void 0 ? _c : base.prefix,
62
+ scope: (_f = (_e = (_d = overrides.scope) !== null && _d !== void 0 ? _d : scope) !== null && _e !== void 0 ? _e : base.scope) !== null && _f !== void 0 ? _f : '',
63
+ includeTimestamp: (_g = overrides.includeTimestamp) !== null && _g !== void 0 ? _g : base.includeTimestamp,
64
+ logger: (_j = (_h = overrides.logger) !== null && _h !== void 0 ? _h : base.logger) !== null && _j !== void 0 ? _j : defaultConsole,
65
+ };
66
+ };
67
+ const createLoggerMethods = (config) => {
68
+ const logWithLevel = (level) => {
69
+ const consoleMethod = getConsoleMethod(level, config.logger);
70
+ return (...args) => {
71
+ if (!isLevelEnabled(level, config))
72
+ return;
73
+ consoleMethod(formatPrefix(level, config), ...args);
74
+ };
75
+ };
76
+ return {
77
+ debug: logWithLevel('debug'),
78
+ info: logWithLevel('info'),
79
+ warn: logWithLevel('warn'),
80
+ error: logWithLevel('error'),
81
+ };
82
+ };
83
+ const createLogger = (scope, input, parentConfig) => {
84
+ const resolvedConfig = resolveConfig(scope, input, parentConfig);
85
+ const methods = createLoggerMethods(resolvedConfig);
86
+ const child = (childScope, overrides) => {
87
+ const combinedScope = childScope
88
+ ? resolvedConfig.scope
89
+ ? `${resolvedConfig.scope}.${childScope}`
90
+ : childScope
91
+ : resolvedConfig.scope;
92
+ return (0, exports.createLogger)(combinedScope, overrides, resolvedConfig);
93
+ };
94
+ return {
95
+ ...methods,
96
+ child,
97
+ isLevelEnabled: (level) => isLevelEnabled(level, resolvedConfig),
98
+ config: resolvedConfig,
99
+ };
100
+ };
101
+ exports.createLogger = createLogger;
102
+ const configureDataTableLogging = (options) => {
103
+ globalConfig = resolveConfig(options.scope, options, globalConfig);
104
+ };
105
+ exports.configureDataTableLogging = configureDataTableLogging;
106
+ const getDataTableLoggingConfig = () => ({ ...globalConfig });
107
+ exports.getDataTableLoggingConfig = getDataTableLoggingConfig;
@@ -0,0 +1,9 @@
1
+ import type { DataTableColumn } from '../types/column.types';
2
+ export interface SelectionColumnConfig {
3
+ multiSelect?: boolean;
4
+ }
5
+ /** Auto-generated checkbox selection column, driven by the SelectionFeature. */
6
+ export declare const createSelectionColumn: <T>(config: Partial<DataTableColumn<T>> & SelectionColumnConfig) => DataTableColumn<T, any>;
7
+ /** Auto-generated expand/collapse column for row detail panels. */
8
+ export declare const createExpandingColumn: <T>(config: Partial<DataTableColumn<T>>) => DataTableColumn<T>;
9
+ //# sourceMappingURL=special-columns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"special-columns.d.ts","sourceRoot":"","sources":["../../src/utils/special-columns.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,WAAW,qBAAqB;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,gFAAgF;AAChF,eAAO,MAAM,qBAAqB,GAAI,CAAC,EACnC,QAAQ,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG,qBAAqB,KAC5D,eAAe,CAAC,CAAC,EAAE,GAAG,CAwCvB,CAAC;AAEH,mEAAmE;AACnE,eAAO,MAAM,qBAAqB,GAAI,CAAC,EAAE,QAAQ,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,KAAG,eAAe,CAAC,CAAC,CA2B9F,CAAC"}