@xcelsior/ui-spreadsheets 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +8 -8
- package/CHANGELOG.md +14 -0
- package/dist/index.js +164 -45
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +164 -45
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
- package/src/components/KeyboardShortcutsModal.tsx +8 -0
- package/src/components/Spreadsheet.tsx +82 -10
- package/src/components/SpreadsheetCell.tsx +4 -2
- package/src/hooks/useSpreadsheetFiltering.ts +71 -45
- package/src/hooks/useSpreadsheetKeyboardShortcuts.ts +66 -2
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @xcelsior/ui-spreadsheets@1.0.
|
|
2
|
+
> @xcelsior/ui-spreadsheets@1.0.3 build /home/circleci/repo/packages/ui/ui-spreadsheets
|
|
3
3
|
> tsup && tsc --noEmit
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
[34mCLI[39m Cleaning output folder
|
|
11
11
|
[34mCJS[39m Build start
|
|
12
12
|
[34mESM[39m Build start
|
|
13
|
-
[32mCJS[39m [1mdist/index.js [22m[
|
|
14
|
-
[32mCJS[39m [1mdist/index.js.map [22m[32m2.
|
|
15
|
-
[32mCJS[39m ⚡️ Build success in
|
|
16
|
-
[32mESM[39m [1mdist/index.mjs [22m[
|
|
17
|
-
[32mESM[39m [1mdist/index.mjs.map [22m[32m2.
|
|
18
|
-
[32mESM[39m ⚡️ Build success in
|
|
13
|
+
[32mCJS[39m [1mdist/index.js [22m[32m151.12 KB[39m
|
|
14
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m2.63 MB[39m
|
|
15
|
+
[32mCJS[39m ⚡️ Build success in 576ms
|
|
16
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m140.30 KB[39m
|
|
17
|
+
[32mESM[39m [1mdist/index.mjs.map [22m[32m2.63 MB[39m
|
|
18
|
+
[32mESM[39m ⚡️ Build success in 577ms
|
|
19
19
|
[34mDTS[39m Build start
|
|
20
|
-
[32mDTS[39m ⚡️ Build success in
|
|
20
|
+
[32mDTS[39m ⚡️ Build success in 8502ms
|
|
21
21
|
[32mDTS[39m [1mdist/index.d.ts [22m[32m22.18 KB[39m
|
|
22
22
|
[32mDTS[39m [1mdist/index.d.mts [22m[32m22.18 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @xcelsior/ui-spreadsheets
|
|
2
2
|
|
|
3
|
+
## 1.0.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e734bf5: improve spreadsheet performance
|
|
8
|
+
- Updated dependencies [e734bf5]
|
|
9
|
+
- @xcelsior/utils@1.0.1
|
|
10
|
+
|
|
11
|
+
## 1.0.2
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 05daf41: added keyboard navigation
|
|
16
|
+
|
|
3
17
|
## 1.0.1
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -212,7 +212,7 @@ var SpreadsheetCell = ({
|
|
|
212
212
|
column,
|
|
213
213
|
row,
|
|
214
214
|
rowIndex,
|
|
215
|
-
rowId
|
|
215
|
+
rowId,
|
|
216
216
|
isEditable = false,
|
|
217
217
|
isEditing = false,
|
|
218
218
|
isFocused = false,
|
|
@@ -261,6 +261,7 @@ var SpreadsheetCell = ({
|
|
|
261
261
|
onConfirm?.();
|
|
262
262
|
} else if (e.key === "Escape") {
|
|
263
263
|
e.preventDefault();
|
|
264
|
+
e.stopPropagation();
|
|
264
265
|
setLocalValue(value);
|
|
265
266
|
onChange?.(value);
|
|
266
267
|
onCancel?.();
|
|
@@ -332,7 +333,7 @@ var SpreadsheetCell = ({
|
|
|
332
333
|
};
|
|
333
334
|
const cellPadding = compactMode ? cellPaddingCompact : cellPaddingNormal;
|
|
334
335
|
const handleCellKeyDown = (e) => {
|
|
335
|
-
if (e.key === "
|
|
336
|
+
if (e.key === " ") {
|
|
336
337
|
e.preventDefault();
|
|
337
338
|
onClick?.(e);
|
|
338
339
|
}
|
|
@@ -352,6 +353,7 @@ var SpreadsheetCell = ({
|
|
|
352
353
|
{
|
|
353
354
|
onClick,
|
|
354
355
|
onKeyDown: handleCellKeyDown,
|
|
356
|
+
"data-cell-id": `${rowId}-${column.id}`,
|
|
355
357
|
className: cn(
|
|
356
358
|
"border border-gray-200 text-xs group cursor-pointer transition-colors",
|
|
357
359
|
cellPadding,
|
|
@@ -2147,6 +2149,7 @@ function KeyboardShortcutsModal({
|
|
|
2147
2149
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ShortcutSection, { title: "General", children: shortcuts.general.map((shortcut, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ShortcutRow, { label: shortcut.label, keys: shortcut.keys }, index)) }),
|
|
2148
2150
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ShortcutSection, { title: "Row Selection", children: shortcuts.rowSelection.map((shortcut, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ShortcutRow, { label: shortcut.label, keys: shortcut.keys }, index)) }),
|
|
2149
2151
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ShortcutSection, { title: "Editing", children: shortcuts.editing.map((shortcut, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ShortcutRow, { label: shortcut.label, keys: shortcut.keys }, index)) }),
|
|
2152
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ShortcutSection, { title: "Cell Navigation", children: shortcuts.navigation.map((shortcut, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ShortcutRow, { label: shortcut.label, keys: shortcut.keys }, index)) }),
|
|
2150
2153
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ShortcutSection, { title: "Row Actions (hover over row #)", children: shortcuts.rowActions.map((action, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
2151
2154
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-gray-600 text-sm", children: action.label }),
|
|
2152
2155
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-gray-500 text-xs", children: action.description })
|
|
@@ -2176,6 +2179,7 @@ var import_design_system = require("@xcelsior/design-system");
|
|
|
2176
2179
|
|
|
2177
2180
|
// src/hooks/useSpreadsheetFiltering.ts
|
|
2178
2181
|
var import_react10 = require("react");
|
|
2182
|
+
var import_utils9 = require("@xcelsior/utils");
|
|
2179
2183
|
function useSpreadsheetFiltering({
|
|
2180
2184
|
data,
|
|
2181
2185
|
columns,
|
|
@@ -2322,19 +2326,10 @@ function useSpreadsheetFiltering({
|
|
|
2322
2326
|
},
|
|
2323
2327
|
[]
|
|
2324
2328
|
);
|
|
2325
|
-
const
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
}
|
|
2330
|
-
if (!columns || !Array.isArray(columns)) return data;
|
|
2331
|
-
let result = [...data];
|
|
2332
|
-
for (const [columnId, filter] of Object.entries(filters)) {
|
|
2333
|
-
if (!filter) continue;
|
|
2334
|
-
const column = columns.find((c) => c.id === columnId);
|
|
2335
|
-
if (!column) continue;
|
|
2336
|
-
result = result.filter((row) => {
|
|
2337
|
-
const value = column.getValue ? column.getValue(row) : row[columnId];
|
|
2329
|
+
const buildFilterPredicate = (0, import_react10.useCallback)(
|
|
2330
|
+
(column, filter) => {
|
|
2331
|
+
return (row) => {
|
|
2332
|
+
const value = column.getValue ? column.getValue(row) : row[column.id];
|
|
2338
2333
|
if (filter.includeBlanks && isBlankValue(value)) {
|
|
2339
2334
|
return true;
|
|
2340
2335
|
}
|
|
@@ -2361,32 +2356,48 @@ function useSpreadsheetFiltering({
|
|
|
2361
2356
|
if (filter.max !== void 0 && numValue > Number(filter.max)) return false;
|
|
2362
2357
|
}
|
|
2363
2358
|
return true;
|
|
2364
|
-
}
|
|
2365
|
-
}
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2359
|
+
};
|
|
2360
|
+
},
|
|
2361
|
+
[applyTextCondition, applyNumberCondition, applyDateCondition]
|
|
2362
|
+
);
|
|
2363
|
+
const buildSortComparator = (0, import_react10.useCallback)(
|
|
2364
|
+
(column, direction) => {
|
|
2365
|
+
return (a, b) => {
|
|
2366
|
+
const aValue = column?.getValue ? column.getValue(a) : a[sortConfig?.columnId];
|
|
2367
|
+
const bValue = column?.getValue ? column.getValue(b) : b[sortConfig?.columnId];
|
|
2371
2368
|
if (aValue === null || aValue === void 0) return 1;
|
|
2372
2369
|
if (bValue === null || bValue === void 0) return -1;
|
|
2373
2370
|
if (typeof aValue === "string" && typeof bValue === "string") {
|
|
2374
|
-
return
|
|
2371
|
+
return direction === "asc" ? aValue.localeCompare(bValue) : bValue.localeCompare(aValue);
|
|
2375
2372
|
}
|
|
2376
|
-
return
|
|
2377
|
-
}
|
|
2373
|
+
return direction === "asc" ? aValue < bValue ? -1 : aValue > bValue ? 1 : 0 : aValue > bValue ? -1 : aValue < bValue ? 1 : 0;
|
|
2374
|
+
};
|
|
2375
|
+
},
|
|
2376
|
+
[sortConfig?.columnId]
|
|
2377
|
+
);
|
|
2378
|
+
const filteredData = (0, import_react10.useMemo)(() => {
|
|
2379
|
+
if (!data || !Array.isArray(data)) return import_utils9.LazyArray.empty();
|
|
2380
|
+
if (serverSide) {
|
|
2381
|
+
return import_utils9.LazyArray.from(data);
|
|
2378
2382
|
}
|
|
2379
|
-
return
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
filters
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2383
|
+
if (!columns || !Array.isArray(columns)) return import_utils9.LazyArray.from(data);
|
|
2384
|
+
let lazyResult = import_utils9.LazyArray.from(data);
|
|
2385
|
+
const filterChain = new import_utils9.FilterChain();
|
|
2386
|
+
for (const [columnId, filter] of Object.entries(filters)) {
|
|
2387
|
+
if (!filter) continue;
|
|
2388
|
+
const column = columns.find((c) => c.id === columnId);
|
|
2389
|
+
if (!column) continue;
|
|
2390
|
+
filterChain.add(buildFilterPredicate(column, filter));
|
|
2391
|
+
}
|
|
2392
|
+
if (!filterChain.isEmpty) {
|
|
2393
|
+
lazyResult = filterChain.applyTo(lazyResult);
|
|
2394
|
+
}
|
|
2395
|
+
if (sortConfig) {
|
|
2396
|
+
const column = columns.find((c) => c.id === sortConfig.columnId);
|
|
2397
|
+
lazyResult = lazyResult.sort(buildSortComparator(column, sortConfig.direction));
|
|
2398
|
+
}
|
|
2399
|
+
return lazyResult;
|
|
2400
|
+
}, [data, filters, sortConfig, columns, serverSide, buildFilterPredicate, buildSortComparator]);
|
|
2390
2401
|
const handleFilterChange = (0, import_react10.useCallback)(
|
|
2391
2402
|
(columnId, filter) => {
|
|
2392
2403
|
const newFilters = { ...filters };
|
|
@@ -2614,6 +2625,10 @@ function useSpreadsheetKeyboardShortcuts({
|
|
|
2614
2625
|
onUndo,
|
|
2615
2626
|
onRedo,
|
|
2616
2627
|
onEscape,
|
|
2628
|
+
onNavigate,
|
|
2629
|
+
onEnterEditMode,
|
|
2630
|
+
hasFocusedCell = false,
|
|
2631
|
+
isEditing = false,
|
|
2617
2632
|
customShortcuts = [],
|
|
2618
2633
|
enabled = true
|
|
2619
2634
|
} = {}) {
|
|
@@ -2626,7 +2641,7 @@ function useSpreadsheetKeyboardShortcuts({
|
|
|
2626
2641
|
if (event.key === "Escape") {
|
|
2627
2642
|
if (showKeyboardShortcuts) {
|
|
2628
2643
|
setShowKeyboardShortcuts(false);
|
|
2629
|
-
} else {
|
|
2644
|
+
} else if (!isEditing) {
|
|
2630
2645
|
onEscape?.();
|
|
2631
2646
|
}
|
|
2632
2647
|
return;
|
|
@@ -2646,6 +2661,33 @@ function useSpreadsheetKeyboardShortcuts({
|
|
|
2646
2661
|
onRedo?.();
|
|
2647
2662
|
return;
|
|
2648
2663
|
}
|
|
2664
|
+
if (hasFocusedCell && !isEditing && !event.metaKey && !event.ctrlKey) {
|
|
2665
|
+
if (event.key === "ArrowUp") {
|
|
2666
|
+
event.preventDefault();
|
|
2667
|
+
onNavigate?.("up");
|
|
2668
|
+
return;
|
|
2669
|
+
}
|
|
2670
|
+
if (event.key === "ArrowDown") {
|
|
2671
|
+
event.preventDefault();
|
|
2672
|
+
onNavigate?.("down");
|
|
2673
|
+
return;
|
|
2674
|
+
}
|
|
2675
|
+
if (event.key === "ArrowLeft") {
|
|
2676
|
+
event.preventDefault();
|
|
2677
|
+
onNavigate?.("left");
|
|
2678
|
+
return;
|
|
2679
|
+
}
|
|
2680
|
+
if (event.key === "ArrowRight") {
|
|
2681
|
+
event.preventDefault();
|
|
2682
|
+
onNavigate?.("right");
|
|
2683
|
+
return;
|
|
2684
|
+
}
|
|
2685
|
+
if (event.key === "F2") {
|
|
2686
|
+
event.preventDefault();
|
|
2687
|
+
onEnterEditMode?.();
|
|
2688
|
+
return;
|
|
2689
|
+
}
|
|
2690
|
+
}
|
|
2649
2691
|
for (const shortcut of customShortcuts) {
|
|
2650
2692
|
const modifiersMatch = (!shortcut.modifiers?.meta || event.metaKey) && (!shortcut.modifiers?.ctrl || event.ctrlKey) && (!shortcut.modifiers?.shift || event.shiftKey) && (!shortcut.modifiers?.alt || event.altKey);
|
|
2651
2693
|
if (event.key === shortcut.key && modifiersMatch) {
|
|
@@ -2657,7 +2699,18 @@ function useSpreadsheetKeyboardShortcuts({
|
|
|
2657
2699
|
};
|
|
2658
2700
|
document.addEventListener("keydown", handleKeyDown);
|
|
2659
2701
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
2660
|
-
}, [
|
|
2702
|
+
}, [
|
|
2703
|
+
enabled,
|
|
2704
|
+
showKeyboardShortcuts,
|
|
2705
|
+
onUndo,
|
|
2706
|
+
onRedo,
|
|
2707
|
+
onEscape,
|
|
2708
|
+
onNavigate,
|
|
2709
|
+
onEnterEditMode,
|
|
2710
|
+
hasFocusedCell,
|
|
2711
|
+
isEditing,
|
|
2712
|
+
customShortcuts
|
|
2713
|
+
]);
|
|
2661
2714
|
const shortcuts = {
|
|
2662
2715
|
general: [
|
|
2663
2716
|
{ label: "Show keyboard shortcuts", keys: [modifierKey, "/"] },
|
|
@@ -2674,6 +2727,13 @@ function useSpreadsheetKeyboardShortcuts({
|
|
|
2674
2727
|
{ label: "Confirm cell edit", keys: ["Enter"] },
|
|
2675
2728
|
{ label: "Cancel cell edit", keys: ["Escape"] }
|
|
2676
2729
|
],
|
|
2730
|
+
navigation: [
|
|
2731
|
+
{ label: "Navigate up", keys: ["\u2191"] },
|
|
2732
|
+
{ label: "Navigate down", keys: ["\u2193"] },
|
|
2733
|
+
{ label: "Navigate left", keys: ["\u2190"] },
|
|
2734
|
+
{ label: "Navigate right", keys: ["\u2192"] },
|
|
2735
|
+
{ label: "Edit cell", keys: ["F2"] }
|
|
2736
|
+
],
|
|
2677
2737
|
rowActions: [
|
|
2678
2738
|
{ label: "Duplicate row", description: "Click duplicate icon" },
|
|
2679
2739
|
{ label: "Highlight row", description: "Click highlight icon" },
|
|
@@ -2900,23 +2960,82 @@ function Spreadsheet({
|
|
|
2900
2960
|
markAsChanged();
|
|
2901
2961
|
}
|
|
2902
2962
|
}, [popRedoEntry, onCellEdit, markAsChanged]);
|
|
2963
|
+
const paginatedData = (0, import_react14.useMemo)(() => {
|
|
2964
|
+
if (serverSide) {
|
|
2965
|
+
return filteredData;
|
|
2966
|
+
}
|
|
2967
|
+
const startIndex = (currentPage - 1) * pageSize;
|
|
2968
|
+
return filteredData.slice(startIndex, startIndex + pageSize);
|
|
2969
|
+
}, [filteredData, currentPage, pageSize, serverSide]);
|
|
2970
|
+
const handleNavigate = (0, import_react14.useCallback)(
|
|
2971
|
+
(direction) => {
|
|
2972
|
+
if (!focusedCell) return;
|
|
2973
|
+
const currentRowIndex = paginatedData.findIndex(
|
|
2974
|
+
(r) => getRowId(r) === focusedCell.rowId
|
|
2975
|
+
);
|
|
2976
|
+
const currentColIndex = visibleColumns.findIndex((c) => c.id === focusedCell.columnId);
|
|
2977
|
+
if (currentRowIndex === -1 || currentColIndex === -1) return;
|
|
2978
|
+
let newRowIndex = currentRowIndex;
|
|
2979
|
+
let newColIndex = currentColIndex;
|
|
2980
|
+
switch (direction) {
|
|
2981
|
+
case "up":
|
|
2982
|
+
newRowIndex = Math.max(0, currentRowIndex - 1);
|
|
2983
|
+
break;
|
|
2984
|
+
case "down":
|
|
2985
|
+
newRowIndex = Math.min(paginatedData.length - 1, currentRowIndex + 1);
|
|
2986
|
+
break;
|
|
2987
|
+
case "left":
|
|
2988
|
+
newColIndex = Math.max(0, currentColIndex - 1);
|
|
2989
|
+
break;
|
|
2990
|
+
case "right":
|
|
2991
|
+
newColIndex = Math.min(visibleColumns.length - 1, currentColIndex + 1);
|
|
2992
|
+
break;
|
|
2993
|
+
}
|
|
2994
|
+
const newRowId = getRowId(paginatedData[newRowIndex]);
|
|
2995
|
+
const newColumnId = visibleColumns[newColIndex].id;
|
|
2996
|
+
setFocusedCell({ rowId: newRowId, columnId: newColumnId });
|
|
2997
|
+
setEditingCell(null);
|
|
2998
|
+
requestAnimationFrame(() => {
|
|
2999
|
+
const cellElement = tableRef.current?.querySelector(
|
|
3000
|
+
`[data-cell-id="${newRowId}-${newColumnId}"]`
|
|
3001
|
+
);
|
|
3002
|
+
if (cellElement) {
|
|
3003
|
+
cellElement.scrollIntoView({
|
|
3004
|
+
behavior: "smooth",
|
|
3005
|
+
block: "nearest",
|
|
3006
|
+
inline: "nearest"
|
|
3007
|
+
});
|
|
3008
|
+
}
|
|
3009
|
+
});
|
|
3010
|
+
},
|
|
3011
|
+
[focusedCell, paginatedData, visibleColumns, getRowId]
|
|
3012
|
+
);
|
|
3013
|
+
const handleEnterEditMode = (0, import_react14.useCallback)(() => {
|
|
3014
|
+
if (!focusedCell) return;
|
|
3015
|
+
const column = (columns || []).find((c) => c.id === focusedCell.columnId);
|
|
3016
|
+
if (column?.editable && enableCellEditing) {
|
|
3017
|
+
const row = (data || []).find((r) => getRowId(r) === focusedCell.rowId);
|
|
3018
|
+
if (row) {
|
|
3019
|
+
const value = column.getValue ? column.getValue(row) : row[focusedCell.columnId];
|
|
3020
|
+
setEditingCell({ rowId: focusedCell.rowId, columnId: focusedCell.columnId });
|
|
3021
|
+
setEditValue(value);
|
|
3022
|
+
}
|
|
3023
|
+
}
|
|
3024
|
+
}, [focusedCell, columns, data, getRowId, enableCellEditing]);
|
|
2903
3025
|
const { showKeyboardShortcuts, setShowKeyboardShortcuts, shortcuts } = useSpreadsheetKeyboardShortcuts({
|
|
2904
3026
|
onUndo: applyUndo,
|
|
2905
3027
|
onRedo: applyRedo,
|
|
2906
3028
|
onEscape: handleEscapeCallback,
|
|
3029
|
+
onNavigate: handleNavigate,
|
|
3030
|
+
onEnterEditMode: handleEnterEditMode,
|
|
3031
|
+
hasFocusedCell: focusedCell !== null,
|
|
3032
|
+
isEditing: editingCell !== null,
|
|
2907
3033
|
enabled: true
|
|
2908
3034
|
});
|
|
2909
3035
|
const effectiveShowRowIndex = spreadsheetSettings.showRowIndex !== false;
|
|
2910
3036
|
const rowIndexHighlightColor = getColumnHighlight(ROW_INDEX_COLUMN_ID);
|
|
2911
3037
|
const tableRef = (0, import_react14.useRef)(null);
|
|
2912
3038
|
const effectiveTotalItems = serverSide ? totalItems ?? data.length : filteredData.length;
|
|
2913
|
-
const paginatedData = (0, import_react14.useMemo)(() => {
|
|
2914
|
-
if (serverSide) {
|
|
2915
|
-
return filteredData;
|
|
2916
|
-
}
|
|
2917
|
-
const startIndex = (currentPage - 1) * pageSize;
|
|
2918
|
-
return filteredData.slice(startIndex, startIndex + pageSize);
|
|
2919
|
-
}, [filteredData, currentPage, pageSize, serverSide]);
|
|
2920
3039
|
const totalPages = Math.max(1, Math.ceil(effectiveTotalItems / pageSize));
|
|
2921
3040
|
(0, import_react14.useEffect)(() => {
|
|
2922
3041
|
if (!serverSide && currentPage > totalPages) {
|