@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,1081 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useDataTable = useDataTable;
4
+ /**
5
+ * useDataTable — the headless engine.
6
+ *
7
+ * Owns all table logic (data, sorting, filtering, pagination, selection, column
8
+ * state, server fetch, export, the imperative API). No DOM — the render layer
9
+ * consumes the result. Ported from v1 `use-data-table-engine.ts` with:
10
+ * - deprecated prop aliases resolved (enableColumnDragging→enableColumnReordering, …)
11
+ * - `console.log` debug noise replaced by the gated logger
12
+ * - real `getRowId` support (stable row identity across pages)
13
+ * - the obsolete MUI-`<table>` layout math removed (the div/grid layer sizes columns)
14
+ */
15
+ const react_table_1 = require("@tanstack/react-table");
16
+ const react_virtual_1 = require("@tanstack/react-virtual");
17
+ const styles_1 = require("@mui/material/styles");
18
+ const react_1 = require("react");
19
+ const features_1 = require("../features");
20
+ const utils_1 = require("../utils");
21
+ const DEFAULT_INITIAL_STATE = {
22
+ sorting: [],
23
+ pagination: { pageIndex: 0, pageSize: 10 },
24
+ selectionState: { ids: [], type: 'include' },
25
+ globalFilter: '',
26
+ expanded: {},
27
+ columnOrder: [],
28
+ columnPinning: { left: [], right: [] },
29
+ columnVisibility: {},
30
+ columnSizing: {},
31
+ columnFilter: {
32
+ filters: [],
33
+ logic: 'AND',
34
+ pendingFilters: [],
35
+ pendingLogic: 'AND',
36
+ },
37
+ };
38
+ function uiReducer(state, action) {
39
+ switch (action.type) {
40
+ case 'SET_SORTING_RESET_PAGE':
41
+ return { ...state, sorting: action.payload, pagination: { pageIndex: 0, pageSize: state.pagination.pageSize } };
42
+ case 'SET_PAGINATION':
43
+ return { ...state, pagination: action.payload };
44
+ case 'SET_GLOBAL_FILTER_RESET_PAGE':
45
+ return { ...state, globalFilter: action.payload, pagination: { pageIndex: 0, pageSize: state.pagination.pageSize } };
46
+ case 'SET_SELECTION':
47
+ return { ...state, selectionState: action.payload };
48
+ case 'SET_COLUMN_FILTER':
49
+ return { ...state, columnFilter: action.payload };
50
+ case 'SET_COLUMN_FILTER_RESET_PAGE':
51
+ return { ...state, columnFilter: action.payload, pagination: { pageIndex: 0, pageSize: state.pagination.pageSize } };
52
+ case 'SET_EXPANDED':
53
+ return { ...state, expanded: action.payload };
54
+ case 'SET_DENSITY':
55
+ return { ...state, density: action.payload };
56
+ case 'SET_COLUMN_ORDER':
57
+ return { ...state, columnOrder: action.payload };
58
+ case 'SET_COLUMN_PINNING':
59
+ return { ...state, columnPinning: action.payload };
60
+ case 'SET_COLUMN_VISIBILITY':
61
+ return { ...state, columnVisibility: action.payload };
62
+ case 'SET_COLUMN_SIZING':
63
+ return { ...state, columnSizing: action.payload };
64
+ case 'RESTORE_LAYOUT':
65
+ case 'RESET_ALL':
66
+ return { ...state, ...action.payload };
67
+ default:
68
+ return state;
69
+ }
70
+ }
71
+ function useLatestRef(value) {
72
+ const ref = (0, react_1.useRef)(value);
73
+ (0, react_1.useEffect)(() => {
74
+ ref.current = value;
75
+ }, [value]);
76
+ return ref;
77
+ }
78
+ function useEvent(fn) {
79
+ const fnRef = useLatestRef(fn);
80
+ return (0, react_1.useCallback)(((...args) => fnRef.current(...args)), [fnRef]);
81
+ }
82
+ /** Curated filter payload for server export — matches v1's shape (not the full table state). */
83
+ function curateExportFilters(s) {
84
+ return { globalFilter: s.globalFilter, columnFilter: s.columnFilter, sorting: s.sorting, pagination: s.pagination };
85
+ }
86
+ function useDataTable(props) {
87
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
88
+ const { initialState, columns, data = [], idKey = 'id', getRowId: getRowIdProp, dataMode = 'client', initialLoadData = true, onFetchData, onFetchStateChange, onDataStateChange, enableRowSelection = false, enableMultiRowSelection = true, selectMode = 'page', isRowSelectable, onSelectionChange, enableBulkActions = false, enableColumnResizing = false, columnResizeMode = 'onChange', onColumnSizingChange, enableColumnPinning = false, onColumnPinningChange, onColumnVisibilityChange, enableColumnVisibility = true, getRowCanExpand, enablePagination = false, paginationMode = 'client', enableGlobalFilter = true, enableColumnFilter = false, filterMode = 'client', enableSorting = true, sortingMode = 'client', onSortingChange, exportFilename = 'export', exportConcurrency = 'cancelAndRestart', exportChunkSize = 1000, exportStrictTotalCheck = false, exportSanitizeCSV = true, onExportProgress, onExportComplete, onExportError, onServerExport, onExportCancel, onExportStateChange, fitToScreen = true, enableVirtualization = false, loading = false, onPaginationChange, onGlobalFilterChange, slots = {}, slotProps = {}, logging, } = props;
89
+ // --- resolve deprecated aliases (v1 names still accepted)
90
+ const rowCount = (_b = (_a = props.rowCount) !== null && _a !== void 0 ? _a : props.totalRow) !== null && _b !== void 0 ? _b : 0;
91
+ const enableColumnReordering = (_d = (_c = props.enableColumnReordering) !== null && _c !== void 0 ? _c : props.enableColumnDragging) !== null && _d !== void 0 ? _d : false;
92
+ const onColumnOrderChange = (_e = props.onColumnOrderChange) !== null && _e !== void 0 ? _e : props.onColumnDragEnd;
93
+ const enableExpanding = (_g = (_f = props.enableRowExpansion) !== null && _f !== void 0 ? _f : props.enableExpanding) !== null && _g !== void 0 ? _g : false;
94
+ const onColumnFilterChange = (_h = props.onColumnFilterChange) !== null && _h !== void 0 ? _h : props.onColumnFiltersChange;
95
+ // Density is controlled when `density` (or the deprecated `tableSize`) is passed;
96
+ // otherwise it's uncontrolled (driven by the toolbar's density selector → ui.density).
97
+ const controlledDensity = (_j = props.density) !== null && _j !== void 0 ? _j : (props.tableSize === 'small' ? 'compact' : props.tableSize === 'medium' ? 'standard' : undefined);
98
+ const initialDensity = controlledDensity !== null && controlledDensity !== void 0 ? controlledDensity : 'standard';
99
+ const estimateRowHeight = (_l = (_k = props.estimatedRowHeight) !== null && _k !== void 0 ? _k : props.estimateRowHeight) !== null && _l !== void 0 ? _l : 52;
100
+ const theme = (0, styles_1.useTheme)();
101
+ const log = (0, react_1.useMemo)(() => (0, utils_1.createLogger)('engine', logging), [logging]);
102
+ const isServerMode = dataMode === 'server';
103
+ const isServerPagination = paginationMode === 'server' || isServerMode;
104
+ const isServerFiltering = filterMode === 'server' || isServerMode;
105
+ const isServerSorting = sortingMode === 'server' || isServerMode;
106
+ const initialStateConfig = (0, react_1.useMemo)(() => ({ ...DEFAULT_INITIAL_STATE, ...initialState }), [initialState]);
107
+ const initialUIState = (0, react_1.useMemo)(() => {
108
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
109
+ return ({
110
+ sorting: (_a = initialStateConfig.sorting) !== null && _a !== void 0 ? _a : DEFAULT_INITIAL_STATE.sorting,
111
+ pagination: (_b = initialStateConfig.pagination) !== null && _b !== void 0 ? _b : DEFAULT_INITIAL_STATE.pagination,
112
+ globalFilter: (_c = initialStateConfig.globalFilter) !== null && _c !== void 0 ? _c : DEFAULT_INITIAL_STATE.globalFilter,
113
+ selectionState: (_d = initialStateConfig.selectionState) !== null && _d !== void 0 ? _d : DEFAULT_INITIAL_STATE.selectionState,
114
+ columnFilter: (_e = initialStateConfig.columnFilter) !== null && _e !== void 0 ? _e : DEFAULT_INITIAL_STATE.columnFilter,
115
+ expanded: (_f = initialStateConfig.expanded) !== null && _f !== void 0 ? _f : {},
116
+ density: initialDensity,
117
+ columnOrder: (_g = initialStateConfig.columnOrder) !== null && _g !== void 0 ? _g : DEFAULT_INITIAL_STATE.columnOrder,
118
+ columnPinning: (_h = initialStateConfig.columnPinning) !== null && _h !== void 0 ? _h : DEFAULT_INITIAL_STATE.columnPinning,
119
+ columnVisibility: (_j = initialStateConfig.columnVisibility) !== null && _j !== void 0 ? _j : DEFAULT_INITIAL_STATE.columnVisibility,
120
+ columnSizing: (_k = initialStateConfig.columnSizing) !== null && _k !== void 0 ? _k : DEFAULT_INITIAL_STATE.columnSizing,
121
+ });
122
+ }, [initialStateConfig, initialDensity]);
123
+ const [ui, dispatch] = (0, react_1.useReducer)(uiReducer, initialUIState);
124
+ const [serverData, setServerData] = (0, react_1.useState)(null);
125
+ const [serverTotal, setServerTotal] = (0, react_1.useState)(0);
126
+ const [exportPhase, setExportPhase] = (0, react_1.useState)(null);
127
+ const [exportProgress, setExportProgress] = (0, react_1.useState)({});
128
+ const [exportController, setExportController] = (0, react_1.useState)(null);
129
+ const [queuedExportCount, setQueuedExportCount] = (0, react_1.useState)(0);
130
+ const tableContainerRef = (0, react_1.useRef)(null);
131
+ const apiRef = (0, react_1.useRef)(null);
132
+ const exportControllerRef = (0, react_1.useRef)(null);
133
+ const exportQueueRef = (0, react_1.useRef)(Promise.resolve());
134
+ const lastSentRef = (0, react_1.useRef)('');
135
+ const uiRef = useLatestRef(ui);
136
+ const dataRef = useLatestRef(data);
137
+ const serverDataRef = useLatestRef(serverData);
138
+ const nextFetchDelayRef = (0, react_1.useRef)(0);
139
+ const onFetchDataRef = useLatestRef(onFetchData);
140
+ const onFetchStateChangeRef = useLatestRef(onFetchStateChange);
141
+ const onDataStateChangeRef = useLatestRef(onDataStateChange);
142
+ const onSortingChangeRef = useLatestRef(onSortingChange);
143
+ const onPaginationChangeRef = useLatestRef(onPaginationChange);
144
+ const onGlobalFilterChangeRef = useLatestRef(onGlobalFilterChange);
145
+ const onColumnFilterChangeRef = useLatestRef(onColumnFilterChange);
146
+ const onColumnOrderChangeRef = useLatestRef(onColumnOrderChange);
147
+ const onColumnPinningChangeRef = useLatestRef(onColumnPinningChange);
148
+ const onColumnVisibilityChangeRef = useLatestRef(onColumnVisibilityChange);
149
+ const onColumnSizingChangeRef = useLatestRef(onColumnSizingChange);
150
+ const onSelectionChangeRef = useLatestRef(onSelectionChange);
151
+ const onExportProgressRef = useLatestRef(onExportProgress);
152
+ const onExportCompleteRef = useLatestRef(onExportComplete);
153
+ const onExportErrorRef = useLatestRef(onExportError);
154
+ const onExportCancelRef = useLatestRef(onExportCancel);
155
+ const onExportStateChangeRef = useLatestRef(onExportStateChange);
156
+ const onServerExportRef = useLatestRef(onServerExport);
157
+ const fetchHandler = useEvent((filters, opts) => { var _a; return (_a = onFetchDataRef.current) === null || _a === void 0 ? void 0 : _a.call(onFetchDataRef, filters, opts); });
158
+ const { debouncedFetch, isLoading: fetchLoading } = (0, utils_1.useDebouncedFetch)(fetchHandler);
159
+ const tableData = (0, react_1.useMemo)(() => (serverData !== null ? serverData : data), [serverData, data]);
160
+ const tableTotalRow = (0, react_1.useMemo)(() => (serverData !== null ? serverTotal : rowCount || data.length), [serverData, serverTotal, rowCount, data]);
161
+ const tableLoading = (0, react_1.useMemo)(() => (onFetchData ? loading || fetchLoading : loading), [onFetchData, loading, fetchLoading]);
162
+ const getRowId = (0, react_1.useCallback)((row, index) => (getRowIdProp ? getRowIdProp(row, index) : (0, utils_1.generateRowId)(row, index, idKey)), [getRowIdProp, idKey]);
163
+ const enhancedColumns = (0, react_1.useMemo)(() => {
164
+ let cols = [...columns];
165
+ if (enableExpanding) {
166
+ cols = [
167
+ (0, utils_1.createExpandingColumn)((slotProps === null || slotProps === void 0 ? void 0 : slotProps.expandColumn) && typeof slotProps.expandColumn === 'object' ? slotProps.expandColumn : {}),
168
+ ...cols,
169
+ ];
170
+ }
171
+ if (enableRowSelection) {
172
+ cols = [
173
+ (0, utils_1.createSelectionColumn)({
174
+ ...((slotProps === null || slotProps === void 0 ? void 0 : slotProps.selectionColumn) && typeof slotProps.selectionColumn === 'object'
175
+ ? slotProps.selectionColumn
176
+ : {}),
177
+ multiSelect: enableMultiRowSelection,
178
+ }),
179
+ ...cols,
180
+ ];
181
+ }
182
+ return (0, utils_1.withIdsDeep)(cols);
183
+ }, [columns, enableExpanding, enableRowSelection, enableMultiRowSelection, slotProps === null || slotProps === void 0 ? void 0 : slotProps.expandColumn, slotProps === null || slotProps === void 0 ? void 0 : slotProps.selectionColumn]);
184
+ const fetchData = useEvent(async (overrides = {}, options) => {
185
+ var _a, _b;
186
+ const s = uiRef.current;
187
+ const filters = {
188
+ globalFilter: s.globalFilter,
189
+ pagination: s.pagination,
190
+ columnFilter: s.columnFilter,
191
+ sorting: s.sorting,
192
+ ...overrides,
193
+ };
194
+ (_a = onFetchStateChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onFetchStateChangeRef, filters, options === null || options === void 0 ? void 0 : options.meta);
195
+ const handler = onFetchDataRef.current;
196
+ if (!handler)
197
+ return;
198
+ const delay = (_b = options === null || options === void 0 ? void 0 : options.delay) !== null && _b !== void 0 ? _b : 0;
199
+ const result = await debouncedFetch(filters, { debounceDelay: delay, meta: options === null || options === void 0 ? void 0 : options.meta });
200
+ if (result && Array.isArray(result.data) && result.total !== undefined) {
201
+ setServerData(result.data);
202
+ setServerTotal(result.total);
203
+ }
204
+ return result;
205
+ });
206
+ const isSomeRowsSelected = (0, react_1.useMemo)(() => {
207
+ if (!enableBulkActions || !enableRowSelection)
208
+ return false;
209
+ if (ui.selectionState.type === 'exclude')
210
+ return ui.selectionState.ids.length < tableTotalRow;
211
+ return ui.selectionState.ids.length > 0;
212
+ }, [enableBulkActions, enableRowSelection, ui.selectionState, tableTotalRow]);
213
+ const selectedRowCount = (0, react_1.useMemo)(() => {
214
+ if (!enableBulkActions || !enableRowSelection)
215
+ return 0;
216
+ if (ui.selectionState.type === 'exclude')
217
+ return tableTotalRow - ui.selectionState.ids.length;
218
+ return ui.selectionState.ids.length;
219
+ }, [enableBulkActions, enableRowSelection, ui.selectionState, tableTotalRow]);
220
+ const table = (0, react_table_1.useReactTable)({
221
+ _features: [features_1.ColumnFilterFeature, features_1.SelectionFeature],
222
+ data: tableData,
223
+ columns: enhancedColumns,
224
+ initialState: initialStateConfig,
225
+ state: {
226
+ ...(enableSorting ? { sorting: ui.sorting } : {}),
227
+ ...(enablePagination ? { pagination: ui.pagination } : {}),
228
+ ...(enableGlobalFilter ? { globalFilter: ui.globalFilter } : {}),
229
+ ...(enableExpanding ? { expanded: ui.expanded } : {}),
230
+ ...(enableColumnReordering ? { columnOrder: ui.columnOrder } : {}),
231
+ ...(enableColumnPinning ? { columnPinning: ui.columnPinning } : {}),
232
+ ...(enableColumnVisibility ? { columnVisibility: ui.columnVisibility } : {}),
233
+ ...(enableColumnResizing ? { columnSizing: ui.columnSizing } : {}),
234
+ ...(enableColumnFilter ? { columnFilter: ui.columnFilter } : {}),
235
+ ...(enableRowSelection ? { selectionState: ui.selectionState } : {}),
236
+ },
237
+ selectMode,
238
+ enableAdvanceSelection: !!enableRowSelection,
239
+ isRowSelectable: isRowSelectable,
240
+ ...(enableRowSelection
241
+ ? {
242
+ onSelectionStateChange: (updaterOrValue) => {
243
+ dispatch({
244
+ type: 'SET_SELECTION',
245
+ payload: typeof updaterOrValue === 'function'
246
+ ? updaterOrValue(uiRef.current.selectionState)
247
+ : updaterOrValue,
248
+ });
249
+ },
250
+ }
251
+ : {}),
252
+ enableAdvanceColumnFilter: enableColumnFilter,
253
+ onColumnFilterChange: (updater) => {
254
+ const next = typeof updater === 'function' ? updater(uiRef.current.columnFilter) : updater;
255
+ dispatch({ type: 'SET_COLUMN_FILTER', payload: next });
256
+ },
257
+ onColumnFilterApply: (state) => {
258
+ dispatch({ type: 'SET_COLUMN_FILTER_RESET_PAGE', payload: state });
259
+ },
260
+ ...(enableSorting
261
+ ? {
262
+ onSortingChange: (updaterOrValue) => {
263
+ var _a;
264
+ const prev = uiRef.current.sorting;
265
+ const next = typeof updaterOrValue === 'function' ? updaterOrValue(prev) : updaterOrValue;
266
+ const cleaned = (next || []).filter((s) => s === null || s === void 0 ? void 0 : s.id);
267
+ (_a = onSortingChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onSortingChangeRef, cleaned);
268
+ dispatch({ type: 'SET_SORTING_RESET_PAGE', payload: cleaned });
269
+ },
270
+ }
271
+ : {}),
272
+ ...(enablePagination
273
+ ? {
274
+ onPaginationChange: (updater) => {
275
+ var _a;
276
+ const prev = uiRef.current.pagination;
277
+ const next = typeof updater === 'function' ? updater(prev) : updater;
278
+ (_a = onPaginationChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onPaginationChangeRef, next);
279
+ dispatch({ type: 'SET_PAGINATION', payload: next });
280
+ },
281
+ }
282
+ : {}),
283
+ ...(enableGlobalFilter
284
+ ? {
285
+ onGlobalFilterChange: (updaterOrValue) => {
286
+ var _a;
287
+ const prev = uiRef.current.globalFilter;
288
+ const next = typeof updaterOrValue === 'function' ? updaterOrValue(prev) : updaterOrValue;
289
+ (_a = onGlobalFilterChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onGlobalFilterChangeRef, next);
290
+ nextFetchDelayRef.current = 400;
291
+ dispatch({ type: 'SET_GLOBAL_FILTER_RESET_PAGE', payload: next });
292
+ },
293
+ }
294
+ : {}),
295
+ ...(enableExpanding
296
+ ? {
297
+ onExpandedChange: (u) => {
298
+ const prev = uiRef.current.expanded;
299
+ const next = typeof u === 'function' ? u(prev) : u;
300
+ dispatch({ type: 'SET_EXPANDED', payload: next });
301
+ },
302
+ }
303
+ : {}),
304
+ ...(enableColumnReordering
305
+ ? {
306
+ onColumnOrderChange: (u) => {
307
+ var _a;
308
+ const prev = uiRef.current.columnOrder;
309
+ const next = typeof u === 'function' ? u(prev) : u;
310
+ (_a = onColumnOrderChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onColumnOrderChangeRef, next);
311
+ dispatch({ type: 'SET_COLUMN_ORDER', payload: next });
312
+ },
313
+ }
314
+ : {}),
315
+ ...(enableColumnPinning
316
+ ? {
317
+ onColumnPinningChange: (u) => {
318
+ var _a;
319
+ const prev = uiRef.current.columnPinning;
320
+ const next = typeof u === 'function' ? u(prev) : u;
321
+ (_a = onColumnPinningChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onColumnPinningChangeRef, next);
322
+ dispatch({ type: 'SET_COLUMN_PINNING', payload: next });
323
+ },
324
+ }
325
+ : {}),
326
+ ...(enableColumnVisibility
327
+ ? {
328
+ onColumnVisibilityChange: (u) => {
329
+ var _a;
330
+ const prev = uiRef.current.columnVisibility;
331
+ const next = typeof u === 'function' ? u(prev) : u;
332
+ (_a = onColumnVisibilityChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onColumnVisibilityChangeRef, next);
333
+ dispatch({ type: 'SET_COLUMN_VISIBILITY', payload: next });
334
+ },
335
+ }
336
+ : {}),
337
+ ...(enableColumnResizing
338
+ ? {
339
+ onColumnSizingChange: (u) => {
340
+ var _a;
341
+ const prev = uiRef.current.columnSizing;
342
+ const next = typeof u === 'function' ? u(prev) : u;
343
+ (_a = onColumnSizingChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onColumnSizingChangeRef, next);
344
+ dispatch({ type: 'SET_COLUMN_SIZING', payload: next });
345
+ },
346
+ }
347
+ : {}),
348
+ getCoreRowModel: (0, react_table_1.getCoreRowModel)(),
349
+ ...(enableSorting ? { getSortedRowModel: (0, react_table_1.getSortedRowModel)() } : {}),
350
+ ...(enableColumnFilter || enableGlobalFilter ? { getFilteredRowModel: (0, features_1.getCombinedFilteredRowModel)() } : {}),
351
+ ...(enablePagination && !isServerPagination ? { getPaginationRowModel: (0, react_table_1.getPaginationRowModel)() } : {}),
352
+ enableSorting,
353
+ manualSorting: isServerSorting,
354
+ manualFiltering: isServerFiltering,
355
+ enableColumnResizing,
356
+ columnResizeMode,
357
+ columnResizeDirection: theme.direction,
358
+ enableColumnPinning,
359
+ ...(enableExpanding ? { getRowCanExpand: getRowCanExpand } : {}),
360
+ manualPagination: isServerPagination,
361
+ autoResetPageIndex: false,
362
+ rowCount: enablePagination ? tableTotalRow !== null && tableTotalRow !== void 0 ? tableTotalRow : tableData.length : tableData.length,
363
+ getRowId,
364
+ });
365
+ const rows = table.getRowModel().rows;
366
+ const shouldVirtualize = enableVirtualization && rows.length > 0;
367
+ const rowVirtualizer = (0, react_virtual_1.useVirtualizer)({
368
+ count: rows.length,
369
+ getScrollElement: () => tableContainerRef.current,
370
+ estimateSize: () => estimateRowHeight,
371
+ overscan: 8,
372
+ enabled: shouldVirtualize,
373
+ });
374
+ const serverKey = (0, react_1.useMemo)(() => {
375
+ if (!(isServerMode || isServerPagination || isServerFiltering || isServerSorting))
376
+ return null;
377
+ return JSON.stringify({
378
+ sorting: ui.sorting,
379
+ pagination: ui.pagination,
380
+ globalFilter: ui.globalFilter,
381
+ columnFilter: { filters: ui.columnFilter.filters, logic: ui.columnFilter.logic },
382
+ });
383
+ }, [isServerMode, isServerPagination, isServerFiltering, isServerSorting, ui.sorting, ui.pagination, ui.globalFilter, ui.columnFilter]);
384
+ const serverKeyRef = useLatestRef(serverKey);
385
+ const lastServerKeyRef = (0, react_1.useRef)(null);
386
+ (0, react_1.useEffect)(() => {
387
+ if (!initialLoadData)
388
+ return;
389
+ if (serverKeyRef.current)
390
+ lastServerKeyRef.current = serverKeyRef.current;
391
+ if (onFetchData || onFetchStateChange) {
392
+ void fetchData({}, { delay: 0, meta: { reason: 'initial' } });
393
+ }
394
+ // eslint-disable-next-line react-hooks/exhaustive-deps
395
+ }, []);
396
+ (0, react_1.useEffect)(() => {
397
+ var _a;
398
+ if (!serverKey)
399
+ return;
400
+ if (serverKey === lastServerKeyRef.current)
401
+ return;
402
+ lastServerKeyRef.current = serverKey;
403
+ const delay = (_a = nextFetchDelayRef.current) !== null && _a !== void 0 ? _a : 0;
404
+ nextFetchDelayRef.current = 0;
405
+ const timeoutId = setTimeout(() => {
406
+ log.debug('stateChange fetch', delay);
407
+ void fetchData({}, { delay, meta: { reason: 'state-change' } });
408
+ }, 0);
409
+ return () => clearTimeout(timeoutId);
410
+ }, [serverKey, fetchData, log]);
411
+ const handleColumnFilterChangeHandler = (0, react_1.useCallback)((updater, isApply = false) => {
412
+ var _a;
413
+ const prev = uiRef.current.columnFilter;
414
+ const next = typeof updater === 'function' ? updater(prev) : updater;
415
+ if (isApply) {
416
+ nextFetchDelayRef.current = 0;
417
+ dispatch({ type: 'SET_COLUMN_FILTER_RESET_PAGE', payload: next });
418
+ }
419
+ else {
420
+ dispatch({ type: 'SET_COLUMN_FILTER', payload: next });
421
+ }
422
+ (_a = onColumnFilterChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onColumnFilterChangeRef, next, isApply);
423
+ }, [onColumnFilterChangeRef, uiRef]);
424
+ (0, react_1.useEffect)(() => {
425
+ const cb = onDataStateChangeRef.current;
426
+ if (!cb)
427
+ return;
428
+ const live = table.getState();
429
+ const payload = {
430
+ sorting: live.sorting,
431
+ pagination: live.pagination,
432
+ globalFilter: live.globalFilter,
433
+ columnFilter: live.columnFilter,
434
+ columnVisibility: live.columnVisibility,
435
+ columnSizing: live.columnSizing,
436
+ columnOrder: live.columnOrder,
437
+ columnPinning: live.columnPinning,
438
+ };
439
+ const key = JSON.stringify(payload);
440
+ if (key === lastSentRef.current)
441
+ return;
442
+ lastSentRef.current = key;
443
+ cb(payload);
444
+ }, [table, ui.sorting, ui.pagination, ui.globalFilter, ui.columnFilter, ui.columnVisibility, ui.columnSizing, ui.columnOrder, ui.columnPinning, onDataStateChangeRef]);
445
+ const normalizeRefreshOptions = (0, react_1.useCallback)((options, fallbackReason = 'refresh') => {
446
+ var _a, _b, _c;
447
+ if (typeof options === 'boolean')
448
+ return { resetPagination: options, force: false, reason: fallbackReason };
449
+ return {
450
+ resetPagination: (_a = options === null || options === void 0 ? void 0 : options.resetPagination) !== null && _a !== void 0 ? _a : false,
451
+ force: (_b = options === null || options === void 0 ? void 0 : options.force) !== null && _b !== void 0 ? _b : false,
452
+ reason: (_c = options === null || options === void 0 ? void 0 : options.reason) !== null && _c !== void 0 ? _c : fallbackReason,
453
+ };
454
+ }, []);
455
+ const triggerRefresh = (0, react_1.useCallback)(async (options, fallbackReason = 'refresh') => {
456
+ var _a;
457
+ const n = normalizeRefreshOptions(options, fallbackReason);
458
+ const current = uiRef.current.pagination;
459
+ const nextPagination = enablePagination
460
+ ? { pageIndex: n.resetPagination ? 0 : current.pageIndex, pageSize: current.pageSize }
461
+ : undefined;
462
+ if (nextPagination) {
463
+ nextFetchDelayRef.current = 0;
464
+ dispatch({ type: 'SET_PAGINATION', payload: nextPagination });
465
+ (_a = onPaginationChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onPaginationChangeRef, nextPagination);
466
+ }
467
+ const paginationChanged = !!nextPagination &&
468
+ (nextPagination.pageIndex !== current.pageIndex || nextPagination.pageSize !== current.pageSize);
469
+ if (!paginationChanged) {
470
+ await fetchData({}, { delay: 0, meta: { reason: n.reason, force: n.force } });
471
+ }
472
+ }, [enablePagination, fetchData, normalizeRefreshOptions, onPaginationChangeRef, uiRef]);
473
+ const getResetPayload = (0, react_1.useCallback)(() => {
474
+ var _a, _b, _c;
475
+ const resetPagination = enablePagination
476
+ ? initialStateConfig.pagination || { pageIndex: 0, pageSize: 10 }
477
+ : uiRef.current.pagination;
478
+ return {
479
+ sorting: initialStateConfig.sorting || [],
480
+ globalFilter: (_a = initialStateConfig.globalFilter) !== null && _a !== void 0 ? _a : '',
481
+ columnFilter: ((_b = initialStateConfig.columnFilter) !== null && _b !== void 0 ? _b : DEFAULT_INITIAL_STATE.columnFilter),
482
+ ...(enablePagination ? { pagination: resetPagination } : {}),
483
+ selectionState: (_c = initialStateConfig.selectionState) !== null && _c !== void 0 ? _c : DEFAULT_INITIAL_STATE.selectionState,
484
+ expanded: {},
485
+ columnVisibility: initialStateConfig.columnVisibility || {},
486
+ columnSizing: initialStateConfig.columnSizing || {},
487
+ columnOrder: initialStateConfig.columnOrder || [],
488
+ columnPinning: initialStateConfig.columnPinning || { left: [], right: [] },
489
+ };
490
+ }, [enablePagination, initialStateConfig, uiRef]);
491
+ const resetAllAndReload = (0, react_1.useCallback)(() => {
492
+ const payload = getResetPayload();
493
+ dispatch({ type: 'RESET_ALL', payload });
494
+ void fetchData({
495
+ sorting: payload.sorting,
496
+ globalFilter: payload.globalFilter,
497
+ columnFilter: payload.columnFilter,
498
+ ...(enablePagination ? { pagination: payload.pagination } : {}),
499
+ }, { delay: 0, meta: { reason: 'reset', force: true } });
500
+ }, [enablePagination, fetchData, getResetPayload]);
501
+ // --- export policy
502
+ const setExportControllerSafely = (0, react_1.useCallback)((value) => {
503
+ setExportController((current) => {
504
+ const next = typeof value === 'function' ? value(current) : value;
505
+ exportControllerRef.current = next;
506
+ return next;
507
+ });
508
+ }, []);
509
+ const handleExportProgressInternal = (0, react_1.useCallback)((p) => {
510
+ var _a;
511
+ setExportProgress(p || {});
512
+ (_a = onExportProgressRef.current) === null || _a === void 0 ? void 0 : _a.call(onExportProgressRef, p);
513
+ }, [onExportProgressRef]);
514
+ const handleExportStateChangeInternal = (0, react_1.useCallback)((s) => {
515
+ var _a;
516
+ setExportPhase(s.phase);
517
+ if (s.processedRows !== undefined || s.totalRows !== undefined || s.percentage !== undefined) {
518
+ setExportProgress({ processedRows: s.processedRows, totalRows: s.totalRows, percentage: s.percentage });
519
+ }
520
+ (_a = onExportStateChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onExportStateChangeRef, s);
521
+ }, [onExportStateChangeRef]);
522
+ const runExportWithPolicy = (0, react_1.useCallback)(async (options) => {
523
+ var _a;
524
+ const { format, filename, mode, execute } = options;
525
+ const startExecution = async () => {
526
+ const controller = new AbortController();
527
+ setExportProgress({});
528
+ setExportControllerSafely(controller);
529
+ try {
530
+ await execute(controller);
531
+ }
532
+ finally {
533
+ setExportControllerSafely((cur) => (cur === controller ? null : cur));
534
+ }
535
+ };
536
+ if (exportConcurrency === 'queue') {
537
+ setQueuedExportCount((p) => p + 1);
538
+ const runQueued = async () => {
539
+ setQueuedExportCount((p) => Math.max(0, p - 1));
540
+ await startExecution();
541
+ };
542
+ const queuedPromise = exportQueueRef.current.catch(() => undefined).then(runQueued);
543
+ exportQueueRef.current = queuedPromise;
544
+ return queuedPromise;
545
+ }
546
+ const active = exportControllerRef.current;
547
+ if (active) {
548
+ if (exportConcurrency === 'ignoreIfRunning') {
549
+ handleExportStateChangeInternal({
550
+ phase: 'error',
551
+ mode,
552
+ format,
553
+ filename,
554
+ message: 'An export is already running',
555
+ code: 'EXPORT_IN_PROGRESS',
556
+ });
557
+ (_a = onExportErrorRef.current) === null || _a === void 0 ? void 0 : _a.call(onExportErrorRef, { message: 'An export is already running', code: 'EXPORT_IN_PROGRESS' });
558
+ return;
559
+ }
560
+ if (exportConcurrency === 'cancelAndRestart')
561
+ active.abort();
562
+ }
563
+ await startExecution();
564
+ }, [exportConcurrency, handleExportStateChangeInternal, onExportErrorRef, setExportControllerSafely]);
565
+ const handleCancelExport = (0, react_1.useCallback)(() => {
566
+ var _a;
567
+ const active = exportControllerRef.current;
568
+ if (!active)
569
+ return;
570
+ active.abort();
571
+ setExportControllerSafely((cur) => (cur === active ? null : cur));
572
+ (_a = onExportCancelRef.current) === null || _a === void 0 ? void 0 : _a.call(onExportCancelRef);
573
+ }, [onExportCancelRef, setExportControllerSafely]);
574
+ const isExporting = exportController !== null;
575
+ // --- stable API (created once, methods read latest via refs)
576
+ if (!apiRef.current) {
577
+ apiRef.current = {};
578
+ }
579
+ const tableRef = useLatestRef(table);
580
+ (0, react_1.useEffect)(() => {
581
+ const api = apiRef.current;
582
+ api.table = { getTable: () => tableRef.current };
583
+ api.state = {
584
+ getTableState: () => tableRef.current.getState(),
585
+ getCurrentFilters: () => tableRef.current.getState().columnFilter,
586
+ getCurrentSorting: () => tableRef.current.getState().sorting,
587
+ getCurrentPagination: () => tableRef.current.getState().pagination,
588
+ getCurrentSelection: () => uiRef.current.selectionState,
589
+ getGlobalFilter: () => tableRef.current.getState().globalFilter,
590
+ };
591
+ const getBaseData = () => {
592
+ const sData = serverDataRef.current;
593
+ return sData !== null ? sData : dataRef.current;
594
+ };
595
+ const getRowIndexById = (arr, rowId) => arr.findIndex((row, i) => getRowId(row, i) === rowId);
596
+ api.data = {
597
+ refresh: (options) => void triggerRefresh(options, 'refresh'),
598
+ reload: (options = {}) => { var _a; return void triggerRefresh({ ...options, reason: (_a = options.reason) !== null && _a !== void 0 ? _a : 'reload' }, 'reload'); },
599
+ resetAll: () => resetAllAndReload(),
600
+ getAllData: () => [...getBaseData()],
601
+ getRowData: (rowId) => { var _a; return (_a = tableRef.current.getRowModel().rows.find((r) => r.id === rowId)) === null || _a === void 0 ? void 0 : _a.original; },
602
+ getRowByIndex: (index) => { var _a; return (_a = tableRef.current.getRowModel().rows[index]) === null || _a === void 0 ? void 0 : _a.original; },
603
+ getDataCount: () => getBaseData().length,
604
+ getFilteredDataCount: () => tableRef.current.getFilteredRowModel().rows.length,
605
+ updateRow: (rowId, updates) => {
606
+ const base = getBaseData();
607
+ const idx = getRowIndexById(base, rowId);
608
+ if (idx === -1)
609
+ return;
610
+ const next = [...base];
611
+ next[idx] = { ...next[idx], ...updates };
612
+ setServerData(next);
613
+ setServerTotal(next.length);
614
+ },
615
+ updateRowByIndex: (index, updates) => {
616
+ const base = getBaseData();
617
+ if (index < 0 || index >= base.length)
618
+ return;
619
+ const next = [...base];
620
+ next[index] = { ...next[index], ...updates };
621
+ setServerData(next);
622
+ setServerTotal(next.length);
623
+ },
624
+ insertRow: (newRow, index) => {
625
+ const base = getBaseData();
626
+ const next = index == null ? [...base, newRow] : [...base.slice(0, index), newRow, ...base.slice(index)];
627
+ setServerData(next);
628
+ setServerTotal(next.length);
629
+ },
630
+ deleteRow: (rowId) => {
631
+ const base = getBaseData();
632
+ const idx = getRowIndexById(base, rowId);
633
+ if (idx === -1)
634
+ return;
635
+ const next = base.filter((_, i) => i !== idx);
636
+ setServerData(next);
637
+ setServerTotal(next.length);
638
+ },
639
+ deleteRowByIndex: (index) => {
640
+ const base = getBaseData();
641
+ if (index < 0 || index >= base.length)
642
+ return;
643
+ const next = base.filter((_, i) => i !== index);
644
+ setServerData(next);
645
+ setServerTotal(next.length);
646
+ },
647
+ deleteSelectedRows: () => {
648
+ var _a, _b, _c, _d;
649
+ const state = (_b = (_a = tableRef.current).getSelectionState) === null || _b === void 0 ? void 0 : _b.call(_a);
650
+ if (!state || state.type !== 'include' || !state.ids.length)
651
+ return;
652
+ const base = getBaseData();
653
+ const ids = new Set(state.ids);
654
+ const next = base.filter((row, i) => !ids.has(getRowId(row, i)));
655
+ setServerData(next);
656
+ setServerTotal(next.length);
657
+ (_d = (_c = tableRef.current).deselectAll) === null || _d === void 0 ? void 0 : _d.call(_c);
658
+ },
659
+ replaceAllData: (newData) => {
660
+ setServerData(newData);
661
+ setServerTotal(newData.length);
662
+ },
663
+ updateMultipleRows: (updates) => {
664
+ const base = getBaseData();
665
+ const next = [...base];
666
+ for (const { rowId, data: u } of updates) {
667
+ const idx = getRowIndexById(next, rowId);
668
+ if (idx !== -1)
669
+ next[idx] = { ...next[idx], ...u };
670
+ }
671
+ setServerData(next);
672
+ setServerTotal(next.length);
673
+ },
674
+ insertMultipleRows: (newRows, startIndex) => {
675
+ const base = getBaseData();
676
+ const idx = startIndex !== null && startIndex !== void 0 ? startIndex : base.length;
677
+ const next = [...base.slice(0, idx), ...newRows, ...base.slice(idx)];
678
+ setServerData(next);
679
+ setServerTotal(next.length);
680
+ },
681
+ deleteMultipleRows: (rowIds) => {
682
+ const ids = new Set(rowIds);
683
+ const base = getBaseData();
684
+ const next = base.filter((row, i) => !ids.has(getRowId(row, i)));
685
+ setServerData(next);
686
+ setServerTotal(next.length);
687
+ },
688
+ updateField: (rowId, fieldName, value) => api.data.updateRow(rowId, { [fieldName]: value }),
689
+ updateFieldByIndex: (index, fieldName, value) => api.data.updateRowByIndex(index, { [fieldName]: value }),
690
+ findRows: (predicate) => getBaseData().filter(predicate),
691
+ findRowIndex: (predicate) => getBaseData().findIndex(predicate),
692
+ };
693
+ api.layout = {
694
+ saveLayout: () => {
695
+ var _a, _b, _c, _d, _e, _f;
696
+ const s = tableRef.current.getState();
697
+ return {
698
+ columnVisibility: (_a = s.columnVisibility) !== null && _a !== void 0 ? _a : {},
699
+ columnOrder: (_b = s.columnOrder) !== null && _b !== void 0 ? _b : [],
700
+ columnSizing: (_c = s.columnSizing) !== null && _c !== void 0 ? _c : {},
701
+ columnPinning: (_d = s.columnPinning) !== null && _d !== void 0 ? _d : { left: [], right: [] },
702
+ pagination: (_e = s.pagination) !== null && _e !== void 0 ? _e : { pageIndex: 0, pageSize: 10 },
703
+ globalFilter: (_f = s.globalFilter) !== null && _f !== void 0 ? _f : '',
704
+ columnFilter: s.columnFilter,
705
+ };
706
+ },
707
+ restoreLayout: (layout) => {
708
+ var _a, _b, _c;
709
+ if (layout.columnVisibility)
710
+ dispatch({ type: 'SET_COLUMN_VISIBILITY', payload: layout.columnVisibility });
711
+ if (layout.columnOrder) {
712
+ dispatch({ type: 'SET_COLUMN_ORDER', payload: layout.columnOrder });
713
+ (_a = onColumnOrderChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onColumnOrderChangeRef, layout.columnOrder);
714
+ }
715
+ if (layout.columnSizing) {
716
+ dispatch({ type: 'SET_COLUMN_SIZING', payload: layout.columnSizing });
717
+ (_b = onColumnSizingChangeRef.current) === null || _b === void 0 ? void 0 : _b.call(onColumnSizingChangeRef, layout.columnSizing);
718
+ }
719
+ if (layout.columnPinning) {
720
+ dispatch({ type: 'SET_COLUMN_PINNING', payload: layout.columnPinning });
721
+ (_c = onColumnPinningChangeRef.current) === null || _c === void 0 ? void 0 : _c.call(onColumnPinningChangeRef, layout.columnPinning);
722
+ }
723
+ if (layout.pagination && enablePagination)
724
+ dispatch({ type: 'SET_PAGINATION', payload: layout.pagination });
725
+ if (layout.globalFilter !== undefined)
726
+ dispatch({ type: 'SET_GLOBAL_FILTER_RESET_PAGE', payload: layout.globalFilter });
727
+ if (layout.columnFilter)
728
+ dispatch({ type: 'SET_COLUMN_FILTER', payload: layout.columnFilter });
729
+ },
730
+ resetLayout: () => {
731
+ dispatch({ type: 'SET_COLUMN_VISIBILITY', payload: initialStateConfig.columnVisibility || {} });
732
+ dispatch({ type: 'SET_COLUMN_ORDER', payload: initialStateConfig.columnOrder || [] });
733
+ dispatch({ type: 'SET_COLUMN_SIZING', payload: initialStateConfig.columnSizing || {} });
734
+ dispatch({ type: 'SET_COLUMN_PINNING', payload: initialStateConfig.columnPinning || { left: [], right: [] } });
735
+ dispatch({ type: 'SET_GLOBAL_FILTER_RESET_PAGE', payload: '' });
736
+ dispatch({ type: 'SET_COLUMN_FILTER', payload: (initialStateConfig.columnFilter || DEFAULT_INITIAL_STATE.columnFilter) });
737
+ dispatch({ type: 'SET_SORTING_RESET_PAGE', payload: initialStateConfig.sorting || [] });
738
+ dispatch({ type: 'SET_PAGINATION', payload: initialStateConfig.pagination || { pageIndex: 0, pageSize: 10 } });
739
+ },
740
+ resetAll: () => {
741
+ api.layout.resetLayout();
742
+ resetAllAndReload();
743
+ },
744
+ };
745
+ api.sorting = {
746
+ setSorting: (next) => {
747
+ var _a;
748
+ const cleaned = (next || []).filter((s) => s === null || s === void 0 ? void 0 : s.id);
749
+ (_a = onSortingChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onSortingChangeRef, cleaned);
750
+ nextFetchDelayRef.current = 0;
751
+ dispatch({ type: 'SET_SORTING_RESET_PAGE', payload: cleaned });
752
+ },
753
+ sortColumn: (columnId, direction) => {
754
+ var _a;
755
+ const next = direction === false ? [] : [{ id: columnId, desc: direction === 'desc' }];
756
+ (_a = onSortingChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onSortingChangeRef, next);
757
+ nextFetchDelayRef.current = 0;
758
+ dispatch({ type: 'SET_SORTING_RESET_PAGE', payload: next });
759
+ },
760
+ clearSorting: () => {
761
+ var _a;
762
+ (_a = onSortingChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onSortingChangeRef, []);
763
+ nextFetchDelayRef.current = 0;
764
+ dispatch({ type: 'SET_SORTING_RESET_PAGE', payload: [] });
765
+ },
766
+ resetSorting: () => {
767
+ var _a;
768
+ const next = (initialStateConfig.sorting || []);
769
+ (_a = onSortingChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onSortingChangeRef, next);
770
+ nextFetchDelayRef.current = 0;
771
+ dispatch({ type: 'SET_SORTING_RESET_PAGE', payload: next });
772
+ },
773
+ };
774
+ api.pagination = {
775
+ goToPage: (pageIndex) => {
776
+ var _a;
777
+ const prev = uiRef.current.pagination;
778
+ const next = { ...prev, pageIndex };
779
+ (_a = onPaginationChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onPaginationChangeRef, next);
780
+ nextFetchDelayRef.current = 0;
781
+ dispatch({ type: 'SET_PAGINATION', payload: next });
782
+ },
783
+ nextPage: () => {
784
+ const prev = uiRef.current.pagination;
785
+ api.pagination.goToPage(Math.min(prev.pageIndex + 1, Math.max(0, Math.ceil((tableTotalRow !== null && tableTotalRow !== void 0 ? tableTotalRow : 0) / prev.pageSize) - 1)));
786
+ },
787
+ previousPage: () => {
788
+ const prev = uiRef.current.pagination;
789
+ api.pagination.goToPage(Math.max(0, prev.pageIndex - 1));
790
+ },
791
+ setPageSize: (pageSize) => {
792
+ var _a;
793
+ const next = { pageIndex: 0, pageSize };
794
+ (_a = onPaginationChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onPaginationChangeRef, next);
795
+ nextFetchDelayRef.current = 0;
796
+ dispatch({ type: 'SET_PAGINATION', payload: next });
797
+ },
798
+ goToFirstPage: () => api.pagination.goToPage(0),
799
+ goToLastPage: () => {
800
+ const prev = uiRef.current.pagination;
801
+ api.pagination.goToPage(Math.max(0, Math.ceil((tableTotalRow !== null && tableTotalRow !== void 0 ? tableTotalRow : 0) / prev.pageSize) - 1));
802
+ },
803
+ resetPagination: () => {
804
+ var _a;
805
+ const next = (initialStateConfig.pagination || { pageIndex: 0, pageSize: 10 });
806
+ (_a = onPaginationChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onPaginationChangeRef, next);
807
+ nextFetchDelayRef.current = 0;
808
+ dispatch({ type: 'SET_PAGINATION', payload: next });
809
+ },
810
+ };
811
+ api.filtering = {
812
+ setGlobalFilter: (filter) => {
813
+ var _a;
814
+ (_a = onGlobalFilterChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onGlobalFilterChangeRef, filter);
815
+ nextFetchDelayRef.current = 400;
816
+ dispatch({ type: 'SET_GLOBAL_FILTER_RESET_PAGE', payload: filter });
817
+ },
818
+ clearGlobalFilter: () => {
819
+ var _a;
820
+ (_a = onGlobalFilterChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onGlobalFilterChangeRef, '');
821
+ nextFetchDelayRef.current = 400;
822
+ dispatch({ type: 'SET_GLOBAL_FILTER_RESET_PAGE', payload: '' });
823
+ },
824
+ setColumnFilters: (filters, isApply = false) => handleColumnFilterChangeHandler(filters, isApply),
825
+ addColumnFilter: (columnId, operator, value) => { var _a, _b; return (_b = (_a = tableRef.current).addColumnFilter) === null || _b === void 0 ? void 0 : _b.call(_a, columnId, operator, value); },
826
+ removeColumnFilter: (filterId) => { var _a, _b; return (_b = (_a = tableRef.current).removeColumnFilter) === null || _b === void 0 ? void 0 : _b.call(_a, filterId); },
827
+ clearAllFilters: () => { var _a, _b; return (_b = (_a = tableRef.current).resetColumnFilter) === null || _b === void 0 ? void 0 : _b.call(_a); },
828
+ resetFilters: () => {
829
+ var _a;
830
+ const reset = ((_a = initialStateConfig.columnFilter) !== null && _a !== void 0 ? _a : DEFAULT_INITIAL_STATE.columnFilter);
831
+ handleColumnFilterChangeHandler(reset, true);
832
+ },
833
+ };
834
+ api.columnVisibility = {
835
+ showColumn: (id) => dispatch({ type: 'SET_COLUMN_VISIBILITY', payload: { ...uiRef.current.columnVisibility, [id]: true } }),
836
+ hideColumn: (id) => dispatch({ type: 'SET_COLUMN_VISIBILITY', payload: { ...uiRef.current.columnVisibility, [id]: false } }),
837
+ toggleColumn: (id) => {
838
+ var _a, _b;
839
+ // Read actual visibility (absent in the map = visible) so the first
840
+ // toggle on a default-visible column correctly hides it.
841
+ const isVisible = (_b = (_a = tableRef.current.getColumn(id)) === null || _a === void 0 ? void 0 : _a.getIsVisible()) !== null && _b !== void 0 ? _b : true;
842
+ dispatch({ type: 'SET_COLUMN_VISIBILITY', payload: { ...uiRef.current.columnVisibility, [id]: !isVisible } });
843
+ },
844
+ showAllColumns: () => dispatch({ type: 'SET_COLUMN_VISIBILITY', payload: {} }),
845
+ hideAllColumns: () => {
846
+ const all = tableRef.current.getAllLeafColumns().reduce((acc, col) => ({ ...acc, [col.id]: false }), {});
847
+ dispatch({ type: 'SET_COLUMN_VISIBILITY', payload: all });
848
+ },
849
+ resetColumnVisibility: () => dispatch({ type: 'SET_COLUMN_VISIBILITY', payload: initialStateConfig.columnVisibility || {} }),
850
+ };
851
+ api.columnOrdering = {
852
+ setColumnOrder: (next) => {
853
+ var _a;
854
+ dispatch({ type: 'SET_COLUMN_ORDER', payload: next });
855
+ (_a = onColumnOrderChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onColumnOrderChangeRef, next);
856
+ },
857
+ moveColumn: (columnId, toIndex) => {
858
+ var _a;
859
+ const order = uiRef.current.columnOrder.length ? uiRef.current.columnOrder : tableRef.current.getAllLeafColumns().map((c) => c.id);
860
+ const from = order.indexOf(columnId);
861
+ if (from === -1 || toIndex < 0 || toIndex >= order.length)
862
+ return;
863
+ const next = [...order];
864
+ next.splice(from, 1);
865
+ next.splice(toIndex, 0, columnId);
866
+ dispatch({ type: 'SET_COLUMN_ORDER', payload: next });
867
+ (_a = onColumnOrderChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onColumnOrderChangeRef, next);
868
+ },
869
+ resetColumnOrder: () => dispatch({ type: 'SET_COLUMN_ORDER', payload: initialStateConfig.columnOrder || [] }),
870
+ };
871
+ api.columnPinning = {
872
+ pinColumnLeft: (columnId) => {
873
+ var _a;
874
+ const cur = uiRef.current.columnPinning;
875
+ const left = cur.left.includes(columnId) ? cur.left : [...cur.left.filter((id) => id !== columnId), columnId];
876
+ const right = cur.right.filter((id) => id !== columnId);
877
+ dispatch({ type: 'SET_COLUMN_PINNING', payload: { left, right } });
878
+ (_a = onColumnPinningChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onColumnPinningChangeRef, { left, right });
879
+ },
880
+ pinColumnRight: (columnId) => {
881
+ var _a;
882
+ const cur = uiRef.current.columnPinning;
883
+ const left = cur.left.filter((id) => id !== columnId);
884
+ const right = cur.right.includes(columnId) ? cur.right : [...cur.right.filter((id) => id !== columnId), columnId];
885
+ dispatch({ type: 'SET_COLUMN_PINNING', payload: { left, right } });
886
+ (_a = onColumnPinningChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onColumnPinningChangeRef, { left, right });
887
+ },
888
+ unpinColumn: (columnId) => {
889
+ var _a;
890
+ const cur = uiRef.current.columnPinning;
891
+ const left = cur.left.filter((id) => id !== columnId);
892
+ const right = cur.right.filter((id) => id !== columnId);
893
+ dispatch({ type: 'SET_COLUMN_PINNING', payload: { left, right } });
894
+ (_a = onColumnPinningChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onColumnPinningChangeRef, { left, right });
895
+ },
896
+ setPinning: (next) => {
897
+ var _a;
898
+ dispatch({ type: 'SET_COLUMN_PINNING', payload: next });
899
+ (_a = onColumnPinningChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onColumnPinningChangeRef, next);
900
+ },
901
+ resetColumnPinning: () => dispatch({ type: 'SET_COLUMN_PINNING', payload: initialStateConfig.columnPinning || { left: [], right: [] } }),
902
+ };
903
+ api.columnResizing = {
904
+ resizeColumn: (columnId, width) => {
905
+ var _a;
906
+ const cur = uiRef.current.columnSizing;
907
+ dispatch({ type: 'SET_COLUMN_SIZING', payload: { ...cur, [columnId]: width } });
908
+ (_a = onColumnSizingChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onColumnSizingChangeRef, { ...cur, [columnId]: width });
909
+ },
910
+ autoSizeColumn: () => undefined,
911
+ autoSizeAllColumns: () => undefined,
912
+ resetColumnSizing: () => dispatch({ type: 'SET_COLUMN_SIZING', payload: initialStateConfig.columnSizing || {} }),
913
+ };
914
+ api.selection = {
915
+ selectRow: (rowId) => { var _a, _b; return (_b = (_a = tableRef.current).selectRow) === null || _b === void 0 ? void 0 : _b.call(_a, rowId); },
916
+ deselectRow: (rowId) => { var _a, _b; return (_b = (_a = tableRef.current).deselectRow) === null || _b === void 0 ? void 0 : _b.call(_a, rowId); },
917
+ toggleRowSelection: (rowId) => { var _a, _b; return (_b = (_a = tableRef.current).toggleRowSelected) === null || _b === void 0 ? void 0 : _b.call(_a, rowId); },
918
+ selectAll: () => { var _a, _b; return (_b = (_a = tableRef.current).selectAll) === null || _b === void 0 ? void 0 : _b.call(_a); },
919
+ deselectAll: () => { var _a, _b; return (_b = (_a = tableRef.current).deselectAll) === null || _b === void 0 ? void 0 : _b.call(_a); },
920
+ toggleSelectAll: () => { var _a, _b; return (_b = (_a = tableRef.current).toggleAllRowsSelected) === null || _b === void 0 ? void 0 : _b.call(_a); },
921
+ getSelectionState: () => { var _a, _b; return ((_b = (_a = tableRef.current).getSelectionState) === null || _b === void 0 ? void 0 : _b.call(_a)) || { ids: [], type: 'include' }; },
922
+ getSelectedRows: () => tableRef.current.getSelectedRows(),
923
+ getSelectedCount: () => tableRef.current.getSelectedCount(),
924
+ isRowSelected: (rowId) => tableRef.current.getIsRowSelected(rowId) || false,
925
+ };
926
+ api.export = {
927
+ exportCSV: async (options = {}) => {
928
+ var _a;
929
+ const fn = (_a = options.filename) !== null && _a !== void 0 ? _a : exportFilename;
930
+ const mode = dataMode === 'server' && !!onServerExportRef.current ? 'server' : 'client';
931
+ await runExportWithPolicy({
932
+ format: 'csv',
933
+ filename: fn,
934
+ mode,
935
+ execute: async (controller) => {
936
+ var _a, _b, _c, _d, _e;
937
+ const common = {
938
+ format: 'csv',
939
+ filename: fn,
940
+ onProgress: handleExportProgressInternal,
941
+ onComplete: onExportCompleteRef.current,
942
+ onError: onExportErrorRef.current,
943
+ onStateChange: (s) => handleExportStateChangeInternal({ ...s, mode, format: 'csv', filename: fn }),
944
+ signal: controller.signal,
945
+ sanitizeCSV: (_a = options.sanitizeCSV) !== null && _a !== void 0 ? _a : exportSanitizeCSV,
946
+ };
947
+ if (mode === 'server' && onServerExportRef.current) {
948
+ await (0, utils_1.exportServerData)(tableRef.current, {
949
+ ...common,
950
+ fetchData: (filters, selection, signal) => { var _a; return (_a = onServerExportRef.current) === null || _a === void 0 ? void 0 : _a.call(onServerExportRef, filters, selection, signal); },
951
+ currentFilters: curateExportFilters(tableRef.current.getState()),
952
+ selection: (_c = (_b = tableRef.current).getSelectionState) === null || _c === void 0 ? void 0 : _c.call(_b),
953
+ chunkSize: (_d = options.chunkSize) !== null && _d !== void 0 ? _d : exportChunkSize,
954
+ strictTotalCheck: (_e = options.strictTotalCheck) !== null && _e !== void 0 ? _e : exportStrictTotalCheck,
955
+ });
956
+ return;
957
+ }
958
+ await (0, utils_1.exportClientData)(tableRef.current, common);
959
+ },
960
+ });
961
+ },
962
+ exportExcel: async (options = {}) => {
963
+ var _a;
964
+ const fn = (_a = options.filename) !== null && _a !== void 0 ? _a : exportFilename;
965
+ const mode = dataMode === 'server' && !!onServerExportRef.current ? 'server' : 'client';
966
+ await runExportWithPolicy({
967
+ format: 'excel',
968
+ filename: fn,
969
+ mode,
970
+ execute: async (controller) => {
971
+ var _a, _b, _c, _d, _e;
972
+ const common = {
973
+ format: 'excel',
974
+ filename: fn,
975
+ onProgress: handleExportProgressInternal,
976
+ onComplete: onExportCompleteRef.current,
977
+ onError: onExportErrorRef.current,
978
+ onStateChange: (s) => handleExportStateChangeInternal({ ...s, mode, format: 'excel', filename: fn }),
979
+ signal: controller.signal,
980
+ sanitizeCSV: (_a = options.sanitizeCSV) !== null && _a !== void 0 ? _a : exportSanitizeCSV,
981
+ };
982
+ if (mode === 'server' && onServerExportRef.current) {
983
+ await (0, utils_1.exportServerData)(tableRef.current, {
984
+ ...common,
985
+ fetchData: (filters, selection, signal) => { var _a; return (_a = onServerExportRef.current) === null || _a === void 0 ? void 0 : _a.call(onServerExportRef, filters, selection, signal); },
986
+ currentFilters: curateExportFilters(tableRef.current.getState()),
987
+ selection: (_c = (_b = tableRef.current).getSelectionState) === null || _c === void 0 ? void 0 : _c.call(_b),
988
+ chunkSize: (_d = options.chunkSize) !== null && _d !== void 0 ? _d : exportChunkSize,
989
+ strictTotalCheck: (_e = options.strictTotalCheck) !== null && _e !== void 0 ? _e : exportStrictTotalCheck,
990
+ });
991
+ return;
992
+ }
993
+ await (0, utils_1.exportClientData)(tableRef.current, common);
994
+ },
995
+ });
996
+ },
997
+ exportServerData: async (options) => {
998
+ const { format, filename: fn = exportFilename, fetchData: customFetchData } = options;
999
+ await runExportWithPolicy({
1000
+ format,
1001
+ filename: fn,
1002
+ mode: 'server',
1003
+ execute: async (controller) => {
1004
+ var _a, _b, _c, _d, _e;
1005
+ await (0, utils_1.exportServerData)(tableRef.current, {
1006
+ format,
1007
+ filename: fn,
1008
+ fetchData: customFetchData,
1009
+ currentFilters: curateExportFilters(tableRef.current.getState()),
1010
+ selection: (_b = (_a = tableRef.current).getSelectionState) === null || _b === void 0 ? void 0 : _b.call(_a),
1011
+ onProgress: handleExportProgressInternal,
1012
+ onComplete: onExportCompleteRef.current,
1013
+ onError: onExportErrorRef.current,
1014
+ onStateChange: (s) => handleExportStateChangeInternal({ ...s, mode: 'server', format, filename: fn }),
1015
+ signal: controller.signal,
1016
+ chunkSize: (_c = options.chunkSize) !== null && _c !== void 0 ? _c : exportChunkSize,
1017
+ strictTotalCheck: (_d = options.strictTotalCheck) !== null && _d !== void 0 ? _d : exportStrictTotalCheck,
1018
+ sanitizeCSV: (_e = options.sanitizeCSV) !== null && _e !== void 0 ? _e : exportSanitizeCSV,
1019
+ });
1020
+ },
1021
+ });
1022
+ },
1023
+ isExporting: () => exportControllerRef.current != null,
1024
+ cancelExport: () => handleCancelExport(),
1025
+ };
1026
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1027
+ }, [dataMode, exportChunkSize, exportFilename, exportSanitizeCSV, exportStrictTotalCheck, fetchData, handleCancelExport, handleColumnFilterChangeHandler, handleExportProgressInternal, handleExportStateChangeInternal, initialStateConfig, resetAllAndReload, runExportWithPolicy, triggerRefresh, tableTotalRow, getRowId, tableRef, uiRef, serverDataRef, dataRef, enablePagination]);
1028
+ const handleColumnReorder = (0, react_1.useCallback)((draggedId, targetId) => {
1029
+ var _a;
1030
+ const currentOrder = uiRef.current.columnOrder.length > 0
1031
+ ? uiRef.current.columnOrder
1032
+ : enhancedColumns.map((c, idx) => { var _a, _b; return (_b = (_a = c.id) !== null && _a !== void 0 ? _a : c.accessorKey) !== null && _b !== void 0 ? _b : `column_${idx}`; });
1033
+ const from = currentOrder.indexOf(draggedId);
1034
+ const to = currentOrder.indexOf(targetId);
1035
+ if (from === -1 || to === -1)
1036
+ return;
1037
+ const next = [...currentOrder];
1038
+ next.splice(from, 1);
1039
+ next.splice(to, 0, draggedId);
1040
+ dispatch({ type: 'SET_COLUMN_ORDER', payload: next });
1041
+ (_a = onColumnOrderChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onColumnOrderChangeRef, next);
1042
+ }, [enhancedColumns, onColumnOrderChangeRef, uiRef]);
1043
+ (0, react_1.useEffect)(() => {
1044
+ var _a;
1045
+ (_a = onSelectionChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onSelectionChangeRef, ui.selectionState);
1046
+ }, [onSelectionChangeRef, ui.selectionState]);
1047
+ return {
1048
+ table,
1049
+ refs: { tableContainerRef, apiRef, exportControllerRef },
1050
+ derived: {
1051
+ isServerMode,
1052
+ isServerPagination,
1053
+ isServerFiltering,
1054
+ isServerSorting,
1055
+ tableData,
1056
+ tableTotalRow,
1057
+ tableLoading,
1058
+ rows,
1059
+ visibleLeafColumns: table.getVisibleLeafColumns,
1060
+ fitToScreen,
1061
+ density: controlledDensity !== null && controlledDensity !== void 0 ? controlledDensity : ui.density,
1062
+ isExporting,
1063
+ exportPhase,
1064
+ exportProgress,
1065
+ isSomeRowsSelected,
1066
+ selectedRowCount,
1067
+ },
1068
+ state: ui,
1069
+ actions: {
1070
+ fetchData,
1071
+ handleColumnFilterChangeHandler,
1072
+ handleColumnReorder,
1073
+ resetAllAndReload,
1074
+ triggerRefresh,
1075
+ setDensity: (density) => dispatch({ type: 'SET_DENSITY', payload: density }),
1076
+ handleCancelExport,
1077
+ renderRowModel: { rowVirtualizer },
1078
+ },
1079
+ api: apiRef.current,
1080
+ };
1081
+ }